From 12660f34fad91daa49b9d4d3494dd66f07e618f1 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 26 Oct 2022 16:37:00 +0100 Subject: [PATCH 001/147] Testing tweak. --- test/patch_path.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/patch_path.py b/test/patch_path.py index 8137bcd1..64868881 100644 --- a/test/patch_path.py +++ b/test/patch_path.py @@ -9,5 +9,8 @@ import pathlib PROJ_ROOT = pathlib.Path(__file__).parent.parent -if os.environ.get('TEST_QUESTDB_PATCH_PATH') == '1': +def patch(): sys.path.append(str(PROJ_ROOT / 'src')) + +if os.environ.get('TEST_QUESTDB_PATCH_PATH') == '1': + patch() \ No newline at end of file From 9e93993040076c70fce9a15ada080fc1b7a62654 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 26 Oct 2022 17:05:14 +0100 Subject: [PATCH 002/147] Updated to c-questdb-client 2.1.1 --- c-questdb-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c-questdb-client b/c-questdb-client index 473c21eb..2cd4e7fb 160000 --- a/c-questdb-client +++ b/c-questdb-client @@ -1 +1 @@ -Subproject commit 473c21ebc35b689a2e2a1cac0a1be1dfbdf7c4b6 +Subproject commit 2cd4e7fb3ad10b20a7de28527cdf18cf240b9634 From e56027c415a5709d211f3edffa1b2a583ef092d0 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 28 Oct 2022 23:01:19 +0100 Subject: [PATCH 003/147] Some progress.. --- src/questdb/ingress.pyx | 209 +++++++++++++++++++++++++++++++++++++--- test/test.py | 46 ++++++++- 2 files changed, 243 insertions(+), 12 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 06b364dd..ad42c66e 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -331,6 +331,16 @@ cdef class TimestampNanos: return self._value +def _check_is_pandas(data): + exp_mod = 'pandas.core.frame' + exp_name = 'DataFrame' + t = type(data) + if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): + raise TypeError( + f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + + f'not {t.__module__}.{t.__qualname__}.') + + cdef class Sender cdef class Buffer @@ -928,17 +938,194 @@ cdef class Buffer: # """ # raise ValueError('nyi') - # def pandas( - # self, - # table_name: str, - # data: pd.DataFrame, - # *, - # symbols: Union[bool, List[int]]=False, - # at: Union[None, TimestampNanos, datetime]=None): - # """ - # Add a pandas DataFrame to the buffer. - # """ - # raise ValueError('nyi') + cdef _pandas( + self, + object data, + object table_name, + object table_name_col, + object symbols, + object at): + # First, we need to make sure that `data` is a dataframe. + # We specifically avoid using `isinstance` here because we don't want + # to add a library dependency on pandas itself. We simply rely on its API. + # The only reason to validate here is to avoid obscure "AttributeError" + # exceptions later. + cdef int name_col + cdef object name_owner + cdef line_sender_table_name c_table_name + cdef list symbol_indices + cdef int at_col + cdef int64_t at_value + _check_is_pandas(data) + name_col, name_owner = _pandas_resolve_table_name( + data, table_name, table_name_col, &c_table_name) + symbol_indices = _pandas_resolve_symbols(data, symbols) + at_col, at_value = _pandas_resolve_at(data, at) + + def pandas( + self, + data, # : pd.DataFrame + *, + table_name: Optional[str] = None, + table_name_col: Union[None, int, str] = None, + symbols: Union[bool, List[int], List[str]] = False, + at: Union[None, int, str, TimestampNanos, datetime] = None): + """ + Add a pandas DataFrame to the buffer. + """ + # See https://cython.readthedocs.io/en/latest/src/userguide/ + # numpy_tutorial.html#numpy-tutorial + self._pandas(data, table_name, table_name_col, symbols, at) + + +cdef tuple _pandas_resolve_table_name( + object data, + object table_name, + object table_name_col, + line_sender_table_name* name_out): + """ + Return a tuple-pair of: + * int column index + * object + + If the column index is -1, then `name_out` is set and either the returned + object is None or a bytes object to track ownership of data in `name_out`. + + Alternatively, if the returned column index > 0, then `name_out` is not set + and the column index relates to which pandas column contains the table name + on a per-row basis. In such case, the object is always None. + + This method validates input and may raise. + """ + cdef int col_index + if table_name is not None: + if table_name_col is not None: + raise ValueError( + 'Can specify only one of `table_name` or `table_name_col`.') + if isinstance(table_name, str): + try: + return -1, str_to_table_name(table_name, name_out) + except IngressError as ie: + raise ValueError(f'Bad argument `table_name`: {ie}') + else: + raise TypeError(f'Bad argument `table_name`: Must be str.') + elif table_name_col is not None: + if isinstance(table_name_col, str): + col_index = data.columns.get_loc(table_name_col) + elif isinstance(table_name_col, int): + col_index = _bind_col_index(table_name_col, len(data.columns)) + else: + raise TypeError( + f'Bad argument `table_name_col`: ' + + 'must be a column name (str) or index (int).') + _check_column_is_str( + data, + col_index, + 'Bad argument `table_name_col`: ', + table_name_col) + return col_index, None + else: + raise ValueError( + 'Must specify at least one of `table_name` or `table_name_col`.') + + +cdef int _bind_col_index(int col_index, int col_count) except -1: + """ + Validate that `col_index` is in bounds for `col_count`. + This function also converts negative indicies (e.g. -1 for last column) to + positive indicies. + """ + if col_index < 0: + col_index += col_count # We convert negative indicies to positive ones. + if not (0 <= col_index < col_count): + raise ValueError(f'{col_index} index out of range') + return col_index + + +cdef object _column_is_str(object data, int col_index): + """ + Return True if the column at `col_index` is a string column. + """ + cdef str col_kind + cdef object[:] obj_col + col_kind = data.dtypes[col_index].kind + if col_kind == 'S': # string, string[pyarrow] + return True + elif col_kind == 'O': # object + for index in range(obj_col.shape[0]): + if not isinstance(obj_col[index], str): + return False + return True + else: + return False + + +cdef object _check_column_is_str(data, col_index, err_msg_prefix, col_name): + cdef str col_kind + cdef object[:] obj_col + col_kind = data.dtypes[col_index].kind + if col_kind in 'SO': + if not _column_is_str(data, col_index): + raise TypeError( + err_msg_prefix + + 'Found non-string value ' + + f'in column {col_name!r}.') + else: + raise TypeError( + err_msg_prefix + + f'Bad dtype `{data.dtypes[col_index]}` for the ' + + f'{col_name!r} column: Must be a strings column.') + + +cdef list _pandas_resolve_symbols(object data, list symbols): + """ + Return a list of column indices. + """ + cdef int col_index + cdef list symbol_indices = [] + if symbols is False: + return symbol_indices + elif symbols is True: + for col_index in range(len(data.columns)): + if _column_is_str(data, col_index): + symbol_indices.append(col_index) + return symbol_indices + else: + symbol_indices = [] + for symbol in symbols: + if isinstance(symbol, str): + col_index = data.columns.get_loc(symbol) + elif isinstance(symbol, int): + col_index = _bind_col_index(symbol, len(data.columns)) + else: + raise TypeError( + f'Bad argument `symbols`: ' + + 'must be a column name (str) or index (int).') + symbol_indices.append(col_index) + return symbol_indices + + +cdef tuple _pandas_resolve_at(object data, object at): + cdef int col_index + cdef str col_kind + if at is None: + return -1, 0 # Special value for `at_now`. + elif isinstance(at, TimestampNanos): + return -1, at._value + elif isinstance(at, datetime): + return -1, datetime_to_nanos(at) + elif isinstance(at, str): + col_index = data.columns.get_loc(at) + elif isinstance(at, int): + col_index = _bind_col_index(at, len(data.columns)) + else: + raise TypeError( + f'Bad argument `at`: Unsupported type {type(at)}. ' + + 'Must be one of: None, TimestampNanos, datetime, ' + + 'int (column index), str (colum name)') + col_kind = data.dtypes[col_index].kind + if col_kind == 'M': # datetime + return col_index, 0 _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' diff --git a/test/test.py b/test/test.py index 392839f0..d6ab921f 100755 --- a/test/test.py +++ b/test/test.py @@ -1,11 +1,14 @@ #!/usr/bin/env python3 import sys +from typing import Type sys.dont_write_bytecode = True import os import unittest import datetime import time +import numpy as np +import pandas as pd import patch_path from mock_server import Server @@ -139,7 +142,6 @@ def test_int_range(self): buf.row('tbl1', columns={'num': -2**63-1}) - class TestSender(unittest.TestCase): def test_basic(self): with Server() as server, qi.Sender('localhost', server.port) as sender: @@ -393,5 +395,47 @@ def test_bad_init_args(self): qi.Sender(host='localhost', port=9009, max_name_len=-1) +def _pandas(*args, **kwargs): + buf = qi.Buffer() + buf.pandas(*args, **kwargs) + return str(buf) + + +DF1 = pd.DataFrame({ + 'A': [1.0, 2.0, 3.0], + 'B': [1, 2, 3], + 'C': [ + pd.Timestamp('20180310'), + pd.Timestamp('20180311'), + pd.Timestamp('20180312')], + 'D': ['foo', 'bar', True]}) + + +class TestPandas(unittest.TestCase): + def test_bad_dataframe(self): + with self.assertRaisesRegex(TypeError, 'Expected pandas'): + _pandas([]) + + def test_no_table_name(self): + with self.assertRaisesRegex(ValueError, 'Must specify at least one of'): + _pandas(DF1) + + def test_bad_table_name_type(self): + with self.assertRaisesRegex(TypeError, 'Must be str'): + _pandas(DF1, table_name=1.5) + + def test_invalid_table_name(self): + with self.assertRaisesRegex(ValueError, '`table_name`: Bad string "."'): + _pandas(DF1, table_name='.') + + def test_invalid_column_dtype(self): + with self.assertRaisesRegex(TypeError, '`table_name_col`: Bad dtype'): + _pandas(DF1, table_name_col='B') + + def test_bad_str_obj_col(self): + with self.assertRaisesRegex(TypeError, 'Found non-string value'): + _pandas(DF1, table_name_col='D') + + if __name__ == '__main__': unittest.main() From d6920983bc03225351b95a1446fc071d8c196536 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 1 Nov 2022 10:51:13 +0000 Subject: [PATCH 004/147] Fixed broken check. --- src/questdb/ingress.pyx | 1 + test/test.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index aefba79b..a2185058 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1052,6 +1052,7 @@ cdef object _column_is_str(object data, int col_index): if col_kind == 'S': # string, string[pyarrow] return True elif col_kind == 'O': # object + obj_col = data.iloc[:, col_index].to_numpy() for index in range(obj_col.shape[0]): if not isinstance(obj_col[index], str): return False diff --git a/test/test.py b/test/test.py index d6ab921f..1a8ebd07 100755 --- a/test/test.py +++ b/test/test.py @@ -435,6 +435,10 @@ def test_invalid_column_dtype(self): def test_bad_str_obj_col(self): with self.assertRaisesRegex(TypeError, 'Found non-string value'): _pandas(DF1, table_name_col='D') + with self.assertRaisesRegex(TypeError, 'Found non-string value'): + _pandas(DF1, table_name_col=3) + with self.assertRaisesRegex(TypeError, 'Found non-string value'): + _pandas(DF1, table_name_col=-1) if __name__ == '__main__': From a92a858f139b837fc90bb16fcc34a40201f8e85a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 1 Nov 2022 11:28:59 +0000 Subject: [PATCH 005/147] symbols validation. --- src/questdb/ingress.pyx | 29 +++++++++++++++++++++-------- test/test.py | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index a2185058..80e88a36 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1013,7 +1013,8 @@ cdef tuple _pandas_resolve_table_name( if isinstance(table_name_col, str): col_index = data.columns.get_loc(table_name_col) elif isinstance(table_name_col, int): - col_index = _bind_col_index(table_name_col, len(data.columns)) + col_index = _bind_col_index( + 'table_name_col', table_name_col, len(data.columns)) else: raise TypeError( f'Bad argument `table_name_col`: ' + @@ -1029,16 +1030,18 @@ cdef tuple _pandas_resolve_table_name( 'Must specify at least one of `table_name` or `table_name_col`.') -cdef int _bind_col_index(int col_index, int col_count) except -1: +cdef int _bind_col_index(str arg_name, int col_index, int col_count) except -1: """ Validate that `col_index` is in bounds for `col_count`. This function also converts negative indicies (e.g. -1 for last column) to positive indicies. """ + cdef orig_col_index = col_index if col_index < 0: col_index += col_count # We convert negative indicies to positive ones. if not (0 <= col_index < col_count): - raise ValueError(f'{col_index} index out of range') + raise IndexError( + f'Bad argument `{arg_name}`: {orig_col_index} index out of range') return col_index @@ -1078,12 +1081,13 @@ cdef object _check_column_is_str(data, col_index, err_msg_prefix, col_name): f'{col_name!r} column: Must be a strings column.') -cdef list _pandas_resolve_symbols(object data, list symbols): +cdef list _pandas_resolve_symbols(object data, object symbols): """ Return a list of column indices. """ cdef int col_index cdef list symbol_indices = [] + cdef object symbol if symbols is False: return symbol_indices elif symbols is True: @@ -1092,16 +1096,25 @@ cdef list _pandas_resolve_symbols(object data, list symbols): symbol_indices.append(col_index) return symbol_indices else: + if not isinstance(symbols, (tuple, list)): + raise TypeError( + f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + 'of column names (str) or indices (int).') symbol_indices = [] for symbol in symbols: if isinstance(symbol, str): col_index = data.columns.get_loc(symbol) elif isinstance(symbol, int): - col_index = _bind_col_index(symbol, len(data.columns)) + col_index = _bind_col_index('symbol', symbol, len(data.columns)) else: raise TypeError( - f'Bad argument `symbols`: ' + - 'must be a column name (str) or index (int).') + f'Bad argument `symbols`: Elements must ' + + 'be a column name (str) or index (int).') + _check_column_is_str( + data, + col_index, + 'Bad element in argument `symbols`: ', + symbol) symbol_indices.append(col_index) return symbol_indices @@ -1118,7 +1131,7 @@ cdef tuple _pandas_resolve_at(object data, object at): elif isinstance(at, str): col_index = data.columns.get_loc(at) elif isinstance(at, int): - col_index = _bind_col_index(at, len(data.columns)) + col_index = _bind_col_index('at', at, len(data.columns)) else: raise TypeError( f'Bad argument `at`: Unsupported type {type(at)}. ' + diff --git a/test/test.py b/test/test.py index 1a8ebd07..97658c12 100755 --- a/test/test.py +++ b/test/test.py @@ -431,6 +431,12 @@ def test_invalid_table_name(self): def test_invalid_column_dtype(self): with self.assertRaisesRegex(TypeError, '`table_name_col`: Bad dtype'): _pandas(DF1, table_name_col='B') + with self.assertRaisesRegex(TypeError, '`table_name_col`: Bad dtype'): + _pandas(DF1, table_name_col=1) + with self.assertRaisesRegex(TypeError, '`table_name_col`: Bad dtype'): + _pandas(DF1, table_name_col=-3) + with self.assertRaisesRegex(IndexError, '`table_name_col`: -5 index'): + _pandas(DF1, table_name_col=-5) def test_bad_str_obj_col(self): with self.assertRaisesRegex(TypeError, 'Found non-string value'): @@ -440,6 +446,18 @@ def test_bad_str_obj_col(self): with self.assertRaisesRegex(TypeError, 'Found non-string value'): _pandas(DF1, table_name_col=-1) + def test_bad_symbol(self): + with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + _pandas(DF1, table_name='tbl1', symbols=0) + with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + _pandas(DF1, table_name='tbl1', symbols={}) + with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + _pandas(DF1, table_name='tbl1', symbols=None) + with self.assertRaisesRegex(TypeError, '.*element.*symbols.*float.*0'): + _pandas(DF1, table_name='tbl1', symbols=(0,)) + with self.assertRaisesRegex(TypeError, '.*element.*symbols.*int.*1'): + _pandas(DF1, table_name='tbl1', symbols=[1]) + if __name__ == '__main__': unittest.main() From bebbc8a504cb39e4f0ef6ccac0bd0ad51d671098 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 1 Nov 2022 14:53:37 +0000 Subject: [PATCH 006/147] Added repl command to proj script. --- proj.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proj.py b/proj.py index de09db79..88edfc78 100755 --- a/proj.py +++ b/proj.py @@ -112,6 +112,11 @@ def cibuildwheel(*args): *args) +@command +def repl(*args): + _run('python3', env={'PYTHONPATH': str(PROJ_ROOT / 'src')}) + + @command def cw(*args): cibuildwheel(args) From ab05dece0f27a99f12e57a30fbd6d9fc8d8c9f11 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 1 Nov 2022 14:54:12 +0000 Subject: [PATCH 007/147] Progress with pandas method input validation. --- src/questdb/ingress.pyx | 119 ++++++++++++++++++++++++++++++++++------ test/test.py | 10 ++++ 2 files changed, 113 insertions(+), 16 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 80e88a36..ad530cea 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -31,6 +31,7 @@ API for fast data ingestion into QuestDB. """ from libc.stdint cimport uint8_t, uint64_t, int64_t +from libc.stdlib cimport malloc, realloc, free, abort from cpython.datetime cimport datetime from cpython.bool cimport bool, PyBool_Check from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject @@ -77,6 +78,7 @@ cdef extern from "Python.h": char* PyBytes_AsString(object o) +import cython from enum import Enum from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable import pathlib @@ -331,7 +333,7 @@ cdef class TimestampNanos: return self._value -def _check_is_pandas(data): +cdef _check_is_pandas(data): exp_mod = 'pandas.core.frame' exp_name = 'DataFrame' t = type(data) @@ -950,17 +952,31 @@ cdef class Buffer: # to add a library dependency on pandas itself. We simply rely on its API. # The only reason to validate here is to avoid obscure "AttributeError" # exceptions later. + cdef int col_count cdef int name_col cdef object name_owner cdef line_sender_table_name c_table_name - cdef list symbol_indices + cdef IntVec symbol_indices + cdef IntVec field_indices cdef int at_col cdef int64_t at_value _check_is_pandas(data) + col_count = len(data.columns) name_col, name_owner = _pandas_resolve_table_name( - data, table_name, table_name_col, &c_table_name) - symbol_indices = _pandas_resolve_symbols(data, symbols) - at_col, at_value = _pandas_resolve_at(data, at) + data, table_name, table_name_col, col_count, &c_table_name) + symbol_indices = _pandas_resolve_symbols(data, symbols, col_count) + at_col, at_value = _pandas_resolve_at(data, at, col_count) + field_indices = _pandas_resolve_fields( + name_col, symbol_indices, at_col, col_count) + import sys + sys.stderr.write(f'_pandas :: (A) ' + + 'name_col: {name_col}, ' + + 'name_owner: {name_owner}, ' + + 'symbol_indices: {symbol_indices}' + + 'at_col: {at_col}, ' + + 'at_value: {at_value}, ' + + 'field_indices: {field_indices}' + + '\n') def pandas( self, @@ -978,10 +994,38 @@ cdef class Buffer: self._pandas(data, table_name, table_name_col, symbols, at) +@cython.internal +cdef class IntVec: + cdef int capacity + cdef int size + cdef int* ptr + + def __cinit__(self): + self.capacity = 8 + self.size = 0 + self.ptr = malloc(self.capacity * sizeof(int)) + if not self.ptr: + abort() + + def __dealloc__(self): + if self.ptr != NULL: + free(self.ptr) + + cdef void append(self, int value): + if self.size == self.capacity: + self.capacity = self.capacity * 2 + self.ptr = realloc(self.ptr, self.capacity * sizeof(int)) + if not self.ptr: + abort() + self.ptr[self.size] = value + self.size += 1 + + cdef tuple _pandas_resolve_table_name( object data, object table_name, object table_name_col, + int col_count, line_sender_table_name* name_out): """ Return a tuple-pair of: @@ -1011,10 +1055,10 @@ cdef tuple _pandas_resolve_table_name( raise TypeError(f'Bad argument `table_name`: Must be str.') elif table_name_col is not None: if isinstance(table_name_col, str): - col_index = data.columns.get_loc(table_name_col) + col_index = _pandas_get_loc(data, table_name_col, 'table_name_col') elif isinstance(table_name_col, int): col_index = _bind_col_index( - 'table_name_col', table_name_col, len(data.columns)) + 'table_name_col', table_name_col, col_count) else: raise TypeError( f'Bad argument `table_name_col`: ' + @@ -1030,6 +1074,32 @@ cdef tuple _pandas_resolve_table_name( 'Must specify at least one of `table_name` or `table_name_col`.') +cdef IntVec _pandas_resolve_fields( + int name_col, IntVec symbol_indices, int at_col, int col_count): + """ + Return a list of field column indices. + i.e. a list of all columns which are not the table name column, symbols or + the at timestamp column. + """ + # We rely on `symbol_indices` being sorted. + cdef int col_index = 0 + cdef int sym_index = 0 + cdef int sym_len = symbol_indices.size + cdef IntVec res = IntVec() + while col_index < col_count: + if col_index == name_col or col_index == at_col: + col_index += 1 + continue + while sym_index < sym_len and symbol_indices.ptr[sym_index] < col_index: + sym_index += 1 + if sym_index < sym_len and symbol_indices.ptr[sym_index] == col_index: + col_index += 1 + continue + res.append(col_index) + col_index += 1 + return res + + cdef int _bind_col_index(str arg_name, int col_index, int col_count) except -1: """ Validate that `col_index` is in bounds for `col_count`. @@ -1081,17 +1151,17 @@ cdef object _check_column_is_str(data, col_index, err_msg_prefix, col_name): f'{col_name!r} column: Must be a strings column.') -cdef list _pandas_resolve_symbols(object data, object symbols): +cdef IntVec _pandas_resolve_symbols(object data, object symbols, int col_count): """ Return a list of column indices. """ cdef int col_index - cdef list symbol_indices = [] + cdef IntVec symbol_indices = IntVec() cdef object symbol if symbols is False: return symbol_indices elif symbols is True: - for col_index in range(len(data.columns)): + for col_index in range(col_count): if _column_is_str(data, col_index): symbol_indices.append(col_index) return symbol_indices @@ -1100,12 +1170,11 @@ cdef list _pandas_resolve_symbols(object data, object symbols): raise TypeError( f'Bad argument `symbols`: Must be a bool or a tuple or list '+ 'of column names (str) or indices (int).') - symbol_indices = [] for symbol in symbols: if isinstance(symbol, str): - col_index = data.columns.get_loc(symbol) + col_index = _pandas_get_loc(data, symbol, 'symbols') elif isinstance(symbol, int): - col_index = _bind_col_index('symbol', symbol, len(data.columns)) + col_index = _bind_col_index('symbol', symbol, col_count) else: raise TypeError( f'Bad argument `symbols`: Elements must ' + @@ -1119,7 +1188,21 @@ cdef list _pandas_resolve_symbols(object data, object symbols): return symbol_indices -cdef tuple _pandas_resolve_at(object data, object at): +cdef int _pandas_get_loc(object data, str col_name, str arg_name) except -1: + """ + Return the column index for `col_name`. + """ + cdef int col_index + try: + col_index = data.columns.get_loc(col_name) + except KeyError: + raise KeyError( + f'Bad argument `{arg_name}`: ' + + f'Column {col_name!r} not found in the dataframe.') + return col_index + + +cdef tuple _pandas_resolve_at(object data, object at, int col_count): cdef int col_index cdef str col_kind if at is None: @@ -1129,9 +1212,9 @@ cdef tuple _pandas_resolve_at(object data, object at): elif isinstance(at, datetime): return -1, datetime_to_nanos(at) elif isinstance(at, str): - col_index = data.columns.get_loc(at) + col_index = _pandas_get_loc(data, at, 'at') elif isinstance(at, int): - col_index = _bind_col_index('at', at, len(data.columns)) + col_index = _bind_col_index('at', at, col_count) else: raise TypeError( f'Bad argument `at`: Unsupported type {type(at)}. ' + @@ -1140,6 +1223,10 @@ cdef tuple _pandas_resolve_at(object data, object at): col_kind = data.dtypes[col_index].kind if col_kind == 'M': # datetime return col_index, 0 + else: + raise TypeError( + f'Bad argument `at`: Bad dtype `{data.dtypes[col_index]}` ' + + f'for the {at!r} column: Must be a datetime column.') _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' diff --git a/test/test.py b/test/test.py index 97658c12..66dc3040 100755 --- a/test/test.py +++ b/test/test.py @@ -458,6 +458,16 @@ def test_bad_symbol(self): with self.assertRaisesRegex(TypeError, '.*element.*symbols.*int.*1'): _pandas(DF1, table_name='tbl1', symbols=[1]) + def test_bad_at(self): + with self.assertRaisesRegex(KeyError, '`at`.*2018.*not found in the'): + _pandas(DF1, table_name='tbl1', at='2018-03-10T00:00:00Z') + with self.assertRaisesRegex(TypeError, '`at`.*float64.*be a datetime'): + _pandas(DF1, table_name='tbl1', at='A') + with self.assertRaisesRegex(TypeError, '`at`.*int64.*be a datetime'): + _pandas(DF1, table_name='tbl1', at=1) + with self.assertRaisesRegex(TypeError, '`at`.*object.*be a datetime'): + _pandas(DF1, table_name='tbl1', at=-1) + if __name__ == '__main__': unittest.main() From dc65b2cb88d4985c35df8d620e49d1068f923def Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 1 Nov 2022 16:19:06 +0000 Subject: [PATCH 008/147] Moved Python IntVec to C int_vec. --- src/questdb/ingress.pyx | 175 +++++++++++++++++++++++----------------- test/test.py | 13 +++ 2 files changed, 112 insertions(+), 76 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index ad530cea..9e40c5ef 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -953,30 +953,38 @@ cdef class Buffer: # The only reason to validate here is to avoid obscure "AttributeError" # exceptions later. cdef int col_count + cdef int row_count cdef int name_col cdef object name_owner cdef line_sender_table_name c_table_name - cdef IntVec symbol_indices - cdef IntVec field_indices + cdef int_vec symbol_indices = int_vec_new() + cdef int_vec field_indices = int_vec_new() cdef int at_col cdef int64_t at_value - _check_is_pandas(data) - col_count = len(data.columns) - name_col, name_owner = _pandas_resolve_table_name( - data, table_name, table_name_col, col_count, &c_table_name) - symbol_indices = _pandas_resolve_symbols(data, symbols, col_count) - at_col, at_value = _pandas_resolve_at(data, at, col_count) - field_indices = _pandas_resolve_fields( - name_col, symbol_indices, at_col, col_count) - import sys - sys.stderr.write(f'_pandas :: (A) ' + - 'name_col: {name_col}, ' + - 'name_owner: {name_owner}, ' + - 'symbol_indices: {symbol_indices}' + - 'at_col: {at_col}, ' + - 'at_value: {at_value}, ' + - 'field_indices: {field_indices}' + - '\n') + cdef int row_index + try: + _check_is_pandas(data) + col_count = len(data.columns) + name_col, name_owner = _pandas_resolve_table_name( + data, table_name, table_name_col, col_count, &c_table_name) + symbol_indices = _pandas_resolve_symbols(data, symbols, col_count) + at_col, at_value = _pandas_resolve_at(data, at, col_count) + field_indices = _pandas_resolve_fields( + name_col, &symbol_indices, at_col, col_count) + import sys + sys.stderr.write('_pandas :: (A) ' + + f'name_col: {name_col}, ' + + f'name_owner: {name_owner}, ' + + f'symbol_indices: {int_vec_str(&symbol_indices)}, ' + + f'at_col: {at_col}, ' + + f'at_value: {at_value}, ' + + f'field_indices: {int_vec_str(&field_indices)}' + + '\n') + row_count = len(data) + finally: + int_vec_free(&field_indices) + int_vec_free(&symbol_indices) + def pandas( self, @@ -994,31 +1002,41 @@ cdef class Buffer: self._pandas(data, table_name, table_name_col, symbols, at) -@cython.internal -cdef class IntVec: - cdef int capacity - cdef int size - cdef int* ptr +cdef struct c_int_vec: + size_t capacity + size_t size + int* d - def __cinit__(self): - self.capacity = 8 - self.size = 0 - self.ptr = malloc(self.capacity * sizeof(int)) - if not self.ptr: - abort() +ctypedef c_int_vec int_vec - def __dealloc__(self): - if self.ptr != NULL: - free(self.ptr) +cdef int_vec int_vec_new(): + cdef int_vec vec + vec.capacity = 0 + vec.size = 0 + vec.d = NULL + return vec + +cdef void int_vec_free(int_vec* vec): + if vec.d: + free(vec.d) + vec.d = NULL - cdef void append(self, int value): - if self.size == self.capacity: - self.capacity = self.capacity * 2 - self.ptr = realloc(self.ptr, self.capacity * sizeof(int)) - if not self.ptr: - abort() - self.ptr[self.size] = value - self.size += 1 +cdef str int_vec_str(int_vec* vec): + return 'int_vec' + str([vec.d[i] for i in range(vec.size)]) + +cdef void int_vec_push(int_vec* vec, int value): + if vec.capacity == 0: + vec.capacity = 8 + vec.d = malloc(vec.capacity * sizeof(int)) + if vec.d == NULL: + abort() + elif vec.size == vec.capacity: + vec.capacity = vec.capacity * 2 + vec.d = realloc(vec.d, vec.capacity * sizeof(int)) + if not vec.d: + abort() + vec.d[vec.size] = value + vec.size += 1 cdef tuple _pandas_resolve_table_name( @@ -1074,8 +1092,8 @@ cdef tuple _pandas_resolve_table_name( 'Must specify at least one of `table_name` or `table_name_col`.') -cdef IntVec _pandas_resolve_fields( - int name_col, IntVec symbol_indices, int at_col, int col_count): +cdef int_vec _pandas_resolve_fields( + int name_col, const int_vec* symbol_indices, int at_col, int col_count): """ Return a list of field column indices. i.e. a list of all columns which are not the table name column, symbols or @@ -1085,17 +1103,17 @@ cdef IntVec _pandas_resolve_fields( cdef int col_index = 0 cdef int sym_index = 0 cdef int sym_len = symbol_indices.size - cdef IntVec res = IntVec() + cdef int_vec res = int_vec_new() while col_index < col_count: if col_index == name_col or col_index == at_col: col_index += 1 continue - while sym_index < sym_len and symbol_indices.ptr[sym_index] < col_index: + while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: sym_index += 1 - if sym_index < sym_len and symbol_indices.ptr[sym_index] == col_index: + if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: col_index += 1 continue - res.append(col_index) + int_vec_push(&res, col_index) col_index += 1 return res @@ -1151,41 +1169,46 @@ cdef object _check_column_is_str(data, col_index, err_msg_prefix, col_name): f'{col_name!r} column: Must be a strings column.') -cdef IntVec _pandas_resolve_symbols(object data, object symbols, int col_count): +cdef int_vec _pandas_resolve_symbols( + object data, object symbols, int col_count): """ Return a list of column indices. """ cdef int col_index - cdef IntVec symbol_indices = IntVec() + cdef int_vec symbol_indices = int_vec_new() cdef object symbol - if symbols is False: - return symbol_indices - elif symbols is True: - for col_index in range(col_count): - if _column_is_str(data, col_index): - symbol_indices.append(col_index) - return symbol_indices - else: - if not isinstance(symbols, (tuple, list)): - raise TypeError( - f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - 'of column names (str) or indices (int).') - for symbol in symbols: - if isinstance(symbol, str): - col_index = _pandas_get_loc(data, symbol, 'symbols') - elif isinstance(symbol, int): - col_index = _bind_col_index('symbol', symbol, col_count) - else: + try: + if symbols is False: + return symbol_indices + elif symbols is True: + for col_index in range(col_count): + if _column_is_str(data, col_index): + int_vec_push(&symbol_indices, col_index) + return symbol_indices + else: + if not isinstance(symbols, (tuple, list)): raise TypeError( - f'Bad argument `symbols`: Elements must ' + - 'be a column name (str) or index (int).') - _check_column_is_str( - data, - col_index, - 'Bad element in argument `symbols`: ', - symbol) - symbol_indices.append(col_index) - return symbol_indices + f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + 'of column names (str) or indices (int).') + for symbol in symbols: + if isinstance(symbol, str): + col_index = _pandas_get_loc(data, symbol, 'symbols') + elif isinstance(symbol, int): + col_index = _bind_col_index('symbol', symbol, col_count) + else: + raise TypeError( + f'Bad argument `symbols`: Elements must ' + + 'be a column name (str) or index (int).') + _check_column_is_str( + data, + col_index, + 'Bad element in argument `symbols`: ', + symbol) + int_vec_push(&symbol_indices, col_index) + return symbol_indices + except: + int_vec_free(&symbol_indices) + raise cdef int _pandas_get_loc(object data, str col_name, str arg_name) except -1: diff --git a/test/test.py b/test/test.py index 66dc3040..4d5abf7d 100755 --- a/test/test.py +++ b/test/test.py @@ -411,6 +411,16 @@ def _pandas(*args, **kwargs): 'D': ['foo', 'bar', True]}) +DF2 = pd.DataFrame({ + 'T': ['t1', 't2', 't1'], + 'A': [1.0, 2.0, 3.0], + 'B': [1, 2, 3], + 'C': [ + pd.Timestamp('20180310'), + pd.Timestamp('20180311'), + pd.Timestamp('20180312')]}) + + class TestPandas(unittest.TestCase): def test_bad_dataframe(self): with self.assertRaisesRegex(TypeError, 'Expected pandas'): @@ -467,6 +477,9 @@ def test_bad_at(self): _pandas(DF1, table_name='tbl1', at=1) with self.assertRaisesRegex(TypeError, '`at`.*object.*be a datetime'): _pandas(DF1, table_name='tbl1', at=-1) + + def test_basic(self): + _pandas(DF2, table_name_col=0, symbols=[0], at=-1) if __name__ == '__main__': From a46490ad4f17eec9816289d41ce259d3d8905367 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 2 Nov 2022 15:12:48 +0000 Subject: [PATCH 009/147] More code to avoid python lists. --- src/questdb/ingress.pyx | 153 +++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 43 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 9e40c5ef..dd16bc92 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -962,15 +962,22 @@ cdef class Buffer: cdef int at_col cdef int64_t at_value cdef int row_index + cdef column_name_vec symbol_names = column_name_vec_new() + cdef column_name_vec field_names = column_name_vec_new() + cdef list name_owners try: _check_is_pandas(data) col_count = len(data.columns) name_col, name_owner = _pandas_resolve_table_name( data, table_name, table_name_col, col_count, &c_table_name) - symbol_indices = _pandas_resolve_symbols(data, symbols, col_count) + _pandas_resolve_symbols( + data, symbols, col_count, &symbol_indices) at_col, at_value = _pandas_resolve_at(data, at, col_count) - field_indices = _pandas_resolve_fields( - name_col, &symbol_indices, at_col, col_count) + _pandas_resolve_fields( + name_col, &symbol_indices, at_col, col_count, &field_indices) + name_owners = _pandas_resolve_col_names( + data, &symbol_indices, &field_indices, + &symbol_names, &field_names) import sys sys.stderr.write('_pandas :: (A) ' + f'name_col: {name_col}, ' + @@ -982,10 +989,11 @@ cdef class Buffer: '\n') row_count = len(data) finally: + column_name_vec_free(&field_names) + column_name_vec_free(&symbol_names) int_vec_free(&field_indices) int_vec_free(&symbol_indices) - def pandas( self, data, # : pd.DataFrame @@ -1039,6 +1047,44 @@ cdef void int_vec_push(int_vec* vec, int value): vec.size += 1 +cdef struct c_column_name_vec: + size_t capacity + size_t size + line_sender_column_name* d + +ctypedef c_column_name_vec column_name_vec + +cdef column_name_vec column_name_vec_new(): + cdef column_name_vec vec + vec.capacity = 0 + vec.size = 0 + vec.d = NULL + return vec + +cdef void column_name_vec_free(column_name_vec* vec): + if vec.d: + free(vec.d) + vec.d = NULL + +cdef void column_name_vec_push( + column_name_vec* vec, line_sender_column_name value): + if vec.capacity == 0: + vec.capacity = 8 + vec.d = malloc( + vec.capacity * sizeof(line_sender_column_name)) + if vec.d == NULL: + abort() + elif vec.size == vec.capacity: + vec.capacity = vec.capacity * 2 + vec.d = realloc( + vec.d, + vec.capacity * sizeof(line_sender_column_name)) + if not vec.d: + abort() + vec.d[vec.size] = value + vec.size += 1 + + cdef tuple _pandas_resolve_table_name( object data, object table_name, @@ -1092,8 +1138,12 @@ cdef tuple _pandas_resolve_table_name( 'Must specify at least one of `table_name` or `table_name_col`.') -cdef int_vec _pandas_resolve_fields( - int name_col, const int_vec* symbol_indices, int at_col, int col_count): +cdef int _pandas_resolve_fields( + int name_col, + const int_vec* symbol_indices, + int at_col, + int col_count, + int_vec* field_indices_out) except -1: """ Return a list of field column indices. i.e. a list of all columns which are not the table name column, symbols or @@ -1103,7 +1153,6 @@ cdef int_vec _pandas_resolve_fields( cdef int col_index = 0 cdef int sym_index = 0 cdef int sym_len = symbol_indices.size - cdef int_vec res = int_vec_new() while col_index < col_count: if col_index == name_col or col_index == at_col: col_index += 1 @@ -1113,9 +1162,29 @@ cdef int_vec _pandas_resolve_fields( if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: col_index += 1 continue - int_vec_push(&res, col_index) + int_vec_push(field_indices_out, col_index) col_index += 1 - return res + return 0 + + +cdef list _pandas_resolve_col_names( + object data, + const int_vec* symbol_indices, + const int_vec* field_indices, + column_name_vec* symbol_names_out, + column_name_vec* field_names_out): + cdef list name_owners = [] + cdef line_sender_column_name c_name + cdef int col_index + for col_index in range(symbol_indices.size): + col_index = symbol_indices.d[col_index] + name_owners.append(str_to_column_name(data.columns[col_index], &c_name)) + column_name_vec_push(symbol_names_out, c_name) + for col_index in range(field_indices.size): + col_index = field_indices.d[col_index] + name_owners.append(str_to_column_name(data.columns[col_index], &c_name)) + column_name_vec_push(field_names_out, c_name) + return name_owners cdef int _bind_col_index(str arg_name, int col_index, int col_count) except -1: @@ -1169,46 +1238,44 @@ cdef object _check_column_is_str(data, col_index, err_msg_prefix, col_name): f'{col_name!r} column: Must be a strings column.') -cdef int_vec _pandas_resolve_symbols( - object data, object symbols, int col_count): +cdef int _pandas_resolve_symbols( + object data, + object symbols, + int col_count, + int_vec* symbol_indices_out) except -1: """ Return a list of column indices. """ cdef int col_index - cdef int_vec symbol_indices = int_vec_new() cdef object symbol - try: - if symbols is False: - return symbol_indices - elif symbols is True: - for col_index in range(col_count): - if _column_is_str(data, col_index): - int_vec_push(&symbol_indices, col_index) - return symbol_indices - else: - if not isinstance(symbols, (tuple, list)): + if symbols is False: + return 0 + elif symbols is True: + for col_index in range(col_count): + if _column_is_str(data, col_index): + int_vec_push(symbol_indices_out, col_index) + return 0 + else: + if not isinstance(symbols, (tuple, list)): + raise TypeError( + f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + 'of column names (str) or indices (int).') + for symbol in symbols: + if isinstance(symbol, str): + col_index = _pandas_get_loc(data, symbol, 'symbols') + elif isinstance(symbol, int): + col_index = _bind_col_index('symbol', symbol, col_count) + else: raise TypeError( - f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - 'of column names (str) or indices (int).') - for symbol in symbols: - if isinstance(symbol, str): - col_index = _pandas_get_loc(data, symbol, 'symbols') - elif isinstance(symbol, int): - col_index = _bind_col_index('symbol', symbol, col_count) - else: - raise TypeError( - f'Bad argument `symbols`: Elements must ' + - 'be a column name (str) or index (int).') - _check_column_is_str( - data, - col_index, - 'Bad element in argument `symbols`: ', - symbol) - int_vec_push(&symbol_indices, col_index) - return symbol_indices - except: - int_vec_free(&symbol_indices) - raise + f'Bad argument `symbols`: Elements must ' + + 'be a column name (str) or index (int).') + _check_column_is_str( + data, + col_index, + 'Bad element in argument `symbols`: ', + symbol) + int_vec_push(symbol_indices_out, col_index) + return 0 cdef int _pandas_get_loc(object data, str col_name, str arg_name) except -1: From 737f970c49fd99fe3b358d68efcd33b30059f34d Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 2 Nov 2022 16:03:36 +0000 Subject: [PATCH 010/147] CI fixup. --- ci/cibuildwheel.yaml | 7 +++++++ ci/run_tests_pipeline.yaml | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ci/cibuildwheel.yaml b/ci/cibuildwheel.yaml index 1f612720..cf0bb883 100644 --- a/ci/cibuildwheel.yaml +++ b/ci/cibuildwheel.yaml @@ -69,6 +69,7 @@ stages: set -o errexit python3 -m pip install --upgrade pip pip3 install cibuildwheel==2.11.1 + pip3 install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -84,6 +85,7 @@ stages: set -o errexit python3 -m pip install --upgrade pip pip3 install cibuildwheel==2.11.1 + pip3 install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -101,6 +103,7 @@ stages: set -o errexit python3 -m pip install --upgrade pip pip3 install cibuildwheel==2.11.1 + pip3 install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -118,6 +121,7 @@ stages: set -o errexit python3 -m pip install --upgrade pip pip3 install cibuildwheel==2.11.1 + pip3 install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -135,6 +139,7 @@ stages: set -o errexit python3 -m pip install --upgrade pip pip3 install cibuildwheel==2.11.1 + pip3 install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -152,6 +157,7 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.1 + pip3 install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -167,6 +173,7 @@ stages: set -o errexit python -m pip install --upgrade pip pip install cibuildwheel==2.11.1 + pip3 install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels diff --git a/ci/run_tests_pipeline.yaml b/ci/run_tests_pipeline.yaml index 78834b50..ed5df7e2 100644 --- a/ci/run_tests_pipeline.yaml +++ b/ci/run_tests_pipeline.yaml @@ -28,7 +28,9 @@ stages: submodules: true - task: UsePythonVersion@0 - script: python3 --version - - script: python3 -m pip install cython + - script: | + python3 -m pip install cython + python3 -m pip install pandas displayName: Installing Python dependencies - script: python3 proj.py build displayName: "Build" From d574486826b7158a2cb535cd42652ad561a16609 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 2 Nov 2022 16:28:49 +0000 Subject: [PATCH 011/147] CI fixup 2. --- ci/cibuildwheel.yaml | 35 +++++++++++++++++++++-------------- ci/run_tests_pipeline.yaml | 1 + 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ci/cibuildwheel.yaml b/ci/cibuildwheel.yaml index cf0bb883..3645078a 100644 --- a/ci/cibuildwheel.yaml +++ b/ci/cibuildwheel.yaml @@ -68,8 +68,9 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - pip3 install cibuildwheel==2.11.1 - pip3 install pandas + python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install numpy + python3 -m pip install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -84,8 +85,9 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - pip3 install cibuildwheel==2.11.1 - pip3 install pandas + python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install numpy + python3 -m pip install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -102,8 +104,9 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - pip3 install cibuildwheel==2.11.1 - pip3 install pandas + python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install numpy + python3 -m pip install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -120,8 +123,9 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - pip3 install cibuildwheel==2.11.1 - pip3 install pandas + python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install numpy + python3 -m pip install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -138,8 +142,9 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - pip3 install cibuildwheel==2.11.1 - pip3 install pandas + python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install numpy + python3 -m pip install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -157,7 +162,8 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.1 - pip3 install pandas + python3 -m pip install numpy + python3 -m pip install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -171,9 +177,10 @@ stages: - task: UsePythonVersion@0 - bash: | set -o errexit - python -m pip install --upgrade pip - pip install cibuildwheel==2.11.1 - pip3 install pandas + python3 -m pip install --upgrade pip + python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install numpy + python3 -m pip install pandas displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels diff --git a/ci/run_tests_pipeline.yaml b/ci/run_tests_pipeline.yaml index ed5df7e2..924d238a 100644 --- a/ci/run_tests_pipeline.yaml +++ b/ci/run_tests_pipeline.yaml @@ -30,6 +30,7 @@ stages: - script: python3 --version - script: | python3 -m pip install cython + python3 -m pip install numpy python3 -m pip install pandas displayName: Installing Python dependencies - script: python3 proj.py build From b1c17b0489036f12d3d30d86e25ace568f0c01bf Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 2 Nov 2022 17:16:52 +0000 Subject: [PATCH 012/147] CI fixup 3. --- pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e01713a6..4a8e0d8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,9 @@ requires = [ # Setuptools 18.0 and above properly handles Cython extensions. "setuptools>=45.2.0", "wheel>=0.34.2", - "cython>=0.29.24"] + "cython>=0.29.24", + "pandas>=1.5.1", + "numpy>=1.23.4"] [tool.cibuildwheel] From fc9905467ffcb0cc3b566d99df97ff2a39fb5098 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 2 Nov 2022 18:02:33 +0000 Subject: [PATCH 013/147] CI fixup 4. --- ci/cibuildwheel.yaml | 14 +++++++------- dev_requirements.txt | 4 +++- pyproject.toml | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ci/cibuildwheel.yaml b/ci/cibuildwheel.yaml index 3645078a..f9662e0f 100644 --- a/ci/cibuildwheel.yaml +++ b/ci/cibuildwheel.yaml @@ -68,7 +68,7 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas displayName: Install dependencies @@ -85,7 +85,7 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas displayName: Install dependencies @@ -104,7 +104,7 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas displayName: Install dependencies @@ -123,7 +123,7 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas displayName: Install dependencies @@ -142,7 +142,7 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas displayName: Install dependencies @@ -161,7 +161,7 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas displayName: Install dependencies @@ -178,7 +178,7 @@ stages: - bash: | set -o errexit python3 -m pip install --upgrade pip - python3 -m pip install cibuildwheel==2.11.1 + python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas displayName: Install dependencies diff --git a/dev_requirements.txt b/dev_requirements.txt index a5e835a7..097910ca 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,8 +1,10 @@ setuptools>=45.2.0 Cython>=0.29.32 wheel>=0.34.2 -cibuildwheel>=2.11.1 +cibuildwheel>=2.11.2 Sphinx>=5.0.2 sphinx-rtd-theme>=1.0.0 twine>=4.0.1 bump2version>=1.0.1 +pandas>=1.3.5 +numpy>=1.21.6 \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 4a8e0d8b..1e9b705b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,8 +45,8 @@ requires = [ "setuptools>=45.2.0", "wheel>=0.34.2", "cython>=0.29.24", - "pandas>=1.5.1", - "numpy>=1.23.4"] + "pandas>=1.3.5", + "numpy>=1.21.6"] [tool.cibuildwheel] From 365493802e8ee1217655a6925e395a90b06cbc9e Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 2 Nov 2022 18:34:26 +0000 Subject: [PATCH 014/147] CI fixup 5. --- pyproject.toml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1e9b705b..1903d979 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,15 +44,17 @@ requires = [ # Setuptools 18.0 and above properly handles Cython extensions. "setuptools>=45.2.0", "wheel>=0.34.2", - "cython>=0.29.24", - "pandas>=1.3.5", - "numpy>=1.21.6"] + "cython>=0.29.24"] [tool.cibuildwheel] # See: https://cibuildwheel.readthedocs.io/en/stable/options/#configuration-file build-verbosity = "3" before-build = "python {project}/install_rust.py" +before-test = """ + python -m pip install numpy>=1.21.6 + python -m pip install pandas>=1.3.5 + """ test-command = "python {project}/test/test.py -v" skip = [ # No 32-bit musl C native tool chain for Rust. From 7102dddb428a827d63a5c402f3e391fed1a600dd Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 4 Nov 2022 14:03:17 +0000 Subject: [PATCH 015/147] Types and buffers. --- src/questdb/ingress.pyx | 159 ++++++++++++++++++++++++++++++++++------ test/test.py | 2 +- 2 files changed, 138 insertions(+), 23 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index dd16bc92..667c33e4 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -30,8 +30,9 @@ API for fast data ingestion into QuestDB. """ +# For prototypes: https://github.com/cython/cython/tree/master/Cython/Includes from libc.stdint cimport uint8_t, uint64_t, int64_t -from libc.stdlib cimport malloc, realloc, free, abort +from libc.stdlib cimport malloc, calloc, realloc, free, abort from cpython.datetime cimport datetime from cpython.bool cimport bool, PyBool_Check from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject @@ -39,6 +40,7 @@ from cpython.object cimport PyObject from cpython.float cimport PyFloat_Check from cpython.int cimport PyInt_Check from cpython.unicode cimport PyUnicode_Check +from cpython.buffer cimport Py_buffer, PyObject_GetBuffer, PyBuffer_Release from .line_sender cimport * @@ -333,7 +335,7 @@ cdef class TimestampNanos: return self._value -cdef _check_is_pandas(data): +cdef _check_is_pandas_dataframe(data): exp_mod = 'pandas.core.frame' exp_name = 'DataFrame' t = type(data) @@ -946,7 +948,8 @@ cdef class Buffer: object table_name, object table_name_col, object symbols, - object at): + object at, + bint sort): # First, we need to make sure that `data` is a dataframe. # We specifically avoid using `isinstance` here because we don't want # to add a library dependency on pandas itself. We simply rely on its API. @@ -961,12 +964,15 @@ cdef class Buffer: cdef int_vec field_indices = int_vec_new() cdef int at_col cdef int64_t at_value - cdef int row_index cdef column_name_vec symbol_names = column_name_vec_new() cdef column_name_vec field_names = column_name_vec_new() - cdef list name_owners + cdef list name_owners = None + cdef int row_index + cdef dtype_t* dtypes = NULL + cdef Py_buffer** col_buffers = NULL + cdef int col_index try: - _check_is_pandas(data) + _check_is_pandas_dataframe(data) col_count = len(data.columns) name_col, name_owner = _pandas_resolve_table_name( data, table_name, table_name_col, col_count, &c_table_name) @@ -978,6 +984,10 @@ cdef class Buffer: name_owners = _pandas_resolve_col_names( data, &symbol_indices, &field_indices, &symbol_names, &field_names) + dtypes = calloc(col_count, sizeof(dtype_t)) + _pandas_resolve_dtypes(data, col_count, dtypes) + col_buffers = calloc(col_count, sizeof(Py_buffer*)) + _pandas_resolve_col_buffers(data, col_count, dtypes, col_buffers) import sys sys.stderr.write('_pandas :: (A) ' + f'name_col: {name_col}, ' + @@ -988,7 +998,21 @@ cdef class Buffer: f'field_indices: {int_vec_str(&field_indices)}' + '\n') row_count = len(data) + # for row_index in range(row_count): + # if name_col > -1: + # data.iloc[:, name_col] + # else: + # if not line_sender_buffer_table(self._impl, c_table_name, &err): + # raise c_err_to_py(err) finally: + if col_buffers != NULL: + for col_index in range(col_count): + if col_buffers[col_index] != NULL: + PyBuffer_Release(col_buffers[col_index]) + free(col_buffers) + free(dtypes) + if name_owners: # no-op to avoid "unused variable" warning + pass column_name_vec_free(&field_names) column_name_vec_free(&symbol_names) int_vec_free(&field_indices) @@ -1001,13 +1025,14 @@ cdef class Buffer: table_name: Optional[str] = None, table_name_col: Union[None, int, str] = None, symbols: Union[bool, List[int], List[str]] = False, - at: Union[None, int, str, TimestampNanos, datetime] = None): + at: Union[None, int, str, TimestampNanos, datetime] = None, + sort: bool = True): """ Add a pandas DataFrame to the buffer. """ # See https://cython.readthedocs.io/en/latest/src/userguide/ # numpy_tutorial.html#numpy-tutorial - self._pandas(data, table_name, table_name_col, symbols, at) + self._pandas(data, table_name, table_name_col, symbols, at, sort) cdef struct c_int_vec: @@ -1085,6 +1110,34 @@ cdef void column_name_vec_push( vec.size += 1 +cdef enum col_type_t: + COL_TYPE_INT = 0 + COL_TYPE_FLOAT = 1 + COL_TYPE_STRING = 2 + COL_TYPE_BOOL = 3 + COL_TYPE_DATE = 4 + COL_TYPE_TIME = 5 + COL_TYPE_DATETIME = 6 + COL_TYPE_BLOB = 7 + COL_TYPE_NULL = 8 + +# Inspired by a Py_buffer. +# See: https://docs.python.org/3/c-api/buffer.html +# This is simpler as we discard Python-specifics and it's one-dimensional only, +# i.e. `ndim` is always 1. +# If this stuff makes no sense to you: +# http://jakevdp.github.io/blog/2014/05/05/introduction-to-the-python-buffer-protocol/ +# and https://www.youtube.com/watch?v=10smLBD0kXg +cdef struct column_buf_t: + col_type_t dtype # internal enum value of supported pandas type. + void* d # start of the buffer (pointer to element 0) + ssize_t nbytes # size of the buffer in bytes + ssize_t count # number of elements in the buffer (aka shape[0]) + ssize_t itemsize # element size in bytes (!=nbytes/count due to strides) + ssize_t stride # stride in bytes between elements + # NB: We don't support suboffsets. + + cdef tuple _pandas_resolve_table_name( object data, object table_name, @@ -1127,7 +1180,7 @@ cdef tuple _pandas_resolve_table_name( raise TypeError( f'Bad argument `table_name_col`: ' + 'must be a column name (str) or index (int).') - _check_column_is_str( + _pandas_check_column_is_str( data, col_index, 'Bad argument `table_name_col`: ', @@ -1175,7 +1228,7 @@ cdef list _pandas_resolve_col_names( column_name_vec* field_names_out): cdef list name_owners = [] cdef line_sender_column_name c_name - cdef int col_index + cdef size_t col_index for col_index in range(symbol_indices.size): col_index = symbol_indices.d[col_index] name_owners.append(str_to_column_name(data.columns[col_index], &c_name)) @@ -1202,31 +1255,31 @@ cdef int _bind_col_index(str arg_name, int col_index, int col_count) except -1: return col_index -cdef object _column_is_str(object data, int col_index): +cdef object _pandas_column_is_str(object data, int col_index): """ Return True if the column at `col_index` is a string column. """ cdef str col_kind - cdef object[:] obj_col col_kind = data.dtypes[col_index].kind if col_kind == 'S': # string, string[pyarrow] return True elif col_kind == 'O': # object - obj_col = data.iloc[:, col_index].to_numpy() - for index in range(obj_col.shape[0]): - if not isinstance(obj_col[index], str): - return False - return True + if len(data.index) == 0: + return True + else: + # We only check the first element and hope for the rest. + # We also accept None as a null value. + return isinstance(data.iloc[0, col_index], (str, None)) else: return False -cdef object _check_column_is_str(data, col_index, err_msg_prefix, col_name): +cdef object _pandas_check_column_is_str( + data, col_index, err_msg_prefix, col_name): cdef str col_kind - cdef object[:] obj_col col_kind = data.dtypes[col_index].kind if col_kind in 'SO': - if not _column_is_str(data, col_index): + if not _pandas_column_is_str(data, col_index): raise TypeError( err_msg_prefix + 'Found non-string value ' + @@ -1252,7 +1305,7 @@ cdef int _pandas_resolve_symbols( return 0 elif symbols is True: for col_index in range(col_count): - if _column_is_str(data, col_index): + if _pandas_column_is_str(data, col_index): int_vec_push(symbol_indices_out, col_index) return 0 else: @@ -1269,7 +1322,7 @@ cdef int _pandas_resolve_symbols( raise TypeError( f'Bad argument `symbols`: Elements must ' + 'be a column name (str) or index (int).') - _check_column_is_str( + _pandas_check_column_is_str( data, col_index, 'Bad element in argument `symbols`: ', @@ -1319,6 +1372,68 @@ cdef tuple _pandas_resolve_at(object data, object at, int col_count): f'for the {at!r} column: Must be a datetime column.') +cdef struct dtype_t: + # A ripoff of a subset of PyArray_Descr as we were able to extract from numpy.dtype. + # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html?highlight=dtype#numpy.dtype + # See: https://numpy.org/doc/stable/reference/c-api/types-and-structures.html#c.PyArray_Descr + int alignment + char kind + int itemsize + char byteorder + bint hasobject + + +cdef char _str_to_char(str field, str s) except 0: + cdef int res + if len(s) != 1: + raise ValueError( + f'dtype.{field}: Expected a single character, got {s!r}') + res = ord(s[0]) + if res <= 0 or res > 127: ## ascii, exclude nul-termintor + raise ValueError( + f'dtype.{field}: Character out of ASCII range, got {s!r}') + return res + + +cdef int _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except -1: + """ + Parse a numpy dtype and return a dtype_t. + """ + dtype_out.alignment = np_dtype.alignment + dtype_out.kind = _str_to_char('kind', np_dtype.kind) + dtype_out.itemsize = np_dtype.itemsize + dtype_out.byteorder = _str_to_char('byteorder', np_dtype.byteorder) + dtype_out.hasobject = np_dtype.hasobject + + +cdef int _pandas_resolve_dtypes( + object data, int col_count, dtype_t* dtypes_out) except -1: + cdef int col_index + for col_index in range(col_count): + _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) + + +cdef Py_buffer* _pandas_buf_from_np(object nparr, const dtype_t* dtype) except? NULL: + return NULL + + +cdef int _pandas_resolve_col_buffers( + object data, int col_count, const dtype_t* dtypes, + Py_buffer** col_buffers) except -1: + """ + Map pandas columns to array of col_buffers. + """ + # Note: By calling "to_numpy" we are throwing away what might be an Arrow. + # This is particularly expensive for string columns. + # If you want to use Arrow (i.e. your data comes from Parquet) please ask + # for the feature in our issue tracker. + cdef int col_index + for col_index in range(col_count): + col_buffers[col_index] = _pandas_buf_from_np( + data.iloc[:, col_index].to_numpy(), &dtypes[col_index]) + + + _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' 'v1.0.2' '/troubleshooting.html#inspecting-and-debugging-errors#flush-failed') diff --git a/test/test.py b/test/test.py index 4d5abf7d..98b9a27d 100755 --- a/test/test.py +++ b/test/test.py @@ -408,7 +408,7 @@ def _pandas(*args, **kwargs): pd.Timestamp('20180310'), pd.Timestamp('20180311'), pd.Timestamp('20180312')], - 'D': ['foo', 'bar', True]}) + 'D': [True, 'foo', 'bar']}) DF2 = pd.DataFrame({ From 5d6d4be27ddf623f4612df5d07143629189c92aa Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 4 Nov 2022 16:23:55 +0000 Subject: [PATCH 016/147] Improved column index handling, actually getting buffers from numpy arrays. --- src/questdb/ingress.pyx | 197 ++++++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 87 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 667c33e4..a141a167 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -40,7 +40,8 @@ from cpython.object cimport PyObject from cpython.float cimport PyFloat_Check from cpython.int cimport PyInt_Check from cpython.unicode cimport PyUnicode_Check -from cpython.buffer cimport Py_buffer, PyObject_GetBuffer, PyBuffer_Release +from cpython.buffer cimport Py_buffer, PyObject_CheckBuffer, \ + PyObject_GetBuffer, PyBuffer_Release, PyBUF_STRIDES from .line_sender cimport * @@ -955,30 +956,29 @@ cdef class Buffer: # to add a library dependency on pandas itself. We simply rely on its API. # The only reason to validate here is to avoid obscure "AttributeError" # exceptions later. - cdef int col_count - cdef int row_count - cdef int name_col + cdef size_t col_count + cdef ssize_t name_col cdef object name_owner cdef line_sender_table_name c_table_name - cdef int_vec symbol_indices = int_vec_new() - cdef int_vec field_indices = int_vec_new() - cdef int at_col + cdef size_t_vec symbol_indices = size_t_vec_new() + cdef size_t_vec field_indices = size_t_vec_new() + cdef ssize_t at_col cdef int64_t at_value cdef column_name_vec symbol_names = column_name_vec_new() cdef column_name_vec field_names = column_name_vec_new() cdef list name_owners = None - cdef int row_index cdef dtype_t* dtypes = NULL - cdef Py_buffer** col_buffers = NULL - cdef int col_index + cdef size_t set_buf_count = 0 + cdef Py_buffer* col_buffers = NULL + cdef size_t col_index try: _check_is_pandas_dataframe(data) col_count = len(data.columns) name_col, name_owner = _pandas_resolve_table_name( data, table_name, table_name_col, col_count, &c_table_name) - _pandas_resolve_symbols( - data, symbols, col_count, &symbol_indices) at_col, at_value = _pandas_resolve_at(data, at, col_count) + _pandas_resolve_symbols( + data, at_col, symbols, col_count, &symbol_indices) _pandas_resolve_fields( name_col, &symbol_indices, at_col, col_count, &field_indices) name_owners = _pandas_resolve_col_names( @@ -986,18 +986,19 @@ cdef class Buffer: &symbol_names, &field_names) dtypes = calloc(col_count, sizeof(dtype_t)) _pandas_resolve_dtypes(data, col_count, dtypes) - col_buffers = calloc(col_count, sizeof(Py_buffer*)) - _pandas_resolve_col_buffers(data, col_count, dtypes, col_buffers) + col_buffers = calloc(col_count, sizeof(Py_buffer)) + _pandas_resolve_col_buffers( + data, col_count, dtypes, col_buffers, &set_buf_count) import sys sys.stderr.write('_pandas :: (A) ' + f'name_col: {name_col}, ' + f'name_owner: {name_owner}, ' + - f'symbol_indices: {int_vec_str(&symbol_indices)}, ' + + f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + f'at_col: {at_col}, ' + f'at_value: {at_value}, ' + - f'field_indices: {int_vec_str(&field_indices)}' + + f'field_indices: {size_t_vec_str(&field_indices)}' + '\n') - row_count = len(data) + # row_count = len(data) # for row_index in range(row_count): # if name_col > -1: # data.iloc[:, name_col] @@ -1006,17 +1007,16 @@ cdef class Buffer: # raise c_err_to_py(err) finally: if col_buffers != NULL: - for col_index in range(col_count): - if col_buffers[col_index] != NULL: - PyBuffer_Release(col_buffers[col_index]) + for col_index in range(set_buf_count): + PyBuffer_Release(&col_buffers[col_index]) free(col_buffers) free(dtypes) if name_owners: # no-op to avoid "unused variable" warning pass column_name_vec_free(&field_names) column_name_vec_free(&symbol_names) - int_vec_free(&field_indices) - int_vec_free(&symbol_indices) + size_t_vec_free(&field_indices) + size_t_vec_free(&symbol_indices) def pandas( self, @@ -1035,37 +1035,37 @@ cdef class Buffer: self._pandas(data, table_name, table_name_col, symbols, at, sort) -cdef struct c_int_vec: +cdef struct c_size_t_vec: size_t capacity size_t size - int* d + size_t* d -ctypedef c_int_vec int_vec +ctypedef c_size_t_vec size_t_vec -cdef int_vec int_vec_new(): - cdef int_vec vec +cdef size_t_vec size_t_vec_new(): + cdef size_t_vec vec vec.capacity = 0 vec.size = 0 - vec.d = NULL + vec.d = NULL return vec -cdef void int_vec_free(int_vec* vec): +cdef void size_t_vec_free(size_t_vec* vec): if vec.d: free(vec.d) vec.d = NULL -cdef str int_vec_str(int_vec* vec): - return 'int_vec' + str([vec.d[i] for i in range(vec.size)]) +cdef str size_t_vec_str(size_t_vec* vec): + return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) -cdef void int_vec_push(int_vec* vec, int value): +cdef void size_t_vec_push(size_t_vec* vec, size_t value): if vec.capacity == 0: vec.capacity = 8 - vec.d = malloc(vec.capacity * sizeof(int)) + vec.d = malloc(vec.capacity * sizeof(size_t)) if vec.d == NULL: abort() elif vec.size == vec.capacity: vec.capacity = vec.capacity * 2 - vec.d = realloc(vec.d, vec.capacity * sizeof(int)) + vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) if not vec.d: abort() vec.d[vec.size] = value @@ -1142,7 +1142,7 @@ cdef tuple _pandas_resolve_table_name( object data, object table_name, object table_name_col, - int col_count, + size_t col_count, line_sender_table_name* name_out): """ Return a tuple-pair of: @@ -1158,7 +1158,7 @@ cdef tuple _pandas_resolve_table_name( This method validates input and may raise. """ - cdef int col_index + cdef size_t col_index = 0 if table_name is not None: if table_name_col is not None: raise ValueError( @@ -1169,16 +1169,16 @@ cdef tuple _pandas_resolve_table_name( except IngressError as ie: raise ValueError(f'Bad argument `table_name`: {ie}') else: - raise TypeError(f'Bad argument `table_name`: Must be str.') + raise TypeError('Bad argument `table_name`: Must be str.') elif table_name_col is not None: if isinstance(table_name_col, str): - col_index = _pandas_get_loc(data, table_name_col, 'table_name_col') + _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) elif isinstance(table_name_col, int): - col_index = _bind_col_index( - 'table_name_col', table_name_col, col_count) + _bind_col_index( + 'table_name_col', table_name_col, col_count, &col_index) else: raise TypeError( - f'Bad argument `table_name_col`: ' + + 'Bad argument `table_name_col`: ' + 'must be a column name (str) or index (int).') _pandas_check_column_is_str( data, @@ -1193,21 +1193,24 @@ cdef tuple _pandas_resolve_table_name( cdef int _pandas_resolve_fields( int name_col, - const int_vec* symbol_indices, + const size_t_vec* symbol_indices, int at_col, - int col_count, - int_vec* field_indices_out) except -1: + size_t col_count, + size_t_vec* field_indices_out) except -1: """ Return a list of field column indices. i.e. a list of all columns which are not the table name column, symbols or the at timestamp column. """ # We rely on `symbol_indices` being sorted. - cdef int col_index = 0 - cdef int sym_index = 0 - cdef int sym_len = symbol_indices.size + cdef size_t col_index = 0 + cdef size_t sym_index = 0 + cdef size_t sym_len = symbol_indices.size while col_index < col_count: - if col_index == name_col or col_index == at_col: + if (name_col >= 0) and (col_index == name_col): + col_index += 1 + continue + if (at_col >= 0) and (col_index == at_col): col_index += 1 continue while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: @@ -1215,15 +1218,15 @@ cdef int _pandas_resolve_fields( if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: col_index += 1 continue - int_vec_push(field_indices_out, col_index) + size_t_vec_push(field_indices_out, col_index) col_index += 1 return 0 cdef list _pandas_resolve_col_names( object data, - const int_vec* symbol_indices, - const int_vec* field_indices, + const size_t_vec* symbol_indices, + const size_t_vec* field_indices, column_name_vec* symbol_names_out, column_name_vec* field_names_out): cdef list name_owners = [] @@ -1240,19 +1243,27 @@ cdef list _pandas_resolve_col_names( return name_owners -cdef int _bind_col_index(str arg_name, int col_index, int col_count) except -1: +cdef bint _bind_col_index( + str arg_name, int col_num, size_t col_count, + size_t* col_index) except False: """ Validate that `col_index` is in bounds for `col_count`. This function also converts negative indicies (e.g. -1 for last column) to positive indicies. """ - cdef orig_col_index = col_index - if col_index < 0: - col_index += col_count # We convert negative indicies to positive ones. - if not (0 <= col_index < col_count): + cdef bint bad = False + cdef int orig_col_num = col_num + if col_num < 0: + col_num += col_count # Try convert negative offsets to positive ones. + if col_num < 0: + bad = True + if (not bad) and (col_num >= col_count): + bad = True + if bad: raise IndexError( - f'Bad argument `{arg_name}`: {orig_col_index} index out of range') - return col_index + f'Bad argument `{arg_name}`: {orig_col_num} index out of range') + col_index[0] = col_num + return True cdef object _pandas_column_is_str(object data, int col_index): @@ -1260,6 +1271,7 @@ cdef object _pandas_column_is_str(object data, int col_index): Return True if the column at `col_index` is a string column. """ cdef str col_kind + cdef object col col_kind = data.dtypes[col_index].kind if col_kind == 'S': # string, string[pyarrow] return True @@ -1269,13 +1281,14 @@ cdef object _pandas_column_is_str(object data, int col_index): else: # We only check the first element and hope for the rest. # We also accept None as a null value. - return isinstance(data.iloc[0, col_index], (str, None)) + col = data.iloc[0, col_index] + return (col is None) or isinstance(col, str) else: return False cdef object _pandas_check_column_is_str( - data, col_index, err_msg_prefix, col_name): + object data, size_t col_index, str err_msg_prefix, object col_name): cdef str col_kind col_kind = data.dtypes[col_index].kind if col_kind in 'SO': @@ -1293,20 +1306,21 @@ cdef object _pandas_check_column_is_str( cdef int _pandas_resolve_symbols( object data, + ssize_t at_col, object symbols, - int col_count, - int_vec* symbol_indices_out) except -1: + size_t col_count, + size_t_vec* symbol_indices_out) except -1: """ Return a list of column indices. """ - cdef int col_index + cdef size_t col_index = 0 cdef object symbol if symbols is False: return 0 elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): - int_vec_push(symbol_indices_out, col_index) + size_t_vec_push(symbol_indices_out, col_index) return 0 else: if not isinstance(symbols, (tuple, list)): @@ -1315,38 +1329,43 @@ cdef int _pandas_resolve_symbols( 'of column names (str) or indices (int).') for symbol in symbols: if isinstance(symbol, str): - col_index = _pandas_get_loc(data, symbol, 'symbols') + _pandas_get_loc(data, symbol, 'symbols', &col_index) elif isinstance(symbol, int): - col_index = _bind_col_index('symbol', symbol, col_count) + _bind_col_index('symbol', symbol, col_count, &col_index) else: raise TypeError( f'Bad argument `symbols`: Elements must ' + 'be a column name (str) or index (int).') + if (at_col >= 0) and (col_index == at_col): + raise ValueError( + f'Bad argument `symbols`: Cannot use the `at` column ' + + f'({data.columns[at_col]!r}) as a symbol column.') _pandas_check_column_is_str( data, col_index, 'Bad element in argument `symbols`: ', symbol) - int_vec_push(symbol_indices_out, col_index) + size_t_vec_push(symbol_indices_out, col_index) return 0 -cdef int _pandas_get_loc(object data, str col_name, str arg_name) except -1: +cdef bint _pandas_get_loc( + object data, str col_name, str arg_name, + size_t* col_index_out) except False: """ Return the column index for `col_name`. """ - cdef int col_index try: - col_index = data.columns.get_loc(col_name) + col_index_out[0] = data.columns.get_loc(col_name) + return True except KeyError: raise KeyError( f'Bad argument `{arg_name}`: ' + f'Column {col_name!r} not found in the dataframe.') - return col_index -cdef tuple _pandas_resolve_at(object data, object at, int col_count): - cdef int col_index +cdef tuple _pandas_resolve_at(object data, object at, size_t col_count): + cdef size_t col_index cdef str col_kind if at is None: return -1, 0 # Special value for `at_now`. @@ -1355,9 +1374,9 @@ cdef tuple _pandas_resolve_at(object data, object at, int col_count): elif isinstance(at, datetime): return -1, datetime_to_nanos(at) elif isinstance(at, str): - col_index = _pandas_get_loc(data, at, 'at') + _pandas_get_loc(data, at, 'at', &col_index) elif isinstance(at, int): - col_index = _bind_col_index('at', at, col_count) + _bind_col_index('at', at, col_count, &col_index) else: raise TypeError( f'Bad argument `at`: Unsupported type {type(at)}. ' + @@ -1407,19 +1426,15 @@ cdef int _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except -1: cdef int _pandas_resolve_dtypes( - object data, int col_count, dtype_t* dtypes_out) except -1: - cdef int col_index + object data, size_t col_count, dtype_t* dtypes_out) except -1: + cdef size_t col_index for col_index in range(col_count): _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) -cdef Py_buffer* _pandas_buf_from_np(object nparr, const dtype_t* dtype) except? NULL: - return NULL - - cdef int _pandas_resolve_col_buffers( - object data, int col_count, const dtype_t* dtypes, - Py_buffer** col_buffers) except -1: + object data, size_t col_count, const dtype_t* dtypes, + Py_buffer* col_buffers, size_t* set_buf_count) except -1: """ Map pandas columns to array of col_buffers. """ @@ -1427,11 +1442,19 @@ cdef int _pandas_resolve_col_buffers( # This is particularly expensive for string columns. # If you want to use Arrow (i.e. your data comes from Parquet) please ask # for the feature in our issue tracker. - cdef int col_index + cdef size_t col_index + cdef object nparr + cdef Py_buffer* view + cdef const dtype_t* dtype for col_index in range(col_count): - col_buffers[col_index] = _pandas_buf_from_np( - data.iloc[:, col_index].to_numpy(), &dtypes[col_index]) - + nparr = data.iloc[:, col_index].to_numpy() + view = &col_buffers[col_index] + dtype = &dtypes[col_index] + if not PyObject_CheckBuffer(nparr): + raise TypeError( + f'Bad column: Expected a numpy array, got {nparr!r}') + PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) + set_buf_count[0] += 1 # Set to avoid wrongly calling `PyBuffer_Release`. _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' From 95a66bc67cb22c23331940957f984b6f59d3514b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 4 Nov 2022 17:20:30 +0000 Subject: [PATCH 017/147] Introducing a small rust lib to convert python strings to UTF-8 without incurring lots of garbage. --- pystr_to_str_ref/Cargo.lock | 16 ++++++++ pystr_to_str_ref/Cargo.toml | 11 ++++++ pystr_to_str_ref/src/lib.rs | 78 +++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 pystr_to_str_ref/Cargo.lock create mode 100644 pystr_to_str_ref/Cargo.toml create mode 100644 pystr_to_str_ref/src/lib.rs diff --git a/pystr_to_str_ref/Cargo.lock b/pystr_to_str_ref/Cargo.lock new file mode 100644 index 00000000..762cd976 --- /dev/null +++ b/pystr_to_str_ref/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "pystr_to_str_ref" +version = "0.1.0" +dependencies = [ + "widestring", +] + +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" diff --git a/pystr_to_str_ref/Cargo.toml b/pystr_to_str_ref/Cargo.toml new file mode 100644 index 00000000..3a3db77f --- /dev/null +++ b/pystr_to_str_ref/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "pystr_to_str_ref" +version = "0.1.0" +edition = "2021" + +[dependencies] +widestring = "1.0.2" + +[lib] +name = "pystr_to_str_ref" +crate-type = ["staticlib"] \ No newline at end of file diff --git a/pystr_to_str_ref/src/lib.rs b/pystr_to_str_ref/src/lib.rs new file mode 100644 index 00000000..ef822e1c --- /dev/null +++ b/pystr_to_str_ref/src/lib.rs @@ -0,0 +1,78 @@ +use std::ffi::{c_void, c_char}; +use std::fmt::Write; + +#[allow(non_camel_case_types)] +pub struct converter(String); + +#[no_mangle] +pub unsafe extern "C" fn questdb_pystr_converter_new() -> *mut converter { + Box::into_raw(Box::new(converter(String::with_capacity(64)))) +} + +#[no_mangle] +pub unsafe extern "C" fn questdb_pystr_converter_free(c: *mut converter) { + if !c.is_null() { + drop(Box::from_raw(c)); + } +} + +fn encode_ucs1(dest: &mut String, buf: &[u8]) -> bool { + write!(dest, "'nyi").unwrap(); + false +} + +fn encode_ucs2(dest: &mut String, buf: &[u16]) -> bool { + write!(dest, "'nyi").unwrap(); + false +} + +fn encode_ucs4(dest: &mut String, buf: &[u32]) -> bool { + write!(dest, "'nyi").unwrap(); + false +} + +/// Converts a Python string to a UTF8 buffer. +/// * Width is 1 for UCS1, 2 for UCS2, 4 for UCS4. +/// * Count is the number of code points. +/// * Input is the pointer to the UCS{1,2,4} data. +/// * size_out is the resulting size in bytes of the UTF8 string. +/// * buf_out is set to point to the UTF8 string. +/// Returns true for success of false for failure. +/// In case of failure, size_out and buf_out contain the error message. +#[no_mangle] +pub unsafe extern "C" fn questdb_pystr_to_convert( + c: *mut converter, + width: u8, count: usize, input: *const c_void, + size_out: *mut usize, buf_out: *mut *const c_char) -> bool { + let sbuf: &mut String = &mut (*c).0; + sbuf.clear(); + let ok = match width { + 1 => encode_ucs1( + sbuf, + std::slice::from_raw_parts(input as *const u8, count)), + 2 => encode_ucs2( + sbuf, + std::slice::from_raw_parts(input as *const u16, count)), + 4 => encode_ucs4( + sbuf, + std::slice::from_raw_parts(input as *const u32, count)), + _ => { + write!(sbuf, "Unsupported width: {}", width).unwrap(); + false + }, + }; + *size_out = sbuf.len(); + *buf_out = sbuf.as_ptr() as *const c_char; + ok +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} From e43e5646212b800761be7af05da9231fe6ef29d6 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 4 Nov 2022 18:08:45 +0000 Subject: [PATCH 018/147] Implemented conversions for UCS1/2/4. --- pystr_to_str_ref/Cargo.lock | 9 ------ pystr_to_str_ref/Cargo.toml | 3 -- pystr_to_str_ref/src/lib.rs | 57 ++++++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/pystr_to_str_ref/Cargo.lock b/pystr_to_str_ref/Cargo.lock index 762cd976..cf213d76 100644 --- a/pystr_to_str_ref/Cargo.lock +++ b/pystr_to_str_ref/Cargo.lock @@ -5,12 +5,3 @@ version = 3 [[package]] name = "pystr_to_str_ref" version = "0.1.0" -dependencies = [ - "widestring", -] - -[[package]] -name = "widestring" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" diff --git a/pystr_to_str_ref/Cargo.toml b/pystr_to_str_ref/Cargo.toml index 3a3db77f..b28f684a 100644 --- a/pystr_to_str_ref/Cargo.toml +++ b/pystr_to_str_ref/Cargo.toml @@ -3,9 +3,6 @@ name = "pystr_to_str_ref" version = "0.1.0" edition = "2021" -[dependencies] -widestring = "1.0.2" - [lib] name = "pystr_to_str_ref" crate-type = ["staticlib"] \ No newline at end of file diff --git a/pystr_to_str_ref/src/lib.rs b/pystr_to_str_ref/src/lib.rs index ef822e1c..de10a093 100644 --- a/pystr_to_str_ref/src/lib.rs +++ b/pystr_to_str_ref/src/lib.rs @@ -17,18 +17,52 @@ pub unsafe extern "C" fn questdb_pystr_converter_free(c: *mut converter) { } fn encode_ucs1(dest: &mut String, buf: &[u8]) -> bool { - write!(dest, "'nyi").unwrap(); - false + // len(chr(2 ** 8 - 1).encode('utf-8')) == 2 + let utf8_mult = 2; + dest.reserve(utf8_mult * buf.len()); + for b in buf.iter() { + dest.push(*b as char); + } + true } fn encode_ucs2(dest: &mut String, buf: &[u16]) -> bool { - write!(dest, "'nyi").unwrap(); - false + // len(chr(2 ** 16 - 1).encode('utf-8')) == 3 + let utf8_mult = 3; + dest.reserve(utf8_mult * buf.len()); + for b in buf.iter() { + // Checking for validity is not optional: + // >>> for n in range(2 ** 16): + // >>> chr(n).encode('utf-8') + // UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' + // in position 0: surrogates not allowed + match char::from_u32(*b as u32) { + Some(c) => dest.push(c), + None => { + dest.clear(); + write!(dest, "invalid ucs2 code point: {}", b).unwrap(); + return false + } + } + } + true } fn encode_ucs4(dest: &mut String, buf: &[u32]) -> bool { - write!(dest, "'nyi").unwrap(); - false + // Max 4 bytes allowed by RFC: https://www.rfc-editor.org/rfc/rfc3629#page-4 + let utf8_mult = 4; + dest.reserve(utf8_mult * buf.len()); + for b in buf.iter() { + match char::from_u32(*b) { + Some(c) => dest.push(c), + None => { + dest.clear(); + write!(dest, "invalid ucs4 code point: {}", b).unwrap(); + return false + } + } + } + true } /// Converts a Python string to a UTF8 buffer. @@ -65,14 +99,3 @@ pub unsafe extern "C" fn questdb_pystr_to_convert( *buf_out = sbuf.as_ptr() as *const c_char; ok } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} From 25bc49b264d2f5a6cac8cb0bc3a5b9e053e375c2 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 4 Nov 2022 18:23:38 +0000 Subject: [PATCH 019/147] Renamed rust lib and wired up the build and linkage bits in setup.py --- .../Cargo.lock | 2 +- .../Cargo.toml | 2 +- .../src/lib.rs | 0 setup.py | 30 ++++++++++++++----- 4 files changed, 25 insertions(+), 9 deletions(-) rename {pystr_to_str_ref => pystr-to-str-ref}/Cargo.lock (83%) rename {pystr_to_str_ref => pystr-to-str-ref}/Cargo.toml (80%) rename {pystr_to_str_ref => pystr-to-str-ref}/src/lib.rs (100%) diff --git a/pystr_to_str_ref/Cargo.lock b/pystr-to-str-ref/Cargo.lock similarity index 83% rename from pystr_to_str_ref/Cargo.lock rename to pystr-to-str-ref/Cargo.lock index cf213d76..66255837 100644 --- a/pystr_to_str_ref/Cargo.lock +++ b/pystr-to-str-ref/Cargo.lock @@ -3,5 +3,5 @@ version = 3 [[package]] -name = "pystr_to_str_ref" +name = "pystr-to-str-ref" version = "0.1.0" diff --git a/pystr_to_str_ref/Cargo.toml b/pystr-to-str-ref/Cargo.toml similarity index 80% rename from pystr_to_str_ref/Cargo.toml rename to pystr-to-str-ref/Cargo.toml index b28f684a..5291b5c9 100644 --- a/pystr_to_str_ref/Cargo.toml +++ b/pystr-to-str-ref/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "pystr_to_str_ref" +name = "pystr-to-str-ref" version = "0.1.0" edition = "2021" diff --git a/pystr_to_str_ref/src/lib.rs b/pystr-to-str-ref/src/lib.rs similarity index 100% rename from pystr_to_str_ref/src/lib.rs rename to pystr-to-str-ref/src/lib.rs diff --git a/setup.py b/setup.py index 3b0e93d1..19a2866c 100755 --- a/setup.py +++ b/setup.py @@ -22,7 +22,8 @@ def ingress_extension(): - lib_name = None + lib_prefix = '' + lib_suffix = '' lib_paths = [] libraries = [] extra_compile_args = [] @@ -30,27 +31,38 @@ def ingress_extension(): extra_objects = [] questdb_rs_ffi_dir = PROJ_ROOT / 'c-questdb-client' / 'questdb-rs-ffi' + pystr_to_str_ref_dir = PROJ_ROOT / 'pystr-to-str-ref' questdb_client_lib_dir = None + pystr_to_str_ref_lib_dir = None if PLATFORM == 'win32' and MODE == '32bit': questdb_client_lib_dir = \ questdb_rs_ffi_dir / 'target' / WIN_32BIT_CARGO_TARGET / 'release' + pystr_to_str_ref_lib_dir = \ + pystr_to_str_ref_dir / 'target' / WIN_32BIT_CARGO_TARGET / 'release' else: questdb_client_lib_dir = questdb_rs_ffi_dir / 'target' / 'release' + pystr_to_str_ref_lib_dir = pystr_to_str_ref_dir / 'target' / 'release' if PLATFORM == 'darwin': - lib_name = 'libquestdb_client.a' - extra_objects = [str(questdb_client_lib_dir / lib_name)] + lib_prefix = 'lib' + lib_suffix = '.a' extra_link_args.extend(['-framework', 'Security']) elif PLATFORM == 'win32': - lib_name = 'questdb_client.lib' - extra_objects = [str(questdb_client_lib_dir / lib_name)] + lib_prefix = '' + lib_suffix = '.lib' libraries.extend(['wsock32', 'ws2_32', 'AdvAPI32', 'bcrypt', 'UserEnv']) elif PLATFORM == 'linux': - lib_name = 'libquestdb_client.a' - extra_objects = [str(questdb_client_lib_dir / lib_name)] + lib_prefix = 'lib' + lib_suffix = '.a' else: raise NotImplementedError(f'Unsupported platform: {PLATFORM}') + extra_objects = [ + str(loc / f'{lib_prefix}{name}{lib_suffix}') + for loc, name in ( + (questdb_client_lib_dir, 'questdb_client'), + (pystr_to_str_ref_lib_dir, 'pystr_to_str_ref'))] + return Extension( "questdb.ingress", ["src/questdb/ingress.pyx"], @@ -102,6 +114,10 @@ def cargo_build(): cargo_args, cwd=str(PROJ_ROOT / 'c-questdb-client' / 'questdb-rs-ffi')) + subprocess.check_call( + cargo_args, + cwd=str(PROJ_ROOT / 'pystr-to-str-ref')) + class questdb_build_ext(build_ext): """ From b199db6ed8d3d1027bfe63b660b614fe783692d7 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Sat, 5 Nov 2022 11:13:57 +0000 Subject: [PATCH 020/147] Auxilliary rust lib rename. --- proj.py | 1 + {pystr-to-str-ref => pystr-to-utf8}/Cargo.lock | 2 +- {pystr-to-str-ref => pystr-to-utf8}/Cargo.toml | 4 ++-- {pystr-to-str-ref => pystr-to-utf8}/src/lib.rs | 0 setup.py | 14 +++++++------- 5 files changed, 11 insertions(+), 10 deletions(-) rename {pystr-to-str-ref => pystr-to-utf8}/Cargo.lock (83%) rename {pystr-to-str-ref => pystr-to-utf8}/Cargo.toml (60%) rename {pystr-to-str-ref => pystr-to-utf8}/src/lib.rs (100%) diff --git a/proj.py b/proj.py index 88edfc78..28d30539 100755 --- a/proj.py +++ b/proj.py @@ -133,6 +133,7 @@ def clean(): _rmtree(PROJ_ROOT / 'dist') _rmtree(PROJ_ROOT / 'c-questdb-client' / 'questdb-rs-ffi' / 'target') _rmtree(PROJ_ROOT / 'c-questdb-client' / 'build') + _rmtree(PROJ_ROOT / 'pystr-to-utf8' / 'target') _rmtree(PROJ_ROOT / 'src' / 'questdb.egg-info') _rmtree(PROJ_ROOT / 'venv') _rmtree(PROJ_ROOT / 'wheelhouse') diff --git a/pystr-to-str-ref/Cargo.lock b/pystr-to-utf8/Cargo.lock similarity index 83% rename from pystr-to-str-ref/Cargo.lock rename to pystr-to-utf8/Cargo.lock index 66255837..f42018c4 100644 --- a/pystr-to-str-ref/Cargo.lock +++ b/pystr-to-utf8/Cargo.lock @@ -3,5 +3,5 @@ version = 3 [[package]] -name = "pystr-to-str-ref" +name = "pystr-to-utf8" version = "0.1.0" diff --git a/pystr-to-str-ref/Cargo.toml b/pystr-to-utf8/Cargo.toml similarity index 60% rename from pystr-to-str-ref/Cargo.toml rename to pystr-to-utf8/Cargo.toml index 5291b5c9..d11819ef 100644 --- a/pystr-to-str-ref/Cargo.toml +++ b/pystr-to-utf8/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "pystr-to-str-ref" +name = "pystr-to-utf8" version = "0.1.0" edition = "2021" [lib] -name = "pystr_to_str_ref" +name = "pystr_to_utf8" crate-type = ["staticlib"] \ No newline at end of file diff --git a/pystr-to-str-ref/src/lib.rs b/pystr-to-utf8/src/lib.rs similarity index 100% rename from pystr-to-str-ref/src/lib.rs rename to pystr-to-utf8/src/lib.rs diff --git a/setup.py b/setup.py index 19a2866c..585a64b1 100755 --- a/setup.py +++ b/setup.py @@ -31,17 +31,17 @@ def ingress_extension(): extra_objects = [] questdb_rs_ffi_dir = PROJ_ROOT / 'c-questdb-client' / 'questdb-rs-ffi' - pystr_to_str_ref_dir = PROJ_ROOT / 'pystr-to-str-ref' + pystr_to_utf8_dir = PROJ_ROOT / 'pystr-to-utf8' questdb_client_lib_dir = None - pystr_to_str_ref_lib_dir = None + pystr_to_utf8_lib_dir = None if PLATFORM == 'win32' and MODE == '32bit': questdb_client_lib_dir = \ questdb_rs_ffi_dir / 'target' / WIN_32BIT_CARGO_TARGET / 'release' - pystr_to_str_ref_lib_dir = \ - pystr_to_str_ref_dir / 'target' / WIN_32BIT_CARGO_TARGET / 'release' + pystr_to_utf8_lib_dir = \ + pystr_to_utf8_dir / 'target' / WIN_32BIT_CARGO_TARGET / 'release' else: questdb_client_lib_dir = questdb_rs_ffi_dir / 'target' / 'release' - pystr_to_str_ref_lib_dir = pystr_to_str_ref_dir / 'target' / 'release' + pystr_to_utf8_lib_dir = pystr_to_utf8_dir / 'target' / 'release' if PLATFORM == 'darwin': lib_prefix = 'lib' @@ -61,7 +61,7 @@ def ingress_extension(): str(loc / f'{lib_prefix}{name}{lib_suffix}') for loc, name in ( (questdb_client_lib_dir, 'questdb_client'), - (pystr_to_str_ref_lib_dir, 'pystr_to_str_ref'))] + (pystr_to_utf8_lib_dir, 'pystr_to_utf8'))] return Extension( "questdb.ingress", @@ -116,7 +116,7 @@ def cargo_build(): subprocess.check_call( cargo_args, - cwd=str(PROJ_ROOT / 'pystr-to-str-ref')) + cwd=str(PROJ_ROOT / 'pystr-to-utf8')) class questdb_build_ext(build_ext): From 7b5200ecbd13a4d2fad5d4f1f65fa07818f81134 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Sat, 5 Nov 2022 11:54:55 +0000 Subject: [PATCH 021/147] Reworked API for better buffer reuse and for individual UCS1, 2, 4 functions. --- pystr-to-utf8/src/lib.rs | 121 ++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 41 deletions(-) diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index de10a093..db867fba 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -1,31 +1,78 @@ -use std::ffi::{c_void, c_char}; +use std::ffi::c_char; use std::fmt::Write; +use std::slice::from_raw_parts; #[allow(non_camel_case_types)] -pub struct converter(String); +pub struct qdb_pystr_buf(String); #[no_mangle] -pub unsafe extern "C" fn questdb_pystr_converter_new() -> *mut converter { - Box::into_raw(Box::new(converter(String::with_capacity(64)))) +pub unsafe extern "C" fn qdb_pystr_buf_new() -> *mut qdb_pystr_buf { + Box::into_raw(Box::new(qdb_pystr_buf(String::with_capacity(64)))) } +/// Get current position. Use in conjunction with `truncate`. #[no_mangle] -pub unsafe extern "C" fn questdb_pystr_converter_free(c: *mut converter) { - if !c.is_null() { - drop(Box::from_raw(c)); +pub unsafe extern "C" fn qdb_pystr_buf_tell(b: *mut qdb_pystr_buf) -> usize { + let b = &mut *b; + b.0.len() +} + +/// Trim the string to the given length. Use in conjunction with `tell`. +#[no_mangle] +pub unsafe extern "C" fn qdb_pystr_buf_truncate( + b: *mut qdb_pystr_buf, len: usize) { + let b = &mut *b; + b.0.truncate(len) +} + +/// Reset the converter's buffer to zero length. +#[no_mangle] +pub unsafe extern "C" fn qdb_pystr_buf_clear(b: *mut qdb_pystr_buf) { + let b = &mut *b; + b.0.clear() +} + +#[no_mangle] +pub unsafe extern "C" fn qdb_pystr_buf_free(b: *mut qdb_pystr_buf) { + if !b.is_null() { + drop(Box::from_raw(b)); } } -fn encode_ucs1(dest: &mut String, buf: &[u8]) -> bool { +#[inline] +fn encode_ucs1(dest: &mut String, buf: &[u8]) { // len(chr(2 ** 8 - 1).encode('utf-8')) == 2 let utf8_mult = 2; dest.reserve(utf8_mult * buf.len()); - for b in buf.iter() { - dest.push(*b as char); + for &b in buf.iter() { + dest.push(b as char); } - true } +#[no_mangle] +pub unsafe extern "C" fn qdb_ucs1_to_utf8( + b: *mut qdb_pystr_buf, + count: usize, input: *const u8, + size_out: *mut usize, buf_out: *mut *const c_char) { + let b = &mut *b; + let i = from_raw_parts(input, count); + if i.is_ascii() { + // Zero-copy optmization: + // is_ascii does a WORD-sized scan, so it's faster than the copy logic. + // We can also avoid the copy altogether and return back the same ptr. + // We get away with this because 7-bit ascii is a subset of UTF-8. + *size_out = count; + *buf_out = input as *const c_char; + } + else { + let last = b.0.len(); + encode_ucs1(&mut b.0, i); + *size_out = b.0.len() - last; + *buf_out = b.0.as_ptr() as *const c_char; + } +} + +#[inline] fn encode_ucs2(dest: &mut String, buf: &[u16]) -> bool { // len(chr(2 ** 16 - 1).encode('utf-8')) == 3 let utf8_mult = 3; @@ -48,6 +95,20 @@ fn encode_ucs2(dest: &mut String, buf: &[u16]) -> bool { true } +#[no_mangle] +pub unsafe extern "C" fn qdb_ucs2_to_utf8(b: *mut qdb_pystr_buf, + count: usize, input: *const u16, + size_out: *mut usize, buf_out: *mut *const c_char) -> bool { + let b = &mut *b; + let i = from_raw_parts(input, count); + let last = b.0.len(); + let ok = encode_ucs2(&mut b.0, i); + *size_out = b.0.len() - last; + *buf_out = b.0.as_ptr() as *const c_char; + ok +} + +#[inline] fn encode_ucs4(dest: &mut String, buf: &[u32]) -> bool { // Max 4 bytes allowed by RFC: https://www.rfc-editor.org/rfc/rfc3629#page-4 let utf8_mult = 4; @@ -65,37 +126,15 @@ fn encode_ucs4(dest: &mut String, buf: &[u32]) -> bool { true } -/// Converts a Python string to a UTF8 buffer. -/// * Width is 1 for UCS1, 2 for UCS2, 4 for UCS4. -/// * Count is the number of code points. -/// * Input is the pointer to the UCS{1,2,4} data. -/// * size_out is the resulting size in bytes of the UTF8 string. -/// * buf_out is set to point to the UTF8 string. -/// Returns true for success of false for failure. -/// In case of failure, size_out and buf_out contain the error message. #[no_mangle] -pub unsafe extern "C" fn questdb_pystr_to_convert( - c: *mut converter, - width: u8, count: usize, input: *const c_void, +pub unsafe extern "C" fn qdb_ucs4_to_utf8(b: *mut qdb_pystr_buf, + count: usize, input: *const u32, size_out: *mut usize, buf_out: *mut *const c_char) -> bool { - let sbuf: &mut String = &mut (*c).0; - sbuf.clear(); - let ok = match width { - 1 => encode_ucs1( - sbuf, - std::slice::from_raw_parts(input as *const u8, count)), - 2 => encode_ucs2( - sbuf, - std::slice::from_raw_parts(input as *const u16, count)), - 4 => encode_ucs4( - sbuf, - std::slice::from_raw_parts(input as *const u32, count)), - _ => { - write!(sbuf, "Unsupported width: {}", width).unwrap(); - false - }, - }; - *size_out = sbuf.len(); - *buf_out = sbuf.as_ptr() as *const c_char; + let b = &mut *b; + let i = from_raw_parts(input, count); + let last = b.0.len(); + let ok = encode_ucs4(&mut b.0, i); + *size_out = b.0.len() - last; + *buf_out = b.0.as_ptr() as *const c_char; ok } From e94570213e751df8707192dab78293910bd05ce1 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Sat, 5 Nov 2022 22:34:41 +0000 Subject: [PATCH 022/147] cbindgen to generate C .h and Cython .pxd headers. --- pystr-to-utf8/Cargo.lock | 235 ++++++++++++++++++++++++ pystr-to-utf8/Cargo.toml | 6 +- pystr-to-utf8/README.md | 7 + pystr-to-utf8/build.rs | 49 +++++ pystr-to-utf8/cbindgen.toml | 59 ++++++ pystr-to-utf8/include/pystr_to_utf8.h | 103 +++++++++++ pystr-to-utf8/include/pystr_to_utf8.pxd | 52 ++++++ pystr-to-utf8/src/lib.rs | 40 +++- 8 files changed, 549 insertions(+), 2 deletions(-) create mode 100644 pystr-to-utf8/README.md create mode 100644 pystr-to-utf8/build.rs create mode 100644 pystr-to-utf8/cbindgen.toml create mode 100644 pystr-to-utf8/include/pystr_to_utf8.h create mode 100644 pystr-to-utf8/include/pystr_to_utf8.pxd diff --git a/pystr-to-utf8/Cargo.lock b/pystr-to-utf8/Cargo.lock index f42018c4..5210f8ca 100644 --- a/pystr-to-utf8/Cargo.lock +++ b/pystr-to-utf8/Cargo.lock @@ -2,6 +2,241 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cbindgen" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb" +dependencies = [ + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "libc" +version = "0.2.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + [[package]] name = "pystr-to-utf8" version = "0.1.0" +dependencies = [ + "cbindgen", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "serde" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/pystr-to-utf8/Cargo.toml b/pystr-to-utf8/Cargo.toml index d11819ef..4eb8f445 100644 --- a/pystr-to-utf8/Cargo.toml +++ b/pystr-to-utf8/Cargo.toml @@ -2,7 +2,11 @@ name = "pystr-to-utf8" version = "0.1.0" edition = "2021" +publish = false [lib] name = "pystr_to_utf8" -crate-type = ["staticlib"] \ No newline at end of file +crate-type = ["staticlib"] + +[build-dependencies] +cbindgen = { version = "0.24.3", optional = true, default-features = false } \ No newline at end of file diff --git a/pystr-to-utf8/README.md b/pystr-to-utf8/README.md new file mode 100644 index 00000000..de8641b9 --- /dev/null +++ b/pystr-to-utf8/README.md @@ -0,0 +1,7 @@ +By default, when compiling, we don't re-generate the .h and .pxd include files. +This is to speed up compile time. + +If you've updated the API, regenerate them by running: + +$ cargo clean +$ cargo build --features cbindgen diff --git a/pystr-to-utf8/build.rs b/pystr-to-utf8/build.rs new file mode 100644 index 00000000..14a2e71d --- /dev/null +++ b/pystr-to-utf8/build.rs @@ -0,0 +1,49 @@ +#[cfg(feature = "cbindgen")] +extern crate cbindgen; + +const BAD_PXD: &str = " +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list"; + +#[cfg(feature = "cbindgen")] +fn main() -> Result<(), Box> { + let crate_dir = std::env::var("CARGO_MANIFEST_DIR")?; + let bindings = cbindgen::generate(&crate_dir)?; + bindings.write_to_file("include/pystr_to_utf8.h"); + + let config = cbindgen::Config { + language: cbindgen::Language::Cython, + documentation: true, + cython: cbindgen::CythonConfig { + header: Some("\"pystr_to_utf8.h\"".to_owned()), + cimports: std::collections::BTreeMap::new()}, + usize_is_size_t: true, + ..Default::default() + }; + + let bindings = cbindgen::Builder::new() + .with_crate(&crate_dir) + .with_config(config) + .generate()?; + + // Insted of just writing out the file: + // bindings.write_to_file("include/pystr_to_utf8.pxd"); + // We need to do some post-processing to make it work our code. + // The default output is too opinionated and has unwanted typedefs. + let mut pxd = Vec::new(); + bindings.write(&mut pxd); + let pxd = String::from_utf8(pxd)?; + if !pxd.contains(BAD_PXD) { + panic!("cbindgen generated unexpected pxd: {}", pxd); + } + let pxd = pxd.replace(BAD_PXD, ""); + let pxd = pxd.replace("bool", "bint"); + // println!("{}", &pxd); + std::fs::write("include/pystr_to_utf8.pxd", &pxd)?; + Ok(()) +} + +#[cfg(not(feature = "cbindgen"))] +fn main() {} + diff --git a/pystr-to-utf8/cbindgen.toml b/pystr-to-utf8/cbindgen.toml new file mode 100644 index 00000000..8f02840b --- /dev/null +++ b/pystr-to-utf8/cbindgen.toml @@ -0,0 +1,59 @@ +language = "C" + +header = """/******************************************************************************* + * ___ _ ____ ____ + * / _ \\ _ _ ___ ___| |_| _ \\| __ ) + * | | | | | | |/ _ \\/ __| __| | | | _ \\ + * | |_| | |_| | __/\\__ \\ |_| |_| | |_) | + * \\__\\_\\\\__,_|\\___||___/\\__|____/|____/ + * + * Copyright (c) 2014-2019 Appsicle + * Copyright (c) 2019-2022 QuestDB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/""" + +pragma_once = true + +autogen_warning = "// This header is auto-generated. Do not edit directly!" + +# A list of sys headers to #include (with angle brackets) +# default: [] +sys_includes = ["stdint.h", "stddef.h", "stdbool.h"] + +# A list of headers to #include (with quotes) +# default: [] +includes = [] # ["my_great_lib.h"] + +# Suppress cbindgen's default includes. +no_includes = true + +# #ifdef __cplusplus +# extern "C" { +# #endif // __cplusplus +cpp_compat = true + +# Code Style Options +braces = "NextLine" +line_length = 79 +tab_width = 4 +documentation = true +documentation_style = "doxy" + +# Codegen Options +style = "type" +usize_is_size_t = true + +[fn] +args = "vertical" diff --git a/pystr-to-utf8/include/pystr_to_utf8.h b/pystr-to-utf8/include/pystr_to_utf8.h new file mode 100644 index 00000000..4fc15c4f --- /dev/null +++ b/pystr-to-utf8/include/pystr_to_utf8.h @@ -0,0 +1,103 @@ +/******************************************************************************* + * ___ _ ____ ____ + * / _ \ _ _ ___ ___| |_| _ \| __ ) + * | | | | | | |/ _ \/ __| __| | | | _ \ + * | |_| | |_| | __/\__ \ |_| |_| | |_) | + * \__\_\\__,_|\___||___/\__|____/|____/ + * + * Copyright (c) 2014-2019 Appsicle + * Copyright (c) 2019-2022 QuestDB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#pragma once + +// This header is auto-generated. Do not edit directly! + +#include +#include +#include + +typedef struct qdb_pystr_buf qdb_pystr_buf; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Prepare a new buffer. The buffer must be freed with `qdb_pystr_free`. + * The `qdb_ucsX_to_utf8` functions will write to this buffer. + */ +qdb_pystr_buf *qdb_pystr_buf_new(void); + +/** + * Get current position. Use in conjunction with `truncate`. + */ +size_t qdb_pystr_buf_tell(qdb_pystr_buf *b); + +/** + * Trim the buffer to the given length. Use in conjunction with `tell`. + */ +void qdb_pystr_buf_truncate(qdb_pystr_buf *b, + size_t len); + +/** + * Reset the converter's buffer to zero length. + */ +void qdb_pystr_buf_clear(qdb_pystr_buf *b); + +/** + * Free the buffer. Must be called after `qdb_pystr_buf_new`. + */ +void qdb_pystr_buf_free(qdb_pystr_buf *b); + +/** + * Convert a Py_UCS1 string to UTF-8. + * Returns a `buf_out` borrowed ptr of `size_out` len. + * The buffer is borrowed either from `input` or from `b`. + */ +void qdb_ucs1_to_utf8(qdb_pystr_buf *b, + size_t count, + const uint8_t *input, + size_t *size_out, + const char **buf_out); + +/** + * Convert a Py_UCS2 string to UTF-8. + * Returns a `buf_out` borrowed ptr of `size_out` len. + * The buffer is borrowed from `b`. + * In case of errors, returns `false` and the buffer is an error message. + */ +bool qdb_ucs2_to_utf8(qdb_pystr_buf *b, + size_t count, + const uint16_t *input, + size_t *size_out, + const char **buf_out); + +/** + * Convert a Py_UCS4 string to UTF-8. + * Returns a `buf_out` borrowed ptr of `size_out` len. + * The buffer is borrowed from `b`. + * In case of errors, returns `false` and the buffer is an error message. + */ +bool qdb_ucs4_to_utf8(qdb_pystr_buf *b, + size_t count, + const uint32_t *input, + size_t *size_out, + const char **buf_out); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/pystr-to-utf8/include/pystr_to_utf8.pxd b/pystr-to-utf8/include/pystr_to_utf8.pxd new file mode 100644 index 00000000..70900c3d --- /dev/null +++ b/pystr-to-utf8/include/pystr_to_utf8.pxd @@ -0,0 +1,52 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t + +cdef extern from "pystr_to_utf8.h": + + cdef struct qdb_pystr_buf: + pass + + # Prepare a new buffer. The buffer must be freed with `qdb_pystr_free`. + # The `qdb_ucsX_to_utf8` functions will write to this buffer. + qdb_pystr_buf *qdb_pystr_buf_new(); + + # Get current position. Use in conjunction with `truncate`. + size_t qdb_pystr_buf_tell(qdb_pystr_buf *b); + + # Trim the buffer to the given length. Use in conjunction with `tell`. + void qdb_pystr_buf_truncate(qdb_pystr_buf *b, size_t len); + + # Reset the converter's buffer to zero length. + void qdb_pystr_buf_clear(qdb_pystr_buf *b); + + # Free the buffer. Must be called after `qdb_pystr_buf_new`. + void qdb_pystr_buf_free(qdb_pystr_buf *b); + + # Convert a Py_UCS1 string to UTF-8. + # Returns a `buf_out` borrowed ptr of `size_out` len. + # The buffer is borrowed either from `input` or from `b`. + void qdb_ucs1_to_utf8(qdb_pystr_buf *b, + size_t count, + const uint8_t *input, + size_t *size_out, + const char **buf_out); + + # Convert a Py_UCS2 string to UTF-8. + # Returns a `buf_out` borrowed ptr of `size_out` len. + # The buffer is borrowed from `b`. + # In case of errors, returns `false` and the buffer is an error message. + bint qdb_ucs2_to_utf8(qdb_pystr_buf *b, + size_t count, + const uint16_t *input, + size_t *size_out, + const char **buf_out); + + # Convert a Py_UCS4 string to UTF-8. + # Returns a `buf_out` borrowed ptr of `size_out` len. + # The buffer is borrowed from `b`. + # In case of errors, returns `false` and the buffer is an error message. + bint qdb_ucs4_to_utf8(qdb_pystr_buf *b, + size_t count, + const uint32_t *input, + size_t *size_out, + const char **buf_out); diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index db867fba..936920b8 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -1,3 +1,27 @@ +/******************************************************************************* + * ___ _ ____ ____ + * / _ \ _ _ ___ ___| |_| _ \| __ ) + * | | | | | | |/ _ \/ __| __| | | | _ \ + * | |_| | |_| | __/\__ \ |_| |_| | |_) | + * \__\_\\__,_|\___||___/\__|____/|____/ + * + * Copyright (c) 2014-2019 Appsicle + * Copyright (c) 2019-2022 QuestDB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + use std::ffi::c_char; use std::fmt::Write; use std::slice::from_raw_parts; @@ -5,6 +29,8 @@ use std::slice::from_raw_parts; #[allow(non_camel_case_types)] pub struct qdb_pystr_buf(String); +/// Prepare a new buffer. The buffer must be freed with `qdb_pystr_free`. +/// The `qdb_ucsX_to_utf8` functions will write to this buffer. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_new() -> *mut qdb_pystr_buf { Box::into_raw(Box::new(qdb_pystr_buf(String::with_capacity(64)))) @@ -17,7 +43,7 @@ pub unsafe extern "C" fn qdb_pystr_buf_tell(b: *mut qdb_pystr_buf) -> usize { b.0.len() } -/// Trim the string to the given length. Use in conjunction with `tell`. +/// Trim the buffer to the given length. Use in conjunction with `tell`. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_truncate( b: *mut qdb_pystr_buf, len: usize) { @@ -32,6 +58,7 @@ pub unsafe extern "C" fn qdb_pystr_buf_clear(b: *mut qdb_pystr_buf) { b.0.clear() } +/// Free the buffer. Must be called after `qdb_pystr_buf_new`. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_free(b: *mut qdb_pystr_buf) { if !b.is_null() { @@ -49,6 +76,9 @@ fn encode_ucs1(dest: &mut String, buf: &[u8]) { } } +/// Convert a Py_UCS1 string to UTF-8. +/// Returns a `buf_out` borrowed ptr of `size_out` len. +/// The buffer is borrowed either from `input` or from `b`. #[no_mangle] pub unsafe extern "C" fn qdb_ucs1_to_utf8( b: *mut qdb_pystr_buf, @@ -95,6 +125,10 @@ fn encode_ucs2(dest: &mut String, buf: &[u16]) -> bool { true } +/// Convert a Py_UCS2 string to UTF-8. +/// Returns a `buf_out` borrowed ptr of `size_out` len. +/// The buffer is borrowed from `b`. +/// In case of errors, returns `false` and the buffer is an error message. #[no_mangle] pub unsafe extern "C" fn qdb_ucs2_to_utf8(b: *mut qdb_pystr_buf, count: usize, input: *const u16, @@ -126,6 +160,10 @@ fn encode_ucs4(dest: &mut String, buf: &[u32]) -> bool { true } +/// Convert a Py_UCS4 string to UTF-8. +/// Returns a `buf_out` borrowed ptr of `size_out` len. +/// The buffer is borrowed from `b`. +/// In case of errors, returns `false` and the buffer is an error message. #[no_mangle] pub unsafe extern "C" fn qdb_ucs4_to_utf8(b: *mut qdb_pystr_buf, count: usize, input: *const u32, From 161f6aef973f057b742e2a09ffb2e5ec6749c403 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 7 Nov 2022 17:28:46 +0000 Subject: [PATCH 023/147] cbindgen fixup & including lib headers from setup.py --- pystr-to-utf8/build.rs | 1 + setup.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pystr-to-utf8/build.rs b/pystr-to-utf8/build.rs index 14a2e71d..dcb1ce9f 100644 --- a/pystr-to-utf8/build.rs +++ b/pystr-to-utf8/build.rs @@ -1,6 +1,7 @@ #[cfg(feature = "cbindgen")] extern crate cbindgen; +#[cfg(feature = "cbindgen")] const BAD_PXD: &str = " cdef extern from *: ctypedef bint bool diff --git a/setup.py b/setup.py index 585a64b1..5afb8322 100755 --- a/setup.py +++ b/setup.py @@ -66,7 +66,9 @@ def ingress_extension(): return Extension( "questdb.ingress", ["src/questdb/ingress.pyx"], - include_dirs=["c-questdb-client/include"], + include_dirs=[ + "c-questdb-client/include", + "pystr-to-utf8/include"], library_dirs=lib_paths, libraries=libraries, extra_compile_args=extra_compile_args, From 5b5d58bbc836731e193426ad724fc985798d12ec Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 7 Nov 2022 18:52:48 +0000 Subject: [PATCH 024/147] Wrote Cython function to invoke 'pystr-to-utf8' lib. Additional refactoring. --- .vscode/settings.json | 3 +- pystr-to-utf8/build.rs | 3 +- pystr-to-utf8/src/lib.rs | 22 ++---- src/questdb/ingress.pyx | 75 ++++++++++++++++++- .../include => src/questdb}/pystr_to_utf8.pxd | 16 ++-- 5 files changed, 90 insertions(+), 29 deletions(-) rename {pystr-to-utf8/include => src/questdb}/pystr_to_utf8.pxd (81%) diff --git a/.vscode/settings.json b/.vscode/settings.json index a7d0fc7b..0963694b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "esbonio.sphinx.confDir": "" + "esbonio.sphinx.confDir": "", + "cmake.configureOnOpen": false } \ No newline at end of file diff --git a/pystr-to-utf8/build.rs b/pystr-to-utf8/build.rs index dcb1ce9f..28f15936 100644 --- a/pystr-to-utf8/build.rs +++ b/pystr-to-utf8/build.rs @@ -40,8 +40,9 @@ fn main() -> Result<(), Box> { } let pxd = pxd.replace(BAD_PXD, ""); let pxd = pxd.replace("bool", "bint"); + let pxd = pxd.replace(";", ""); // println!("{}", &pxd); - std::fs::write("include/pystr_to_utf8.pxd", &pxd)?; + std::fs::write("../src/questdb/pystr_to_utf8.pxd", &pxd)?; Ok(()) } diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index 936920b8..045e4d0b 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -86,20 +86,10 @@ pub unsafe extern "C" fn qdb_ucs1_to_utf8( size_out: *mut usize, buf_out: *mut *const c_char) { let b = &mut *b; let i = from_raw_parts(input, count); - if i.is_ascii() { - // Zero-copy optmization: - // is_ascii does a WORD-sized scan, so it's faster than the copy logic. - // We can also avoid the copy altogether and return back the same ptr. - // We get away with this because 7-bit ascii is a subset of UTF-8. - *size_out = count; - *buf_out = input as *const c_char; - } - else { - let last = b.0.len(); - encode_ucs1(&mut b.0, i); - *size_out = b.0.len() - last; - *buf_out = b.0.as_ptr() as *const c_char; - } + let last = b.0.len(); + encode_ucs1(&mut b.0, i); + *size_out = b.0.len() - last; + *buf_out = b.0.as_ptr() as *const c_char; } #[inline] @@ -117,7 +107,7 @@ fn encode_ucs2(dest: &mut String, buf: &[u16]) -> bool { Some(c) => dest.push(c), None => { dest.clear(); - write!(dest, "invalid ucs2 code point: {}", b).unwrap(); + write!(dest, "invalid UCS-2 code point: {}", b).unwrap(); return false } } @@ -152,7 +142,7 @@ fn encode_ucs4(dest: &mut String, buf: &[u32]) -> bool { Some(c) => dest.push(c), None => { dest.clear(); - write!(dest, "invalid ucs4 code point: {}", b).unwrap(); + write!(dest, "invalid UCS-4 code point: {}", b).unwrap(); return false } } diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index a141a167..f915150c 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -31,7 +31,7 @@ API for fast data ingestion into QuestDB. """ # For prototypes: https://github.com/cython/cython/tree/master/Cython/Includes -from libc.stdint cimport uint8_t, uint64_t, int64_t +from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t from libc.stdlib cimport malloc, calloc, realloc, free, abort from cpython.datetime cimport datetime from cpython.bool cimport bool, PyBool_Check @@ -41,12 +41,16 @@ from cpython.float cimport PyFloat_Check from cpython.int cimport PyInt_Check from cpython.unicode cimport PyUnicode_Check from cpython.buffer cimport Py_buffer, PyObject_CheckBuffer, \ - PyObject_GetBuffer, PyBuffer_Release, PyBUF_STRIDES + PyObject_GetBuffer, PyBuffer_Release, PyBUF_READ, PyBUF_STRIDES +from cpython.memoryview cimport PyMemoryView_FromMemory from .line_sender cimport * +from .pystr_to_utf8 cimport * cdef extern from "Python.h": ctypedef uint8_t Py_UCS1 # unicodeobject.h + ctypedef uint16_t Py_UCS2 + ctypedef uint32_t Py_UCS4 ctypedef unsigned int uint @@ -73,8 +77,11 @@ cdef extern from "Python.h": # Get length. Py_ssize_t PyUnicode_GET_LENGTH(object o) - # Zero-copy access to buffer. + # Zero-copy access to string buffer. + int PyUnicode_KIND(object o) Py_UCS1* PyUnicode_1BYTE_DATA(object o) + Py_UCS2* PyUnicode_2BYTE_DATA(object o) + Py_UCS4* PyUnicode_4BYTE_DATA(object o) Py_ssize_t PyBytes_GET_SIZE(object o) @@ -165,6 +172,68 @@ cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): return IngressError(tup[0], fmt.format(tup[1])) +cdef object _unpack_utf8_decode_error(line_sender_utf8* err_msg): + cdef object mview + cdef str msg + mview = PyMemoryView_FromMemory( + err_msg.buf, + err_msg.len, + PyBUF_READ) + return IngressError(IngressErrorCode.InvalidUtf8, mview.decode('utf-8')) + + +cdef bint str_to_buffered_utf8( + qdb_pystr_buf* b, + str string, + line_sender_utf8* utf8_out) except False: + cdef size_t count + cdef int kind + PyUnicode_READY(string) + count = (PyUnicode_GET_LENGTH(string)) + + # We optimize the common case of ASCII strings. + # This avoid memory allocations and copies altogether. + # We get away with this because ASCII is a subset of UTF-8. + if PyUnicode_IS_COMPACT_ASCII(string): + utf8_out.len = count + utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) + return True + + kind = PyUnicode_KIND(string) + if kind == PyUnicode_1BYTE_KIND: + # No error handling for UCS1: All code points translate into valid UTF8. + qdb_ucs1_to_utf8( + b, + count, + PyUnicode_1BYTE_DATA(string), + &utf8_out.len, + &utf8_out.buf) + elif kind == PyUnicode_2BYTE_KIND: + if not qdb_ucs2_to_utf8( + b, + count, + PyUnicode_2BYTE_DATA(string), + &utf8_out.len, + &utf8_out.buf): + raise _unpack_utf8_decode_error(utf8_out) + elif kind == PyUnicode_4BYTE_KIND: + if not qdb_ucs4_to_utf8( + b, + count, + + # This cast is required and is possibly a Cython compiler bug. + # It doesn't recognize that `const Py_UCS4*` + # is the same as `const uint32_t*`. + PyUnicode_4BYTE_DATA(string), + + &utf8_out.len, + &utf8_out.buf): + raise _unpack_utf8_decode_error(utf8_out) + else: + raise ValueError(f'Unknown UCS kind: {kind}.') + return True + + cdef bytes str_to_utf8(str string, line_sender_utf8* utf8_out): """ Init the `utf8_out` object from the `string`. diff --git a/pystr-to-utf8/include/pystr_to_utf8.pxd b/src/questdb/pystr_to_utf8.pxd similarity index 81% rename from pystr-to-utf8/include/pystr_to_utf8.pxd rename to src/questdb/pystr_to_utf8.pxd index 70900c3d..d3b57bbe 100644 --- a/pystr-to-utf8/include/pystr_to_utf8.pxd +++ b/src/questdb/pystr_to_utf8.pxd @@ -8,19 +8,19 @@ cdef extern from "pystr_to_utf8.h": # Prepare a new buffer. The buffer must be freed with `qdb_pystr_free`. # The `qdb_ucsX_to_utf8` functions will write to this buffer. - qdb_pystr_buf *qdb_pystr_buf_new(); + qdb_pystr_buf *qdb_pystr_buf_new() # Get current position. Use in conjunction with `truncate`. - size_t qdb_pystr_buf_tell(qdb_pystr_buf *b); + size_t qdb_pystr_buf_tell(qdb_pystr_buf *b) # Trim the buffer to the given length. Use in conjunction with `tell`. - void qdb_pystr_buf_truncate(qdb_pystr_buf *b, size_t len); + void qdb_pystr_buf_truncate(qdb_pystr_buf *b, size_t len) # Reset the converter's buffer to zero length. - void qdb_pystr_buf_clear(qdb_pystr_buf *b); + void qdb_pystr_buf_clear(qdb_pystr_buf *b) # Free the buffer. Must be called after `qdb_pystr_buf_new`. - void qdb_pystr_buf_free(qdb_pystr_buf *b); + void qdb_pystr_buf_free(qdb_pystr_buf *b) # Convert a Py_UCS1 string to UTF-8. # Returns a `buf_out` borrowed ptr of `size_out` len. @@ -29,7 +29,7 @@ cdef extern from "pystr_to_utf8.h": size_t count, const uint8_t *input, size_t *size_out, - const char **buf_out); + const char **buf_out) # Convert a Py_UCS2 string to UTF-8. # Returns a `buf_out` borrowed ptr of `size_out` len. @@ -39,7 +39,7 @@ cdef extern from "pystr_to_utf8.h": size_t count, const uint16_t *input, size_t *size_out, - const char **buf_out); + const char **buf_out) # Convert a Py_UCS4 string to UTF-8. # Returns a `buf_out` borrowed ptr of `size_out` len. @@ -49,4 +49,4 @@ cdef extern from "pystr_to_utf8.h": size_t count, const uint32_t *input, size_t *size_out, - const char **buf_out); + const char **buf_out) From 12598c4bf96d61f2c3d0507bb74c8036c2f1d225 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 8 Nov 2022 09:45:09 +0000 Subject: [PATCH 025/147] Transitioned all string buffer conversions to new Rust code lib. --- pystr-to-utf8/src/lib.rs | 2 +- src/questdb/ingress.pyx | 210 +++++++++++++++++++++++---------------- 2 files changed, 123 insertions(+), 89 deletions(-) diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index 045e4d0b..da2b40f6 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -78,7 +78,7 @@ fn encode_ucs1(dest: &mut String, buf: &[u8]) { /// Convert a Py_UCS1 string to UTF-8. /// Returns a `buf_out` borrowed ptr of `size_out` len. -/// The buffer is borrowed either from `input` or from `b`. +/// The buffer is borrowed from `b`. #[no_mangle] pub unsafe extern "C" fn qdb_ucs1_to_utf8( b: *mut qdb_pystr_buf, diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index f915150c..e495f6cd 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -182,10 +182,18 @@ cdef object _unpack_utf8_decode_error(line_sender_utf8* err_msg): return IngressError(IngressErrorCode.InvalidUtf8, mview.decode('utf-8')) -cdef bint str_to_buffered_utf8( +cdef bint str_to_utf8( qdb_pystr_buf* b, str string, line_sender_utf8* utf8_out) except False: + """ + Convert a Python string to a UTF-8 borrowed buffer. + This is done without allocating new Python `bytes` objects. + In case the string is an ASCII string, it's also generally zero-copy. + The `utf8_out` param will point to (borrow from) either the ASCII buffer + inside the original Python object or a part of memory allocated inside the + `b` buffer. + """ cdef size_t count cdef int kind PyUnicode_READY(string) @@ -234,53 +242,36 @@ cdef bint str_to_buffered_utf8( return True -cdef bytes str_to_utf8(str string, line_sender_utf8* utf8_out): - """ - Init the `utf8_out` object from the `string`. - If the string is held as a UCS1 and is purely ascii, then - the memory is borrowed. - Otherwise the string is first encoded to UTF-8 into a bytes object - and such bytes object is returned to transfer ownership and extend - the lifetime of the buffer pointed to by `utf8_out`. - """ - # Note that we bypass `line_sender_utf8_init`. - cdef bytes owner = None - PyUnicode_READY(string) - if PyUnicode_IS_COMPACT_ASCII(string): - utf8_out.len = (PyUnicode_GET_LENGTH(string)) - utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) - return owner - else: - owner = string.encode('utf-8') - utf8_out.len = (PyBytes_GET_SIZE(owner)) - utf8_out.buf = (PyBytes_AsString(owner)) - return owner - - -cdef bytes str_to_table_name(str string, line_sender_table_name* name_out): +cdef bint str_to_table_name( + qdb_pystr_buf* b, + str string, + line_sender_table_name* name_out) except False: """ Python string to borrowed C table name. Also see `str_to_utf8`. """ cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - cdef bytes owner = str_to_utf8(string, &utf8) + str_to_utf8(b, string, &utf8) if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): raise c_err_to_py(err) - return owner + return True -cdef bytes str_to_column_name(str string, line_sender_column_name* name_out): +cdef bint str_to_column_name( + qdb_pystr_buf* b, + str string, + line_sender_column_name* name_out) except False: """ Python string to borrowed C column name. Also see `str_to_utf8`. """ cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - cdef bytes owner = str_to_utf8(string, &utf8) + str_to_utf8(b, string, &utf8) if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): raise c_err_to_py(err) - return owner + return True cdef int64_t datetime_to_micros(datetime dt): @@ -490,6 +481,7 @@ cdef class Buffer: """ cdef line_sender_buffer* _impl + cdef qdb_pystr_buf* _b cdef size_t _init_capacity cdef size_t _max_name_len cdef object _row_complete_sender @@ -504,6 +496,7 @@ cdef class Buffer: cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): self._impl = line_sender_buffer_with_max_name_len(max_name_len) + self._b = qdb_pystr_buf_new() line_sender_buffer_reserve(self._impl, init_capacity) self._init_capacity = init_capacity self._max_name_len = max_name_len @@ -511,6 +504,7 @@ cdef class Buffer: def __dealloc__(self): self._row_complete_sender = None + qdb_pystr_buf_free(self._b) line_sender_buffer_free(self._impl) @property @@ -557,6 +551,7 @@ cdef class Buffer: ``sender.flush(buffer, clear=False)``. """ line_sender_buffer_clear(self._impl) + qdb_pystr_buf_clear(self._b) def __len__(self) -> int: """ @@ -591,17 +586,21 @@ cdef class Buffer: cdef inline int _table(self, str table_name) except -1: cdef line_sender_error* err = NULL cdef line_sender_table_name c_table_name - cdef bytes owner = str_to_table_name(table_name, &c_table_name) + str_to_table_name(self._cleared_b(), table_name, &c_table_name) if not line_sender_buffer_table(self._impl, c_table_name, &err): raise c_err_to_py(err) return 0 + cdef inline qdb_pystr_buf* _cleared_b(self): + qdb_pystr_buf_clear(self._b) + return self._b + cdef inline int _symbol(self, str name, str value) except -1: cdef line_sender_error* err = NULL cdef line_sender_column_name c_name cdef line_sender_utf8 c_value - cdef bytes owner_name = str_to_column_name(name, &c_name) - cdef bytes owner_value = str_to_utf8(value, &c_value) + str_to_column_name(self._cleared_b(), name, &c_name) + str_to_utf8(self._b, value, &c_value) if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): raise c_err_to_py(err) return 0 @@ -631,7 +630,7 @@ cdef class Buffer: self, line_sender_column_name c_name, str value) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 c_value - cdef bytes owner_value = str_to_utf8(value, &c_value) + str_to_utf8(self._b, value, &c_value) if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): raise c_err_to_py(err) return 0 @@ -653,7 +652,7 @@ cdef class Buffer: cdef inline int _column(self, str name, object value) except -1: cdef line_sender_column_name c_name - cdef bytes owner_name = str_to_column_name(name, &c_name) + str_to_column_name(self._cleared_b(), name, &c_name) if PyBool_Check(value): return self._column_bool(c_name, value) elif PyInt_Check(value): @@ -1012,14 +1011,14 @@ cdef class Buffer: # """ # raise ValueError('nyi') - cdef _pandas( + cdef bint _pandas( self, object data, object table_name, object table_name_col, object symbols, object at, - bint sort): + bint sort) except False: # First, we need to make sure that `data` is a dataframe. # We specifically avoid using `isinstance` here because we don't want # to add a library dependency on pandas itself. We simply rely on its API. @@ -1032,7 +1031,7 @@ cdef class Buffer: cdef size_t_vec symbol_indices = size_t_vec_new() cdef size_t_vec field_indices = size_t_vec_new() cdef ssize_t at_col - cdef int64_t at_value + cdef int64_t at_value = 0 cdef column_name_vec symbol_names = column_name_vec_new() cdef column_name_vec field_names = column_name_vec_new() cdef list name_owners = None @@ -1043,14 +1042,17 @@ cdef class Buffer: try: _check_is_pandas_dataframe(data) col_count = len(data.columns) - name_col, name_owner = _pandas_resolve_table_name( + qdb_pystr_buf_clear(self._b) + name_col = _pandas_resolve_table_name( + self._b, data, table_name, table_name_col, col_count, &c_table_name) - at_col, at_value = _pandas_resolve_at(data, at, col_count) + at_col = _pandas_resolve_at(data, at, col_count, &at_value) _pandas_resolve_symbols( data, at_col, symbols, col_count, &symbol_indices) _pandas_resolve_fields( name_col, &symbol_indices, at_col, col_count, &field_indices) - name_owners = _pandas_resolve_col_names( + _pandas_resolve_col_names( + self._b, data, &symbol_indices, &field_indices, &symbol_names, &field_names) dtypes = calloc(col_count, sizeof(dtype_t)) @@ -1061,7 +1063,6 @@ cdef class Buffer: import sys sys.stderr.write('_pandas :: (A) ' + f'name_col: {name_col}, ' + - f'name_owner: {name_owner}, ' + f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + f'at_col: {at_col}, ' + f'at_value: {at_value}, ' + @@ -1074,6 +1075,7 @@ cdef class Buffer: # else: # if not line_sender_buffer_table(self._impl, c_table_name, &err): # raise c_err_to_py(err) + return True finally: if col_buffers != NULL: for col_index in range(set_buf_count): @@ -1101,7 +1103,22 @@ cdef class Buffer: """ # See https://cython.readthedocs.io/en/latest/src/userguide/ # numpy_tutorial.html#numpy-tutorial + import sys + sys.stderr.write('pandas :: (A) ' + + f'table_name: {table_name}, ' + + f'table_name_col: {table_name_col}, ' + + f'symbols: {symbols}, ' + + f'at: {at}, ' + + f'sort: {sort}' + + '\n') self._pandas(data, table_name, table_name_col, symbols, at, sort) + sys.stderr.write('pandas :: (B) ' + + f'table_name: {table_name}, ' + + f'table_name_col: {table_name_col}, ' + + f'symbols: {symbols}, ' + + f'at: {at}, ' + + f'sort: {sort}' + + '\n') cdef struct c_size_t_vec: @@ -1207,12 +1224,13 @@ cdef struct column_buf_t: # NB: We don't support suboffsets. -cdef tuple _pandas_resolve_table_name( +cdef ssize_t _pandas_resolve_table_name( + qdb_pystr_buf* b, object data, object table_name, object table_name_col, size_t col_count, - line_sender_table_name* name_out): + line_sender_table_name* name_out) except -2: """ Return a tuple-pair of: * int column index @@ -1234,7 +1252,8 @@ cdef tuple _pandas_resolve_table_name( 'Can specify only one of `table_name` or `table_name_col`.') if isinstance(table_name, str): try: - return -1, str_to_table_name(table_name, name_out) + str_to_table_name(b, table_name, name_out) + return -1 # Magic value for "no column index". except IngressError as ie: raise ValueError(f'Bad argument `table_name`: {ie}') else: @@ -1254,7 +1273,7 @@ cdef tuple _pandas_resolve_table_name( col_index, 'Bad argument `table_name_col`: ', table_name_col) - return col_index, None + return col_index else: raise ValueError( 'Must specify at least one of `table_name` or `table_name_col`.') @@ -1267,9 +1286,10 @@ cdef int _pandas_resolve_fields( size_t col_count, size_t_vec* field_indices_out) except -1: """ - Return a list of field column indices. - i.e. a list of all columns which are not the table name column, symbols or - the at timestamp column. + Populate vec of field column indices via `field_indices_out`. + Returns the length of the list. + The vec will contain all columns which are not the table name column, + symbols or the at timestamp column. """ # We rely on `symbol_indices` being sorted. cdef size_t col_index = 0 @@ -1292,24 +1312,24 @@ cdef int _pandas_resolve_fields( return 0 -cdef list _pandas_resolve_col_names( +cdef bint _pandas_resolve_col_names( + qdb_pystr_buf* b, object data, const size_t_vec* symbol_indices, const size_t_vec* field_indices, column_name_vec* symbol_names_out, - column_name_vec* field_names_out): - cdef list name_owners = [] + column_name_vec* field_names_out) except False: cdef line_sender_column_name c_name cdef size_t col_index for col_index in range(symbol_indices.size): col_index = symbol_indices.d[col_index] - name_owners.append(str_to_column_name(data.columns[col_index], &c_name)) + str_to_column_name(b, data.columns[col_index], &c_name) column_name_vec_push(symbol_names_out, c_name) for col_index in range(field_indices.size): col_index = field_indices.d[col_index] - name_owners.append(str_to_column_name(data.columns[col_index], &c_name)) + str_to_column_name(b, data.columns[col_index], &c_name) column_name_vec_push(field_names_out, c_name) - return name_owners + return True cdef bint _bind_col_index( @@ -1339,6 +1359,7 @@ cdef object _pandas_column_is_str(object data, int col_index): """ Return True if the column at `col_index` is a string column. """ + # NB: Returning `object` rather than `bint` to allow for exceptions. cdef str col_kind cdef object col col_kind = data.dtypes[col_index].kind @@ -1380,7 +1401,8 @@ cdef int _pandas_resolve_symbols( size_t col_count, size_t_vec* symbol_indices_out) except -1: """ - Return a list of column indices. + Populate vec of symbol column indices via `symbol_indices_out`. + Returns the length of the vec. """ cdef size_t col_index = 0 cdef object symbol @@ -1433,15 +1455,22 @@ cdef bint _pandas_get_loc( f'Column {col_name!r} not found in the dataframe.') -cdef tuple _pandas_resolve_at(object data, object at, size_t col_count): +cdef ssize_t _pandas_resolve_at( + object data, + object at, + size_t col_count, + int64_t* at_value_out) except -2: cdef size_t col_index cdef str col_kind if at is None: - return -1, 0 # Special value for `at_now`. + at_value_out[0] = 0 # Special value for `at_now`. + return -1 elif isinstance(at, TimestampNanos): - return -1, at._value + at_value_out[0] = at._value + return -1 elif isinstance(at, datetime): - return -1, datetime_to_nanos(at) + at_value_out[0] = datetime_to_nanos(at) + return -1 elif isinstance(at, str): _pandas_get_loc(data, at, 'at', &col_index) elif isinstance(at, int): @@ -1453,7 +1482,8 @@ cdef tuple _pandas_resolve_at(object data, object at, size_t col_count): 'int (column index), str (colum name)') col_kind = data.dtypes[col_index].kind if col_kind == 'M': # datetime - return col_index, 0 + at_value_out[0] = 0 + return col_index else: raise TypeError( f'Bad argument `at`: Bad dtype `{data.dtypes[col_index]}` ' + @@ -1483,7 +1513,7 @@ cdef char _str_to_char(str field, str s) except 0: return res -cdef int _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except -1: +cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: """ Parse a numpy dtype and return a dtype_t. """ @@ -1492,18 +1522,20 @@ cdef int _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except -1: dtype_out.itemsize = np_dtype.itemsize dtype_out.byteorder = _str_to_char('byteorder', np_dtype.byteorder) dtype_out.hasobject = np_dtype.hasobject + return True -cdef int _pandas_resolve_dtypes( - object data, size_t col_count, dtype_t* dtypes_out) except -1: +cdef bint _pandas_resolve_dtypes( + object data, size_t col_count, dtype_t* dtypes_out) except False: cdef size_t col_index for col_index in range(col_count): _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) + return True -cdef int _pandas_resolve_col_buffers( +cdef bint _pandas_resolve_col_buffers( object data, size_t col_count, const dtype_t* dtypes, - Py_buffer* col_buffers, size_t* set_buf_count) except -1: + Py_buffer* col_buffers, size_t* set_buf_count) except False: """ Map pandas columns to array of col_buffers. """ @@ -1523,7 +1555,8 @@ cdef int _pandas_resolve_col_buffers( raise TypeError( f'Bad column: Expected a numpy array, got {nparr!r}') PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) - set_buf_count[0] += 1 # Set to avoid wrongly calling `PyBuffer_Release`. + set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. + return True _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' @@ -1685,15 +1718,12 @@ cdef class Sender: cdef line_sender_error* err = NULL cdef line_sender_utf8 host_utf8 - cdef bytes host_owner cdef str port_str cdef line_sender_utf8 port_utf8 - cdef bytes port_owner cdef str interface_str cdef line_sender_utf8 interface_utf8 - cdef bytes interface_owner cdef str a_key_id cdef bytes a_key_id_owner @@ -1711,12 +1741,21 @@ cdef class Sender: cdef bytes a_pub_key_y_owner cdef line_sender_utf8 a_pub_key_y_utf8 - cdef bytes ca_owner cdef line_sender_utf8 ca_utf8 + cdef qdb_pystr_buf* b + self._opts = NULL self._impl = NULL - self._buffer = None + + self._init_capacity = init_capacity + self._max_name_len = max_name_len + + self._buffer = Buffer( + init_capacity=init_capacity, + max_name_len=max_name_len) + + b = self._buffer._b if PyInt_Check(port): port_str = str(port) @@ -1726,12 +1765,12 @@ cdef class Sender: raise TypeError( f'port must be an integer or a string, not {type(port)}') - host_owner = str_to_utf8(host, &host_utf8) - port_owner = str_to_utf8(port_str, &port_utf8) + str_to_utf8(b, host, &host_utf8) + str_to_utf8(b, port_str, &port_utf8) self._opts = line_sender_opts_new_service(host_utf8, port_utf8) if interface is not None: - interface_owner = str_to_utf8(interface, &interface_utf8) + str_to_utf8(b, interface, &interface_utf8) line_sender_opts_net_interface(self._opts, interface_utf8) if auth is not None: @@ -1739,10 +1778,10 @@ cdef class Sender: a_priv_key, a_pub_key_x, a_pub_key_y) = auth - a_key_id_owner = str_to_utf8(a_key_id, &a_key_id_utf8) - a_priv_key_owner = str_to_utf8(a_priv_key, &a_priv_key_utf8) - a_pub_key_x_owner = str_to_utf8(a_pub_key_x, &a_pub_key_x_utf8) - a_pub_key_y_owner = str_to_utf8(a_pub_key_y, &a_pub_key_y_utf8) + str_to_utf8(b, a_key_id, &a_key_id_utf8) + str_to_utf8(b, a_priv_key, &a_priv_key_utf8) + str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) + str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) line_sender_opts_auth( self._opts, a_key_id_utf8, @@ -1757,11 +1796,11 @@ cdef class Sender: if tls == 'insecure_skip_verify': line_sender_opts_tls_insecure_skip_verify(self._opts) else: - ca_owner = str_to_utf8(tls, &ca_utf8) + str_to_utf8(b, tls, &ca_utf8) line_sender_opts_tls_ca(self._opts, ca_utf8) elif isinstance(tls, pathlib.Path): tls = str(tls) - ca_owner = str_to_utf8(tls, &ca_utf8) + str_to_utf8(b, tls, &ca_utf8) line_sender_opts_tls_ca(self._opts, ca_utf8) else: raise TypeError( @@ -1771,13 +1810,6 @@ cdef class Sender: if read_timeout is not None: line_sender_opts_read_timeout(self._opts, read_timeout) - self._init_capacity = init_capacity - self._max_name_len = max_name_len - - self._buffer = Buffer( - init_capacity=init_capacity, - max_name_len=max_name_len) - self._auto_flush_enabled = not not auto_flush self._auto_flush_watermark = int(auto_flush) \ if self._auto_flush_enabled else 0 @@ -1785,6 +1817,8 @@ cdef class Sender: raise ValueError( 'auto_flush_watermark must be >= 0, ' f'not {self._auto_flush_watermark}') + + qdb_pystr_buf_clear(b) def new_buffer(self): """ From 3544312869990b061adb0ad3e7bf721344942f26 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 8 Nov 2022 10:48:15 +0000 Subject: [PATCH 026/147] Made pystr_to_utf8 addresses stable. --- pystr-to-utf8/include/pystr_to_utf8.h | 12 +++-- pystr-to-utf8/src/lib.rs | 63 +++++++++++++++++++++------ src/questdb/pystr_to_utf8.pxd | 10 +++-- 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/pystr-to-utf8/include/pystr_to_utf8.h b/pystr-to-utf8/include/pystr_to_utf8.h index 4fc15c4f..44353c72 100644 --- a/pystr-to-utf8/include/pystr_to_utf8.h +++ b/pystr-to-utf8/include/pystr_to_utf8.h @@ -32,6 +32,12 @@ typedef struct qdb_pystr_buf qdb_pystr_buf; +typedef struct +{ + size_t chain; + size_t string; +} qdb_pystr_pos; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -45,13 +51,13 @@ qdb_pystr_buf *qdb_pystr_buf_new(void); /** * Get current position. Use in conjunction with `truncate`. */ -size_t qdb_pystr_buf_tell(qdb_pystr_buf *b); +qdb_pystr_pos qdb_pystr_buf_tell(qdb_pystr_buf *b); /** * Trim the buffer to the given length. Use in conjunction with `tell`. */ void qdb_pystr_buf_truncate(qdb_pystr_buf *b, - size_t len); + qdb_pystr_pos pos); /** * Reset the converter's buffer to zero length. @@ -66,7 +72,7 @@ void qdb_pystr_buf_free(qdb_pystr_buf *b); /** * Convert a Py_UCS1 string to UTF-8. * Returns a `buf_out` borrowed ptr of `size_out` len. - * The buffer is borrowed either from `input` or from `b`. + * The buffer is borrowed from `b`. */ void qdb_ucs1_to_utf8(qdb_pystr_buf *b, size_t count, diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index da2b40f6..70b37e84 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -27,35 +27,55 @@ use std::fmt::Write; use std::slice::from_raw_parts; #[allow(non_camel_case_types)] -pub struct qdb_pystr_buf(String); +pub struct qdb_pystr_buf(Vec); + +#[repr(C)] +#[allow(non_camel_case_types)] +#[derive(Debug, Clone, Copy)] +pub struct qdb_pystr_pos { + pub chain: usize, + pub string: usize +} /// Prepare a new buffer. The buffer must be freed with `qdb_pystr_free`. /// The `qdb_ucsX_to_utf8` functions will write to this buffer. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_new() -> *mut qdb_pystr_buf { - Box::into_raw(Box::new(qdb_pystr_buf(String::with_capacity(64)))) + Box::into_raw(Box::new(qdb_pystr_buf(Vec::new()))) } /// Get current position. Use in conjunction with `truncate`. #[no_mangle] -pub unsafe extern "C" fn qdb_pystr_buf_tell(b: *mut qdb_pystr_buf) -> usize { +pub unsafe extern "C" fn qdb_pystr_buf_tell( + b: *mut qdb_pystr_buf) -> qdb_pystr_pos { let b = &mut *b; - b.0.len() + let chain_pos = b.0.len(); + let string_pos = if chain_pos > 0 { + b.0[chain_pos - 1].len() + } else { + 0 + }; + qdb_pystr_pos { chain: chain_pos, string: string_pos } } /// Trim the buffer to the given length. Use in conjunction with `tell`. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_truncate( - b: *mut qdb_pystr_buf, len: usize) { + b: *mut qdb_pystr_buf, pos: qdb_pystr_pos) { let b = &mut *b; - b.0.truncate(len) + b.0.truncate(pos.chain + 1); + if !b.0.is_empty() { + b.0[pos.chain].truncate(pos.string); + } } /// Reset the converter's buffer to zero length. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_clear(b: *mut qdb_pystr_buf) { let b = &mut *b; - b.0.clear() + if !b.0.is_empty() { + b.0.clear(); + } } /// Free the buffer. Must be called after `qdb_pystr_buf_new`. @@ -66,11 +86,28 @@ pub unsafe extern "C" fn qdb_pystr_buf_free(b: *mut qdb_pystr_buf) { } } +const MIN_BUF_LEN: usize = 64; + +/// A carefully crafted buffer with spare capacity for `len` bytes. +/// This is necessary to return "stable" addresses and avoid segfaults. +/// Rust is unaware we are borrowing its memory and could try to free it as +/// part of a reallocation if we were to use a `String` directly. +fn get_dest<'a>(chain: &'a mut Vec, len: usize) -> &'a mut String { + if !chain.is_empty() { + let last = chain.last_mut().unwrap(); + if last.capacity() - last.len() >= len { + return chain.last_mut().unwrap(); + } + } + chain.push(String::with_capacity(std::cmp::max(len, MIN_BUF_LEN))); + chain.last_mut().unwrap() +} + #[inline] -fn encode_ucs1(dest: &mut String, buf: &[u8]) { +fn encode_ucs1(chain: &mut Vec, buf: &[u8]) { // len(chr(2 ** 8 - 1).encode('utf-8')) == 2 let utf8_mult = 2; - dest.reserve(utf8_mult * buf.len()); + let dest = get_dest(chain, utf8_mult * buf.len()); for &b in buf.iter() { dest.push(b as char); } @@ -93,10 +130,10 @@ pub unsafe extern "C" fn qdb_ucs1_to_utf8( } #[inline] -fn encode_ucs2(dest: &mut String, buf: &[u16]) -> bool { +fn encode_ucs2(chain: &mut Vec, buf: &[u16]) -> bool { // len(chr(2 ** 16 - 1).encode('utf-8')) == 3 let utf8_mult = 3; - dest.reserve(utf8_mult * buf.len()); + let dest = get_dest(chain, utf8_mult * buf.len()); for b in buf.iter() { // Checking for validity is not optional: // >>> for n in range(2 ** 16): @@ -133,10 +170,10 @@ pub unsafe extern "C" fn qdb_ucs2_to_utf8(b: *mut qdb_pystr_buf, } #[inline] -fn encode_ucs4(dest: &mut String, buf: &[u32]) -> bool { +fn encode_ucs4(chain: &mut Vec, buf: &[u32]) -> bool { // Max 4 bytes allowed by RFC: https://www.rfc-editor.org/rfc/rfc3629#page-4 let utf8_mult = 4; - dest.reserve(utf8_mult * buf.len()); + let dest = get_dest(chain, utf8_mult * buf.len()); for b in buf.iter() { match char::from_u32(*b) { Some(c) => dest.push(c), diff --git a/src/questdb/pystr_to_utf8.pxd b/src/questdb/pystr_to_utf8.pxd index d3b57bbe..857d0ee7 100644 --- a/src/questdb/pystr_to_utf8.pxd +++ b/src/questdb/pystr_to_utf8.pxd @@ -6,15 +6,19 @@ cdef extern from "pystr_to_utf8.h": cdef struct qdb_pystr_buf: pass + cdef struct qdb_pystr_pos: + size_t chain + size_t string + # Prepare a new buffer. The buffer must be freed with `qdb_pystr_free`. # The `qdb_ucsX_to_utf8` functions will write to this buffer. qdb_pystr_buf *qdb_pystr_buf_new() # Get current position. Use in conjunction with `truncate`. - size_t qdb_pystr_buf_tell(qdb_pystr_buf *b) + qdb_pystr_pos qdb_pystr_buf_tell(qdb_pystr_buf *b) # Trim the buffer to the given length. Use in conjunction with `tell`. - void qdb_pystr_buf_truncate(qdb_pystr_buf *b, size_t len) + void qdb_pystr_buf_truncate(qdb_pystr_buf *b, qdb_pystr_pos pos) # Reset the converter's buffer to zero length. void qdb_pystr_buf_clear(qdb_pystr_buf *b) @@ -24,7 +28,7 @@ cdef extern from "pystr_to_utf8.h": # Convert a Py_UCS1 string to UTF-8. # Returns a `buf_out` borrowed ptr of `size_out` len. - # The buffer is borrowed either from `input` or from `b`. + # The buffer is borrowed from `b`. void qdb_ucs1_to_utf8(qdb_pystr_buf *b, size_t count, const uint8_t *input, From 9fce68b6ae812e93fe17fedf66a64bab9de6ac6e Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 8 Nov 2022 11:02:53 +0000 Subject: [PATCH 027/147] Rust str to utf8 lib fixes (but still broken - ongoing) --- pystr-to-utf8/src/lib.rs | 49 +++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index 70b37e84..3b4e1017 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -104,13 +104,15 @@ fn get_dest<'a>(chain: &'a mut Vec, len: usize) -> &'a mut String { } #[inline] -fn encode_ucs1(chain: &mut Vec, buf: &[u8]) { +fn encode_ucs1<'a, 'b>(chain: &'a mut Vec, buf: &'b [u8]) -> &'a str { // len(chr(2 ** 8 - 1).encode('utf-8')) == 2 let utf8_mult = 2; let dest = get_dest(chain, utf8_mult * buf.len()); + let last = dest.len(); for &b in buf.iter() { dest.push(b as char); } + &dest[last..] } /// Convert a Py_UCS1 string to UTF-8. @@ -123,17 +125,19 @@ pub unsafe extern "C" fn qdb_ucs1_to_utf8( size_out: *mut usize, buf_out: *mut *const c_char) { let b = &mut *b; let i = from_raw_parts(input, count); - let last = b.0.len(); - encode_ucs1(&mut b.0, i); - *size_out = b.0.len() - last; - *buf_out = b.0.as_ptr() as *const c_char; + let res = encode_ucs1(&mut b.0, i); + *size_out = res.len(); + *buf_out = res.as_ptr() as *const c_char; } #[inline] -fn encode_ucs2(chain: &mut Vec, buf: &[u16]) -> bool { +fn encode_ucs2<'a, 'b>( + chain: &'a mut Vec, buf: &'b [u16]) -> (bool, &'a str) { // len(chr(2 ** 16 - 1).encode('utf-8')) == 3 let utf8_mult = 3; let dest = get_dest(chain, utf8_mult * buf.len()); + let last = dest.len(); + let mut ok = true; for b in buf.iter() { // Checking for validity is not optional: // >>> for n in range(2 ** 16): @@ -143,13 +147,14 @@ fn encode_ucs2(chain: &mut Vec, buf: &[u16]) -> bool { match char::from_u32(*b as u32) { Some(c) => dest.push(c), None => { - dest.clear(); + dest.truncate(last); write!(dest, "invalid UCS-2 code point: {}", b).unwrap(); - return false + ok = false; + break; } } } - true + (ok, &dest[last..]) } /// Convert a Py_UCS2 string to UTF-8. @@ -162,29 +167,32 @@ pub unsafe extern "C" fn qdb_ucs2_to_utf8(b: *mut qdb_pystr_buf, size_out: *mut usize, buf_out: *mut *const c_char) -> bool { let b = &mut *b; let i = from_raw_parts(input, count); - let last = b.0.len(); - let ok = encode_ucs2(&mut b.0, i); - *size_out = b.0.len() - last; - *buf_out = b.0.as_ptr() as *const c_char; + let (ok, res) = encode_ucs2(&mut b.0, i); + *size_out = res.len(); + *buf_out = res.as_ptr() as *const c_char; ok } #[inline] -fn encode_ucs4(chain: &mut Vec, buf: &[u32]) -> bool { +fn encode_ucs4<'a, 'b>( + chain: &'a mut Vec, buf: &'b[u32]) -> (bool, &'a str) { // Max 4 bytes allowed by RFC: https://www.rfc-editor.org/rfc/rfc3629#page-4 let utf8_mult = 4; let dest = get_dest(chain, utf8_mult * buf.len()); + let last = dest.len(); + let mut ok = true; for b in buf.iter() { match char::from_u32(*b) { Some(c) => dest.push(c), None => { - dest.clear(); + dest.truncate(last); write!(dest, "invalid UCS-4 code point: {}", b).unwrap(); - return false + ok = false; + break; } } } - true + (ok, &dest[last..]) } /// Convert a Py_UCS4 string to UTF-8. @@ -197,9 +205,8 @@ pub unsafe extern "C" fn qdb_ucs4_to_utf8(b: *mut qdb_pystr_buf, size_out: *mut usize, buf_out: *mut *const c_char) -> bool { let b = &mut *b; let i = from_raw_parts(input, count); - let last = b.0.len(); - let ok = encode_ucs4(&mut b.0, i); - *size_out = b.0.len() - last; - *buf_out = b.0.as_ptr() as *const c_char; + let (ok, res) = encode_ucs4(&mut b.0, i); + *size_out = res.len(); + *buf_out = res.as_ptr() as *const c_char; ok } From 91553577810df884fbf6d1ece7520c5cf0047623 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 8 Nov 2022 11:30:59 +0000 Subject: [PATCH 028/147] Minor unicode test improvement. Transcoding works now. --- test/test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/test.py b/test/test.py index 98b9a27d..e21566bf 100755 --- a/test/test.py +++ b/test/test.py @@ -109,8 +109,11 @@ def test_no_symbol_or_col_args(self): def test_unicode(self): buf = qi.Buffer() - buf.row('tbl1', symbols={'questdb1': '❤️'}, columns={'questdb2': '❤️'}) - self.assertEqual(str(buf), 'tbl1,questdb1=❤️ questdb2="❤️"\n') + buf.row( + 'tbl1', + symbols={'questdb1': '❤️'}, + columns={'questdb2': '❤️' * 100}) + self.assertEqual(str(buf), f'tbl1,questdb1=❤️ questdb2="{"❤️" * 100}"\n') def test_float(self): buf = qi.Buffer() From f953ad037445d1046c149e9e283fff5d93af66ed Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 8 Nov 2022 17:06:07 +0000 Subject: [PATCH 029/147] Rust PyStr lib tests and a few bugfixes. --- proj.py | 1 + pystr-to-utf8/src/lib.rs | 16 ++-- pystr-to-utf8/src/tests.rs | 169 +++++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 pystr-to-utf8/src/tests.rs diff --git a/proj.py b/proj.py index 28d30539..5ee7a8e4 100755 --- a/proj.py +++ b/proj.py @@ -68,6 +68,7 @@ def build(): @command def test(all=False, patch_path='1', *args): + _run('cargo', 'test', cwd=PROJ_ROOT / 'pystr-to-utf8') env = {'TEST_QUESTDB_PATCH_PATH': patch_path} if _arg2bool(all): env['TEST_QUESTDB_INTEGRATION'] = '1' diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index 3b4e1017..6a2c9095 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -31,7 +31,7 @@ pub struct qdb_pystr_buf(Vec); #[repr(C)] #[allow(non_camel_case_types)] -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct qdb_pystr_pos { pub chain: usize, pub string: usize @@ -47,8 +47,8 @@ pub unsafe extern "C" fn qdb_pystr_buf_new() -> *mut qdb_pystr_buf { /// Get current position. Use in conjunction with `truncate`. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_tell( - b: *mut qdb_pystr_buf) -> qdb_pystr_pos { - let b = &mut *b; + b: *const qdb_pystr_buf) -> qdb_pystr_pos { + let b = &*b; let chain_pos = b.0.len(); let string_pos = if chain_pos > 0 { b.0[chain_pos - 1].len() @@ -63,9 +63,9 @@ pub unsafe extern "C" fn qdb_pystr_buf_tell( pub unsafe extern "C" fn qdb_pystr_buf_truncate( b: *mut qdb_pystr_buf, pos: qdb_pystr_pos) { let b = &mut *b; - b.0.truncate(pos.chain + 1); + b.0.truncate(pos.chain); if !b.0.is_empty() { - b.0[pos.chain].truncate(pos.string); + b.0[pos.chain - 1].truncate(pos.string); } } @@ -74,7 +74,8 @@ pub unsafe extern "C" fn qdb_pystr_buf_truncate( pub unsafe extern "C" fn qdb_pystr_buf_clear(b: *mut qdb_pystr_buf) { let b = &mut *b; if !b.0.is_empty() { - b.0.clear(); + b.0.truncate(1); + b.0[0].clear(); } } @@ -210,3 +211,6 @@ pub unsafe extern "C" fn qdb_ucs4_to_utf8(b: *mut qdb_pystr_buf, *buf_out = res.as_ptr() as *const c_char; ok } + +#[cfg(test)] +mod tests; diff --git a/pystr-to-utf8/src/tests.rs b/pystr-to-utf8/src/tests.rs new file mode 100644 index 00000000..30ddd6fe --- /dev/null +++ b/pystr-to-utf8/src/tests.rs @@ -0,0 +1,169 @@ +use super::*; + +struct Buf { + buf: *mut qdb_pystr_buf, +} + +impl Buf { + fn new() -> Self { + Self { + buf: unsafe { qdb_pystr_buf_new() }, + } + } + + fn chain(&self) -> &Vec { + unsafe { &(*self.buf).0 } + } + + fn chain_mut(&mut self) -> &mut Vec { + unsafe { &mut (*self.buf).0 } + } + + fn clear(&mut self) { + unsafe { qdb_pystr_buf_clear(self.buf) } + } + + fn tell(&self) -> qdb_pystr_pos { + unsafe { qdb_pystr_buf_tell(self.buf) } + } + + fn truncate(&mut self, pos: qdb_pystr_pos) { + unsafe { qdb_pystr_buf_truncate(self.buf, pos) } + } + + fn ucs1_to_utf8(&mut self, input: &[u8]) -> &'static str { + let mut size_out = 0; + let mut buf_out = std::ptr::null(); + unsafe { + qdb_ucs1_to_utf8( + self.buf, + input.len(), + input.as_ptr(), + &mut size_out, + &mut buf_out); + } + let slice = unsafe { + from_raw_parts(buf_out as *const u8, size_out) }; + std::str::from_utf8(slice).unwrap() + } + + fn ucs2_to_utf8(&mut self, input: &[u16]) -> Result<&'static str, &'static str> { + let mut size_out = 0; + let mut buf_out = std::ptr::null(); + let ok = unsafe { + qdb_ucs2_to_utf8( + self.buf, + input.len(), + input.as_ptr(), + &mut size_out, + &mut buf_out) + }; + let slice = unsafe { + from_raw_parts(buf_out as *const u8, size_out) }; + let msg = std::str::from_utf8(slice).unwrap(); + if ok { + Ok(msg) + } else { + Err(msg) + } + } + + fn ucs4_to_utf8(&mut self, input: &[u32]) -> Result<&'static str, &'static str> { + let mut size_out = 0; + let mut buf_out = std::ptr::null(); + let ok = unsafe { + qdb_ucs4_to_utf8( + self.buf, + input.len(), + input.as_ptr(), + &mut size_out, + &mut buf_out) + }; + let slice = unsafe { + from_raw_parts(buf_out as *const u8, size_out) }; + let msg = std::str::from_utf8(slice).unwrap(); + if ok { + Ok(msg) + } else { + Err(msg) + } + } +} + +impl Drop for Buf { + fn drop(&mut self) { + unsafe { + qdb_pystr_buf_free(self.buf); + } + } +} + +#[test] +fn test_empty() { + let b = Buf::new(); + assert_eq!(b.chain().len(), 0); + let pos = b.tell(); + assert_eq!(pos.chain, 0); + assert_eq!(pos.string, 0); +} + +#[test] +fn test_ucs1() { + let mut b = Buf::new(); + let s1 = b.ucs1_to_utf8(b"hello"); + assert_eq!(s1, "hello"); + assert_eq!(b.chain_mut().len(), 1); + assert_eq!(b.chain_mut()[0].as_str().as_ptr(), s1.as_ptr()); + assert_eq!(b.chain()[0], "hello"); + assert_eq!(b.tell().chain, 1); + assert_eq!(b.tell().string, 5); + b.clear(); + assert_eq!(b.chain().len(), 1); + assert_eq!(b.chain()[0], ""); + let s2 = b.ucs1_to_utf8(b""); + assert_eq!(s2, ""); + assert_eq!(b.tell(), qdb_pystr_pos { chain: 1, string: 0 }); + assert_eq!(s2.as_ptr(), b.chain()[0].as_str().as_ptr()); + let s3 = b.ucs1_to_utf8(b"10\xb5"); + assert_eq!(s3, "10µ"); + assert_eq!(s3.len(), 4); // 3 bytes in UCS-1, 4 bytes in UTF-8. + assert_eq!(b.chain().len(), 1); + assert_eq!(s3.as_ptr(), unsafe { + b.chain()[0].as_str().as_ptr().add(s2.len()) + }); + assert_eq!(b.tell(), qdb_pystr_pos { + chain: 1, string: s2.len() + s3.len() }); +} + +#[test] +fn test_resize_and_truncate() { + + let mut b = Buf::new(); + let s1 = b.ucs1_to_utf8(b"abcdefghijklmnopqrstuvwxyz"); + assert_eq!(s1, "abcdefghijklmnopqrstuvwxyz"); + assert_eq!(b.chain_mut().len(), 1); + assert_eq!(b.chain_mut()[0].as_str().as_ptr(), s1.as_ptr()); + + let big_string = "hello world".repeat(1000); + assert!(big_string.len() > MIN_BUF_LEN); + let s2 = b.ucs1_to_utf8(big_string.as_bytes()); + assert_eq!(s2, big_string); + assert_eq!(b.chain_mut().len(), 2); + assert_eq!(b.chain_mut()[0].as_str().as_ptr(), s1.as_ptr()); + assert_eq!(b.chain_mut()[1].as_str().as_ptr(), s2.as_ptr()); + assert_eq!(b.tell(), qdb_pystr_pos { chain: 2, string: 11000 }); + b.truncate(b.tell()); + assert_eq!(b.tell(), qdb_pystr_pos { chain: 2, string: 11000 }); + + let spare = b.chain_mut()[1].capacity() - b.chain_mut()[1].len(); + assert!(spare > 4); + + let test_string = "ab"; + let s3 = b.ucs1_to_utf8(test_string.as_bytes()); + assert_eq!(s3, test_string); + assert_eq!(b.chain_mut().len(), 2); + assert_eq!(b.chain_mut()[0].as_str().as_ptr(), s1.as_ptr()); + assert_eq!(b.chain_mut()[1].as_str().as_ptr(), s2.as_ptr()); + assert_eq!(b.tell(), qdb_pystr_pos { + chain: 2, string: 11000 + test_string.len() }); +} From ab1566c12e431e40cc440f67a93fef50295bf463 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 8 Nov 2022 17:13:02 +0000 Subject: [PATCH 030/147] Updated pystr lib readme. --- pystr-to-utf8/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pystr-to-utf8/README.md b/pystr-to-utf8/README.md index de8641b9..607f98b1 100644 --- a/pystr-to-utf8/README.md +++ b/pystr-to-utf8/README.md @@ -1,7 +1,11 @@ -By default, when compiling, we don't re-generate the .h and .pxd include files. +By default, when compiling, we don't re-generate the `.h` and `.pxd` files. This is to speed up compile time. If you've updated the API, regenerate them by running: +``` $ cargo clean $ cargo build --features cbindgen +``` + +Then make sure to commit the updated generated files. From d79955f93cf9fb7b409b7114148b4436e66efcde Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 9 Nov 2022 17:57:30 +0000 Subject: [PATCH 031/147] More pystr-to_utf8 tests and improvements. --- pystr-to-utf8/build.rs | 2 +- pystr-to-utf8/include/pystr_to_utf8.h | 16 +++-- pystr-to-utf8/src/lib.rs | 73 ++++++++++++++--------- pystr-to-utf8/src/tests.rs | 85 +++++++++++++++++++++++---- src/questdb/ingress.pyx | 24 ++++---- src/questdb/pystr_to_utf8.pxd | 16 +++-- 6 files changed, 149 insertions(+), 67 deletions(-) diff --git a/pystr-to-utf8/build.rs b/pystr-to-utf8/build.rs index 28f15936..a93cb918 100644 --- a/pystr-to-utf8/build.rs +++ b/pystr-to-utf8/build.rs @@ -28,7 +28,7 @@ fn main() -> Result<(), Box> { .with_config(config) .generate()?; - // Insted of just writing out the file: + // Instead of just writing out the file: // bindings.write_to_file("include/pystr_to_utf8.pxd"); // We need to do some post-processing to make it work our code. // The default output is too opinionated and has unwanted typedefs. diff --git a/pystr-to-utf8/include/pystr_to_utf8.h b/pystr-to-utf8/include/pystr_to_utf8.h index 44353c72..9bb3b9ea 100644 --- a/pystr-to-utf8/include/pystr_to_utf8.h +++ b/pystr-to-utf8/include/pystr_to_utf8.h @@ -51,10 +51,10 @@ qdb_pystr_buf *qdb_pystr_buf_new(void); /** * Get current position. Use in conjunction with `truncate`. */ -qdb_pystr_pos qdb_pystr_buf_tell(qdb_pystr_buf *b); +qdb_pystr_pos qdb_pystr_buf_tell(const qdb_pystr_buf *b); /** - * Trim the buffer to the given length. Use in conjunction with `tell`. + * Trim the buffer to the given position. Use in conjunction with `tell`. */ void qdb_pystr_buf_truncate(qdb_pystr_buf *b, qdb_pystr_pos pos); @@ -84,25 +84,29 @@ void qdb_ucs1_to_utf8(qdb_pystr_buf *b, * Convert a Py_UCS2 string to UTF-8. * Returns a `buf_out` borrowed ptr of `size_out` len. * The buffer is borrowed from `b`. - * In case of errors, returns `false` and the buffer is an error message. + * In case of errors, returns `false` and bad_codepoint_out is set to the + * offending codepoint. */ bool qdb_ucs2_to_utf8(qdb_pystr_buf *b, size_t count, const uint16_t *input, size_t *size_out, - const char **buf_out); + const char **buf_out, + uint32_t *bad_codepoint_out); /** * Convert a Py_UCS4 string to UTF-8. * Returns a `buf_out` borrowed ptr of `size_out` len. * The buffer is borrowed from `b`. - * In case of errors, returns `false` and the buffer is an error message. + * In case of errors, returns `false` and bad_codepoint_out is set to the + * offending codepoint. */ bool qdb_ucs4_to_utf8(qdb_pystr_buf *b, size_t count, const uint32_t *input, size_t *size_out, - const char **buf_out); + const char **buf_out, + uint32_t *bad_codepoint_out); #ifdef __cplusplus } // extern "C" diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index 6a2c9095..9a19cabf 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -23,7 +23,6 @@ ******************************************************************************/ use std::ffi::c_char; -use std::fmt::Write; use std::slice::from_raw_parts; #[allow(non_camel_case_types)] @@ -58,7 +57,7 @@ pub unsafe extern "C" fn qdb_pystr_buf_tell( qdb_pystr_pos { chain: chain_pos, string: string_pos } } -/// Trim the buffer to the given length. Use in conjunction with `tell`. +/// Trim the buffer to the given position. Use in conjunction with `tell`. #[no_mangle] pub unsafe extern "C" fn qdb_pystr_buf_truncate( b: *mut qdb_pystr_buf, pos: qdb_pystr_pos) { @@ -87,7 +86,7 @@ pub unsafe extern "C" fn qdb_pystr_buf_free(b: *mut qdb_pystr_buf) { } } -const MIN_BUF_LEN: usize = 64; +const MIN_BUF_LEN: usize = 1024; /// A carefully crafted buffer with spare capacity for `len` bytes. /// This is necessary to return "stable" addresses and avoid segfaults. @@ -133,12 +132,11 @@ pub unsafe extern "C" fn qdb_ucs1_to_utf8( #[inline] fn encode_ucs2<'a, 'b>( - chain: &'a mut Vec, buf: &'b [u16]) -> (bool, &'a str) { + chain: &'a mut Vec, buf: &'b [u16]) -> Result<&'a str, u32> { // len(chr(2 ** 16 - 1).encode('utf-8')) == 3 let utf8_mult = 3; let dest = get_dest(chain, utf8_mult * buf.len()); let last = dest.len(); - let mut ok = true; for b in buf.iter() { // Checking for validity is not optional: // >>> for n in range(2 ** 16): @@ -149,67 +147,84 @@ fn encode_ucs2<'a, 'b>( Some(c) => dest.push(c), None => { dest.truncate(last); - write!(dest, "invalid UCS-2 code point: {}", b).unwrap(); - ok = false; - break; + return Err(*b as u32); } } } - (ok, &dest[last..]) + Ok(&dest[last..]) } /// Convert a Py_UCS2 string to UTF-8. /// Returns a `buf_out` borrowed ptr of `size_out` len. /// The buffer is borrowed from `b`. -/// In case of errors, returns `false` and the buffer is an error message. +/// In case of errors, returns `false` and bad_codepoint_out is set to the +/// offending codepoint. #[no_mangle] pub unsafe extern "C" fn qdb_ucs2_to_utf8(b: *mut qdb_pystr_buf, - count: usize, input: *const u16, - size_out: *mut usize, buf_out: *mut *const c_char) -> bool { + count: usize, + input: *const u16, + size_out: *mut usize, + buf_out: *mut *const c_char, + bad_codepoint_out: *mut u32) -> bool { let b = &mut *b; let i = from_raw_parts(input, count); - let (ok, res) = encode_ucs2(&mut b.0, i); - *size_out = res.len(); - *buf_out = res.as_ptr() as *const c_char; - ok + match encode_ucs2(&mut b.0, i) { + Ok(res) => { + *size_out = res.len(); + *buf_out = res.as_ptr() as *const c_char; + true + } + Err(bad) => { + *bad_codepoint_out = bad; + false + } + } } #[inline] fn encode_ucs4<'a, 'b>( - chain: &'a mut Vec, buf: &'b[u32]) -> (bool, &'a str) { + chain: &'a mut Vec, buf: &'b[u32]) -> Result<&'a str, u32> { // Max 4 bytes allowed by RFC: https://www.rfc-editor.org/rfc/rfc3629#page-4 let utf8_mult = 4; let dest = get_dest(chain, utf8_mult * buf.len()); let last = dest.len(); - let mut ok = true; for b in buf.iter() { match char::from_u32(*b) { Some(c) => dest.push(c), None => { dest.truncate(last); - write!(dest, "invalid UCS-4 code point: {}", b).unwrap(); - ok = false; - break; + return Err(*b); } } } - (ok, &dest[last..]) + Ok(&dest[last..]) } /// Convert a Py_UCS4 string to UTF-8. /// Returns a `buf_out` borrowed ptr of `size_out` len. /// The buffer is borrowed from `b`. -/// In case of errors, returns `false` and the buffer is an error message. +/// In case of errors, returns `false` and bad_codepoint_out is set to the +/// offending codepoint. #[no_mangle] pub unsafe extern "C" fn qdb_ucs4_to_utf8(b: *mut qdb_pystr_buf, - count: usize, input: *const u32, - size_out: *mut usize, buf_out: *mut *const c_char) -> bool { + count: usize, + input: *const u32, + size_out: *mut usize, + buf_out: *mut *const c_char, + bad_codepoint_out: *mut u32) -> bool { let b = &mut *b; let i = from_raw_parts(input, count); - let (ok, res) = encode_ucs4(&mut b.0, i); - *size_out = res.len(); - *buf_out = res.as_ptr() as *const c_char; - ok + match encode_ucs4(&mut b.0, i) { + Ok(res) => { + *size_out = res.len(); + *buf_out = res.as_ptr() as *const c_char; + true + } + Err(bad) => { + *bad_codepoint_out = bad; + false + } + } } #[cfg(test)] diff --git a/pystr-to-utf8/src/tests.rs b/pystr-to-utf8/src/tests.rs index 30ddd6fe..9f38cdd4 100644 --- a/pystr-to-utf8/src/tests.rs +++ b/pystr-to-utf8/src/tests.rs @@ -47,45 +47,49 @@ impl Buf { std::str::from_utf8(slice).unwrap() } - fn ucs2_to_utf8(&mut self, input: &[u16]) -> Result<&'static str, &'static str> { + fn ucs2_to_utf8(&mut self, input: &[u16]) -> Result<&'static str, u32> { let mut size_out = 0; let mut buf_out = std::ptr::null(); + let mut bad_codepoint = 0u32; let ok = unsafe { qdb_ucs2_to_utf8( self.buf, input.len(), input.as_ptr(), &mut size_out, - &mut buf_out) + &mut buf_out, + &mut bad_codepoint) }; - let slice = unsafe { - from_raw_parts(buf_out as *const u8, size_out) }; - let msg = std::str::from_utf8(slice).unwrap(); if ok { + let slice = unsafe { + from_raw_parts(buf_out as *const u8, size_out) }; + let msg = std::str::from_utf8(slice).unwrap(); Ok(msg) } else { - Err(msg) + Err(bad_codepoint) } } - fn ucs4_to_utf8(&mut self, input: &[u32]) -> Result<&'static str, &'static str> { + fn ucs4_to_utf8(&mut self, input: &[u32]) -> Result<&'static str, u32> { let mut size_out = 0; let mut buf_out = std::ptr::null(); + let mut bad_codepoint = 0u32; let ok = unsafe { qdb_ucs4_to_utf8( self.buf, input.len(), input.as_ptr(), &mut size_out, - &mut buf_out) + &mut buf_out, + &mut bad_codepoint) }; - let slice = unsafe { - from_raw_parts(buf_out as *const u8, size_out) }; - let msg = std::str::from_utf8(slice).unwrap(); if ok { + let slice = unsafe { + from_raw_parts(buf_out as *const u8, size_out) }; + let msg = std::str::from_utf8(slice).unwrap(); Ok(msg) } else { - Err(msg) + Err(bad_codepoint) } } } @@ -137,7 +141,6 @@ fn test_ucs1() { #[test] fn test_resize_and_truncate() { - let mut b = Buf::new(); let s1 = b.ucs1_to_utf8(b"abcdefghijklmnopqrstuvwxyz"); assert_eq!(s1, "abcdefghijklmnopqrstuvwxyz"); @@ -167,3 +170,59 @@ fn test_resize_and_truncate() { assert_eq!(b.tell(), qdb_pystr_pos { chain: 2, string: 11000 + test_string.len() }); } + +#[test] +fn test_ucs2() { + let mut b = Buf::new(); + + // We first check code points within the ASCII range. + let s1 = b.ucs2_to_utf8( + &[0x61, 0x62, 0x63, 0x64, 0x65]).unwrap(); + assert_eq!(s1, "abcde"); + assert_eq!(s1.len(), 5); + + // Now chars outside ASCII range, but within UCS-1 range. + // These will yield two bytes each in UTF-8. + let s2 = b.ucs2_to_utf8( + &[0x00f0, 0x00e3, 0x00b5, 0x00b6]) + .unwrap(); + assert_eq!(s2, "ðãµ¶"); + assert_eq!(s2.len(), 8); + + // Now chars that actually require two bytes in UCS-2, but also fit in + // two bytes in UTF-8. + let s3 = b.ucs2_to_utf8( + &[0x0100, 0x069c]) + .unwrap(); + assert_eq!(s3, "Āڜ"); + assert_eq!(s3.len(), 4); + + // Now chars that require two bytes in UCS-2 and 3 bytes in UTF-8. + let s4 = b.ucs2_to_utf8( + &[0x569c, 0xa4c2]) + .unwrap(); + assert_eq!(s4, "嚜꓂"); + assert_eq!(s4.len(), 6); + + // Quick check that we're just writing to the same buffer. + assert_eq!(b.tell(), qdb_pystr_pos { + chain: 1, + string: [s1, s2, s3, s4].iter().map(|s| s.len()).sum() }); + + // Now we finally check that errors are captured. + // For this, we use a code point which is valid in a Python string + // (in UCS-2), but which is not valid when encoded as UTF-8. + // >>> chr(0xd800).encode('utf-8') + // Traceback (most recent call last): + // File "", line 1, in + // UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' + // in position 0: surrogates not allowed + let before_pos = b.tell(); + let s5 = b.ucs2_to_utf8(&[0x061, 0xd800]); + assert!(s5.is_err()); + assert_eq!(s5.unwrap_err(), 0xd800 as u32); + + // Even though 0x061 (ASCII char 'a') was valid and successfully encoded, + // we also want to be sure that the buffer was not modified and appended to. + assert_eq!(b.tell(), before_pos); +} diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index e495f6cd..0d29ab70 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -172,14 +172,11 @@ cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): return IngressError(tup[0], fmt.format(tup[1])) -cdef object _unpack_utf8_decode_error(line_sender_utf8* err_msg): - cdef object mview - cdef str msg - mview = PyMemoryView_FromMemory( - err_msg.buf, - err_msg.len, - PyBUF_READ) - return IngressError(IngressErrorCode.InvalidUtf8, mview.decode('utf-8')) +cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): + return IngressError( + IngressErrorCode.InvalidUtf8, + f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + + 'Cannot be encoded as UTF-8.') cdef bint str_to_utf8( @@ -196,6 +193,7 @@ cdef bint str_to_utf8( """ cdef size_t count cdef int kind + cdef uint32_t bad_codepoint = 0 PyUnicode_READY(string) count = (PyUnicode_GET_LENGTH(string)) @@ -222,8 +220,9 @@ cdef bint str_to_utf8( count, PyUnicode_2BYTE_DATA(string), &utf8_out.len, - &utf8_out.buf): - raise _unpack_utf8_decode_error(utf8_out) + &utf8_out.buf, + &bad_codepoint): + raise _utf8_decode_error(string, bad_codepoint) elif kind == PyUnicode_4BYTE_KIND: if not qdb_ucs4_to_utf8( b, @@ -235,8 +234,9 @@ cdef bint str_to_utf8( PyUnicode_4BYTE_DATA(string), &utf8_out.len, - &utf8_out.buf): - raise _unpack_utf8_decode_error(utf8_out) + &utf8_out.buf, + &bad_codepoint): + raise _utf8_decode_error(string, bad_codepoint) else: raise ValueError(f'Unknown UCS kind: {kind}.') return True diff --git a/src/questdb/pystr_to_utf8.pxd b/src/questdb/pystr_to_utf8.pxd index 857d0ee7..1822e26c 100644 --- a/src/questdb/pystr_to_utf8.pxd +++ b/src/questdb/pystr_to_utf8.pxd @@ -15,9 +15,9 @@ cdef extern from "pystr_to_utf8.h": qdb_pystr_buf *qdb_pystr_buf_new() # Get current position. Use in conjunction with `truncate`. - qdb_pystr_pos qdb_pystr_buf_tell(qdb_pystr_buf *b) + qdb_pystr_pos qdb_pystr_buf_tell(const qdb_pystr_buf *b) - # Trim the buffer to the given length. Use in conjunction with `tell`. + # Trim the buffer to the given position. Use in conjunction with `tell`. void qdb_pystr_buf_truncate(qdb_pystr_buf *b, qdb_pystr_pos pos) # Reset the converter's buffer to zero length. @@ -38,19 +38,23 @@ cdef extern from "pystr_to_utf8.h": # Convert a Py_UCS2 string to UTF-8. # Returns a `buf_out` borrowed ptr of `size_out` len. # The buffer is borrowed from `b`. - # In case of errors, returns `false` and the buffer is an error message. + # In case of errors, returns `false` and bad_codepoint_out is set to the + # offending codepoint. bint qdb_ucs2_to_utf8(qdb_pystr_buf *b, size_t count, const uint16_t *input, size_t *size_out, - const char **buf_out) + const char **buf_out, + uint32_t *bad_codepoint_out) # Convert a Py_UCS4 string to UTF-8. # Returns a `buf_out` borrowed ptr of `size_out` len. # The buffer is borrowed from `b`. - # In case of errors, returns `false` and the buffer is an error message. + # In case of errors, returns `false` and bad_codepoint_out is set to the + # offending codepoint. bint qdb_ucs4_to_utf8(qdb_pystr_buf *b, size_t count, const uint32_t *input, size_t *size_out, - const char **buf_out) + const char **buf_out, + uint32_t *bad_codepoint_out) From e8980d57782a7f349cb5784d6ac23cdfa9507699 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 9 Nov 2022 20:22:24 +0000 Subject: [PATCH 032/147] Added UCS-4 tests. --- pystr-to-utf8/src/tests.rs | 87 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/pystr-to-utf8/src/tests.rs b/pystr-to-utf8/src/tests.rs index 9f38cdd4..68da613e 100644 --- a/pystr-to-utf8/src/tests.rs +++ b/pystr-to-utf8/src/tests.rs @@ -225,4 +225,91 @@ fn test_ucs2() { // Even though 0x061 (ASCII char 'a') was valid and successfully encoded, // we also want to be sure that the buffer was not modified and appended to. assert_eq!(b.tell(), before_pos); + + // Now we check that the buffer is still in a valid state. + let s6 = b.ucs2_to_utf8(&[0x062, 0x063]).unwrap(); + assert_eq!(s6, "bc"); + assert_eq!(b.tell(), qdb_pystr_pos { + chain: 1, + string: [s1, s2, s3, s4, s6].iter().map(|s| s.len()).sum() }); } + +#[test] +fn test_ucs4() { + let mut b = Buf::new(); + + // We first check code points within the ASCII range. + let s1 = b.ucs4_to_utf8( + &[0x61, 0x62, 0x63, 0x64, 0x65]).unwrap(); + assert_eq!(s1, "abcde"); + assert_eq!(s1.len(), 5); + + // Now chars outside ASCII range, but within UCS-1 range. + // These will yield two bytes each in UTF-8. + let s2 = b.ucs4_to_utf8( + &[0x00f0, 0x00e3, 0x00b5, 0x00b6]) + .unwrap(); + assert_eq!(s2, "ðãµ¶"); + assert_eq!(s2.len(), 8); + + // Now chars that actually require two bytes in UCS-2, but also fit in + // two bytes in UTF-8. + let s3 = b.ucs4_to_utf8( + &[0x0100, 0x069c]) + .unwrap(); + assert_eq!(s3, "Āڜ"); + assert_eq!(s3.len(), 4); + + // Now chars that require two bytes in UCS-2 and 3 bytes in UTF-8. + let s4 = b.ucs4_to_utf8( + &[0x569c, 0xa4c2]) + .unwrap(); + assert_eq!(s4, "嚜꓂"); + assert_eq!(s4.len(), 6); + + // Now chars that require four bytes in UCS-4 and 4 bytes in UTF-8. + let s5 = b.ucs4_to_utf8( + &[0x1f4a9, 0x1f99e]) + .unwrap(); + assert_eq!(s5, "💩🦞"); + assert_eq!(s5.len(), 8); + + // Quick check that we're just writing to the same buffer. + assert_eq!(b.tell(), qdb_pystr_pos { + chain: 1, + string: [s1, s2, s3, s4, s5].iter().map(|s| s.len()).sum() }); + + // Now we finally check that errors are captured. + // For this, we use a code point which is valid in a Python string + // (in UCS-4), but which is not valid when encoded as UTF-8. + // >>> chr(0xd800).encode('utf-8') + // Traceback (most recent call last): + // File "", line 1, in + // UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' + // in position 0: surrogates not allowed + let before_pos = b.tell(); + let s6 = b.ucs4_to_utf8(&[0x061, 0xd800]); + assert!(s6.is_err()); + assert_eq!(s6.unwrap_err(), 0xd800 as u32); + + // Even though 0x061 (ASCII char 'a') was valid and successfully encoded, + // we also want to be sure that the buffer was not modified and appended to. + assert_eq!(b.tell(), before_pos); + + // We repeat the same with chars with code points higher than the u16 type. + let before_pos = b.tell(); + let s7 = b.ucs4_to_utf8(&[0x061, 0x110000]); + assert!(s7.is_err()); + assert_eq!(s7.unwrap_err(), 0x110000); + + // Even though 0x061 (ASCII char 'a') was valid and successfully encoded, + // we also want to be sure that the buffer was not modified and appended to. + assert_eq!(b.tell(), before_pos); + + // Now we check that the buffer is still in a valid state. + let s8 = b.ucs4_to_utf8(&[0x062, 0x063]).unwrap(); + assert_eq!(s8, "bc"); + assert_eq!(b.tell(), qdb_pystr_pos { + chain: 1, + string: [s1, s2, s3, s4, s5, s8].iter().map(|s| s.len()).sum() }); +} \ No newline at end of file From 644bdba514d4e810dca244320543bf95fa981a56 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 10 Nov 2022 10:44:07 +0000 Subject: [PATCH 033/147] More unicode testing. --- test/test.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/test/test.py b/test/test.py index e21566bf..e4e26731 100755 --- a/test/test.py +++ b/test/test.py @@ -109,11 +109,43 @@ def test_no_symbol_or_col_args(self): def test_unicode(self): buf = qi.Buffer() + buf.row( + 'tbl1', # ASCII + symbols={'questdb1': 'q❤️p'}, # Mixed ASCII and UCS-2 + columns={'questdb2': '❤️' * 1200}) # Over the 1024 buffer prealloc. buf.row( 'tbl1', - symbols={'questdb1': '❤️'}, - columns={'questdb2': '❤️' * 100}) - self.assertEqual(str(buf), f'tbl1,questdb1=❤️ questdb2="{"❤️" * 100}"\n') + symbols={ + 'Questo è il nome di una colonna': # Non-ASCII UCS-1 + 'Це символьне значення'}, # UCS-2, 2 bytes for UTF-8. + columns={ + 'questdb1': '', # Empty string + 'questdb2': '嚜꓂', # UCS-2, 3 bytes for UTF-8. + 'questdb3': '💩🦞'}) # UCS-4, 4 bytes for UTF-8. + self.assertEqual(str(buf), + f'tbl1,questdb1=q❤️p questdb2="{"❤️" * 1200}"\n' + + 'tbl1,Questo\\ è\\ il\\ nome\\ di\\ una\\ colonna=' + + 'Це\\ символьне\\ значення ' + + 'questdb1="",questdb2="嚜꓂",questdb3="💩🦞"\n') + + buf.clear() + buf.row('tbl1', symbols={'questdb1': 'q❤️p'}) + self.assertEqual(str(buf), 'tbl1,questdb1=q❤️p\n') + + # A bad char in Python. + with self.assertRaisesRegex( + qi.IngressError, + '.*codepoint 0xd800 in string .*'): + buf.row('tbl1', symbols={'questdb1': 'a\ud800'}) + + # Strong exception safety: no partial writes. + # Ensure we can continue using the buffer after an error. + buf.row('tbl1', symbols={'questdb1': 'another line of input'}) + self.assertEqual( + str(buf), + 'tbl1,questdb1=q❤️p\n' + + # Note: No partially written failed line here. + 'tbl1,questdb1=another\\ line\\ of\\ input\n') def test_float(self): buf = qi.Buffer() From b071edf6823f210ecd8daf31609e6d51a205f029 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 10 Nov 2022 13:02:05 +0000 Subject: [PATCH 034/147] Fixed include for cython generation compatability. --- pystr-to-utf8/cbindgen.toml | 2 +- pystr-to-utf8/include/pystr_to_utf8.h | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pystr-to-utf8/cbindgen.toml b/pystr-to-utf8/cbindgen.toml index 8f02840b..d9f4e5d0 100644 --- a/pystr-to-utf8/cbindgen.toml +++ b/pystr-to-utf8/cbindgen.toml @@ -52,7 +52,7 @@ documentation = true documentation_style = "doxy" # Codegen Options -style = "type" +style = "both" usize_is_size_t = true [fn] diff --git a/pystr-to-utf8/include/pystr_to_utf8.h b/pystr-to-utf8/include/pystr_to_utf8.h index 9bb3b9ea..cf783284 100644 --- a/pystr-to-utf8/include/pystr_to_utf8.h +++ b/pystr-to-utf8/include/pystr_to_utf8.h @@ -32,7 +32,7 @@ typedef struct qdb_pystr_buf qdb_pystr_buf; -typedef struct +typedef struct qdb_pystr_pos { size_t chain; size_t string; @@ -46,35 +46,35 @@ extern "C" { * Prepare a new buffer. The buffer must be freed with `qdb_pystr_free`. * The `qdb_ucsX_to_utf8` functions will write to this buffer. */ -qdb_pystr_buf *qdb_pystr_buf_new(void); +struct qdb_pystr_buf *qdb_pystr_buf_new(void); /** * Get current position. Use in conjunction with `truncate`. */ -qdb_pystr_pos qdb_pystr_buf_tell(const qdb_pystr_buf *b); +struct qdb_pystr_pos qdb_pystr_buf_tell(const struct qdb_pystr_buf *b); /** * Trim the buffer to the given position. Use in conjunction with `tell`. */ -void qdb_pystr_buf_truncate(qdb_pystr_buf *b, - qdb_pystr_pos pos); +void qdb_pystr_buf_truncate(struct qdb_pystr_buf *b, + struct qdb_pystr_pos pos); /** * Reset the converter's buffer to zero length. */ -void qdb_pystr_buf_clear(qdb_pystr_buf *b); +void qdb_pystr_buf_clear(struct qdb_pystr_buf *b); /** * Free the buffer. Must be called after `qdb_pystr_buf_new`. */ -void qdb_pystr_buf_free(qdb_pystr_buf *b); +void qdb_pystr_buf_free(struct qdb_pystr_buf *b); /** * Convert a Py_UCS1 string to UTF-8. * Returns a `buf_out` borrowed ptr of `size_out` len. * The buffer is borrowed from `b`. */ -void qdb_ucs1_to_utf8(qdb_pystr_buf *b, +void qdb_ucs1_to_utf8(struct qdb_pystr_buf *b, size_t count, const uint8_t *input, size_t *size_out, @@ -87,7 +87,7 @@ void qdb_ucs1_to_utf8(qdb_pystr_buf *b, * In case of errors, returns `false` and bad_codepoint_out is set to the * offending codepoint. */ -bool qdb_ucs2_to_utf8(qdb_pystr_buf *b, +bool qdb_ucs2_to_utf8(struct qdb_pystr_buf *b, size_t count, const uint16_t *input, size_t *size_out, @@ -101,7 +101,7 @@ bool qdb_ucs2_to_utf8(qdb_pystr_buf *b, * In case of errors, returns `false` and bad_codepoint_out is set to the * offending codepoint. */ -bool qdb_ucs4_to_utf8(qdb_pystr_buf *b, +bool qdb_ucs4_to_utf8(struct qdb_pystr_buf *b, size_t count, const uint32_t *input, size_t *size_out, From 091e4c87f929108b629ee3ebaaa62b5a2826f3c4 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 10 Nov 2022 15:10:55 +0000 Subject: [PATCH 035/147] Table name columns, symbols and timestamps now work! --- src/questdb/ingress.pyx | 206 ++++++++++++++++++++++++++++++++++++---- test/test.py | 16 +++- 2 files changed, 198 insertions(+), 24 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 0d29ab70..188e0b7a 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1026,7 +1026,6 @@ cdef class Buffer: # exceptions later. cdef size_t col_count cdef ssize_t name_col - cdef object name_owner cdef line_sender_table_name c_table_name cdef size_t_vec symbol_indices = size_t_vec_new() cdef size_t_vec field_indices = size_t_vec_new() @@ -1034,11 +1033,13 @@ cdef class Buffer: cdef int64_t at_value = 0 cdef column_name_vec symbol_names = column_name_vec_new() cdef column_name_vec field_names = column_name_vec_new() - cdef list name_owners = None cdef dtype_t* dtypes = NULL cdef size_t set_buf_count = 0 cdef Py_buffer* col_buffers = NULL cdef size_t col_index + cdef qdb_pystr_pos str_buf_marker + cdef size_t row_count + cdef Py_buffer* cur_col try: _check_is_pandas_dataframe(data) col_count = len(data.columns) @@ -1048,7 +1049,7 @@ cdef class Buffer: data, table_name, table_name_col, col_count, &c_table_name) at_col = _pandas_resolve_at(data, at, col_count, &at_value) _pandas_resolve_symbols( - data, at_col, symbols, col_count, &symbol_indices) + data, name_col, at_col, symbols, col_count, &symbol_indices) _pandas_resolve_fields( name_col, &symbol_indices, at_col, col_count, &field_indices) _pandas_resolve_col_names( @@ -1060,6 +1061,12 @@ cdef class Buffer: col_buffers = calloc(col_count, sizeof(Py_buffer)) _pandas_resolve_col_buffers( data, col_count, dtypes, col_buffers, &set_buf_count) + + # We've used the str buffer up to a point for the headers. + # Instead of clearing it (which would clear the headers' memory) + # we will truncate (rewind) back to this position. + str_buf_marker = qdb_pystr_buf_tell(self._b) + import sys sys.stderr.write('_pandas :: (A) ' + f'name_col: {name_col}, ' + @@ -1068,26 +1075,52 @@ cdef class Buffer: f'at_value: {at_value}, ' + f'field_indices: {size_t_vec_str(&field_indices)}' + '\n') - # row_count = len(data) - # for row_index in range(row_count): - # if name_col > -1: - # data.iloc[:, name_col] - # else: - # if not line_sender_buffer_table(self._impl, c_table_name, &err): - # raise c_err_to_py(err) + row_count = len(data) + self._clear_marker() + for row_index in range(row_count): + qdb_pystr_buf_truncate(self._b, str_buf_marker) + try: + self._set_marker() + _pandas_row_table_name( + self._impl, + self._b, + dtypes, + col_buffers, + name_col, + row_index, + c_table_name) + _pandas_row_symbols( + self._impl, + self._b, + dtypes, + col_buffers, + row_index, + &symbol_names, + &symbol_indices) + # _pandas_row_fields(...) # TODO [amunra]: implement + _pandas_row_at( + self._impl, + dtypes, + col_buffers, + row_index, + at_col, + at_value) + except: + self._rewind_to_marker() + raise return True finally: + self._clear_marker() if col_buffers != NULL: for col_index in range(set_buf_count): PyBuffer_Release(&col_buffers[col_index]) free(col_buffers) free(dtypes) - if name_owners: # no-op to avoid "unused variable" warning - pass column_name_vec_free(&field_names) column_name_vec_free(&symbol_names) size_t_vec_free(&field_indices) size_t_vec_free(&symbol_indices) + qdb_pystr_buf_clear(self._b) def pandas( self, @@ -1396,6 +1429,7 @@ cdef object _pandas_check_column_is_str( cdef int _pandas_resolve_symbols( object data, + ssize_t table_name_col, ssize_t at_col, object symbols, size_t col_count, @@ -1427,6 +1461,10 @@ cdef int _pandas_resolve_symbols( raise TypeError( f'Bad argument `symbols`: Elements must ' + 'be a column name (str) or index (int).') + if (table_name_col >= 0) and (col_index == table_name_col): + raise ValueError( + f'Bad argument `symbols`: Cannot use the same column ' + + f'{symbol!r} as both the table_name and as a symbol.') if (at_col >= 0) and (col_index == at_col): raise ValueError( f'Bad argument `symbols`: Cannot use the `at` column ' + @@ -1461,7 +1499,7 @@ cdef ssize_t _pandas_resolve_at( size_t col_count, int64_t* at_value_out) except -2: cdef size_t col_index - cdef str col_kind + cdef object dtype if at is None: at_value_out[0] = 0 # Special value for `at_now`. return -1 @@ -1480,14 +1518,24 @@ cdef ssize_t _pandas_resolve_at( f'Bad argument `at`: Unsupported type {type(at)}. ' + 'Must be one of: None, TimestampNanos, datetime, ' + 'int (column index), str (colum name)') - col_kind = data.dtypes[col_index].kind - if col_kind == 'M': # datetime + dtype = data.dtypes[col_index] + if _pandas_is_supported_datetime(dtype): at_value_out[0] = 0 return col_index else: raise TypeError( - f'Bad argument `at`: Bad dtype `{data.dtypes[col_index]}` ' + - f'for the {at!r} column: Must be a datetime column.') + f'Bad argument `at`: Bad dtype `{dtype}` ' + + f'for the {at!r} column: Must be a datetime64[ns] column.') + + +cdef object _pandas_is_supported_datetime(object dtype): + # We currently only accept datetime64[ns] columns. + return ( + (dtype.kind == 'M') and + (dtype.itemsize == 8) and + (dtype.byteorder == '=') and + (dtype.alignment == 8) and + (not dtype.hasobject)) cdef struct dtype_t: @@ -1506,8 +1554,8 @@ cdef char _str_to_char(str field, str s) except 0: if len(s) != 1: raise ValueError( f'dtype.{field}: Expected a single character, got {s!r}') - res = ord(s[0]) - if res <= 0 or res > 127: ## ascii, exclude nul-termintor + res = ord(s) + if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. raise ValueError( f'dtype.{field}: Character out of ASCII range, got {s!r}') return res @@ -1555,10 +1603,130 @@ cdef bint _pandas_resolve_col_buffers( raise TypeError( f'Bad column: Expected a numpy array, got {nparr!r}') PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) + # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. return True +cdef inline const void* _pandas_get_cell( + Py_buffer* col_buffer, size_t row_index): + return col_buffer.buf + (row_index * col_buffer.strides[0]) + + +cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' +cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' + + +cdef bint _pandas_get_str_cell( + qdb_pystr_buf* b, + dtype_t* dtype, + Py_buffer* col_buffer, + size_t row_index, + line_sender_utf8* utf8_out) except False: + cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: + # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. + # TODO: Improve error messaging. Error message should include the column name. + str_to_utf8(b, ((cell)[0]), utf8_out) + else: + raise TypeError( + f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. + return True + + +cdef int64_t _pandas_get_timestamp_cell( + dtype_t* dtype, + Py_buffer* col_buffer, + size_t row_index) except -1: + # Note: Type is pre-validated by `_pandas_is_supported_datetime`. + cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + cdef int64_t res = (cell)[0] + if res < 0: + # TODO [amunra]: Improve error messaging. Add column name. + raise ValueError( + f'Bad value: Negative timestamp, got {res}') + return res + + +cdef bint _pandas_row_table_name( + line_sender_buffer* impl, + qdb_pystr_buf* b, + dtype_t* dtypes, + Py_buffer* col_buffers, + ssize_t name_col, + size_t row_index, + line_sender_table_name c_table_name) except False: + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if name_col >= 0: + _pandas_get_str_cell( + b, + &dtypes[name_col], + &col_buffers[name_col], + row_index, + &utf8) + if not line_sender_table_name_init(&c_table_name, utf8.len, utf8.buf, &err): + raise c_err_to_py(err) + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + return True + + +cdef bint _pandas_row_symbols( + line_sender_buffer* impl, + qdb_pystr_buf* b, + dtype_t* dtypes, + Py_buffer* col_buffers, + size_t row_index, + const column_name_vec* symbol_names, + const size_t_vec* symbol_indices) except False: + cdef line_sender_error* err = NULL + cdef size_t sym_index + cdef size_t col_index + cdef dtype_t* dtype + cdef Py_buffer* col_buffer + cdef line_sender_column_name col_name + cdef line_sender_utf8 symbol + for sym_index in range(symbol_indices.size): + col_name = symbol_names.d[sym_index] + col_index = symbol_indices.d[sym_index] + col_buffer = &col_buffers[col_index] + dtype = &dtypes[col_index] + _pandas_get_str_cell( + b, + dtype, + col_buffer, + row_index, + &symbol) + if not line_sender_buffer_symbol(impl, col_name, symbol, &err): + raise c_err_to_py(err) + return True + + +cdef bint _pandas_row_at( + line_sender_buffer* impl, + dtype_t* dtypes, + Py_buffer* col_buffers, + size_t row_index, + ssize_t at_col, + int64_t at_value) except False: + cdef line_sender_error* err = NULL + cdef Py_buffer* col_buffer + cdef dtype_t* dtype + if at_col >= 0: + col_buffer = &col_buffers[at_col] + dtype = &dtypes[at_col] + at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + if at_value > 0: + if not line_sender_buffer_at(impl, at_value, &err): + raise c_err_to_py(err) + else: + if not line_sender_buffer_at_now(impl, &err): + raise c_err_to_py(err) + return True + + + _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' 'v1.0.2' '/troubleshooting.html#inspecting-and-debugging-errors#flush-failed') diff --git a/test/test.py b/test/test.py index e4e26731..0afe1626 100755 --- a/test/test.py +++ b/test/test.py @@ -448,9 +448,11 @@ def _pandas(*args, **kwargs): DF2 = pd.DataFrame({ 'T': ['t1', 't2', 't1'], - 'A': [1.0, 2.0, 3.0], - 'B': [1, 2, 3], - 'C': [ + 'A': ['a1', 'a2', 'a3'], + 'B': ['b1', 'b2', 'b3'], + 'C': [1.0, 2.0, 3.0], + 'D': [1, 2, 3], + 'E': [ pd.Timestamp('20180310'), pd.Timestamp('20180311'), pd.Timestamp('20180312')]}) @@ -514,8 +516,12 @@ def test_bad_at(self): _pandas(DF1, table_name='tbl1', at=-1) def test_basic(self): - _pandas(DF2, table_name_col=0, symbols=[0], at=-1) - + buf = _pandas(DF2, table_name_col='T', symbols=['A', 'B'], at=-1) + self.assertEqual( + buf, + 't1,A=a1,B=b1 1520640000000000000\n' + + 't2,A=a2,B=b2 1520726400000000000\n' + + 't1,A=a3,B=b3 1520812800000000000\n') if __name__ == '__main__': unittest.main() From 29895f6e1fa9641dfb6beee571ed8c1a679f5069 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 11 Nov 2022 10:25:44 +0000 Subject: [PATCH 036/147] Handling null column values in strings. --- src/questdb/ingress.pyx | 50 ++++++++++++++++++++++++++++++++++------- test/test.py | 16 ++++++++----- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 188e0b7a..339dcdea 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1040,6 +1040,7 @@ cdef class Buffer: cdef qdb_pystr_pos str_buf_marker cdef size_t row_count cdef Py_buffer* cur_col + _pandas_may_set_na_type() try: _check_is_pandas_dataframe(data) col_count = len(data.columns) @@ -1257,6 +1258,16 @@ cdef struct column_buf_t: # NB: We don't support suboffsets. +cdef object _PANDAS_NA = None + + +cdef object _pandas_may_set_na_type(): + global _PANDAS_NA + if _PANDAS_NA is None: + import pandas as pd + _PANDAS_NA = pd.NA + + cdef ssize_t _pandas_resolve_table_name( qdb_pystr_buf* b, object data, @@ -1565,11 +1576,12 @@ cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: """ Parse a numpy dtype and return a dtype_t. """ - dtype_out.alignment = np_dtype.alignment + dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) dtype_out.kind = _str_to_char('kind', np_dtype.kind) - dtype_out.itemsize = np_dtype.itemsize - dtype_out.byteorder = _str_to_char('byteorder', np_dtype.byteorder) - dtype_out.hasobject = np_dtype.hasobject + dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) + dtype_out.byteorder = _str_to_char( + 'byteorder', getattr(np_dtype, 'byteorder', '=')) + dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) return True @@ -1622,12 +1634,24 @@ cdef bint _pandas_get_str_cell( dtype_t* dtype, Py_buffer* col_buffer, size_t row_index, + bint* is_null_out, line_sender_utf8* utf8_out) except False: cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + cdef object obj if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. # TODO: Improve error messaging. Error message should include the column name. - str_to_utf8(b, ((cell)[0]), utf8_out) + obj = ((cell)[0]) + if (obj is None) or (obj is _PANDAS_NA): + is_null_out[0] = True + else: + is_null_out[0] = False + try: + str_to_utf8(b, obj, utf8_out) + except TypeError as e: + raise TypeError( + 'Bad column: Expected a string, ' + + f'got {obj!r} ({type(obj)!r})') from e else: raise TypeError( f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. @@ -1657,6 +1681,7 @@ cdef bint _pandas_row_table_name( size_t row_index, line_sender_table_name c_table_name) except False: cdef line_sender_error* err = NULL + cdef bint is_null = False cdef line_sender_utf8 utf8 if name_col >= 0: _pandas_get_str_cell( @@ -1664,8 +1689,14 @@ cdef bint _pandas_row_table_name( &dtypes[name_col], &col_buffers[name_col], row_index, + &is_null, &utf8) - if not line_sender_table_name_init(&c_table_name, utf8.len, utf8.buf, &err): + if is_null: + # TODO [amunra]: Improve error messaging. Add column name. + raise ValueError( + f'Bad value: `None` table name value at row {row_index}.') + if not line_sender_table_name_init( + &c_table_name, utf8.len, utf8.buf, &err): raise c_err_to_py(err) if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) @@ -1687,6 +1718,7 @@ cdef bint _pandas_row_symbols( cdef Py_buffer* col_buffer cdef line_sender_column_name col_name cdef line_sender_utf8 symbol + cdef bint is_null = False for sym_index in range(symbol_indices.size): col_name = symbol_names.d[sym_index] col_index = symbol_indices.d[sym_index] @@ -1697,9 +1729,11 @@ cdef bint _pandas_row_symbols( dtype, col_buffer, row_index, + &is_null, &symbol) - if not line_sender_buffer_symbol(impl, col_name, symbol, &err): - raise c_err_to_py(err) + if not is_null: + if not line_sender_buffer_symbol(impl, col_name, symbol, &err): + raise c_err_to_py(err) return True diff --git a/test/test.py b/test/test.py index 0afe1626..eea4a267 100755 --- a/test/test.py +++ b/test/test.py @@ -449,10 +449,12 @@ def _pandas(*args, **kwargs): DF2 = pd.DataFrame({ 'T': ['t1', 't2', 't1'], 'A': ['a1', 'a2', 'a3'], - 'B': ['b1', 'b2', 'b3'], - 'C': [1.0, 2.0, 3.0], - 'D': [1, 2, 3], - 'E': [ + 'B': ['b1', None, 'b3'], + 'C': pd.Series(['b1', None, 'b3'], dtype='string'), + 'D': pd.Series(['a1', 'a2', 'a3'], dtype='string'), + 'E': [1.0, 2.0, 3.0], + 'F': [1, 2, 3], + 'G': [ pd.Timestamp('20180310'), pd.Timestamp('20180311'), pd.Timestamp('20180312')]}) @@ -516,7 +518,11 @@ def test_bad_at(self): _pandas(DF1, table_name='tbl1', at=-1) def test_basic(self): - buf = _pandas(DF2, table_name_col='T', symbols=['A', 'B'], at=-1) + buf = _pandas( + DF2, + table_name_col='T', + symbols=['A', 'B', 'C', 'D'], + at=-1) self.assertEqual( buf, 't1,A=a1,B=b1 1520640000000000000\n' + From ef6735bee0cf7dc9372580ffef2b0b10d57e10a0 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 11 Nov 2022 10:47:38 +0000 Subject: [PATCH 037/147] Added arrow C data interface type definitions. --- src/questdb/arrow_c_data_interface.h | 111 +++++++++++++++++++++++++ src/questdb/arrow_c_data_interface.pxd | 38 +++++++++ src/questdb/extra_cpython.pxd | 41 +++++++++ src/questdb/ingress.pyx | 42 +--------- 4 files changed, 192 insertions(+), 40 deletions(-) create mode 100644 src/questdb/arrow_c_data_interface.h create mode 100644 src/questdb/arrow_c_data_interface.pxd create mode 100644 src/questdb/extra_cpython.pxd diff --git a/src/questdb/arrow_c_data_interface.h b/src/questdb/arrow_c_data_interface.h new file mode 100644 index 00000000..d58417e6 --- /dev/null +++ b/src/questdb/arrow_c_data_interface.h @@ -0,0 +1,111 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ARROW_C_DATA_INTERFACE +#define ARROW_C_DATA_INTERFACE + +#define ARROW_FLAG_DICTIONARY_ORDERED 1 +#define ARROW_FLAG_NULLABLE 2 +#define ARROW_FLAG_MAP_KEYS_SORTED 4 + +struct ArrowSchema { + // Array type description + const char* format; + const char* name; + const char* metadata; + int64_t flags; + int64_t n_children; + struct ArrowSchema** children; + struct ArrowSchema* dictionary; + + // Release callback + void (*release)(struct ArrowSchema*); + // Opaque producer-specific data + void* private_data; +}; + +struct ArrowArray { + // Array data description + int64_t length; + int64_t null_count; + int64_t offset; + int64_t n_buffers; + int64_t n_children; + const void** buffers; + struct ArrowArray** children; + struct ArrowArray* dictionary; + + // Release callback + void (*release)(struct ArrowArray*); + // Opaque producer-specific data + void* private_data; +}; + +#endif // ARROW_C_DATA_INTERFACE + +#ifndef ARROW_C_STREAM_INTERFACE +#define ARROW_C_STREAM_INTERFACE + +struct ArrowArrayStream { + // Callback to get the stream type + // (will be the same for all arrays in the stream). + // + // Return value: 0 if successful, an `errno`-compatible error code otherwise. + // + // If successful, the ArrowSchema must be released independently from the stream. + int (*get_schema)(struct ArrowArrayStream*, struct ArrowSchema* out); + + // Callback to get the next array + // (if no error and the array is released, the stream has ended) + // + // Return value: 0 if successful, an `errno`-compatible error code otherwise. + // + // If successful, the ArrowArray must be released independently from the stream. + int (*get_next)(struct ArrowArrayStream*, struct ArrowArray* out); + + // Callback to get optional detailed error information. + // This must only be called if the last stream operation failed + // with a non-0 return code. + // + // Return value: pointer to a null-terminated character array describing + // the last error, or NULL if no description is available. + // + // The returned pointer is only valid until the next operation on this stream + // (including release). + const char* (*get_last_error)(struct ArrowArrayStream*); + + // Release callback: release the stream's own resources. + // Note that arrays returned by `get_next` must be individually released. + void (*release)(struct ArrowArrayStream*); + + // Opaque producer-specific data + void* private_data; +}; + +#endif // ARROW_C_STREAM_INTERFACE + +#ifdef __cplusplus +} +#endif diff --git a/src/questdb/arrow_c_data_interface.pxd b/src/questdb/arrow_c_data_interface.pxd new file mode 100644 index 00000000..8c0b5472 --- /dev/null +++ b/src/questdb/arrow_c_data_interface.pxd @@ -0,0 +1,38 @@ +from libc.stdint cimport int64_t + +cdef extern from "arrow_c_data_interface.h": + + cdef int ARROW_FLAG_DICTIONARY_ORDERED + cdef int ARROW_FLAG_NULLABLE + cdef int ARROW_FLAG_MAP_KEYS_SORTED + + cdef struct ArrowSchema: + # Array type description + const char* format + const char* name + const char* metadata + int64_t flags + int64_t n_children + ArrowSchema** children + ArrowSchema* dictionary + + # Release callback + void (*release)(ArrowSchema*) + # Opaque producer-specific data + void* private_data + + cdef struct ArrowArray: + # Array data description + int64_t length + int64_t null_count + int64_t offset + int64_t n_buffers + int64_t n_children + const void** buffers + ArrowArray** children + ArrowArray* dictionary + + # Release callback + void (*release)(ArrowArray*) + # Opaque producer-specific data + void* private_data diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd new file mode 100644 index 00000000..7dde79d9 --- /dev/null +++ b/src/questdb/extra_cpython.pxd @@ -0,0 +1,41 @@ +from libc.stdint cimport uint8_t, uint16_t, uint32_t + +cdef extern from "Python.h": + ctypedef uint8_t Py_UCS1 # unicodeobject.h + ctypedef uint16_t Py_UCS2 + ctypedef uint32_t Py_UCS4 + + ctypedef unsigned int uint + + cdef enum PyUnicode_Kind: + PyUnicode_1BYTE_KIND + PyUnicode_2BYTE_KIND + PyUnicode_4BYTE_KIND + + # Note: Returning an `object` rather than `PyObject` as the function + # returns a new reference rather than borrowing an existing one. + object PyUnicode_FromKindAndData( + int kind, const void* buffer, Py_ssize_t size) + + # Ditto, see comment on why not returning a `PyObject` above. + str PyUnicode_FromStringAndSize( + const char* u, Py_ssize_t size) + + # Must be called before accessing data or is compact check. + int PyUnicode_READY(object o) except -1 + + # Is UCS1 and ascii (and therefore valid UTF-8). + bint PyUnicode_IS_COMPACT_ASCII(object o) + + # Get length. + Py_ssize_t PyUnicode_GET_LENGTH(object o) + + # Zero-copy access to string buffer. + int PyUnicode_KIND(object o) + Py_UCS1* PyUnicode_1BYTE_DATA(object o) + Py_UCS2* PyUnicode_2BYTE_DATA(object o) + Py_UCS4* PyUnicode_4BYTE_DATA(object o) + + Py_ssize_t PyBytes_GET_SIZE(object o) + + char* PyBytes_AsString(object o) \ No newline at end of file diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 339dcdea..02b4be92 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -46,46 +46,8 @@ from cpython.memoryview cimport PyMemoryView_FromMemory from .line_sender cimport * from .pystr_to_utf8 cimport * - -cdef extern from "Python.h": - ctypedef uint8_t Py_UCS1 # unicodeobject.h - ctypedef uint16_t Py_UCS2 - ctypedef uint32_t Py_UCS4 - - ctypedef unsigned int uint - - cdef enum PyUnicode_Kind: - PyUnicode_1BYTE_KIND - PyUnicode_2BYTE_KIND - PyUnicode_4BYTE_KIND - - # Note: Returning an `object` rather than `PyObject` as the function - # returns a new reference rather than borrowing an existing one. - object PyUnicode_FromKindAndData( - int kind, const void* buffer, Py_ssize_t size) - - # Ditto, see comment on why not returning a `PyObject` above. - str PyUnicode_FromStringAndSize( - const char* u, Py_ssize_t size) - - # Must be called before accessing data or is compact check. - int PyUnicode_READY(object o) except -1 - - # Is UCS1 and ascii (and therefore valid UTF-8). - bint PyUnicode_IS_COMPACT_ASCII(object o) - - # Get length. - Py_ssize_t PyUnicode_GET_LENGTH(object o) - - # Zero-copy access to string buffer. - int PyUnicode_KIND(object o) - Py_UCS1* PyUnicode_1BYTE_DATA(object o) - Py_UCS2* PyUnicode_2BYTE_DATA(object o) - Py_UCS4* PyUnicode_4BYTE_DATA(object o) - - Py_ssize_t PyBytes_GET_SIZE(object o) - - char* PyBytes_AsString(object o) +from .arrow_c_data_interface cimport * +from .extra_cpython cimport * import cython From ead851d29ddfb5c8370b5ed92670a1204c8784a3 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 11 Nov 2022 11:36:01 +0000 Subject: [PATCH 038/147] Code reorg. --- .gitignore | 1 + src/questdb/ingress.pyx | 608 +-------------------------------- src/questdb/pandas_helpers.pxi | 605 ++++++++++++++++++++++++++++++++ 3 files changed, 608 insertions(+), 606 deletions(-) create mode 100644 src/questdb/pandas_helpers.pxi diff --git a/.gitignore b/.gitignore index eaf84826..bcb0cffe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ src/questdb/ingress.html src/questdb/ingress.c +src/questdb/pandas_helpers.html rustup-init.exe # Byte-compiled / optimized / DLL files diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 02b4be92..45662f18 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -49,6 +49,8 @@ from .pystr_to_utf8 cimport * from .arrow_c_data_interface cimport * from .extra_cpython cimport * +include "pandas_helpers.pxi" + import cython from enum import Enum @@ -1117,612 +1119,6 @@ cdef class Buffer: '\n') -cdef struct c_size_t_vec: - size_t capacity - size_t size - size_t* d - -ctypedef c_size_t_vec size_t_vec - -cdef size_t_vec size_t_vec_new(): - cdef size_t_vec vec - vec.capacity = 0 - vec.size = 0 - vec.d = NULL - return vec - -cdef void size_t_vec_free(size_t_vec* vec): - if vec.d: - free(vec.d) - vec.d = NULL - -cdef str size_t_vec_str(size_t_vec* vec): - return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) - -cdef void size_t_vec_push(size_t_vec* vec, size_t value): - if vec.capacity == 0: - vec.capacity = 8 - vec.d = malloc(vec.capacity * sizeof(size_t)) - if vec.d == NULL: - abort() - elif vec.size == vec.capacity: - vec.capacity = vec.capacity * 2 - vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - if not vec.d: - abort() - vec.d[vec.size] = value - vec.size += 1 - - -cdef struct c_column_name_vec: - size_t capacity - size_t size - line_sender_column_name* d - -ctypedef c_column_name_vec column_name_vec - -cdef column_name_vec column_name_vec_new(): - cdef column_name_vec vec - vec.capacity = 0 - vec.size = 0 - vec.d = NULL - return vec - -cdef void column_name_vec_free(column_name_vec* vec): - if vec.d: - free(vec.d) - vec.d = NULL - -cdef void column_name_vec_push( - column_name_vec* vec, line_sender_column_name value): - if vec.capacity == 0: - vec.capacity = 8 - vec.d = malloc( - vec.capacity * sizeof(line_sender_column_name)) - if vec.d == NULL: - abort() - elif vec.size == vec.capacity: - vec.capacity = vec.capacity * 2 - vec.d = realloc( - vec.d, - vec.capacity * sizeof(line_sender_column_name)) - if not vec.d: - abort() - vec.d[vec.size] = value - vec.size += 1 - - -cdef enum col_type_t: - COL_TYPE_INT = 0 - COL_TYPE_FLOAT = 1 - COL_TYPE_STRING = 2 - COL_TYPE_BOOL = 3 - COL_TYPE_DATE = 4 - COL_TYPE_TIME = 5 - COL_TYPE_DATETIME = 6 - COL_TYPE_BLOB = 7 - COL_TYPE_NULL = 8 - -# Inspired by a Py_buffer. -# See: https://docs.python.org/3/c-api/buffer.html -# This is simpler as we discard Python-specifics and it's one-dimensional only, -# i.e. `ndim` is always 1. -# If this stuff makes no sense to you: -# http://jakevdp.github.io/blog/2014/05/05/introduction-to-the-python-buffer-protocol/ -# and https://www.youtube.com/watch?v=10smLBD0kXg -cdef struct column_buf_t: - col_type_t dtype # internal enum value of supported pandas type. - void* d # start of the buffer (pointer to element 0) - ssize_t nbytes # size of the buffer in bytes - ssize_t count # number of elements in the buffer (aka shape[0]) - ssize_t itemsize # element size in bytes (!=nbytes/count due to strides) - ssize_t stride # stride in bytes between elements - # NB: We don't support suboffsets. - - -cdef object _PANDAS_NA = None - - -cdef object _pandas_may_set_na_type(): - global _PANDAS_NA - if _PANDAS_NA is None: - import pandas as pd - _PANDAS_NA = pd.NA - - -cdef ssize_t _pandas_resolve_table_name( - qdb_pystr_buf* b, - object data, - object table_name, - object table_name_col, - size_t col_count, - line_sender_table_name* name_out) except -2: - """ - Return a tuple-pair of: - * int column index - * object - - If the column index is -1, then `name_out` is set and either the returned - object is None or a bytes object to track ownership of data in `name_out`. - - Alternatively, if the returned column index > 0, then `name_out` is not set - and the column index relates to which pandas column contains the table name - on a per-row basis. In such case, the object is always None. - - This method validates input and may raise. - """ - cdef size_t col_index = 0 - if table_name is not None: - if table_name_col is not None: - raise ValueError( - 'Can specify only one of `table_name` or `table_name_col`.') - if isinstance(table_name, str): - try: - str_to_table_name(b, table_name, name_out) - return -1 # Magic value for "no column index". - except IngressError as ie: - raise ValueError(f'Bad argument `table_name`: {ie}') - else: - raise TypeError('Bad argument `table_name`: Must be str.') - elif table_name_col is not None: - if isinstance(table_name_col, str): - _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - elif isinstance(table_name_col, int): - _bind_col_index( - 'table_name_col', table_name_col, col_count, &col_index) - else: - raise TypeError( - 'Bad argument `table_name_col`: ' + - 'must be a column name (str) or index (int).') - _pandas_check_column_is_str( - data, - col_index, - 'Bad argument `table_name_col`: ', - table_name_col) - return col_index - else: - raise ValueError( - 'Must specify at least one of `table_name` or `table_name_col`.') - - -cdef int _pandas_resolve_fields( - int name_col, - const size_t_vec* symbol_indices, - int at_col, - size_t col_count, - size_t_vec* field_indices_out) except -1: - """ - Populate vec of field column indices via `field_indices_out`. - Returns the length of the list. - The vec will contain all columns which are not the table name column, - symbols or the at timestamp column. - """ - # We rely on `symbol_indices` being sorted. - cdef size_t col_index = 0 - cdef size_t sym_index = 0 - cdef size_t sym_len = symbol_indices.size - while col_index < col_count: - if (name_col >= 0) and (col_index == name_col): - col_index += 1 - continue - if (at_col >= 0) and (col_index == at_col): - col_index += 1 - continue - while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: - sym_index += 1 - if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: - col_index += 1 - continue - size_t_vec_push(field_indices_out, col_index) - col_index += 1 - return 0 - - -cdef bint _pandas_resolve_col_names( - qdb_pystr_buf* b, - object data, - const size_t_vec* symbol_indices, - const size_t_vec* field_indices, - column_name_vec* symbol_names_out, - column_name_vec* field_names_out) except False: - cdef line_sender_column_name c_name - cdef size_t col_index - for col_index in range(symbol_indices.size): - col_index = symbol_indices.d[col_index] - str_to_column_name(b, data.columns[col_index], &c_name) - column_name_vec_push(symbol_names_out, c_name) - for col_index in range(field_indices.size): - col_index = field_indices.d[col_index] - str_to_column_name(b, data.columns[col_index], &c_name) - column_name_vec_push(field_names_out, c_name) - return True - - -cdef bint _bind_col_index( - str arg_name, int col_num, size_t col_count, - size_t* col_index) except False: - """ - Validate that `col_index` is in bounds for `col_count`. - This function also converts negative indicies (e.g. -1 for last column) to - positive indicies. - """ - cdef bint bad = False - cdef int orig_col_num = col_num - if col_num < 0: - col_num += col_count # Try convert negative offsets to positive ones. - if col_num < 0: - bad = True - if (not bad) and (col_num >= col_count): - bad = True - if bad: - raise IndexError( - f'Bad argument `{arg_name}`: {orig_col_num} index out of range') - col_index[0] = col_num - return True - - -cdef object _pandas_column_is_str(object data, int col_index): - """ - Return True if the column at `col_index` is a string column. - """ - # NB: Returning `object` rather than `bint` to allow for exceptions. - cdef str col_kind - cdef object col - col_kind = data.dtypes[col_index].kind - if col_kind == 'S': # string, string[pyarrow] - return True - elif col_kind == 'O': # object - if len(data.index) == 0: - return True - else: - # We only check the first element and hope for the rest. - # We also accept None as a null value. - col = data.iloc[0, col_index] - return (col is None) or isinstance(col, str) - else: - return False - - -cdef object _pandas_check_column_is_str( - object data, size_t col_index, str err_msg_prefix, object col_name): - cdef str col_kind - col_kind = data.dtypes[col_index].kind - if col_kind in 'SO': - if not _pandas_column_is_str(data, col_index): - raise TypeError( - err_msg_prefix + - 'Found non-string value ' + - f'in column {col_name!r}.') - else: - raise TypeError( - err_msg_prefix + - f'Bad dtype `{data.dtypes[col_index]}` for the ' + - f'{col_name!r} column: Must be a strings column.') - - -cdef int _pandas_resolve_symbols( - object data, - ssize_t table_name_col, - ssize_t at_col, - object symbols, - size_t col_count, - size_t_vec* symbol_indices_out) except -1: - """ - Populate vec of symbol column indices via `symbol_indices_out`. - Returns the length of the vec. - """ - cdef size_t col_index = 0 - cdef object symbol - if symbols is False: - return 0 - elif symbols is True: - for col_index in range(col_count): - if _pandas_column_is_str(data, col_index): - size_t_vec_push(symbol_indices_out, col_index) - return 0 - else: - if not isinstance(symbols, (tuple, list)): - raise TypeError( - f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - 'of column names (str) or indices (int).') - for symbol in symbols: - if isinstance(symbol, str): - _pandas_get_loc(data, symbol, 'symbols', &col_index) - elif isinstance(symbol, int): - _bind_col_index('symbol', symbol, col_count, &col_index) - else: - raise TypeError( - f'Bad argument `symbols`: Elements must ' + - 'be a column name (str) or index (int).') - if (table_name_col >= 0) and (col_index == table_name_col): - raise ValueError( - f'Bad argument `symbols`: Cannot use the same column ' + - f'{symbol!r} as both the table_name and as a symbol.') - if (at_col >= 0) and (col_index == at_col): - raise ValueError( - f'Bad argument `symbols`: Cannot use the `at` column ' + - f'({data.columns[at_col]!r}) as a symbol column.') - _pandas_check_column_is_str( - data, - col_index, - 'Bad element in argument `symbols`: ', - symbol) - size_t_vec_push(symbol_indices_out, col_index) - return 0 - - -cdef bint _pandas_get_loc( - object data, str col_name, str arg_name, - size_t* col_index_out) except False: - """ - Return the column index for `col_name`. - """ - try: - col_index_out[0] = data.columns.get_loc(col_name) - return True - except KeyError: - raise KeyError( - f'Bad argument `{arg_name}`: ' + - f'Column {col_name!r} not found in the dataframe.') - - -cdef ssize_t _pandas_resolve_at( - object data, - object at, - size_t col_count, - int64_t* at_value_out) except -2: - cdef size_t col_index - cdef object dtype - if at is None: - at_value_out[0] = 0 # Special value for `at_now`. - return -1 - elif isinstance(at, TimestampNanos): - at_value_out[0] = at._value - return -1 - elif isinstance(at, datetime): - at_value_out[0] = datetime_to_nanos(at) - return -1 - elif isinstance(at, str): - _pandas_get_loc(data, at, 'at', &col_index) - elif isinstance(at, int): - _bind_col_index('at', at, col_count, &col_index) - else: - raise TypeError( - f'Bad argument `at`: Unsupported type {type(at)}. ' + - 'Must be one of: None, TimestampNanos, datetime, ' + - 'int (column index), str (colum name)') - dtype = data.dtypes[col_index] - if _pandas_is_supported_datetime(dtype): - at_value_out[0] = 0 - return col_index - else: - raise TypeError( - f'Bad argument `at`: Bad dtype `{dtype}` ' + - f'for the {at!r} column: Must be a datetime64[ns] column.') - - -cdef object _pandas_is_supported_datetime(object dtype): - # We currently only accept datetime64[ns] columns. - return ( - (dtype.kind == 'M') and - (dtype.itemsize == 8) and - (dtype.byteorder == '=') and - (dtype.alignment == 8) and - (not dtype.hasobject)) - - -cdef struct dtype_t: - # A ripoff of a subset of PyArray_Descr as we were able to extract from numpy.dtype. - # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html?highlight=dtype#numpy.dtype - # See: https://numpy.org/doc/stable/reference/c-api/types-and-structures.html#c.PyArray_Descr - int alignment - char kind - int itemsize - char byteorder - bint hasobject - - -cdef char _str_to_char(str field, str s) except 0: - cdef int res - if len(s) != 1: - raise ValueError( - f'dtype.{field}: Expected a single character, got {s!r}') - res = ord(s) - if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. - raise ValueError( - f'dtype.{field}: Character out of ASCII range, got {s!r}') - return res - - -cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: - """ - Parse a numpy dtype and return a dtype_t. - """ - dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) - dtype_out.kind = _str_to_char('kind', np_dtype.kind) - dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) - dtype_out.byteorder = _str_to_char( - 'byteorder', getattr(np_dtype, 'byteorder', '=')) - dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) - return True - - -cdef bint _pandas_resolve_dtypes( - object data, size_t col_count, dtype_t* dtypes_out) except False: - cdef size_t col_index - for col_index in range(col_count): - _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) - return True - - -cdef bint _pandas_resolve_col_buffers( - object data, size_t col_count, const dtype_t* dtypes, - Py_buffer* col_buffers, size_t* set_buf_count) except False: - """ - Map pandas columns to array of col_buffers. - """ - # Note: By calling "to_numpy" we are throwing away what might be an Arrow. - # This is particularly expensive for string columns. - # If you want to use Arrow (i.e. your data comes from Parquet) please ask - # for the feature in our issue tracker. - cdef size_t col_index - cdef object nparr - cdef Py_buffer* view - cdef const dtype_t* dtype - for col_index in range(col_count): - nparr = data.iloc[:, col_index].to_numpy() - view = &col_buffers[col_index] - dtype = &dtypes[col_index] - if not PyObject_CheckBuffer(nparr): - raise TypeError( - f'Bad column: Expected a numpy array, got {nparr!r}') - PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) - # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. - set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. - return True - - -cdef inline const void* _pandas_get_cell( - Py_buffer* col_buffer, size_t row_index): - return col_buffer.buf + (row_index * col_buffer.strides[0]) - - -cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' -cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' - - -cdef bint _pandas_get_str_cell( - qdb_pystr_buf* b, - dtype_t* dtype, - Py_buffer* col_buffer, - size_t row_index, - bint* is_null_out, - line_sender_utf8* utf8_out) except False: - cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - cdef object obj - if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: - # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. - # TODO: Improve error messaging. Error message should include the column name. - obj = ((cell)[0]) - if (obj is None) or (obj is _PANDAS_NA): - is_null_out[0] = True - else: - is_null_out[0] = False - try: - str_to_utf8(b, obj, utf8_out) - except TypeError as e: - raise TypeError( - 'Bad column: Expected a string, ' + - f'got {obj!r} ({type(obj)!r})') from e - else: - raise TypeError( - f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. - return True - - -cdef int64_t _pandas_get_timestamp_cell( - dtype_t* dtype, - Py_buffer* col_buffer, - size_t row_index) except -1: - # Note: Type is pre-validated by `_pandas_is_supported_datetime`. - cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - cdef int64_t res = (cell)[0] - if res < 0: - # TODO [amunra]: Improve error messaging. Add column name. - raise ValueError( - f'Bad value: Negative timestamp, got {res}') - return res - - -cdef bint _pandas_row_table_name( - line_sender_buffer* impl, - qdb_pystr_buf* b, - dtype_t* dtypes, - Py_buffer* col_buffers, - ssize_t name_col, - size_t row_index, - line_sender_table_name c_table_name) except False: - cdef line_sender_error* err = NULL - cdef bint is_null = False - cdef line_sender_utf8 utf8 - if name_col >= 0: - _pandas_get_str_cell( - b, - &dtypes[name_col], - &col_buffers[name_col], - row_index, - &is_null, - &utf8) - if is_null: - # TODO [amunra]: Improve error messaging. Add column name. - raise ValueError( - f'Bad value: `None` table name value at row {row_index}.') - if not line_sender_table_name_init( - &c_table_name, utf8.len, utf8.buf, &err): - raise c_err_to_py(err) - if not line_sender_buffer_table(impl, c_table_name, &err): - raise c_err_to_py(err) - return True - - -cdef bint _pandas_row_symbols( - line_sender_buffer* impl, - qdb_pystr_buf* b, - dtype_t* dtypes, - Py_buffer* col_buffers, - size_t row_index, - const column_name_vec* symbol_names, - const size_t_vec* symbol_indices) except False: - cdef line_sender_error* err = NULL - cdef size_t sym_index - cdef size_t col_index - cdef dtype_t* dtype - cdef Py_buffer* col_buffer - cdef line_sender_column_name col_name - cdef line_sender_utf8 symbol - cdef bint is_null = False - for sym_index in range(symbol_indices.size): - col_name = symbol_names.d[sym_index] - col_index = symbol_indices.d[sym_index] - col_buffer = &col_buffers[col_index] - dtype = &dtypes[col_index] - _pandas_get_str_cell( - b, - dtype, - col_buffer, - row_index, - &is_null, - &symbol) - if not is_null: - if not line_sender_buffer_symbol(impl, col_name, symbol, &err): - raise c_err_to_py(err) - return True - - -cdef bint _pandas_row_at( - line_sender_buffer* impl, - dtype_t* dtypes, - Py_buffer* col_buffers, - size_t row_index, - ssize_t at_col, - int64_t at_value) except False: - cdef line_sender_error* err = NULL - cdef Py_buffer* col_buffer - cdef dtype_t* dtype - if at_col >= 0: - col_buffer = &col_buffers[at_col] - dtype = &dtypes[at_col] - at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - if at_value > 0: - if not line_sender_buffer_at(impl, at_value, &err): - raise c_err_to_py(err) - else: - if not line_sender_buffer_at_now(impl, &err): - raise c_err_to_py(err) - return True - - - _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' 'v1.0.2' '/troubleshooting.html#inspecting-and-debugging-errors#flush-failed') diff --git a/src/questdb/pandas_helpers.pxi b/src/questdb/pandas_helpers.pxi new file mode 100644 index 00000000..ab06ae14 --- /dev/null +++ b/src/questdb/pandas_helpers.pxi @@ -0,0 +1,605 @@ + + +cdef struct c_size_t_vec: + size_t capacity + size_t size + size_t* d + +ctypedef c_size_t_vec size_t_vec + +cdef size_t_vec size_t_vec_new(): + cdef size_t_vec vec + vec.capacity = 0 + vec.size = 0 + vec.d = NULL + return vec + +cdef void size_t_vec_free(size_t_vec* vec): + if vec.d: + free(vec.d) + vec.d = NULL + +cdef str size_t_vec_str(size_t_vec* vec): + return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) + +cdef void size_t_vec_push(size_t_vec* vec, size_t value): + if vec.capacity == 0: + vec.capacity = 8 + vec.d = malloc(vec.capacity * sizeof(size_t)) + if vec.d == NULL: + abort() + elif vec.size == vec.capacity: + vec.capacity = vec.capacity * 2 + vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + if not vec.d: + abort() + vec.d[vec.size] = value + vec.size += 1 + + +cdef struct c_column_name_vec: + size_t capacity + size_t size + line_sender_column_name* d + +ctypedef c_column_name_vec column_name_vec + +cdef column_name_vec column_name_vec_new(): + cdef column_name_vec vec + vec.capacity = 0 + vec.size = 0 + vec.d = NULL + return vec + +cdef void column_name_vec_free(column_name_vec* vec): + if vec.d: + free(vec.d) + vec.d = NULL + +cdef void column_name_vec_push( + column_name_vec* vec, line_sender_column_name value): + if vec.capacity == 0: + vec.capacity = 8 + vec.d = malloc( + vec.capacity * sizeof(line_sender_column_name)) + if vec.d == NULL: + abort() + elif vec.size == vec.capacity: + vec.capacity = vec.capacity * 2 + vec.d = realloc( + vec.d, + vec.capacity * sizeof(line_sender_column_name)) + if not vec.d: + abort() + vec.d[vec.size] = value + vec.size += 1 + + +cdef enum col_type_t: + COL_TYPE_INT = 0 + COL_TYPE_FLOAT = 1 + COL_TYPE_STRING = 2 + COL_TYPE_BOOL = 3 + COL_TYPE_DATE = 4 + COL_TYPE_TIME = 5 + COL_TYPE_DATETIME = 6 + COL_TYPE_BLOB = 7 + COL_TYPE_NULL = 8 + +# Inspired by a Py_buffer. +# See: https://docs.python.org/3/c-api/buffer.html +# This is simpler as we discard Python-specifics and it's one-dimensional only, +# i.e. `ndim` is always 1. +# If this stuff makes no sense to you: +# http://jakevdp.github.io/blog/2014/05/05/introduction-to-the-python-buffer-protocol/ +# and https://www.youtube.com/watch?v=10smLBD0kXg +cdef struct column_buf_t: + col_type_t dtype # internal enum value of supported pandas type. + void* d # start of the buffer (pointer to element 0) + ssize_t nbytes # size of the buffer in bytes + ssize_t count # number of elements in the buffer (aka shape[0]) + ssize_t itemsize # element size in bytes (!=nbytes/count due to strides) + ssize_t stride # stride in bytes between elements + # NB: We don't support suboffsets. + + +cdef object _PANDAS_NA = None + + +cdef object _pandas_may_set_na_type(): + global _PANDAS_NA + if _PANDAS_NA is None: + import pandas as pd + _PANDAS_NA = pd.NA + + +cdef ssize_t _pandas_resolve_table_name( + qdb_pystr_buf* b, + object data, + object table_name, + object table_name_col, + size_t col_count, + line_sender_table_name* name_out) except -2: + """ + Return a tuple-pair of: + * int column index + * object + + If the column index is -1, then `name_out` is set and either the returned + object is None or a bytes object to track ownership of data in `name_out`. + + Alternatively, if the returned column index > 0, then `name_out` is not set + and the column index relates to which pandas column contains the table name + on a per-row basis. In such case, the object is always None. + + This method validates input and may raise. + """ + cdef size_t col_index = 0 + if table_name is not None: + if table_name_col is not None: + raise ValueError( + 'Can specify only one of `table_name` or `table_name_col`.') + if isinstance(table_name, str): + try: + str_to_table_name(b, table_name, name_out) + return -1 # Magic value for "no column index". + except IngressError as ie: + raise ValueError(f'Bad argument `table_name`: {ie}') + else: + raise TypeError('Bad argument `table_name`: Must be str.') + elif table_name_col is not None: + if isinstance(table_name_col, str): + _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + elif isinstance(table_name_col, int): + _bind_col_index( + 'table_name_col', table_name_col, col_count, &col_index) + else: + raise TypeError( + 'Bad argument `table_name_col`: ' + + 'must be a column name (str) or index (int).') + _pandas_check_column_is_str( + data, + col_index, + 'Bad argument `table_name_col`: ', + table_name_col) + return col_index + else: + raise ValueError( + 'Must specify at least one of `table_name` or `table_name_col`.') + + +cdef int _pandas_resolve_fields( + int name_col, + const size_t_vec* symbol_indices, + int at_col, + size_t col_count, + size_t_vec* field_indices_out) except -1: + """ + Populate vec of field column indices via `field_indices_out`. + Returns the length of the list. + The vec will contain all columns which are not the table name column, + symbols or the at timestamp column. + """ + # We rely on `symbol_indices` being sorted. + cdef size_t col_index = 0 + cdef size_t sym_index = 0 + cdef size_t sym_len = symbol_indices.size + while col_index < col_count: + if (name_col >= 0) and (col_index == name_col): + col_index += 1 + continue + if (at_col >= 0) and (col_index == at_col): + col_index += 1 + continue + while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: + sym_index += 1 + if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: + col_index += 1 + continue + size_t_vec_push(field_indices_out, col_index) + col_index += 1 + return 0 + + +cdef bint _pandas_resolve_col_names( + qdb_pystr_buf* b, + object data, + const size_t_vec* symbol_indices, + const size_t_vec* field_indices, + column_name_vec* symbol_names_out, + column_name_vec* field_names_out) except False: + cdef line_sender_column_name c_name + cdef size_t col_index + for col_index in range(symbol_indices.size): + col_index = symbol_indices.d[col_index] + str_to_column_name(b, data.columns[col_index], &c_name) + column_name_vec_push(symbol_names_out, c_name) + for col_index in range(field_indices.size): + col_index = field_indices.d[col_index] + str_to_column_name(b, data.columns[col_index], &c_name) + column_name_vec_push(field_names_out, c_name) + return True + + +cdef bint _bind_col_index( + str arg_name, int col_num, size_t col_count, + size_t* col_index) except False: + """ + Validate that `col_index` is in bounds for `col_count`. + This function also converts negative indicies (e.g. -1 for last column) to + positive indicies. + """ + cdef bint bad = False + cdef int orig_col_num = col_num + if col_num < 0: + col_num += col_count # Try convert negative offsets to positive ones. + if col_num < 0: + bad = True + if (not bad) and (col_num >= col_count): + bad = True + if bad: + raise IndexError( + f'Bad argument `{arg_name}`: {orig_col_num} index out of range') + col_index[0] = col_num + return True + + +cdef object _pandas_column_is_str(object data, int col_index): + """ + Return True if the column at `col_index` is a string column. + """ + # NB: Returning `object` rather than `bint` to allow for exceptions. + cdef str col_kind + cdef object col + col_kind = data.dtypes[col_index].kind + if col_kind == 'S': # string, string[pyarrow] + return True + elif col_kind == 'O': # object + if len(data.index) == 0: + return True + else: + # We only check the first element and hope for the rest. + # We also accept None as a null value. + col = data.iloc[0, col_index] + return (col is None) or isinstance(col, str) + else: + return False + + +cdef object _pandas_check_column_is_str( + object data, size_t col_index, str err_msg_prefix, object col_name): + cdef str col_kind + col_kind = data.dtypes[col_index].kind + if col_kind in 'SO': + if not _pandas_column_is_str(data, col_index): + raise TypeError( + err_msg_prefix + + 'Found non-string value ' + + f'in column {col_name!r}.') + else: + raise TypeError( + err_msg_prefix + + f'Bad dtype `{data.dtypes[col_index]}` for the ' + + f'{col_name!r} column: Must be a strings column.') + + +cdef int _pandas_resolve_symbols( + object data, + ssize_t table_name_col, + ssize_t at_col, + object symbols, + size_t col_count, + size_t_vec* symbol_indices_out) except -1: + """ + Populate vec of symbol column indices via `symbol_indices_out`. + Returns the length of the vec. + """ + cdef size_t col_index = 0 + cdef object symbol + if symbols is False: + return 0 + elif symbols is True: + for col_index in range(col_count): + if _pandas_column_is_str(data, col_index): + size_t_vec_push(symbol_indices_out, col_index) + return 0 + else: + if not isinstance(symbols, (tuple, list)): + raise TypeError( + f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + 'of column names (str) or indices (int).') + for symbol in symbols: + if isinstance(symbol, str): + _pandas_get_loc(data, symbol, 'symbols', &col_index) + elif isinstance(symbol, int): + _bind_col_index('symbol', symbol, col_count, &col_index) + else: + raise TypeError( + f'Bad argument `symbols`: Elements must ' + + 'be a column name (str) or index (int).') + if (table_name_col >= 0) and (col_index == table_name_col): + raise ValueError( + f'Bad argument `symbols`: Cannot use the same column ' + + f'{symbol!r} as both the table_name and as a symbol.') + if (at_col >= 0) and (col_index == at_col): + raise ValueError( + f'Bad argument `symbols`: Cannot use the `at` column ' + + f'({data.columns[at_col]!r}) as a symbol column.') + _pandas_check_column_is_str( + data, + col_index, + 'Bad element in argument `symbols`: ', + symbol) + size_t_vec_push(symbol_indices_out, col_index) + return 0 + + +cdef bint _pandas_get_loc( + object data, str col_name, str arg_name, + size_t* col_index_out) except False: + """ + Return the column index for `col_name`. + """ + try: + col_index_out[0] = data.columns.get_loc(col_name) + return True + except KeyError: + raise KeyError( + f'Bad argument `{arg_name}`: ' + + f'Column {col_name!r} not found in the dataframe.') + + +cdef ssize_t _pandas_resolve_at( + object data, + object at, + size_t col_count, + int64_t* at_value_out) except -2: + cdef size_t col_index + cdef object dtype + if at is None: + at_value_out[0] = 0 # Special value for `at_now`. + return -1 + elif isinstance(at, TimestampNanos): + at_value_out[0] = at._value + return -1 + elif isinstance(at, datetime): + at_value_out[0] = datetime_to_nanos(at) + return -1 + elif isinstance(at, str): + _pandas_get_loc(data, at, 'at', &col_index) + elif isinstance(at, int): + _bind_col_index('at', at, col_count, &col_index) + else: + raise TypeError( + f'Bad argument `at`: Unsupported type {type(at)}. ' + + 'Must be one of: None, TimestampNanos, datetime, ' + + 'int (column index), str (colum name)') + dtype = data.dtypes[col_index] + if _pandas_is_supported_datetime(dtype): + at_value_out[0] = 0 + return col_index + else: + raise TypeError( + f'Bad argument `at`: Bad dtype `{dtype}` ' + + f'for the {at!r} column: Must be a datetime64[ns] column.') + + +cdef object _pandas_is_supported_datetime(object dtype): + # We currently only accept datetime64[ns] columns. + return ( + (dtype.kind == 'M') and + (dtype.itemsize == 8) and + (dtype.byteorder == '=') and + (dtype.alignment == 8) and + (not dtype.hasobject)) + + +cdef struct dtype_t: + # A ripoff of a subset of PyArray_Descr as we were able to extract from numpy.dtype. + # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html?highlight=dtype#numpy.dtype + # See: https://numpy.org/doc/stable/reference/c-api/types-and-structures.html#c.PyArray_Descr + int alignment + char kind + int itemsize + char byteorder + bint hasobject + + +cdef char _str_to_char(str field, str s) except 0: + cdef int res + if len(s) != 1: + raise ValueError( + f'dtype.{field}: Expected a single character, got {s!r}') + res = ord(s) + if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. + raise ValueError( + f'dtype.{field}: Character out of ASCII range, got {s!r}') + return res + + +cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: + """ + Parse a numpy dtype and return a dtype_t. + """ + dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) + dtype_out.kind = _str_to_char('kind', np_dtype.kind) + dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) + dtype_out.byteorder = _str_to_char( + 'byteorder', getattr(np_dtype, 'byteorder', '=')) + dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) + return True + + +cdef bint _pandas_resolve_dtypes( + object data, size_t col_count, dtype_t* dtypes_out) except False: + cdef size_t col_index + for col_index in range(col_count): + _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) + return True + + +cdef bint _pandas_resolve_col_buffers( + object data, size_t col_count, const dtype_t* dtypes, + Py_buffer* col_buffers, size_t* set_buf_count) except False: + """ + Map pandas columns to array of col_buffers. + """ + # Note: By calling "to_numpy" we are throwing away what might be an Arrow. + # This is particularly expensive for string columns. + # If you want to use Arrow (i.e. your data comes from Parquet) please ask + # for the feature in our issue tracker. + cdef size_t col_index + cdef object nparr + cdef Py_buffer* view + cdef const dtype_t* dtype + for col_index in range(col_count): + nparr = data.iloc[:, col_index].to_numpy() + view = &col_buffers[col_index] + dtype = &dtypes[col_index] + if not PyObject_CheckBuffer(nparr): + raise TypeError( + f'Bad column: Expected a numpy array, got {nparr!r}') + PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) + # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. + set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. + return True + + +cdef inline const void* _pandas_get_cell( + Py_buffer* col_buffer, size_t row_index): + return col_buffer.buf + (row_index * col_buffer.strides[0]) + + +cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' +cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' + + +cdef bint _pandas_get_str_cell( + qdb_pystr_buf* b, + dtype_t* dtype, + Py_buffer* col_buffer, + size_t row_index, + bint* is_null_out, + line_sender_utf8* utf8_out) except False: + cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + cdef object obj + if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: + # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. + # TODO: Improve error messaging. Error message should include the column name. + obj = ((cell)[0]) + if (obj is None) or (obj is _PANDAS_NA): + is_null_out[0] = True + else: + is_null_out[0] = False + try: + str_to_utf8(b, obj, utf8_out) + except TypeError as e: + raise TypeError( + 'Bad column: Expected a string, ' + + f'got {obj!r} ({type(obj)!r})') from e + else: + raise TypeError( + f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. + return True + + +cdef int64_t _pandas_get_timestamp_cell( + dtype_t* dtype, + Py_buffer* col_buffer, + size_t row_index) except -1: + # Note: Type is pre-validated by `_pandas_is_supported_datetime`. + cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + cdef int64_t res = (cell)[0] + if res < 0: + # TODO [amunra]: Improve error messaging. Add column name. + raise ValueError( + f'Bad value: Negative timestamp, got {res}') + return res + + +cdef bint _pandas_row_table_name( + line_sender_buffer* impl, + qdb_pystr_buf* b, + dtype_t* dtypes, + Py_buffer* col_buffers, + ssize_t name_col, + size_t row_index, + line_sender_table_name c_table_name) except False: + cdef line_sender_error* err = NULL + cdef bint is_null = False + cdef line_sender_utf8 utf8 + if name_col >= 0: + _pandas_get_str_cell( + b, + &dtypes[name_col], + &col_buffers[name_col], + row_index, + &is_null, + &utf8) + if is_null: + # TODO [amunra]: Improve error messaging. Add column name. + raise ValueError( + f'Bad value: `None` table name value at row {row_index}.') + if not line_sender_table_name_init( + &c_table_name, utf8.len, utf8.buf, &err): + raise c_err_to_py(err) + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + return True + + +cdef bint _pandas_row_symbols( + line_sender_buffer* impl, + qdb_pystr_buf* b, + dtype_t* dtypes, + Py_buffer* col_buffers, + size_t row_index, + const column_name_vec* symbol_names, + const size_t_vec* symbol_indices) except False: + cdef line_sender_error* err = NULL + cdef size_t sym_index + cdef size_t col_index + cdef dtype_t* dtype + cdef Py_buffer* col_buffer + cdef line_sender_column_name col_name + cdef line_sender_utf8 symbol + cdef bint is_null = False + for sym_index in range(symbol_indices.size): + col_name = symbol_names.d[sym_index] + col_index = symbol_indices.d[sym_index] + col_buffer = &col_buffers[col_index] + dtype = &dtypes[col_index] + _pandas_get_str_cell( + b, + dtype, + col_buffer, + row_index, + &is_null, + &symbol) + if not is_null: + if not line_sender_buffer_symbol(impl, col_name, symbol, &err): + raise c_err_to_py(err) + return True + + +cdef bint _pandas_row_at( + line_sender_buffer* impl, + dtype_t* dtypes, + Py_buffer* col_buffers, + size_t row_index, + ssize_t at_col, + int64_t at_value) except False: + cdef line_sender_error* err = NULL + cdef Py_buffer* col_buffer + cdef dtype_t* dtype + if at_col >= 0: + col_buffer = &col_buffers[at_col] + dtype = &dtypes[at_col] + at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + if at_value > 0: + if not line_sender_buffer_at(impl, at_value, &err): + raise c_err_to_py(err) + else: + if not line_sender_buffer_at_now(impl, &err): + raise c_err_to_py(err) + return True From d14eea97741f965adfd3a554096114e7ac9f2bba Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 14 Nov 2022 13:05:13 +0000 Subject: [PATCH 039/147] Consolidated approach writeup and code reorg into .pxi files. --- .gitignore | 4 +- src/questdb/column_name_vec.pxi | 36 + src/questdb/ingress.c | 29176 ++++++++++++++++++++++++++++++ src/questdb/pandas_helpers.md | 104 + src/questdb/pandas_helpers.pxi | 182 +- src/questdb/size_t_vec.pxi | 35 + 6 files changed, 29424 insertions(+), 113 deletions(-) create mode 100644 src/questdb/column_name_vec.pxi create mode 100644 src/questdb/ingress.c create mode 100644 src/questdb/pandas_helpers.md create mode 100644 src/questdb/size_t_vec.pxi diff --git a/.gitignore b/.gitignore index bcb0cffe..ef5fd695 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ -src/questdb/ingress.html -src/questdb/ingress.c -src/questdb/pandas_helpers.html +src/questdb/*.html rustup-init.exe # Byte-compiled / optimized / DLL files diff --git a/src/questdb/column_name_vec.pxi b/src/questdb/column_name_vec.pxi new file mode 100644 index 00000000..8ea920a6 --- /dev/null +++ b/src/questdb/column_name_vec.pxi @@ -0,0 +1,36 @@ +cdef struct c_column_name_vec: + size_t capacity + size_t size + line_sender_column_name* d + +ctypedef c_column_name_vec column_name_vec + +cdef column_name_vec column_name_vec_new(): + cdef column_name_vec vec + vec.capacity = 0 + vec.size = 0 + vec.d = NULL + return vec + +cdef void column_name_vec_free(column_name_vec* vec): + if vec.d: + free(vec.d) + vec.d = NULL + +cdef void column_name_vec_push( + column_name_vec* vec, line_sender_column_name value): + if vec.capacity == 0: + vec.capacity = 8 + vec.d = malloc( + vec.capacity * sizeof(line_sender_column_name)) + if vec.d == NULL: + abort() + elif vec.size == vec.capacity: + vec.capacity = vec.capacity * 2 + vec.d = realloc( + vec.d, + vec.capacity * sizeof(line_sender_column_name)) + if not vec.d: + abort() + vec.d[vec.size] = value + vec.size += 1 diff --git a/src/questdb/ingress.c b/src/questdb/ingress.c new file mode 100644 index 00000000..2e8cf694 --- /dev/null +++ b/src/questdb/ingress.c @@ -0,0 +1,29176 @@ +/* Generated by Cython 0.29.30 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [], + "extra_link_args": [ + "-framework", + "Security" + ], + "extra_objects": [ + "/Users/adam/questdb/repos/py-questdb-client/c-questdb-client/questdb-rs-ffi/target/release/libquestdb_client.a", + "/Users/adam/questdb/repos/py-questdb-client/pystr-to-utf8/target/release/libpystr_to_utf8.a" + ], + "include_dirs": [ + "c-questdb-client/include", + "pystr-to-utf8/include" + ], + "language": "c", + "name": "questdb.ingress", + "sources": [ + "src/questdb/ingress.pyx" + ] + }, + "module_name": "questdb.ingress" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_29_30" +#define CYTHON_HEX_VERSION 0x001D1EF0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_HEX >= 0x07030900) + #endif +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #if PY_VERSION_HEX >= 0x030B00A4 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #elif !defined(CYTHON_FAST_THREAD_STATE) + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL (PY_VERSION_HEX < 0x030A0000) + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #if PY_VERSION_HEX >= 0x030B00A4 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #elif !defined(CYTHON_USE_EXC_INFO_STACK) + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_MAJOR_VERSION < 3 + #include "longintrepr.h" + #endif + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_DefaultClassType PyType_Type +#if PY_VERSION_HEX >= 0x030B00A1 + static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *kwds=NULL, *argcount=NULL, *posonlyargcount=NULL, *kwonlyargcount=NULL; + PyObject *nlocals=NULL, *stacksize=NULL, *flags=NULL, *replace=NULL, *call_result=NULL, *empty=NULL; + const char *fn_cstr=NULL; + const char *name_cstr=NULL; + PyCodeObject* co=NULL; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + if (!(kwds=PyDict_New())) goto end; + if (!(argcount=PyLong_FromLong(a))) goto end; + if (PyDict_SetItemString(kwds, "co_argcount", argcount) != 0) goto end; + if (!(posonlyargcount=PyLong_FromLong(0))) goto end; + if (PyDict_SetItemString(kwds, "co_posonlyargcount", posonlyargcount) != 0) goto end; + if (!(kwonlyargcount=PyLong_FromLong(k))) goto end; + if (PyDict_SetItemString(kwds, "co_kwonlyargcount", kwonlyargcount) != 0) goto end; + if (!(nlocals=PyLong_FromLong(l))) goto end; + if (PyDict_SetItemString(kwds, "co_nlocals", nlocals) != 0) goto end; + if (!(stacksize=PyLong_FromLong(s))) goto end; + if (PyDict_SetItemString(kwds, "co_stacksize", stacksize) != 0) goto end; + if (!(flags=PyLong_FromLong(f))) goto end; + if (PyDict_SetItemString(kwds, "co_flags", flags) != 0) goto end; + if (PyDict_SetItemString(kwds, "co_code", code) != 0) goto end; + if (PyDict_SetItemString(kwds, "co_consts", c) != 0) goto end; + if (PyDict_SetItemString(kwds, "co_names", n) != 0) goto end; + if (PyDict_SetItemString(kwds, "co_varnames", v) != 0) goto end; + if (PyDict_SetItemString(kwds, "co_freevars", fv) != 0) goto end; + if (PyDict_SetItemString(kwds, "co_cellvars", cell) != 0) goto end; + if (PyDict_SetItemString(kwds, "co_linetable", lnos) != 0) goto end; + if (!(fn_cstr=PyUnicode_AsUTF8AndSize(fn, NULL))) goto end; + if (!(name_cstr=PyUnicode_AsUTF8AndSize(name, NULL))) goto end; + if (!(co = PyCode_NewEmpty(fn_cstr, name_cstr, fline))) goto end; + if (!(replace = PyObject_GetAttrString((PyObject*)co, "replace"))) goto cleanup_code_too; + if (!(empty = PyTuple_New(0))) goto cleanup_code_too; // unfortunately __pyx_empty_tuple isn't available here + if (!(call_result = PyObject_Call(replace, empty, kwds))) goto cleanup_code_too; + Py_XDECREF((PyObject*)co); + co = (PyCodeObject*)call_result; + call_result = NULL; + if (0) { + cleanup_code_too: + Py_XDECREF((PyObject*)co); + co = NULL; + } + end: + Py_XDECREF(kwds); + Py_XDECREF(argcount); + Py_XDECREF(posonlyargcount); + Py_XDECREF(kwonlyargcount); + Py_XDECREF(nlocals); + Py_XDECREF(stacksize); + Py_XDECREF(replace); + Py_XDECREF(call_result); + Py_XDECREF(empty); + if (type) { + PyErr_Restore(type, value, traceback); + } + return co; + } +#else + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #if defined(PyUnicode_IS_READY) + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #else + #define __Pyx_PyUnicode_READY(op) (0) + #endif + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__questdb__ingress +#define __PYX_HAVE_API__questdb__ingress +/* Early includes */ +#include +#include +#include +#include +#include "datetime.h" +#include "questdb/ilp/line_sender.h" +#include "pystr_to_utf8.h" +#include "arrow_c_data_interface.h" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime = NULL; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "src/questdb/ingress.pyx", + "src/questdb/size_t_vec.pxi", + "src/questdb/pandas_helpers.pxi", + "stringsource", + "datetime.pxd", + "type.pxd", + "bool.pxd", +}; + +/*--- Type declarations ---*/ +struct __pyx_obj_7questdb_7ingress_TimestampMicros; +struct __pyx_obj_7questdb_7ingress_TimestampNanos; +struct __pyx_obj_7questdb_7ingress_Buffer; +struct __pyx_obj_7questdb_7ingress_Sender; +struct __pyx_t_7questdb_7ingress_c_size_t_vec; +struct __pyx_t_7questdb_7ingress_c_column_name_vec; +struct __pyx_t_7questdb_7ingress_dtype_t; +struct __pyx_t_7questdb_7ingress_col_numpy_data_t; +struct __pyx_t_7questdb_7ingress_col_arrow_data_t; +union __pyx_t_7questdb_7ingress_col_access_t; +struct __pyx_t_7questdb_7ingress_col_cursor_t; +struct __pyx_t_7questdb_7ingress_col_handle_t; +struct __pyx_opt_args_7questdb_7ingress_6Buffer__row; +struct __pyx_opt_args_7questdb_7ingress_6Sender_flush; +struct __pyx_opt_args_7questdb_7ingress_6Sender_close; + +/* "src/questdb/pandas_helpers.pxi":29 + * + * + * cdef enum col_access_tag_t: # <<<<<<<<<<<<<< + * numpy + * arrow + */ +enum __pyx_t_7questdb_7ingress_col_access_tag_t { + __pyx_e_7questdb_7ingress_numpy, + __pyx_e_7questdb_7ingress_arrow +}; + +/* "src/questdb/pandas_helpers.pxi":58 + * + * + * cdef enum col_line_sender_target_t: # <<<<<<<<<<<<<< + * table + * symbol + */ +enum __pyx_t_7questdb_7ingress_col_line_sender_target_t { + __pyx_e_7questdb_7ingress_table, + __pyx_e_7questdb_7ingress_symbol, + __pyx_e_7questdb_7ingress_column_bool, + __pyx_e_7questdb_7ingress_column_i64, + __pyx_e_7questdb_7ingress_column_f64, + __pyx_e_7questdb_7ingress_column_str, + __pyx_e_7questdb_7ingress_column_ts, + __pyx_e_7questdb_7ingress_at +}; + +/* "src/questdb/size_t_vec.pxi":1 + * cdef struct c_size_t_vec: # <<<<<<<<<<<<<< + * size_t capacity + * size_t size + */ +struct __pyx_t_7questdb_7ingress_c_size_t_vec { + size_t capacity; + size_t size; + size_t *d; +}; + +/* "src/questdb/size_t_vec.pxi":6 + * size_t* d + * + * ctypedef c_size_t_vec size_t_vec # <<<<<<<<<<<<<< + * + * cdef size_t_vec size_t_vec_new(): + */ +typedef struct __pyx_t_7questdb_7ingress_c_size_t_vec __pyx_t_7questdb_7ingress_size_t_vec; + +/* "src/questdb/column_name_vec.pxi":1 + * cdef struct c_column_name_vec: # <<<<<<<<<<<<<< + * size_t capacity + * size_t size + */ +struct __pyx_t_7questdb_7ingress_c_column_name_vec { + size_t capacity; + size_t size; + struct line_sender_column_name *d; +}; + +/* "src/questdb/column_name_vec.pxi":6 + * line_sender_column_name* d + * + * ctypedef c_column_name_vec column_name_vec # <<<<<<<<<<<<<< + * + * cdef column_name_vec column_name_vec_new(): + */ +typedef struct __pyx_t_7questdb_7ingress_c_column_name_vec __pyx_t_7questdb_7ingress_column_name_vec; + +/* "src/questdb/pandas_helpers.pxi":6 + * # See: pandas_helpers.md for technical overview. + * + * cdef struct dtype_t: # <<<<<<<<<<<<<< + * # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html + * # ?highlight=dtype#numpy.dtype + */ +struct __pyx_t_7questdb_7ingress_dtype_t { + int alignment; + char kind; + int itemsize; + char byteorder; + int hasobject; +}; + +/* "src/questdb/pandas_helpers.pxi":18 + * + * + * cdef struct col_numpy_data_t: # <<<<<<<<<<<<<< + * dtype_t dtype + * Py_buffer pybuf + */ +struct __pyx_t_7questdb_7ingress_col_numpy_data_t { + struct __pyx_t_7questdb_7ingress_dtype_t dtype; + Py_buffer pybuf; +}; + +/* "src/questdb/pandas_helpers.pxi":23 + * + * + * cdef struct col_arrow_data_t: # <<<<<<<<<<<<<< + * ArrowSchema schema + * size_t n_chunks + */ +struct __pyx_t_7questdb_7ingress_col_arrow_data_t { + struct ArrowSchema schema; + size_t n_chunks; + struct ArrowArray chunks; +}; + +/* "src/questdb/pandas_helpers.pxi":34 + * + * + * cdef union col_access_t: # <<<<<<<<<<<<<< + * col_numpy_data_t numpy + * col_arrow_data_t arrow + */ +union __pyx_t_7questdb_7ingress_col_access_t { + struct __pyx_t_7questdb_7ingress_col_numpy_data_t numpy; + struct __pyx_t_7questdb_7ingress_col_arrow_data_t arrow; +}; + +/* "src/questdb/pandas_helpers.pxi":39 + * + * + * cdef struct col_cursor_t: # <<<<<<<<<<<<<< + * size_t chunk_index + * size_t n_chunks + */ +struct __pyx_t_7questdb_7ingress_col_cursor_t { + size_t chunk_index; + size_t n_chunks; + size_t offset; + size_t length; + uint8_t *validity; + void *data; + uint8_t *utf8_buf; +}; + +/* "src/questdb/pandas_helpers.pxi":69 + * + * + * cdef struct col_handle_t: # <<<<<<<<<<<<<< + * col_access_tag_t access_tag + * col_access_t access + */ +struct __pyx_t_7questdb_7ingress_col_handle_t { + enum __pyx_t_7questdb_7ingress_col_access_tag_t access_tag; + union __pyx_t_7questdb_7ingress_col_access_t access; + struct __pyx_t_7questdb_7ingress_col_cursor_t cursor; + enum __pyx_t_7questdb_7ingress_col_line_sender_target_t target; +}; + +/* "questdb/ingress.pyx":682 + * 'TimestampNanos, datetime, None') + * + * cdef int _row( # <<<<<<<<<<<<<< + * self, + * str table_name, + */ +struct __pyx_opt_args_7questdb_7ingress_6Buffer__row { + int __pyx_n; + PyObject *symbols; + PyObject *columns; + PyObject *at; +}; + +/* "questdb/ingress.pyx":1470 + * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) + * + * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< + * """ + * If called with no arguments, immediately flushes the internal buffer. + */ +struct __pyx_opt_args_7questdb_7ingress_6Sender_flush { + int __pyx_n; + struct __pyx_obj_7questdb_7ingress_Buffer *buffer; + int clear; +}; + +/* "questdb/ingress.pyx":1528 + * self._impl = NULL + * + * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< + * """ + * Disconnect. + */ +struct __pyx_opt_args_7questdb_7ingress_6Sender_close { + int __pyx_n; + int flush; +}; + +/* "questdb/ingress.pyx":261 + * + * + * cdef class TimestampMicros: # <<<<<<<<<<<<<< + * """ + * A timestamp in microseconds since the UNIX epoch. + */ +struct __pyx_obj_7questdb_7ingress_TimestampMicros { + PyObject_HEAD + int64_t _value; +}; + + +/* "questdb/ingress.pyx":312 + * + * + * cdef class TimestampNanos: # <<<<<<<<<<<<<< + * """ + * A timestamp in nanoseconds since the UNIX epoch. + */ +struct __pyx_obj_7questdb_7ingress_TimestampNanos { + PyObject_HEAD + int64_t _value; +}; + + +/* "questdb/ingress.pyx":374 + * + * cdef class Sender + * cdef class Buffer # <<<<<<<<<<<<<< + * + * + */ +struct __pyx_obj_7questdb_7ingress_Buffer { + PyObject_HEAD + struct __pyx_vtabstruct_7questdb_7ingress_Buffer *__pyx_vtab; + struct line_sender_buffer *_impl; + struct qdb_pystr_buf *_b; + size_t _init_capacity; + size_t _max_name_len; + PyObject *_row_complete_sender; +}; + + +/* "questdb/ingress.pyx":373 + * + * + * cdef class Sender # <<<<<<<<<<<<<< + * cdef class Buffer + * + */ +struct __pyx_obj_7questdb_7ingress_Sender { + PyObject_HEAD + struct __pyx_vtabstruct_7questdb_7ingress_Sender *__pyx_vtab; + PyObject *__weakref__; + struct line_sender_opts *_opts; + struct line_sender *_impl; + struct __pyx_obj_7questdb_7ingress_Buffer *_buffer; + int _auto_flush_enabled; + Py_ssize_t _auto_flush_watermark; + size_t _init_capacity; + size_t _max_name_len; +}; + + + +/* "questdb/ingress.pyx":1127 + * + * + * cdef class Sender: # <<<<<<<<<<<<<< + * """ + * A sender is a client that inserts rows into QuestDB via the ILP protocol. + */ + +struct __pyx_vtabstruct_7questdb_7ingress_Sender { + PyObject *(*flush)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args); + PyObject *(*_close)(struct __pyx_obj_7questdb_7ingress_Sender *); + PyObject *(*close)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args); +}; +static struct __pyx_vtabstruct_7questdb_7ingress_Sender *__pyx_vtabptr_7questdb_7ingress_Sender; + + +/* "questdb/ingress.pyx":383 + * + * + * cdef class Buffer: # <<<<<<<<<<<<<< + * """ + * Construct QuestDB-flavored InfluxDB Line Protocol (ILP) messages. + */ + +struct __pyx_vtabstruct_7questdb_7ingress_Buffer { + PyObject *(*_cinit_impl)(struct __pyx_obj_7questdb_7ingress_Buffer *, size_t, size_t); + PyObject *(*_to_str)(struct __pyx_obj_7questdb_7ingress_Buffer *); + int (*_set_marker)(struct __pyx_obj_7questdb_7ingress_Buffer *); + int (*_rewind_to_marker)(struct __pyx_obj_7questdb_7ingress_Buffer *); + PyObject *(*_clear_marker)(struct __pyx_obj_7questdb_7ingress_Buffer *); + int (*_table)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); + struct qdb_pystr_buf *(*_cleared_b)(struct __pyx_obj_7questdb_7ingress_Buffer *); + int (*_symbol)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); + int (*_column_bool)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int); + int (*_column_i64)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int64_t); + int (*_column_f64)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, double); + int (*_column_str)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyObject *); + int (*_column_ts)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *); + int (*_column_dt)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyDateTime_DateTime *); + int (*_column)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); + int (*_may_trigger_row_complete)(struct __pyx_obj_7questdb_7ingress_Buffer *); + int (*_at_ts)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_TimestampNanos *); + int (*_at_dt)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyDateTime_DateTime *); + int (*_at_now)(struct __pyx_obj_7questdb_7ingress_Buffer *); + int (*_at)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); + int (*_row)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args); + int (*_pandas)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int); +}; +static struct __pyx_vtabstruct_7questdb_7ingress_Buffer *__pyx_vtabptr_7questdb_7ingress_Buffer; +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__cinit_impl(struct __pyx_obj_7questdb_7ingress_Buffer *, size_t, size_t); +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__to_str(struct __pyx_obj_7questdb_7ingress_Buffer *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__set_marker(struct __pyx_obj_7questdb_7ingress_Buffer *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(struct __pyx_obj_7questdb_7ingress_Buffer *); +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__clear_marker(struct __pyx_obj_7questdb_7ingress_Buffer *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__table(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); +static CYTHON_INLINE struct qdb_pystr_buf *__pyx_f_7questdb_7ingress_6Buffer__cleared_b(struct __pyx_obj_7questdb_7ingress_Buffer *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__symbol(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_bool(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_i64(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int64_t); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_f64(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, double); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_str(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyObject *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_ts(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_dt(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyDateTime_DateTime *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_ts(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_TimestampNanos *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_dt(struct __pyx_obj_7questdb_7ingress_Buffer *, PyDateTime_DateTime *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_now(struct __pyx_obj_7questdb_7ingress_Buffer *); +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* ListCompAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len)) { + Py_INCREF(x); + PyList_SET_ITEM(list, len, x); + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) +#endif + +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); +#else +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#else +#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif +#if CYTHON_FAST_PYCALL + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" +#if PY_VERSION_HEX >= 0x030b00a6 + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif // CYTHON_FAST_PYCALL +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyObjectFormatSimple.proto */ +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#elif PY_MAJOR_VERSION < 3 + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") :\ + PyObject_Format(s, f)) +#elif CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_str(s) :\ + likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_str(s) :\ + PyObject_Format(s, f)) +#else + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#endif + +/* SwapException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* PyUnicode_Unicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj); + +/* GCCDiagnostics.proto */ +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* BuildPyUnicode.proto */ +static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, + int prepend_sign, char padding_char); + +/* IncludeStringH.proto */ +#include + +/* CIntToPyUnicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char); + +/* JoinPyUnicode.proto */ +static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, + Py_UCS4 max_char); + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* ObjectGetItem.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); +#else +#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) +#endif + +/* PyUnicodeContains.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_ContainsTF(PyObject* substring, PyObject* text, int eq) { + int result = PyUnicode_Contains(text, substring); + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* PyObjectFormatAndDecref.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatSimpleAndDecref(PyObject* s, PyObject* f); +static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatAndDecref(PyObject* s, PyObject* f); + +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* ExtTypeTest.proto */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); + +/* PyIntCompare.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); + +/* UnicodeAsUCS4.proto */ +static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject*); + +/* object_ord.proto */ +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyObject_Ord(c)\ + (likely(PyUnicode_Check(c)) ? (long)__Pyx_PyUnicode_AsPy_UCS4(c) : __Pyx__PyObject_Ord(c)) +#else +#define __Pyx_PyObject_Ord(c) __Pyx__PyObject_Ord(c) +#endif +static long __Pyx__PyObject_Ord(PyObject* c); + +/* GetAttr.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); + +/* GetAttr3.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); + +/* PyObjectCallNoArg.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); +#else +#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) +#endif + +/* CIntToPyUnicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_char(char value, Py_ssize_t width, char padding_char, char format_char); + +/* CIntToPyUnicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_size_t(size_t value, Py_ssize_t width, char padding_char, char format_char); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* PyObjectSetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o, n, NULL) +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value); +#else +#define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n) +#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v) +#endif + +/* UnpackUnboundCMethod.proto */ +typedef struct { + PyObject *type; + PyObject **method_name; + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; + +/* CallUnboundCMethod1.proto */ +static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); +#else +#define __Pyx_CallUnboundCMethod1(cfunc, self, arg) __Pyx__CallUnboundCMethod1(cfunc, self, arg) +#endif + +/* PyObjectFormat.proto */ +#if CYTHON_USE_UNICODE_WRITER +static PyObject* __Pyx_PyObject_Format(PyObject* s, PyObject* f); +#else +#define __Pyx_PyObject_Format(s, f) PyObject_Format(s, f) +#endif + +/* WriteUnraisableException.proto */ +static void __Pyx_WriteUnraisable(const char *name, int clineno, + int lineno, const char *filename, + int full_traceback, int nogil); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod0.proto */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* RaiseNoneIterError.proto */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +/* UnpackTupleError.proto */ +static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); + +/* UnpackTuple2.proto */ +#define __Pyx_unpack_tuple2(tuple, value1, value2, is_tuple, has_known_size, decref_tuple)\ + (likely(is_tuple || PyTuple_Check(tuple)) ?\ + (likely(has_known_size || PyTuple_GET_SIZE(tuple) == 2) ?\ + __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple) :\ + (__Pyx_UnpackTupleError(tuple, 2), -1)) :\ + __Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple)) +static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( + PyObject* tuple, PyObject** value1, PyObject** value2, int decref_tuple); +static int __Pyx_unpack_tuple2_generic( + PyObject* tuple, PyObject** value1, PyObject** value2, int has_known_size, int decref_tuple); + +/* dict_iter.proto */ +static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name, + Py_ssize_t* p_orig_length, int* p_is_dict); +static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos, + PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict); + +/* CIntToPyUnicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* PyObject_GenericGetAttr.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* SetupReduce.proto */ +static int __Pyx_setup_reduce(PyObject* type_obj); + +/* SetVTable.proto */ +static int __Pyx_SetVtable(PyObject *dict, void *vtable); + +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto +#define __PYX_HAVE_RT_ImportType_proto +enum __Pyx_ImportType_CheckSize { + __Pyx_ImportType_CheckSize_Error = 0, + __Pyx_ImportType_CheckSize_Warn = 1, + __Pyx_ImportType_CheckSize_Ignore = 2 +}; +static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +#endif + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* CalculateMetaclass.proto */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases); + +/* SetNameInClass.proto */ +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? _PyDict_SetItem_KnownHash(ns, name, value, ((PyASCIIObject *) name)->hash) : PyObject_SetItem(ns, name, value)) +#elif CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_SetNameInClass(ns, name, value)\ + (likely(PyDict_CheckExact(ns)) ? PyDict_SetItem(ns, name, value) : PyObject_SetItem(ns, name, value)) +#else +#define __Pyx_SetNameInClass(ns, name, value) PyObject_SetItem(ns, name, value) +#endif + +/* FetchCommonType.proto */ +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); + +/* CythonFunctionShared.proto */ +#define __Pyx_CyFunction_USED 1 +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { + PyCFunctionObject func; +#if PY_VERSION_HEX < 0x030500A0 + PyObject *func_weakreflist; +#endif + PyObject *func_dict; + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; + PyObject *func_classobj; + void *defaults; + int defaults_pyobjects; + size_t defaults_size; // used by FusedFunction for copying defaults + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; +} __pyx_CyFunctionObject; +static PyTypeObject *__pyx_CyFunctionType = 0; +#define __Pyx_CyFunction_Check(obj) (__Pyx_TypeCheck(obj, __pyx_CyFunctionType)) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *self, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, + size_t size, + int pyobjects); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(void); + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* Py3ClassCreate.proto */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, + PyObject *mkw, PyObject *modname, PyObject *doc); +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, + PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); + +/* CyFunctionClassCell.proto */ +static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj); + +/* ClassMethod.proto */ +#include "descrobject.h" +static CYTHON_UNUSED PyObject* __Pyx_Method_ClassMethod(PyObject *method); + +/* GetNameInClass.proto */ +#define __Pyx_GetNameInClass(var, nmspace, name) (var) = __Pyx__GetNameInClass(nmspace, name) +static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__line_sender_error_code(enum line_sender_error_code value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE uint64_t __Pyx_PyInt_As_uint64_t(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int64_t __Pyx_PyInt_As_int64_t(PyObject *); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint64_t(uint64_t value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__cinit_impl(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, size_t __pyx_v_init_capacity, size_t __pyx_v_max_name_len); /* proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__to_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__set_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__clear_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__table(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name); /* proto*/ +static CYTHON_INLINE struct qdb_pystr_buf *__pyx_f_7questdb_7ingress_6Buffer__cleared_b(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__symbol(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_bool(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int __pyx_v_value); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_i64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int64_t __pyx_v_value); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_f64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, double __pyx_v_value); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyObject *__pyx_v_value); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_ts); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyDateTime_DateTime *__pyx_v_dt); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_ts); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyDateTime_DateTime *__pyx_v_dt); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_now(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_ts); /* proto*/ +static int __pyx_f_7questdb_7ingress_6Buffer__row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args); /* proto*/ +static int __pyx_f_7questdb_7ingress_6Buffer__pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, CYTHON_UNUSED int __pyx_v_sort); /* proto*/ +static PyObject *__pyx_f_7questdb_7ingress_6Sender_flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args); /* proto*/ +static PyObject *__pyx_f_7questdb_7ingress_6Sender__close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7questdb_7ingress_6Sender_close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args); /* proto*/ + +/* Module declarations from 'libc.stdint' */ + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdlib' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'datetime' */ + +/* Module declarations from 'cpython.datetime' */ +static PyTypeObject *__pyx_ptype_7cpython_8datetime_date = 0; +static PyTypeObject *__pyx_ptype_7cpython_8datetime_time = 0; +static PyTypeObject *__pyx_ptype_7cpython_8datetime_datetime = 0; +static PyTypeObject *__pyx_ptype_7cpython_8datetime_timedelta = 0; +static PyTypeObject *__pyx_ptype_7cpython_8datetime_tzinfo = 0; + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.bool' */ +static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; + +/* Module declarations from 'cpython.weakref' */ + +/* Module declarations from 'cpython.float' */ + +/* Module declarations from 'cpython.int' */ + +/* Module declarations from 'cpython.unicode' */ + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'cpython.memoryview' */ + +/* Module declarations from 'questdb.line_sender' */ + +/* Module declarations from 'questdb.pystr_to_utf8' */ + +/* Module declarations from 'questdb.arrow_c_data_interface' */ + +/* Module declarations from 'questdb.extra_cpython' */ + +/* Module declarations from 'cython' */ + +/* Module declarations from 'questdb.ingress' */ +static PyTypeObject *__pyx_ptype_7questdb_7ingress_TimestampMicros = 0; +static PyTypeObject *__pyx_ptype_7questdb_7ingress_TimestampNanos = 0; +static PyTypeObject *__pyx_ptype_7questdb_7ingress_Sender = 0; +static PyTypeObject *__pyx_ptype_7questdb_7ingress_Buffer = 0; +static PyObject *__pyx_v_7questdb_7ingress__PANDAS_NA = 0; +static char __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_OBJECT; +static char __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_DATETIME; +static __pyx_t_7questdb_7ingress_size_t_vec __pyx_f_7questdb_7ingress_size_t_vec_new(void); /*proto*/ +static void __pyx_f_7questdb_7ingress_size_t_vec_free(__pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress_size_t_vec_str(__pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ +static void __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_t_7questdb_7ingress_size_t_vec *, size_t); /*proto*/ +static __pyx_t_7questdb_7ingress_column_name_vec __pyx_f_7questdb_7ingress_column_name_vec_new(void); /*proto*/ +static void __pyx_f_7questdb_7ingress_column_name_vec_free(__pyx_t_7questdb_7ingress_column_name_vec *); /*proto*/ +static void __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_t_7questdb_7ingress_column_name_vec *, struct line_sender_column_name); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress__pandas_may_set_na_type(void); /*proto*/ +static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_table_name(struct qdb_pystr_buf *, PyObject *, PyObject *, PyObject *, size_t, struct line_sender_table_name *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_resolve_fields(int, __pyx_t_7questdb_7ingress_size_t_vec const *, int, size_t, __pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_resolve_col_names(struct qdb_pystr_buf *, PyObject *, __pyx_t_7questdb_7ingress_size_t_vec const *, __pyx_t_7questdb_7ingress_size_t_vec const *, __pyx_t_7questdb_7ingress_column_name_vec *, __pyx_t_7questdb_7ingress_column_name_vec *); /*proto*/ +static int __pyx_f_7questdb_7ingress__bind_col_index(PyObject *, int, size_t, size_t *); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress__pandas_column_is_str(PyObject *, int); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress__pandas_check_column_is_str(PyObject *, size_t, PyObject *, PyObject *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_resolve_symbols(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *, size_t, __pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_get_loc(PyObject *, PyObject *, PyObject *, size_t *); /*proto*/ +static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_at(PyObject *, PyObject *, size_t, int64_t *); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress__pandas_is_supported_datetime(PyObject *); /*proto*/ +static char __pyx_f_7questdb_7ingress__str_to_char(PyObject *, PyObject *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_parse_dtype(PyObject *, struct __pyx_t_7questdb_7ingress_dtype_t *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_resolve_dtypes(PyObject *, size_t, struct __pyx_t_7questdb_7ingress_dtype_t *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_resolve_col_buffers(PyObject *, size_t, struct __pyx_t_7questdb_7ingress_dtype_t const *, Py_buffer *, size_t *); /*proto*/ +static CYTHON_INLINE void const *__pyx_f_7questdb_7ingress__pandas_get_cell(Py_buffer *, size_t); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_get_str_cell(struct qdb_pystr_buf *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t, int *, struct line_sender_utf8 *); /*proto*/ +static int64_t __pyx_f_7questdb_7ingress__pandas_get_timestamp_cell(struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_row_table_name(struct line_sender_buffer *, struct qdb_pystr_buf *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, Py_ssize_t, size_t, struct line_sender_table_name); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_row_symbols(struct line_sender_buffer *, struct qdb_pystr_buf *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t, __pyx_t_7questdb_7ingress_column_name_vec const *, __pyx_t_7questdb_7ingress_size_t_vec const *); /*proto*/ +static int __pyx_f_7questdb_7ingress__pandas_row_at(struct line_sender_buffer *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t, Py_ssize_t, int64_t); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_code_to_py(enum line_sender_error_code); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_code_and_msg(struct line_sender_error *); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py(struct line_sender_error *); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py_fmt(struct line_sender_error *, PyObject *); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress__utf8_decode_error(PyObject *, uint32_t); /*proto*/ +static int __pyx_f_7questdb_7ingress_str_to_utf8(struct qdb_pystr_buf *, PyObject *, struct line_sender_utf8 *); /*proto*/ +static int __pyx_f_7questdb_7ingress_str_to_table_name(struct qdb_pystr_buf *, PyObject *, struct line_sender_table_name *); /*proto*/ +static int __pyx_f_7questdb_7ingress_str_to_column_name(struct qdb_pystr_buf *, PyObject *, struct line_sender_column_name *); /*proto*/ +static int64_t __pyx_f_7questdb_7ingress_datetime_to_micros(PyDateTime_DateTime *); /*proto*/ +static int64_t __pyx_f_7questdb_7ingress_datetime_to_nanos(PyDateTime_DateTime *); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress__check_is_pandas_dataframe(PyObject *); /*proto*/ +static int __pyx_f_7questdb_7ingress_may_flush_on_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_Sender *); /*proto*/ +#define __Pyx_MODULE_NAME "questdb.ingress" +extern int __pyx_module_is_main_questdb__ingress; +int __pyx_module_is_main_questdb__ingress = 0; + +/* Implementation of 'questdb.ingress' */ +static PyObject *__pyx_builtin_property; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_ValueError; +static PyObject *__pyx_builtin_TypeError; +static PyObject *__pyx_builtin_IndexError; +static PyObject *__pyx_builtin_KeyError; +static PyObject *__pyx_builtin_super; +static const char __pyx_k_M[] = "M"; +static const char __pyx_k_O[] = "O"; +static const char __pyx_k_S[] = "S"; +static const char __pyx_k_x[] = "x"; +static const char __pyx_k_NA[] = "NA"; +static const char __pyx_k_SO[] = "SO"; +static const char __pyx_k__5[] = "`: "; +static const char __pyx_k__6[] = "."; +static const char __pyx_k__9[] = "("; +static const char __pyx_k_at[] = "at"; +static const char __pyx_k_dt[] = "dt"; +static const char __pyx_k_Any[] = "Any"; +static const char __pyx_k__10[] = ". "; +static const char __pyx_k__11[] = "` "; +static const char __pyx_k__12[] = "="; +static const char __pyx_k__14[] = " ("; +static const char __pyx_k__15[] = ")"; +static const char __pyx_k__17[] = ": "; +static const char __pyx_k__24[] = ", "; +static const char __pyx_k__27[] = "\n"; +static const char __pyx_k_cls[] = "cls"; +static const char __pyx_k_doc[] = "__doc__"; +static const char __pyx_k_err[] = "err"; +static const char __pyx_k_got[] = "got "; +static const char __pyx_k_int[] = "int"; +static const char __pyx_k_msg[] = "msg"; +static const char __pyx_k_not[] = "not "; +static const char __pyx_k_row[] = "row"; +static const char __pyx_k_str[] = "str"; +static const char __pyx_k_sys[] = "sys"; +static const char __pyx_k_tls[] = "tls"; +static const char __pyx_k_Dict[] = "Dict"; +static const char __pyx_k_Enum[] = "Enum"; +static const char __pyx_k_List[] = "List"; +static const char __pyx_k_None[] = "None"; +static const char __pyx_k_Path[] = "Path"; +static const char __pyx_k_at_2[] = "at: "; +static const char __pyx_k_auth[] = "auth"; +static const char __pyx_k_bool[] = "bool"; +static const char __pyx_k_code[] = "code"; +static const char __pyx_k_data[] = "data"; +static const char __pyx_k_enum[] = "enum"; +static const char __pyx_k_exit[] = "__exit__"; +static const char __pyx_k_host[] = "host"; +static const char __pyx_k_iloc[] = "iloc"; +static const char __pyx_k_init[] = "__init__"; +static const char __pyx_k_kind[] = "kind"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "name"; +static const char __pyx_k_port[] = "port"; +static const char __pyx_k_self[] = "self"; +static const char __pyx_k_sort[] = "sort"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_Tuple[] = "Tuple"; +static const char __pyx_k_Union[] = "Union"; +static const char __pyx_k_clear[] = "clear"; +static const char __pyx_k_close[] = "close"; +static const char __pyx_k_dtype[] = "dtype."; +static const char __pyx_k_enter[] = "__enter__"; +static const char __pyx_k_float[] = "float"; +static const char __pyx_k_flush[] = "flush"; +static const char __pyx_k_index[] = "index"; +static const char __pyx_k_items[] = "items"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_str_2[] = "__str__"; +static const char __pyx_k_super[] = "super"; +static const char __pyx_k_value[] = "_value"; +static const char __pyx_k_write[] = "write"; +static const char __pyx_k_Buffer[] = "Buffer"; +static const char __pyx_k_Column[] = "Column "; +static const char __pyx_k_Sender[] = "Sender"; +static const char __pyx_k_at_col[] = "at_col: "; +static const char __pyx_k_buffer[] = "buffer"; +static const char __pyx_k_code_2[] = "_code"; +static const char __pyx_k_dtypes[] = "dtypes"; +static const char __pyx_k_exc_tb[] = "_exc_tb"; +static const char __pyx_k_format[] = "format"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_module[] = "__module__"; +static const char __pyx_k_name_2[] = "__name__"; +static const char __pyx_k_pandas[] = "pandas"; +static const char __pyx_k_reduce[] = "__reduce__"; +static const char __pyx_k_return[] = "return"; +static const char __pyx_k_sort_2[] = "sort: "; +static const char __pyx_k_stderr[] = "stderr"; +static const char __pyx_k_symbol[] = "symbol"; +static const char __pyx_k_typing[] = "typing"; +static const char __pyx_k_columns[] = "columns"; +static const char __pyx_k_connect[] = "connect"; +static const char __pyx_k_exc_val[] = "_exc_val"; +static const char __pyx_k_for_the[] = "` for the "; +static const char __pyx_k_get_loc[] = "get_loc"; +static const char __pyx_k_pathlib[] = "pathlib"; +static const char __pyx_k_prepare[] = "__prepare__"; +static const char __pyx_k_reserve[] = "reserve"; +static const char __pyx_k_symbols[] = "symbols"; +static const char __pyx_k_unicode[] = "unicode"; +static const char __pyx_k_value_2[] = "value"; +static const char __pyx_k_Callable[] = "Callable"; +static const char __pyx_k_Iterable[] = "Iterable"; +static const char __pyx_k_KeyError[] = "KeyError"; +static const char __pyx_k_Optional[] = "Optional"; +static const char __pyx_k_TlsError[] = "TlsError"; +static const char __pyx_k_at_value[] = "at_value: "; +static const char __pyx_k_capacity[] = "capacity"; +static const char __pyx_k_datetime[] = "datetime"; +static const char __pyx_k_exc_type[] = "exc_type"; +static const char __pyx_k_getstate[] = "__getstate__"; +static const char __pyx_k_itemsize[] = "itemsize"; +static const char __pyx_k_name_col[] = "name_col: "; +static const char __pyx_k_pandas_A[] = "_pandas :: (A) "; +static const char __pyx_k_pandas_B[] = "pandas :: (B) "; +static const char __pyx_k_property[] = "property"; +static const char __pyx_k_qualname[] = "__qualname__"; +static const char __pyx_k_setstate[] = "__setstate__"; +static const char __pyx_k_to_numpy[] = "to_numpy"; +static const char __pyx_k_AuthError[] = "AuthError"; +static const char __pyx_k_Bad_dtype[] = "Bad dtype `"; +static const char __pyx_k_DataFrame[] = "DataFrame"; +static const char __pyx_k_FLUSH_FMT[] = "_FLUSH_FMT"; +static const char __pyx_k_TypeError[] = "TypeError"; +static const char __pyx_k_alignment[] = "alignment"; +static const char __pyx_k_byteorder[] = "byteorder"; +static const char __pyx_k_for_the_2[] = "for the "; +static const char __pyx_k_hasobject[] = "hasobject"; +static const char __pyx_k_in_column[] = "in column "; +static const char __pyx_k_in_string[] = " in string "; +static const char __pyx_k_interface[] = "interface"; +static const char __pyx_k_metaclass[] = "__metaclass__"; +static const char __pyx_k_pyx_state[] = "__pyx_state"; +static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; +static const char __pyx_k_symbols_2[] = "symbols: "; +static const char __pyx_k_timestamp[] = "timestamp"; +static const char __pyx_k_Buffer_row[] = "Buffer.row"; +static const char __pyx_k_IndexError[] = "IndexError"; +static const char __pyx_k_Sender_row[] = "Sender.row"; +static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_additional[] = "additional"; +static const char __pyx_k_auto_flush[] = "auto_flush"; +static const char __pyx_k_new_buffer[] = "new_buffer"; +static const char __pyx_k_pandas_A_2[] = "pandas :: (A) "; +static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; +static const char __pyx_k_size_t_vec[] = "size_t_vec"; +static const char __pyx_k_table_name[] = "table_name"; +static const char __pyx_k_InvalidName[] = "InvalidName"; +static const char __pyx_k_InvalidUtf8[] = "InvalidUtf8"; +static const char __pyx_k_SocketError[] = "SocketError"; +static const char __pyx_k_microsecond[] = "microsecond"; +static const char __pyx_k_Bad_argument[] = "Bad argument `"; +static const char __pyx_k_Buffer_clear[] = "Buffer.clear"; +static const char __pyx_k_IngressError[] = "IngressError"; +static const char __pyx_k_Sender_close[] = "Sender.close"; +static const char __pyx_k_Sender_flush[] = "Sender.flush"; +static const char __pyx_k_max_name_len[] = "max_name_len"; +static const char __pyx_k_read_timeout[] = "read_timeout"; +static const char __pyx_k_stringsource[] = "stringsource"; +static const char __pyx_k_table_name_2[] = "table_name: "; +static const char __pyx_k_Buffer_pandas[] = "Buffer.pandas"; +static const char __pyx_k_Sender___exit[] = "Sender.__exit__"; +static const char __pyx_k_field_indices[] = "field_indices: "; +static const char __pyx_k_from_datetime[] = "from_datetime"; +static const char __pyx_k_init_capacity[] = "init_capacity"; +static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; +static const char __pyx_k_Buffer_reserve[] = "Buffer.reserve"; +static const char __pyx_k_InvalidApiCall[] = "InvalidApiCall"; +static const char __pyx_k_Must_be_one_of[] = ". Must be one of: "; +static const char __pyx_k_Sender___enter[] = "Sender.__enter__"; +static const char __pyx_k_Sender_connect[] = "Sender.connect"; +static const char __pyx_k_TimestampNanos[] = "TimestampNanos"; +static const char __pyx_k_symbol_indices[] = "symbol_indices: "; +static const char __pyx_k_table_name_col[] = "table_name_col"; +static const char __pyx_k_Buffer_capacity[] = "Buffer.capacity"; +static const char __pyx_k_TimestampMicros[] = "TimestampMicros"; +static const char __pyx_k_questdb_ingress[] = "questdb.ingress"; +static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; +static const char __pyx_k_IngressErrorCode[] = "IngressErrorCode"; +static const char __pyx_k_InvalidTimestamp[] = "InvalidTimestamp"; +static const char __pyx_k_Unknown_UCS_kind[] = "Unknown UCS kind: "; +static const char __pyx_k_Unsupported_type[] = "Unsupported type: "; +static const char __pyx_k_table_name_col_2[] = "table_name_col: "; +static const char __pyx_k_Category_of_Error[] = "Category of Error."; +static const char __pyx_k_IngressError_code[] = "IngressError.code"; +static const char __pyx_k_Sender_new_buffer[] = "Sender.new_buffer"; +static const char __pyx_k_datetime_datetime[] = "datetime.datetime"; +static const char __pyx_k_pandas_core_frame[] = "pandas.core.frame"; +static const char __pyx_k_as_a_symbol_column[] = ") as a symbol column."; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_index_out_of_range[] = " index out of range"; +static const char __pyx_k_CouldNotResolveAddr[] = "CouldNotResolveAddr"; +static const char __pyx_k_IngressError___init[] = "IngressError.__init__"; +static const char __pyx_k_Invalid_codepoint_0x[] = "Invalid codepoint 0x"; +static const char __pyx_k_insecure_skip_verify[] = "insecure_skip_verify"; +static const char __pyx_k_Buffer___reduce_cython[] = "Buffer.__reduce_cython__"; +static const char __pyx_k_Found_non_string_value[] = "Found non-string value "; +static const char __pyx_k_IngressErrorCode___str[] = "IngressErrorCode.__str__"; +static const char __pyx_k_Sender___reduce_cython[] = "Sender.__reduce_cython__"; +static const char __pyx_k_Bad_argument_table_name[] = "Bad argument `table_name`: "; +static const char __pyx_k_src_questdb_ingress_pyx[] = "src/questdb/ingress.pyx"; +static const char __pyx_k_Buffer___setstate_cython[] = "Buffer.__setstate_cython__"; +static const char __pyx_k_NOT_YET_IMPLEMENTED_Kind[] = "NOT YET IMPLEMENTED. Kind: "; +static const char __pyx_k_Sender___setstate_cython[] = "Sender.__setstate_cython__"; +static const char __pyx_k_Bad_argument_at_Bad_dtype[] = "Bad argument `at`: Bad dtype `"; +static const char __pyx_k_Bad_argument_data_Expected[] = "Bad argument `data`: Expected "; +static const char __pyx_k_Cannot_be_encoded_as_UTF_8[] = "Cannot be encoded as UTF-8."; +static const char __pyx_k_not_found_in_the_dataframe[] = " not found in the dataframe."; +static const char __pyx_k_Bad_argument_table_name_col[] = "Bad argument `table_name_col`: "; +static const char __pyx_k_value_must_positive_integer[] = "value must positive integer."; +static const char __pyx_k_Bad_column_Expected_a_string[] = "Bad column: Expected a string, "; +static const char __pyx_k_TimestampNanos_datetime_None[] = "TimestampNanos, datetime, None"; +static const char __pyx_k_TimestampNanos_from_datetime[] = "TimestampNanos.from_datetime"; +static const char __pyx_k_dt_must_be_a_datetime_object[] = "dt must be a datetime object."; +static const char __pyx_k_TimestampMicros_from_datetime[] = "TimestampMicros.from_datetime"; +static const char __pyx_k_TimestampNanos___reduce_cython[] = "TimestampNanos.__reduce_cython__"; +static const char __pyx_k_column_Must_be_a_datetime64_ns[] = " column: Must be a datetime64[ns] column."; +static const char __pyx_k_API_for_fast_data_ingestion_int[] = "\nAPI for fast data ingestion into QuestDB.\n"; +static const char __pyx_k_Bad_argument_symbols_Cannot_use[] = "Bad argument `symbols`: Cannot use the same column "; +static const char __pyx_k_Bad_argument_table_name_Must_be[] = "Bad argument `table_name`: Must be str."; +static const char __pyx_k_Bad_element_in_argument_symbols[] = "Bad element in argument `symbols`: "; +static const char __pyx_k_Bad_value_None_table_name_value[] = "Bad value: `None` table name value at row "; +static const char __pyx_k_Character_out_of_ASCII_range_go[] = ": Character out of ASCII range, got "; +static const char __pyx_k_Expected_a_single_character_got[] = ": Expected a single character, got "; +static const char __pyx_k_Internal_error_converting_error[] = "Internal error converting error code."; +static const char __pyx_k_See_https_py_questdb_client_rea[] = "{} - See https://py-questdb-client.readthedocs.io/en/v1.0.2/troubleshooting.html#inspecting-and-debugging-errors#flush-failed"; +static const char __pyx_k_The_internal_buffer_must_always[] = "The internal buffer must always be cleared."; +static const char __pyx_k_TimestampMicros___reduce_cython[] = "TimestampMicros.__reduce_cython__"; +static const char __pyx_k_additional_must_be_non_negative[] = "additional must be non-negative."; +static const char __pyx_k_as_both_the_table_name_and_as_a[] = " as both the table_name and as a symbol."; +static const char __pyx_k_column_Must_be_a_strings_column[] = " column: Must be a strings column."; +static const char __pyx_k_int_column_index_str_colum_name[] = "int (column index), str (colum name)"; +static const char __pyx_k_An_error_whilst_using_the_Sender[] = "An error whilst using the ``Sender`` or constructing its ``Buffer``."; +static const char __pyx_k_Bad_argument_at_Unsupported_type[] = "Bad argument `at`: Unsupported type "; +static const char __pyx_k_Bad_argument_symbols_Elements_mu[] = "Bad argument `symbols`: Elements must be a column name (str) or index (int)."; +static const char __pyx_k_Bad_argument_symbols_Must_be_a_b[] = "Bad argument `symbols`: Must be a bool or a tuple or list of column names (str) or indices (int)."; +static const char __pyx_k_Bad_argument_table_name_col_must[] = "Bad argument `table_name_col`: must be a column name (str) or index (int)."; +static const char __pyx_k_Bad_column_Expected_a_numpy_arra[] = "Bad column: Expected a numpy array, got "; +static const char __pyx_k_Bad_value_Negative_timestamp_got[] = "Bad value: Negative timestamp, got "; +static const char __pyx_k_Can_specify_only_one_of_table_na[] = "Can specify only one of `table_name` or `table_name_col`."; +static const char __pyx_k_Must_be_one_of_None_TimestampNan[] = "Must be one of: None, TimestampNanos, datetime, "; +static const char __pyx_k_Must_specify_at_least_one_of_tab[] = "Must specify at least one of `table_name` or `table_name_col`."; +static const char __pyx_k_TimestampMicros___setstate_cytho[] = "TimestampMicros.__setstate_cython__"; +static const char __pyx_k_TimestampNanos___setstate_cython[] = "TimestampNanos.__setstate_cython__"; +static const char __pyx_k_auto_flush_watermark_must_be_0_n[] = "auto_flush_watermark must be >= 0, not "; +static const char __pyx_k_connect_can_t_be_called_after_cl[] = "connect() can't be called after close()."; +static const char __pyx_k_flush_can_t_be_called_Not_connec[] = "flush() can't be called: Not connected."; +static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; +static const char __pyx_k_port_must_be_an_integer_or_a_str[] = "port must be an integer or a string, not "; +static const char __pyx_k_tls_must_be_a_bool_a_path_or_str[] = "tls must be a bool, a path or string pointing to CA file or \"insecure_skip_verify\", not "; +static const char __pyx_k_Bad_argument_symbols_Cannot_use_2[] = "Bad argument `symbols`: Cannot use the `at` column "; +static PyObject *__pyx_kp_s_An_error_whilst_using_the_Sender; +static PyObject *__pyx_n_s_Any; +static PyObject *__pyx_n_s_AuthError; +static PyObject *__pyx_kp_u_Bad_argument; +static PyObject *__pyx_kp_u_Bad_argument_at_Bad_dtype; +static PyObject *__pyx_kp_u_Bad_argument_at_Unsupported_type; +static PyObject *__pyx_kp_u_Bad_argument_data_Expected; +static PyObject *__pyx_kp_u_Bad_argument_symbols_Cannot_use; +static PyObject *__pyx_kp_u_Bad_argument_symbols_Cannot_use_2; +static PyObject *__pyx_kp_u_Bad_argument_symbols_Elements_mu; +static PyObject *__pyx_kp_u_Bad_argument_symbols_Must_be_a_b; +static PyObject *__pyx_kp_u_Bad_argument_table_name; +static PyObject *__pyx_kp_u_Bad_argument_table_name_Must_be; +static PyObject *__pyx_kp_u_Bad_argument_table_name_col; +static PyObject *__pyx_kp_u_Bad_argument_table_name_col_must; +static PyObject *__pyx_kp_u_Bad_column_Expected_a_numpy_arra; +static PyObject *__pyx_kp_u_Bad_column_Expected_a_string; +static PyObject *__pyx_kp_u_Bad_dtype; +static PyObject *__pyx_kp_u_Bad_element_in_argument_symbols; +static PyObject *__pyx_kp_u_Bad_value_Negative_timestamp_got; +static PyObject *__pyx_kp_u_Bad_value_None_table_name_value; +static PyObject *__pyx_n_s_Buffer; +static PyObject *__pyx_n_s_Buffer___reduce_cython; +static PyObject *__pyx_n_s_Buffer___setstate_cython; +static PyObject *__pyx_n_s_Buffer_capacity; +static PyObject *__pyx_n_s_Buffer_clear; +static PyObject *__pyx_n_s_Buffer_pandas; +static PyObject *__pyx_n_s_Buffer_reserve; +static PyObject *__pyx_n_s_Buffer_row; +static PyObject *__pyx_n_s_Callable; +static PyObject *__pyx_kp_u_Can_specify_only_one_of_table_na; +static PyObject *__pyx_kp_u_Cannot_be_encoded_as_UTF_8; +static PyObject *__pyx_kp_s_Category_of_Error; +static PyObject *__pyx_kp_u_Character_out_of_ASCII_range_go; +static PyObject *__pyx_kp_u_Column; +static PyObject *__pyx_n_s_CouldNotResolveAddr; +static PyObject *__pyx_n_u_DataFrame; +static PyObject *__pyx_n_s_Dict; +static PyObject *__pyx_n_s_Enum; +static PyObject *__pyx_kp_u_Expected_a_single_character_got; +static PyObject *__pyx_n_s_FLUSH_FMT; +static PyObject *__pyx_kp_u_Found_non_string_value; +static PyObject *__pyx_n_s_IndexError; +static PyObject *__pyx_n_s_IngressError; +static PyObject *__pyx_n_s_IngressErrorCode; +static PyObject *__pyx_n_s_IngressErrorCode___str; +static PyObject *__pyx_n_s_IngressError___init; +static PyObject *__pyx_n_s_IngressError_code; +static PyObject *__pyx_kp_u_Internal_error_converting_error; +static PyObject *__pyx_n_s_InvalidApiCall; +static PyObject *__pyx_n_s_InvalidName; +static PyObject *__pyx_n_s_InvalidTimestamp; +static PyObject *__pyx_n_s_InvalidUtf8; +static PyObject *__pyx_kp_u_Invalid_codepoint_0x; +static PyObject *__pyx_n_s_Iterable; +static PyObject *__pyx_n_s_KeyError; +static PyObject *__pyx_n_s_List; +static PyObject *__pyx_n_u_M; +static PyObject *__pyx_kp_u_Must_be_one_of; +static PyObject *__pyx_kp_u_Must_be_one_of_None_TimestampNan; +static PyObject *__pyx_kp_u_Must_specify_at_least_one_of_tab; +static PyObject *__pyx_n_s_NA; +static PyObject *__pyx_kp_u_NOT_YET_IMPLEMENTED_Kind; +static PyObject *__pyx_kp_u_None; +static PyObject *__pyx_n_u_O; +static PyObject *__pyx_n_s_Optional; +static PyObject *__pyx_n_s_Path; +static PyObject *__pyx_n_u_S; +static PyObject *__pyx_n_u_SO; +static PyObject *__pyx_kp_u_See_https_py_questdb_client_rea; +static PyObject *__pyx_n_s_Sender; +static PyObject *__pyx_n_u_Sender; +static PyObject *__pyx_n_s_Sender___enter; +static PyObject *__pyx_n_s_Sender___exit; +static PyObject *__pyx_n_s_Sender___reduce_cython; +static PyObject *__pyx_n_s_Sender___setstate_cython; +static PyObject *__pyx_n_s_Sender_close; +static PyObject *__pyx_n_s_Sender_connect; +static PyObject *__pyx_n_s_Sender_flush; +static PyObject *__pyx_n_s_Sender_new_buffer; +static PyObject *__pyx_n_s_Sender_row; +static PyObject *__pyx_n_s_SocketError; +static PyObject *__pyx_kp_u_The_internal_buffer_must_always; +static PyObject *__pyx_n_s_TimestampMicros; +static PyObject *__pyx_n_u_TimestampMicros; +static PyObject *__pyx_n_s_TimestampMicros___reduce_cython; +static PyObject *__pyx_n_s_TimestampMicros___setstate_cytho; +static PyObject *__pyx_n_s_TimestampMicros_from_datetime; +static PyObject *__pyx_n_s_TimestampNanos; +static PyObject *__pyx_n_s_TimestampNanos___reduce_cython; +static PyObject *__pyx_n_s_TimestampNanos___setstate_cython; +static PyObject *__pyx_kp_u_TimestampNanos_datetime_None; +static PyObject *__pyx_n_s_TimestampNanos_from_datetime; +static PyObject *__pyx_n_s_TlsError; +static PyObject *__pyx_n_s_Tuple; +static PyObject *__pyx_n_s_TypeError; +static PyObject *__pyx_n_s_Union; +static PyObject *__pyx_kp_u_Unknown_UCS_kind; +static PyObject *__pyx_kp_u_Unsupported_type; +static PyObject *__pyx_n_s_ValueError; +static PyObject *__pyx_kp_u__10; +static PyObject *__pyx_kp_u__11; +static PyObject *__pyx_kp_u__12; +static PyObject *__pyx_kp_u__14; +static PyObject *__pyx_kp_u__15; +static PyObject *__pyx_kp_u__17; +static PyObject *__pyx_kp_u__24; +static PyObject *__pyx_kp_u__27; +static PyObject *__pyx_kp_u__5; +static PyObject *__pyx_kp_u__6; +static PyObject *__pyx_kp_u__9; +static PyObject *__pyx_n_s_additional; +static PyObject *__pyx_kp_u_additional_must_be_non_negative; +static PyObject *__pyx_n_s_alignment; +static PyObject *__pyx_n_u_alignment; +static PyObject *__pyx_kp_u_as_a_symbol_column; +static PyObject *__pyx_kp_u_as_both_the_table_name_and_as_a; +static PyObject *__pyx_n_s_at; +static PyObject *__pyx_n_u_at; +static PyObject *__pyx_kp_u_at_2; +static PyObject *__pyx_kp_u_at_col; +static PyObject *__pyx_kp_u_at_value; +static PyObject *__pyx_n_s_auth; +static PyObject *__pyx_n_s_auto_flush; +static PyObject *__pyx_kp_u_auto_flush_watermark_must_be_0_n; +static PyObject *__pyx_n_u_bool; +static PyObject *__pyx_n_s_buffer; +static PyObject *__pyx_n_s_byteorder; +static PyObject *__pyx_n_u_byteorder; +static PyObject *__pyx_n_s_capacity; +static PyObject *__pyx_n_s_clear; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_close; +static PyObject *__pyx_n_s_cls; +static PyObject *__pyx_n_s_code; +static PyObject *__pyx_n_s_code_2; +static PyObject *__pyx_kp_u_column_Must_be_a_datetime64_ns; +static PyObject *__pyx_kp_u_column_Must_be_a_strings_column; +static PyObject *__pyx_n_s_columns; +static PyObject *__pyx_n_s_connect; +static PyObject *__pyx_kp_u_connect_can_t_be_called_after_cl; +static PyObject *__pyx_n_s_data; +static PyObject *__pyx_n_u_datetime; +static PyObject *__pyx_kp_u_datetime_datetime; +static PyObject *__pyx_n_s_doc; +static PyObject *__pyx_n_s_dt; +static PyObject *__pyx_kp_u_dt_must_be_a_datetime_object; +static PyObject *__pyx_kp_u_dtype; +static PyObject *__pyx_n_s_dtypes; +static PyObject *__pyx_n_s_enter; +static PyObject *__pyx_n_s_enum; +static PyObject *__pyx_n_s_err; +static PyObject *__pyx_n_s_exc_tb; +static PyObject *__pyx_n_s_exc_type; +static PyObject *__pyx_n_s_exc_val; +static PyObject *__pyx_n_s_exit; +static PyObject *__pyx_kp_u_field_indices; +static PyObject *__pyx_n_u_float; +static PyObject *__pyx_n_s_flush; +static PyObject *__pyx_kp_u_flush_can_t_be_called_Not_connec; +static PyObject *__pyx_kp_u_for_the; +static PyObject *__pyx_kp_u_for_the_2; +static PyObject *__pyx_n_s_format; +static PyObject *__pyx_n_s_from_datetime; +static PyObject *__pyx_n_s_get_loc; +static PyObject *__pyx_n_s_getstate; +static PyObject *__pyx_kp_u_got; +static PyObject *__pyx_n_s_hasobject; +static PyObject *__pyx_n_u_hasobject; +static PyObject *__pyx_n_s_host; +static PyObject *__pyx_n_s_iloc; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_kp_u_in_column; +static PyObject *__pyx_kp_u_in_string; +static PyObject *__pyx_n_s_index; +static PyObject *__pyx_kp_u_index_out_of_range; +static PyObject *__pyx_n_s_init; +static PyObject *__pyx_n_s_init_capacity; +static PyObject *__pyx_n_u_insecure_skip_verify; +static PyObject *__pyx_n_u_int; +static PyObject *__pyx_kp_u_int_column_index_str_colum_name; +static PyObject *__pyx_n_s_interface; +static PyObject *__pyx_n_s_items; +static PyObject *__pyx_n_s_itemsize; +static PyObject *__pyx_n_u_itemsize; +static PyObject *__pyx_n_s_kind; +static PyObject *__pyx_n_u_kind; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_max_name_len; +static PyObject *__pyx_n_s_metaclass; +static PyObject *__pyx_n_s_microsecond; +static PyObject *__pyx_n_s_module; +static PyObject *__pyx_n_s_msg; +static PyObject *__pyx_n_s_name; +static PyObject *__pyx_n_s_name_2; +static PyObject *__pyx_kp_u_name_col; +static PyObject *__pyx_n_s_new_buffer; +static PyObject *__pyx_kp_s_no_default___reduce___due_to_non; +static PyObject *__pyx_kp_u_not; +static PyObject *__pyx_kp_u_not_found_in_the_dataframe; +static PyObject *__pyx_n_s_pandas; +static PyObject *__pyx_kp_u_pandas_A; +static PyObject *__pyx_kp_u_pandas_A_2; +static PyObject *__pyx_kp_u_pandas_B; +static PyObject *__pyx_kp_u_pandas_core_frame; +static PyObject *__pyx_n_s_pathlib; +static PyObject *__pyx_n_s_port; +static PyObject *__pyx_kp_u_port_must_be_an_integer_or_a_str; +static PyObject *__pyx_n_s_prepare; +static PyObject *__pyx_n_s_property; +static PyObject *__pyx_n_s_pyx_state; +static PyObject *__pyx_n_s_pyx_vtable; +static PyObject *__pyx_n_s_qualname; +static PyObject *__pyx_n_s_questdb_ingress; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_read_timeout; +static PyObject *__pyx_n_s_reduce; +static PyObject *__pyx_n_s_reduce_cython; +static PyObject *__pyx_n_s_reduce_ex; +static PyObject *__pyx_n_s_reserve; +static PyObject *__pyx_n_s_return; +static PyObject *__pyx_n_s_row; +static PyObject *__pyx_n_s_self; +static PyObject *__pyx_n_s_setstate; +static PyObject *__pyx_n_s_setstate_cython; +static PyObject *__pyx_n_u_size_t_vec; +static PyObject *__pyx_n_s_sort; +static PyObject *__pyx_kp_u_sort_2; +static PyObject *__pyx_kp_s_src_questdb_ingress_pyx; +static PyObject *__pyx_n_s_stderr; +static PyObject *__pyx_n_u_str; +static PyObject *__pyx_n_s_str_2; +static PyObject *__pyx_kp_s_stringsource; +static PyObject *__pyx_n_s_super; +static PyObject *__pyx_n_u_symbol; +static PyObject *__pyx_kp_u_symbol_indices; +static PyObject *__pyx_n_s_symbols; +static PyObject *__pyx_n_u_symbols; +static PyObject *__pyx_kp_u_symbols_2; +static PyObject *__pyx_n_s_sys; +static PyObject *__pyx_n_s_table_name; +static PyObject *__pyx_kp_u_table_name_2; +static PyObject *__pyx_n_s_table_name_col; +static PyObject *__pyx_n_u_table_name_col; +static PyObject *__pyx_kp_u_table_name_col_2; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_timestamp; +static PyObject *__pyx_n_s_tls; +static PyObject *__pyx_kp_u_tls_must_be_a_bool_a_path_or_str; +static PyObject *__pyx_n_s_to_numpy; +static PyObject *__pyx_n_s_typing; +static PyObject *__pyx_n_u_unicode; +static PyObject *__pyx_n_s_value; +static PyObject *__pyx_n_s_value_2; +static PyObject *__pyx_kp_u_value_must_positive_integer; +static PyObject *__pyx_n_s_write; +static PyObject *__pyx_n_u_x; +static PyObject *__pyx_pf_7questdb_7ingress_16IngressErrorCode___str__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_12IngressError___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_code, PyObject *__pyx_v_msg); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_12IngressError_2code(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ +static int __pyx_pf_7questdb_7ingress_15TimestampMicros___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, PyObject *__pyx_v_value); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ +static int __pyx_pf_7questdb_7ingress_14TimestampNanos___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, PyObject *__pyx_v_value); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ +static int __pyx_pf_7questdb_7ingress_6Buffer___cinit__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_init_capacity, PyObject *__pyx_v_max_name_len); /* proto */ +static void __pyx_pf_7questdb_7ingress_6Buffer_2__dealloc__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_4reserve(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_additional); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_6capacity(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_8clear(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static Py_ssize_t __pyx_pf_7questdb_7ingress_6Buffer_10__len__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12__str__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_14row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_16pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, PyBoolObject *__pyx_v_sort); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_18__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_20__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ +static int __pyx_pf_7questdb_7ingress_6Sender___cinit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_host, PyObject *__pyx_v_port, PyObject *__pyx_v_interface, PyObject *__pyx_v_auth, PyObject *__pyx_v_tls, uint64_t __pyx_v_read_timeout, uint64_t __pyx_v_init_capacity, uint64_t __pyx_v_max_name_len, PyObject *__pyx_v_auto_flush); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_2new_buffer(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_4connect(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pf_7questdb_7ingress_6Sender_6__enter__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_8__str__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static Py_ssize_t __pyx_pf_7questdb_7ingress_6Sender_10__len__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12row(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_14flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer, int __pyx_v_clear); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_16close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_v_flush); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_18__exit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_exc_type, CYTHON_UNUSED PyObject *__pyx_v__exc_val, CYTHON_UNUSED PyObject *__pyx_v__exc_tb); /* proto */ +static void __pyx_pf_7questdb_7ingress_6Sender_20__dealloc__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_22__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_24__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ +static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampMicros(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampNanos(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_7questdb_7ingress_Sender(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_tp_new_7questdb_7ingress_Buffer(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static __Pyx_CachedCFunction __pyx_umethod_PyUnicode_Type_format = {0, &__pyx_n_s_format, 0, 0, 0}; +static PyObject *__pyx_int_0; +static PyObject *__pyx_int_8; +static PyObject *__pyx_int_127; +static PyObject *__pyx_int_1000; +static PyObject *__pyx_int_64512; +static PyObject *__pyx_int_65536; +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__2; +static PyObject *__pyx_tuple__3; +static PyObject *__pyx_tuple__4; +static PyObject *__pyx_tuple__7; +static PyObject *__pyx_tuple__8; +static PyObject *__pyx_slice__13; +static PyObject *__pyx_tuple__16; +static PyObject *__pyx_tuple__18; +static PyObject *__pyx_tuple__19; +static PyObject *__pyx_tuple__20; +static PyObject *__pyx_tuple__21; +static PyObject *__pyx_tuple__22; +static PyObject *__pyx_tuple__23; +static PyObject *__pyx_tuple__25; +static PyObject *__pyx_tuple__26; +static PyObject *__pyx_tuple__28; +static PyObject *__pyx_tuple__29; +static PyObject *__pyx_tuple__30; +static PyObject *__pyx_tuple__31; +static PyObject *__pyx_tuple__32; +static PyObject *__pyx_tuple__33; +static PyObject *__pyx_tuple__35; +static PyObject *__pyx_tuple__37; +static PyObject *__pyx_tuple__39; +static PyObject *__pyx_tuple__41; +static PyObject *__pyx_tuple__43; +static PyObject *__pyx_tuple__45; +static PyObject *__pyx_tuple__47; +static PyObject *__pyx_tuple__49; +static PyObject *__pyx_tuple__51; +static PyObject *__pyx_tuple__53; +static PyObject *__pyx_tuple__55; +static PyObject *__pyx_tuple__57; +static PyObject *__pyx_tuple__59; +static PyObject *__pyx_tuple__61; +static PyObject *__pyx_tuple__63; +static PyObject *__pyx_tuple__65; +static PyObject *__pyx_tuple__67; +static PyObject *__pyx_tuple__69; +static PyObject *__pyx_tuple__71; +static PyObject *__pyx_tuple__73; +static PyObject *__pyx_tuple__75; +static PyObject *__pyx_tuple__77; +static PyObject *__pyx_tuple__79; +static PyObject *__pyx_tuple__81; +static PyObject *__pyx_codeobj__34; +static PyObject *__pyx_codeobj__36; +static PyObject *__pyx_codeobj__38; +static PyObject *__pyx_codeobj__40; +static PyObject *__pyx_codeobj__42; +static PyObject *__pyx_codeobj__44; +static PyObject *__pyx_codeobj__46; +static PyObject *__pyx_codeobj__48; +static PyObject *__pyx_codeobj__50; +static PyObject *__pyx_codeobj__52; +static PyObject *__pyx_codeobj__54; +static PyObject *__pyx_codeobj__56; +static PyObject *__pyx_codeobj__58; +static PyObject *__pyx_codeobj__60; +static PyObject *__pyx_codeobj__62; +static PyObject *__pyx_codeobj__64; +static PyObject *__pyx_codeobj__66; +static PyObject *__pyx_codeobj__68; +static PyObject *__pyx_codeobj__70; +static PyObject *__pyx_codeobj__72; +static PyObject *__pyx_codeobj__74; +static PyObject *__pyx_codeobj__76; +static PyObject *__pyx_codeobj__78; +static PyObject *__pyx_codeobj__80; +static PyObject *__pyx_codeobj__82; +/* Late includes */ + +/* "src/questdb/size_t_vec.pxi":8 + * ctypedef c_size_t_vec size_t_vec + * + * cdef size_t_vec size_t_vec_new(): # <<<<<<<<<<<<<< + * cdef size_t_vec vec + * vec.capacity = 0 + */ + +static __pyx_t_7questdb_7ingress_size_t_vec __pyx_f_7questdb_7ingress_size_t_vec_new(void) { + __pyx_t_7questdb_7ingress_size_t_vec __pyx_v_vec; + __pyx_t_7questdb_7ingress_size_t_vec __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("size_t_vec_new", 0); + + /* "src/questdb/size_t_vec.pxi":10 + * cdef size_t_vec size_t_vec_new(): + * cdef size_t_vec vec + * vec.capacity = 0 # <<<<<<<<<<<<<< + * vec.size = 0 + * vec.d = NULL + */ + __pyx_v_vec.capacity = 0; + + /* "src/questdb/size_t_vec.pxi":11 + * cdef size_t_vec vec + * vec.capacity = 0 + * vec.size = 0 # <<<<<<<<<<<<<< + * vec.d = NULL + * return vec + */ + __pyx_v_vec.size = 0; + + /* "src/questdb/size_t_vec.pxi":12 + * vec.capacity = 0 + * vec.size = 0 + * vec.d = NULL # <<<<<<<<<<<<<< + * return vec + * + */ + __pyx_v_vec.d = ((size_t *)NULL); + + /* "src/questdb/size_t_vec.pxi":13 + * vec.size = 0 + * vec.d = NULL + * return vec # <<<<<<<<<<<<<< + * + * cdef void size_t_vec_free(size_t_vec* vec): + */ + __pyx_r = __pyx_v_vec; + goto __pyx_L0; + + /* "src/questdb/size_t_vec.pxi":8 + * ctypedef c_size_t_vec size_t_vec + * + * cdef size_t_vec size_t_vec_new(): # <<<<<<<<<<<<<< + * cdef size_t_vec vec + * vec.capacity = 0 + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/size_t_vec.pxi":15 + * return vec + * + * cdef void size_t_vec_free(size_t_vec* vec): # <<<<<<<<<<<<<< + * if vec.d: + * free(vec.d) + */ + +static void __pyx_f_7questdb_7ingress_size_t_vec_free(__pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_vec) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("size_t_vec_free", 0); + + /* "src/questdb/size_t_vec.pxi":16 + * + * cdef void size_t_vec_free(size_t_vec* vec): + * if vec.d: # <<<<<<<<<<<<<< + * free(vec.d) + * vec.d = NULL + */ + __pyx_t_1 = (__pyx_v_vec->d != 0); + if (__pyx_t_1) { + + /* "src/questdb/size_t_vec.pxi":17 + * cdef void size_t_vec_free(size_t_vec* vec): + * if vec.d: + * free(vec.d) # <<<<<<<<<<<<<< + * vec.d = NULL + * + */ + free(__pyx_v_vec->d); + + /* "src/questdb/size_t_vec.pxi":18 + * if vec.d: + * free(vec.d) + * vec.d = NULL # <<<<<<<<<<<<<< + * + * cdef str size_t_vec_str(size_t_vec* vec): + */ + __pyx_v_vec->d = NULL; + + /* "src/questdb/size_t_vec.pxi":16 + * + * cdef void size_t_vec_free(size_t_vec* vec): + * if vec.d: # <<<<<<<<<<<<<< + * free(vec.d) + * vec.d = NULL + */ + } + + /* "src/questdb/size_t_vec.pxi":15 + * return vec + * + * cdef void size_t_vec_free(size_t_vec* vec): # <<<<<<<<<<<<<< + * if vec.d: + * free(vec.d) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "src/questdb/size_t_vec.pxi":20 + * vec.d = NULL + * + * cdef str size_t_vec_str(size_t_vec* vec): # <<<<<<<<<<<<<< + * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) + * + */ + +static PyObject *__pyx_f_7questdb_7ingress_size_t_vec_str(__pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_vec) { + size_t __pyx_7genexpr__pyx_v_i; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + size_t __pyx_t_2; + size_t __pyx_t_3; + size_t __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("size_t_vec_str", 0); + + /* "src/questdb/size_t_vec.pxi":21 + * + * cdef str size_t_vec_str(size_t_vec* vec): + * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) # <<<<<<<<<<<<<< + * + * cdef void size_t_vec_push(size_t_vec* vec, size_t value): + */ + __Pyx_XDECREF(__pyx_r); + { /* enter inner scope */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __pyx_v_vec->size; + __pyx_t_3 = __pyx_t_2; + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_7genexpr__pyx_v_i = __pyx_t_4; + __pyx_t_5 = __Pyx_PyInt_FromSize_t((__pyx_v_vec->d[__pyx_7genexpr__pyx_v_i])); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(1, 21, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + } /* exit inner scope */ + __pyx_t_5 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_n_u_size_t_vec, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_r = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "src/questdb/size_t_vec.pxi":20 + * vec.d = NULL + * + * cdef str size_t_vec_str(size_t_vec* vec): # <<<<<<<<<<<<<< + * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("questdb.ingress.size_t_vec_str", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/size_t_vec.pxi":23 + * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) + * + * cdef void size_t_vec_push(size_t_vec* vec, size_t value): # <<<<<<<<<<<<<< + * if vec.capacity == 0: + * vec.capacity = 8 + */ + +static void __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_vec, size_t __pyx_v_value) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("size_t_vec_push", 0); + + /* "src/questdb/size_t_vec.pxi":24 + * + * cdef void size_t_vec_push(size_t_vec* vec, size_t value): + * if vec.capacity == 0: # <<<<<<<<<<<<<< + * vec.capacity = 8 + * vec.d = malloc(vec.capacity * sizeof(size_t)) + */ + __pyx_t_1 = ((__pyx_v_vec->capacity == 0) != 0); + if (__pyx_t_1) { + + /* "src/questdb/size_t_vec.pxi":25 + * cdef void size_t_vec_push(size_t_vec* vec, size_t value): + * if vec.capacity == 0: + * vec.capacity = 8 # <<<<<<<<<<<<<< + * vec.d = malloc(vec.capacity * sizeof(size_t)) + * if vec.d == NULL: + */ + __pyx_v_vec->capacity = 8; + + /* "src/questdb/size_t_vec.pxi":26 + * if vec.capacity == 0: + * vec.capacity = 8 + * vec.d = malloc(vec.capacity * sizeof(size_t)) # <<<<<<<<<<<<<< + * if vec.d == NULL: + * abort() + */ + __pyx_v_vec->d = ((size_t *)malloc((__pyx_v_vec->capacity * (sizeof(size_t))))); + + /* "src/questdb/size_t_vec.pxi":27 + * vec.capacity = 8 + * vec.d = malloc(vec.capacity * sizeof(size_t)) + * if vec.d == NULL: # <<<<<<<<<<<<<< + * abort() + * elif vec.size == vec.capacity: + */ + __pyx_t_1 = ((__pyx_v_vec->d == NULL) != 0); + if (__pyx_t_1) { + + /* "src/questdb/size_t_vec.pxi":28 + * vec.d = malloc(vec.capacity * sizeof(size_t)) + * if vec.d == NULL: + * abort() # <<<<<<<<<<<<<< + * elif vec.size == vec.capacity: + * vec.capacity = vec.capacity * 2 + */ + abort(); + + /* "src/questdb/size_t_vec.pxi":27 + * vec.capacity = 8 + * vec.d = malloc(vec.capacity * sizeof(size_t)) + * if vec.d == NULL: # <<<<<<<<<<<<<< + * abort() + * elif vec.size == vec.capacity: + */ + } + + /* "src/questdb/size_t_vec.pxi":24 + * + * cdef void size_t_vec_push(size_t_vec* vec, size_t value): + * if vec.capacity == 0: # <<<<<<<<<<<<<< + * vec.capacity = 8 + * vec.d = malloc(vec.capacity * sizeof(size_t)) + */ + goto __pyx_L3; + } + + /* "src/questdb/size_t_vec.pxi":29 + * if vec.d == NULL: + * abort() + * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< + * vec.capacity = vec.capacity * 2 + * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + */ + __pyx_t_1 = ((__pyx_v_vec->size == __pyx_v_vec->capacity) != 0); + if (__pyx_t_1) { + + /* "src/questdb/size_t_vec.pxi":30 + * abort() + * elif vec.size == vec.capacity: + * vec.capacity = vec.capacity * 2 # <<<<<<<<<<<<<< + * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + * if not vec.d: + */ + __pyx_v_vec->capacity = (__pyx_v_vec->capacity * 2); + + /* "src/questdb/size_t_vec.pxi":31 + * elif vec.size == vec.capacity: + * vec.capacity = vec.capacity * 2 + * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) # <<<<<<<<<<<<<< + * if not vec.d: + * abort() + */ + __pyx_v_vec->d = ((size_t *)realloc(__pyx_v_vec->d, (__pyx_v_vec->capacity * (sizeof(size_t))))); + + /* "src/questdb/size_t_vec.pxi":32 + * vec.capacity = vec.capacity * 2 + * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + * if not vec.d: # <<<<<<<<<<<<<< + * abort() + * vec.d[vec.size] = value + */ + __pyx_t_1 = ((!(__pyx_v_vec->d != 0)) != 0); + if (__pyx_t_1) { + + /* "src/questdb/size_t_vec.pxi":33 + * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + * if not vec.d: + * abort() # <<<<<<<<<<<<<< + * vec.d[vec.size] = value + * vec.size += 1 + */ + abort(); + + /* "src/questdb/size_t_vec.pxi":32 + * vec.capacity = vec.capacity * 2 + * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + * if not vec.d: # <<<<<<<<<<<<<< + * abort() + * vec.d[vec.size] = value + */ + } + + /* "src/questdb/size_t_vec.pxi":29 + * if vec.d == NULL: + * abort() + * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< + * vec.capacity = vec.capacity * 2 + * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + */ + } + __pyx_L3:; + + /* "src/questdb/size_t_vec.pxi":34 + * if not vec.d: + * abort() + * vec.d[vec.size] = value # <<<<<<<<<<<<<< + * vec.size += 1 + */ + (__pyx_v_vec->d[__pyx_v_vec->size]) = __pyx_v_value; + + /* "src/questdb/size_t_vec.pxi":35 + * abort() + * vec.d[vec.size] = value + * vec.size += 1 # <<<<<<<<<<<<<< + */ + __pyx_v_vec->size = (__pyx_v_vec->size + 1); + + /* "src/questdb/size_t_vec.pxi":23 + * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) + * + * cdef void size_t_vec_push(size_t_vec* vec, size_t value): # <<<<<<<<<<<<<< + * if vec.capacity == 0: + * vec.capacity = 8 + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "src/questdb/column_name_vec.pxi":8 + * ctypedef c_column_name_vec column_name_vec + * + * cdef column_name_vec column_name_vec_new(): # <<<<<<<<<<<<<< + * cdef column_name_vec vec + * vec.capacity = 0 + */ + +static __pyx_t_7questdb_7ingress_column_name_vec __pyx_f_7questdb_7ingress_column_name_vec_new(void) { + __pyx_t_7questdb_7ingress_column_name_vec __pyx_v_vec; + __pyx_t_7questdb_7ingress_column_name_vec __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("column_name_vec_new", 0); + + /* "src/questdb/column_name_vec.pxi":10 + * cdef column_name_vec column_name_vec_new(): + * cdef column_name_vec vec + * vec.capacity = 0 # <<<<<<<<<<<<<< + * vec.size = 0 + * vec.d = NULL + */ + __pyx_v_vec.capacity = 0; + + /* "src/questdb/column_name_vec.pxi":11 + * cdef column_name_vec vec + * vec.capacity = 0 + * vec.size = 0 # <<<<<<<<<<<<<< + * vec.d = NULL + * return vec + */ + __pyx_v_vec.size = 0; + + /* "src/questdb/column_name_vec.pxi":12 + * vec.capacity = 0 + * vec.size = 0 + * vec.d = NULL # <<<<<<<<<<<<<< + * return vec + * + */ + __pyx_v_vec.d = ((struct line_sender_column_name *)NULL); + + /* "src/questdb/column_name_vec.pxi":13 + * vec.size = 0 + * vec.d = NULL + * return vec # <<<<<<<<<<<<<< + * + * cdef void column_name_vec_free(column_name_vec* vec): + */ + __pyx_r = __pyx_v_vec; + goto __pyx_L0; + + /* "src/questdb/column_name_vec.pxi":8 + * ctypedef c_column_name_vec column_name_vec + * + * cdef column_name_vec column_name_vec_new(): # <<<<<<<<<<<<<< + * cdef column_name_vec vec + * vec.capacity = 0 + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/column_name_vec.pxi":15 + * return vec + * + * cdef void column_name_vec_free(column_name_vec* vec): # <<<<<<<<<<<<<< + * if vec.d: + * free(vec.d) + */ + +static void __pyx_f_7questdb_7ingress_column_name_vec_free(__pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_vec) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("column_name_vec_free", 0); + + /* "src/questdb/column_name_vec.pxi":16 + * + * cdef void column_name_vec_free(column_name_vec* vec): + * if vec.d: # <<<<<<<<<<<<<< + * free(vec.d) + * vec.d = NULL + */ + __pyx_t_1 = (__pyx_v_vec->d != 0); + if (__pyx_t_1) { + + /* "src/questdb/column_name_vec.pxi":17 + * cdef void column_name_vec_free(column_name_vec* vec): + * if vec.d: + * free(vec.d) # <<<<<<<<<<<<<< + * vec.d = NULL + * + */ + free(__pyx_v_vec->d); + + /* "src/questdb/column_name_vec.pxi":18 + * if vec.d: + * free(vec.d) + * vec.d = NULL # <<<<<<<<<<<<<< + * + * cdef void column_name_vec_push( + */ + __pyx_v_vec->d = NULL; + + /* "src/questdb/column_name_vec.pxi":16 + * + * cdef void column_name_vec_free(column_name_vec* vec): + * if vec.d: # <<<<<<<<<<<<<< + * free(vec.d) + * vec.d = NULL + */ + } + + /* "src/questdb/column_name_vec.pxi":15 + * return vec + * + * cdef void column_name_vec_free(column_name_vec* vec): # <<<<<<<<<<<<<< + * if vec.d: + * free(vec.d) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "src/questdb/column_name_vec.pxi":20 + * vec.d = NULL + * + * cdef void column_name_vec_push( # <<<<<<<<<<<<<< + * column_name_vec* vec, line_sender_column_name value): + * if vec.capacity == 0: + */ + +static void __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_vec, struct line_sender_column_name __pyx_v_value) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("column_name_vec_push", 0); + + /* "src/questdb/column_name_vec.pxi":22 + * cdef void column_name_vec_push( + * column_name_vec* vec, line_sender_column_name value): + * if vec.capacity == 0: # <<<<<<<<<<<<<< + * vec.capacity = 8 + * vec.d = malloc( + */ + __pyx_t_1 = ((__pyx_v_vec->capacity == 0) != 0); + if (__pyx_t_1) { + + /* "src/questdb/column_name_vec.pxi":23 + * column_name_vec* vec, line_sender_column_name value): + * if vec.capacity == 0: + * vec.capacity = 8 # <<<<<<<<<<<<<< + * vec.d = malloc( + * vec.capacity * sizeof(line_sender_column_name)) + */ + __pyx_v_vec->capacity = 8; + + /* "src/questdb/column_name_vec.pxi":24 + * if vec.capacity == 0: + * vec.capacity = 8 + * vec.d = malloc( # <<<<<<<<<<<<<< + * vec.capacity * sizeof(line_sender_column_name)) + * if vec.d == NULL: + */ + __pyx_v_vec->d = ((struct line_sender_column_name *)malloc((__pyx_v_vec->capacity * (sizeof(struct line_sender_column_name))))); + + /* "src/questdb/column_name_vec.pxi":26 + * vec.d = malloc( + * vec.capacity * sizeof(line_sender_column_name)) + * if vec.d == NULL: # <<<<<<<<<<<<<< + * abort() + * elif vec.size == vec.capacity: + */ + __pyx_t_1 = ((__pyx_v_vec->d == NULL) != 0); + if (__pyx_t_1) { + + /* "src/questdb/column_name_vec.pxi":27 + * vec.capacity * sizeof(line_sender_column_name)) + * if vec.d == NULL: + * abort() # <<<<<<<<<<<<<< + * elif vec.size == vec.capacity: + * vec.capacity = vec.capacity * 2 + */ + abort(); + + /* "src/questdb/column_name_vec.pxi":26 + * vec.d = malloc( + * vec.capacity * sizeof(line_sender_column_name)) + * if vec.d == NULL: # <<<<<<<<<<<<<< + * abort() + * elif vec.size == vec.capacity: + */ + } + + /* "src/questdb/column_name_vec.pxi":22 + * cdef void column_name_vec_push( + * column_name_vec* vec, line_sender_column_name value): + * if vec.capacity == 0: # <<<<<<<<<<<<<< + * vec.capacity = 8 + * vec.d = malloc( + */ + goto __pyx_L3; + } + + /* "src/questdb/column_name_vec.pxi":28 + * if vec.d == NULL: + * abort() + * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< + * vec.capacity = vec.capacity * 2 + * vec.d = realloc( + */ + __pyx_t_1 = ((__pyx_v_vec->size == __pyx_v_vec->capacity) != 0); + if (__pyx_t_1) { + + /* "src/questdb/column_name_vec.pxi":29 + * abort() + * elif vec.size == vec.capacity: + * vec.capacity = vec.capacity * 2 # <<<<<<<<<<<<<< + * vec.d = realloc( + * vec.d, + */ + __pyx_v_vec->capacity = (__pyx_v_vec->capacity * 2); + + /* "src/questdb/column_name_vec.pxi":30 + * elif vec.size == vec.capacity: + * vec.capacity = vec.capacity * 2 + * vec.d = realloc( # <<<<<<<<<<<<<< + * vec.d, + * vec.capacity * sizeof(line_sender_column_name)) + */ + __pyx_v_vec->d = ((struct line_sender_column_name *)realloc(__pyx_v_vec->d, (__pyx_v_vec->capacity * (sizeof(struct line_sender_column_name))))); + + /* "src/questdb/column_name_vec.pxi":33 + * vec.d, + * vec.capacity * sizeof(line_sender_column_name)) + * if not vec.d: # <<<<<<<<<<<<<< + * abort() + * vec.d[vec.size] = value + */ + __pyx_t_1 = ((!(__pyx_v_vec->d != 0)) != 0); + if (__pyx_t_1) { + + /* "src/questdb/column_name_vec.pxi":34 + * vec.capacity * sizeof(line_sender_column_name)) + * if not vec.d: + * abort() # <<<<<<<<<<<<<< + * vec.d[vec.size] = value + * vec.size += 1 + */ + abort(); + + /* "src/questdb/column_name_vec.pxi":33 + * vec.d, + * vec.capacity * sizeof(line_sender_column_name)) + * if not vec.d: # <<<<<<<<<<<<<< + * abort() + * vec.d[vec.size] = value + */ + } + + /* "src/questdb/column_name_vec.pxi":28 + * if vec.d == NULL: + * abort() + * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< + * vec.capacity = vec.capacity * 2 + * vec.d = realloc( + */ + } + __pyx_L3:; + + /* "src/questdb/column_name_vec.pxi":35 + * if not vec.d: + * abort() + * vec.d[vec.size] = value # <<<<<<<<<<<<<< + * vec.size += 1 + */ + (__pyx_v_vec->d[__pyx_v_vec->size]) = __pyx_v_value; + + /* "src/questdb/column_name_vec.pxi":36 + * abort() + * vec.d[vec.size] = value + * vec.size += 1 # <<<<<<<<<<<<<< + */ + __pyx_v_vec->size = (__pyx_v_vec->size + 1); + + /* "src/questdb/column_name_vec.pxi":20 + * vec.d = NULL + * + * cdef void column_name_vec_push( # <<<<<<<<<<<<<< + * column_name_vec* vec, line_sender_column_name value): + * if vec.capacity == 0: + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "src/questdb/pandas_helpers.pxi":79 + * + * + * cdef object _pandas_may_set_na_type(): # <<<<<<<<<<<<<< + * global _PANDAS_NA + * if _PANDAS_NA is None: + */ + +static PyObject *__pyx_f_7questdb_7ingress__pandas_may_set_na_type(void) { + PyObject *__pyx_v_pd = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_may_set_na_type", 0); + + /* "src/questdb/pandas_helpers.pxi":81 + * cdef object _pandas_may_set_na_type(): + * global _PANDAS_NA + * if _PANDAS_NA is None: # <<<<<<<<<<<<<< + * import pandas as pd + * _PANDAS_NA = pd.NA + */ + __pyx_t_1 = (__pyx_v_7questdb_7ingress__PANDAS_NA == Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":82 + * global _PANDAS_NA + * if _PANDAS_NA is None: + * import pandas as pd # <<<<<<<<<<<<<< + * _PANDAS_NA = pd.NA + * + */ + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pandas, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_pd = __pyx_t_3; + __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":83 + * if _PANDAS_NA is None: + * import pandas as pd + * _PANDAS_NA = pd.NA # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_pd, __pyx_n_s_NA); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 83, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_v_7questdb_7ingress__PANDAS_NA); + __Pyx_DECREF_SET(__pyx_v_7questdb_7ingress__PANDAS_NA, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_3); + __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":81 + * cdef object _pandas_may_set_na_type(): + * global _PANDAS_NA + * if _PANDAS_NA is None: # <<<<<<<<<<<<<< + * import pandas as pd + * _PANDAS_NA = pd.NA + */ + } + + /* "src/questdb/pandas_helpers.pxi":79 + * + * + * cdef object _pandas_may_set_na_type(): # <<<<<<<<<<<<<< + * global _PANDAS_NA + * if _PANDAS_NA is None: + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress._pandas_may_set_na_type", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_pd); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":86 + * + * + * cdef ssize_t _pandas_resolve_table_name( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * object data, + */ + +static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_table_name(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, size_t __pyx_v_col_count, struct line_sender_table_name *__pyx_v_name_out) { + size_t __pyx_v_col_index; + PyObject *__pyx_v_ie = NULL; + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + int __pyx_t_12; + char const *__pyx_t_13; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + PyObject *__pyx_t_16 = NULL; + PyObject *__pyx_t_17 = NULL; + PyObject *__pyx_t_18 = NULL; + PyObject *__pyx_t_19 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_resolve_table_name", 0); + + /* "src/questdb/pandas_helpers.pxi":107 + * This method validates input and may raise. + * """ + * cdef size_t col_index = 0 # <<<<<<<<<<<<<< + * if table_name is not None: + * if table_name_col is not None: + */ + __pyx_v_col_index = 0; + + /* "src/questdb/pandas_helpers.pxi":108 + * """ + * cdef size_t col_index = 0 + * if table_name is not None: # <<<<<<<<<<<<<< + * if table_name_col is not None: + * raise ValueError( + */ + __pyx_t_1 = (__pyx_v_table_name != Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":109 + * cdef size_t col_index = 0 + * if table_name is not None: + * if table_name_col is not None: # <<<<<<<<<<<<<< + * raise ValueError( + * 'Can specify only one of `table_name` or `table_name_col`.') + */ + __pyx_t_2 = (__pyx_v_table_name_col != Py_None); + __pyx_t_1 = (__pyx_t_2 != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":110 + * if table_name is not None: + * if table_name_col is not None: + * raise ValueError( # <<<<<<<<<<<<<< + * 'Can specify only one of `table_name` or `table_name_col`.') + * if isinstance(table_name, str): + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 110, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":109 + * cdef size_t col_index = 0 + * if table_name is not None: + * if table_name_col is not None: # <<<<<<<<<<<<<< + * raise ValueError( + * 'Can specify only one of `table_name` or `table_name_col`.') + */ + } + + /* "src/questdb/pandas_helpers.pxi":112 + * raise ValueError( + * 'Can specify only one of `table_name` or `table_name_col`.') + * if isinstance(table_name, str): # <<<<<<<<<<<<<< + * try: + * str_to_table_name(b, table_name, name_out) + */ + __pyx_t_1 = PyUnicode_Check(__pyx_v_table_name); + __pyx_t_2 = (__pyx_t_1 != 0); + if (likely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":113 + * 'Can specify only one of `table_name` or `table_name_col`.') + * if isinstance(table_name, str): + * try: # <<<<<<<<<<<<<< + * str_to_table_name(b, table_name, name_out) + * return -1 # Magic value for "no column index". + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + /*try:*/ { + + /* "src/questdb/pandas_helpers.pxi":114 + * if isinstance(table_name, str): + * try: + * str_to_table_name(b, table_name, name_out) # <<<<<<<<<<<<<< + * return -1 # Magic value for "no column index". + * except IngressError as ie: + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_table_name))||((__pyx_v_table_name) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_table_name)->tp_name), 0))) __PYX_ERR(2, 114, __pyx_L6_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_str_to_table_name(__pyx_v_b, ((PyObject*)__pyx_v_table_name), __pyx_v_name_out); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 114, __pyx_L6_error) + + /* "src/questdb/pandas_helpers.pxi":115 + * try: + * str_to_table_name(b, table_name, name_out) + * return -1 # Magic value for "no column index". # <<<<<<<<<<<<<< + * except IngressError as ie: + * raise ValueError(f'Bad argument `table_name`: {ie}') + */ + __pyx_r = -1L; + goto __pyx_L10_try_return; + + /* "src/questdb/pandas_helpers.pxi":113 + * 'Can specify only one of `table_name` or `table_name_col`.') + * if isinstance(table_name, str): + * try: # <<<<<<<<<<<<<< + * str_to_table_name(b, table_name, name_out) + * return -1 # Magic value for "no column index". + */ + } + __pyx_L6_error:; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":116 + * str_to_table_name(b, table_name, name_out) + * return -1 # Magic value for "no column index". + * except IngressError as ie: # <<<<<<<<<<<<<< + * raise ValueError(f'Bad argument `table_name`: {ie}') + * else: + */ + __Pyx_ErrFetch(&__pyx_t_3, &__pyx_t_7, &__pyx_t_8); + __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 116, __pyx_L8_except_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_3, __pyx_t_9); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_ErrRestore(__pyx_t_3, __pyx_t_7, __pyx_t_8); + __pyx_t_3 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; + if (__pyx_t_10) { + __Pyx_AddTraceback("questdb.ingress._pandas_resolve_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_3) < 0) __PYX_ERR(2, 116, __pyx_L8_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_7); + __pyx_v_ie = __pyx_t_7; + /*try:*/ { + + /* "src/questdb/pandas_helpers.pxi":117 + * return -1 # Magic value for "no column index". + * except IngressError as ie: + * raise ValueError(f'Bad argument `table_name`: {ie}') # <<<<<<<<<<<<<< + * else: + * raise TypeError('Bad argument `table_name`: Must be str.') + */ + __pyx_t_9 = __Pyx_PyObject_FormatSimple(__pyx_v_ie, __pyx_empty_unicode); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 117, __pyx_L17_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_argument_table_name, __pyx_t_9); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 117, __pyx_L17_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_11); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 117, __pyx_L17_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(2, 117, __pyx_L17_error) + } + + /* "src/questdb/pandas_helpers.pxi":116 + * str_to_table_name(b, table_name, name_out) + * return -1 # Magic value for "no column index". + * except IngressError as ie: # <<<<<<<<<<<<<< + * raise ValueError(f'Bad argument `table_name`: {ie}') + * else: + */ + /*finally:*/ { + __pyx_L17_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16) < 0)) __Pyx_ErrFetch(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16); + __Pyx_XGOTREF(__pyx_t_14); + __Pyx_XGOTREF(__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_16); + __Pyx_XGOTREF(__pyx_t_17); + __Pyx_XGOTREF(__pyx_t_18); + __Pyx_XGOTREF(__pyx_t_19); + __pyx_t_10 = __pyx_lineno; __pyx_t_12 = __pyx_clineno; __pyx_t_13 = __pyx_filename; + { + __Pyx_DECREF(__pyx_v_ie); + __pyx_v_ie = NULL; + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_17); + __Pyx_XGIVEREF(__pyx_t_18); + __Pyx_XGIVEREF(__pyx_t_19); + __Pyx_ExceptionReset(__pyx_t_17, __pyx_t_18, __pyx_t_19); + } + __Pyx_XGIVEREF(__pyx_t_14); + __Pyx_XGIVEREF(__pyx_t_15); + __Pyx_XGIVEREF(__pyx_t_16); + __Pyx_ErrRestore(__pyx_t_14, __pyx_t_15, __pyx_t_16); + __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; + __pyx_lineno = __pyx_t_10; __pyx_clineno = __pyx_t_12; __pyx_filename = __pyx_t_13; + goto __pyx_L8_except_error; + } + } + } + goto __pyx_L8_except_error; + __pyx_L8_except_error:; + + /* "src/questdb/pandas_helpers.pxi":113 + * 'Can specify only one of `table_name` or `table_name_col`.') + * if isinstance(table_name, str): + * try: # <<<<<<<<<<<<<< + * str_to_table_name(b, table_name, name_out) + * return -1 # Magic value for "no column index". + */ + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); + goto __pyx_L1_error; + __pyx_L10_try_return:; + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); + goto __pyx_L0; + } + + /* "src/questdb/pandas_helpers.pxi":112 + * raise ValueError( + * 'Can specify only one of `table_name` or `table_name_col`.') + * if isinstance(table_name, str): # <<<<<<<<<<<<<< + * try: + * str_to_table_name(b, table_name, name_out) + */ + } + + /* "src/questdb/pandas_helpers.pxi":119 + * raise ValueError(f'Bad argument `table_name`: {ie}') + * else: + * raise TypeError('Bad argument `table_name`: Must be str.') # <<<<<<<<<<<<<< + * elif table_name_col is not None: + * if isinstance(table_name_col, str): + */ + /*else*/ { + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 119, __pyx_L1_error) + } + + /* "src/questdb/pandas_helpers.pxi":108 + * """ + * cdef size_t col_index = 0 + * if table_name is not None: # <<<<<<<<<<<<<< + * if table_name_col is not None: + * raise ValueError( + */ + } + + /* "src/questdb/pandas_helpers.pxi":120 + * else: + * raise TypeError('Bad argument `table_name`: Must be str.') + * elif table_name_col is not None: # <<<<<<<<<<<<<< + * if isinstance(table_name_col, str): + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + */ + __pyx_t_2 = (__pyx_v_table_name_col != Py_None); + __pyx_t_1 = (__pyx_t_2 != 0); + if (likely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":121 + * raise TypeError('Bad argument `table_name`: Must be str.') + * elif table_name_col is not None: + * if isinstance(table_name_col, str): # <<<<<<<<<<<<<< + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + * elif isinstance(table_name_col, int): + */ + __pyx_t_1 = PyUnicode_Check(__pyx_v_table_name_col); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":122 + * elif table_name_col is not None: + * if isinstance(table_name_col, str): + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) # <<<<<<<<<<<<<< + * elif isinstance(table_name_col, int): + * _bind_col_index( + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_table_name_col))||((__pyx_v_table_name_col) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_table_name_col)->tp_name), 0))) __PYX_ERR(2, 122, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress__pandas_get_loc(__pyx_v_data, ((PyObject*)__pyx_v_table_name_col), __pyx_n_u_table_name_col, (&__pyx_v_col_index)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 122, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":121 + * raise TypeError('Bad argument `table_name`: Must be str.') + * elif table_name_col is not None: + * if isinstance(table_name_col, str): # <<<<<<<<<<<<<< + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + * elif isinstance(table_name_col, int): + */ + goto __pyx_L23; + } + + /* "src/questdb/pandas_helpers.pxi":123 + * if isinstance(table_name_col, str): + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + * elif isinstance(table_name_col, int): # <<<<<<<<<<<<<< + * _bind_col_index( + * 'table_name_col', table_name_col, col_count, &col_index) + */ + __pyx_t_2 = PyInt_Check(__pyx_v_table_name_col); + __pyx_t_1 = (__pyx_t_2 != 0); + if (likely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":125 + * elif isinstance(table_name_col, int): + * _bind_col_index( + * 'table_name_col', table_name_col, col_count, &col_index) # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_table_name_col); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 125, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":124 + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + * elif isinstance(table_name_col, int): + * _bind_col_index( # <<<<<<<<<<<<<< + * 'table_name_col', table_name_col, col_count, &col_index) + * else: + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress__bind_col_index(__pyx_n_u_table_name_col, __pyx_t_12, __pyx_v_col_count, (&__pyx_v_col_index)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 124, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":123 + * if isinstance(table_name_col, str): + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + * elif isinstance(table_name_col, int): # <<<<<<<<<<<<<< + * _bind_col_index( + * 'table_name_col', table_name_col, col_count, &col_index) + */ + goto __pyx_L23; + } + + /* "src/questdb/pandas_helpers.pxi":127 + * 'table_name_col', table_name_col, col_count, &col_index) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * 'Bad argument `table_name_col`: ' + + * 'must be a column name (str) or index (int).') + */ + /*else*/ { + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 127, __pyx_L1_error) + } + __pyx_L23:; + + /* "src/questdb/pandas_helpers.pxi":130 + * 'Bad argument `table_name_col`: ' + + * 'must be a column name (str) or index (int).') + * _pandas_check_column_is_str( # <<<<<<<<<<<<<< + * data, + * col_index, + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress__pandas_check_column_is_str(__pyx_v_data, __pyx_v_col_index, __pyx_kp_u_Bad_argument_table_name_col, __pyx_v_table_name_col); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":135 + * 'Bad argument `table_name_col`: ', + * table_name_col) + * return col_index # <<<<<<<<<<<<<< + * else: + * raise ValueError( + */ + __pyx_r = __pyx_v_col_index; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":120 + * else: + * raise TypeError('Bad argument `table_name`: Must be str.') + * elif table_name_col is not None: # <<<<<<<<<<<<<< + * if isinstance(table_name_col, str): + * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + */ + } + + /* "src/questdb/pandas_helpers.pxi":137 + * return col_index + * else: + * raise ValueError( # <<<<<<<<<<<<<< + * 'Must specify at least one of `table_name` or `table_name_col`.') + * + */ + /*else*/ { + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 137, __pyx_L1_error) + } + + /* "src/questdb/pandas_helpers.pxi":86 + * + * + * cdef ssize_t _pandas_resolve_table_name( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * object data, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("questdb.ingress._pandas_resolve_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -2L; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ie); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":141 + * + * + * cdef int _pandas_resolve_fields( # <<<<<<<<<<<<<< + * int name_col, + * const size_t_vec* symbol_indices, + */ + +static int __pyx_f_7questdb_7ingress__pandas_resolve_fields(int __pyx_v_name_col, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_symbol_indices, int __pyx_v_at_col, size_t __pyx_v_col_count, __pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_field_indices_out) { + size_t __pyx_v_col_index; + size_t __pyx_v_sym_index; + size_t __pyx_v_sym_len; + int __pyx_r; + __Pyx_RefNannyDeclarations + size_t __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + __Pyx_RefNannySetupContext("_pandas_resolve_fields", 0); + + /* "src/questdb/pandas_helpers.pxi":154 + * """ + * # We rely on `symbol_indices` being sorted. + * cdef size_t col_index = 0 # <<<<<<<<<<<<<< + * cdef size_t sym_index = 0 + * cdef size_t sym_len = symbol_indices.size + */ + __pyx_v_col_index = 0; + + /* "src/questdb/pandas_helpers.pxi":155 + * # We rely on `symbol_indices` being sorted. + * cdef size_t col_index = 0 + * cdef size_t sym_index = 0 # <<<<<<<<<<<<<< + * cdef size_t sym_len = symbol_indices.size + * while col_index < col_count: + */ + __pyx_v_sym_index = 0; + + /* "src/questdb/pandas_helpers.pxi":156 + * cdef size_t col_index = 0 + * cdef size_t sym_index = 0 + * cdef size_t sym_len = symbol_indices.size # <<<<<<<<<<<<<< + * while col_index < col_count: + * if (name_col >= 0) and (col_index == name_col): + */ + __pyx_t_1 = __pyx_v_symbol_indices->size; + __pyx_v_sym_len = __pyx_t_1; + + /* "src/questdb/pandas_helpers.pxi":157 + * cdef size_t sym_index = 0 + * cdef size_t sym_len = symbol_indices.size + * while col_index < col_count: # <<<<<<<<<<<<<< + * if (name_col >= 0) and (col_index == name_col): + * col_index += 1 + */ + while (1) { + __pyx_t_2 = ((__pyx_v_col_index < __pyx_v_col_count) != 0); + if (!__pyx_t_2) break; + + /* "src/questdb/pandas_helpers.pxi":158 + * cdef size_t sym_len = symbol_indices.size + * while col_index < col_count: + * if (name_col >= 0) and (col_index == name_col): # <<<<<<<<<<<<<< + * col_index += 1 + * continue + */ + __pyx_t_3 = ((__pyx_v_name_col >= 0) != 0); + if (__pyx_t_3) { + } else { + __pyx_t_2 = __pyx_t_3; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_3 = ((__pyx_v_col_index == ((size_t)__pyx_v_name_col)) != 0); + __pyx_t_2 = __pyx_t_3; + __pyx_L6_bool_binop_done:; + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":159 + * while col_index < col_count: + * if (name_col >= 0) and (col_index == name_col): + * col_index += 1 # <<<<<<<<<<<<<< + * continue + * if (at_col >= 0) and (col_index == at_col): + */ + __pyx_v_col_index = (__pyx_v_col_index + 1); + + /* "src/questdb/pandas_helpers.pxi":160 + * if (name_col >= 0) and (col_index == name_col): + * col_index += 1 + * continue # <<<<<<<<<<<<<< + * if (at_col >= 0) and (col_index == at_col): + * col_index += 1 + */ + goto __pyx_L3_continue; + + /* "src/questdb/pandas_helpers.pxi":158 + * cdef size_t sym_len = symbol_indices.size + * while col_index < col_count: + * if (name_col >= 0) and (col_index == name_col): # <<<<<<<<<<<<<< + * col_index += 1 + * continue + */ + } + + /* "src/questdb/pandas_helpers.pxi":161 + * col_index += 1 + * continue + * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< + * col_index += 1 + * continue + */ + __pyx_t_3 = ((__pyx_v_at_col >= 0) != 0); + if (__pyx_t_3) { + } else { + __pyx_t_2 = __pyx_t_3; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_3 = ((__pyx_v_col_index == ((size_t)__pyx_v_at_col)) != 0); + __pyx_t_2 = __pyx_t_3; + __pyx_L9_bool_binop_done:; + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":162 + * continue + * if (at_col >= 0) and (col_index == at_col): + * col_index += 1 # <<<<<<<<<<<<<< + * continue + * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: + */ + __pyx_v_col_index = (__pyx_v_col_index + 1); + + /* "src/questdb/pandas_helpers.pxi":163 + * if (at_col >= 0) and (col_index == at_col): + * col_index += 1 + * continue # <<<<<<<<<<<<<< + * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: + * sym_index += 1 + */ + goto __pyx_L3_continue; + + /* "src/questdb/pandas_helpers.pxi":161 + * col_index += 1 + * continue + * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< + * col_index += 1 + * continue + */ + } + + /* "src/questdb/pandas_helpers.pxi":164 + * col_index += 1 + * continue + * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: # <<<<<<<<<<<<<< + * sym_index += 1 + * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: + */ + while (1) { + __pyx_t_3 = ((__pyx_v_sym_index < __pyx_v_sym_len) != 0); + if (__pyx_t_3) { + } else { + __pyx_t_2 = __pyx_t_3; + goto __pyx_L13_bool_binop_done; + } + __pyx_t_3 = (((__pyx_v_symbol_indices->d[__pyx_v_sym_index]) < __pyx_v_col_index) != 0); + __pyx_t_2 = __pyx_t_3; + __pyx_L13_bool_binop_done:; + if (!__pyx_t_2) break; + + /* "src/questdb/pandas_helpers.pxi":165 + * continue + * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: + * sym_index += 1 # <<<<<<<<<<<<<< + * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: + * col_index += 1 + */ + __pyx_v_sym_index = (__pyx_v_sym_index + 1); + } + + /* "src/questdb/pandas_helpers.pxi":166 + * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: + * sym_index += 1 + * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: # <<<<<<<<<<<<<< + * col_index += 1 + * continue + */ + __pyx_t_3 = ((__pyx_v_sym_index < __pyx_v_sym_len) != 0); + if (__pyx_t_3) { + } else { + __pyx_t_2 = __pyx_t_3; + goto __pyx_L16_bool_binop_done; + } + __pyx_t_3 = (((__pyx_v_symbol_indices->d[__pyx_v_sym_index]) == __pyx_v_col_index) != 0); + __pyx_t_2 = __pyx_t_3; + __pyx_L16_bool_binop_done:; + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":167 + * sym_index += 1 + * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: + * col_index += 1 # <<<<<<<<<<<<<< + * continue + * size_t_vec_push(field_indices_out, col_index) + */ + __pyx_v_col_index = (__pyx_v_col_index + 1); + + /* "src/questdb/pandas_helpers.pxi":168 + * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: + * col_index += 1 + * continue # <<<<<<<<<<<<<< + * size_t_vec_push(field_indices_out, col_index) + * col_index += 1 + */ + goto __pyx_L3_continue; + + /* "src/questdb/pandas_helpers.pxi":166 + * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: + * sym_index += 1 + * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: # <<<<<<<<<<<<<< + * col_index += 1 + * continue + */ + } + + /* "src/questdb/pandas_helpers.pxi":169 + * col_index += 1 + * continue + * size_t_vec_push(field_indices_out, col_index) # <<<<<<<<<<<<<< + * col_index += 1 + * return 0 + */ + __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_v_field_indices_out, __pyx_v_col_index); + + /* "src/questdb/pandas_helpers.pxi":170 + * continue + * size_t_vec_push(field_indices_out, col_index) + * col_index += 1 # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_v_col_index = (__pyx_v_col_index + 1); + __pyx_L3_continue:; + } + + /* "src/questdb/pandas_helpers.pxi":171 + * size_t_vec_push(field_indices_out, col_index) + * col_index += 1 + * return 0 # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":141 + * + * + * cdef int _pandas_resolve_fields( # <<<<<<<<<<<<<< + * int name_col, + * const size_t_vec* symbol_indices, + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":174 + * + * + * cdef bint _pandas_resolve_col_names( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * object data, + */ + +static int __pyx_f_7questdb_7ingress__pandas_resolve_col_names(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_data, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_symbol_indices, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_field_indices, __pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_symbol_names_out, __pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_field_names_out) { + struct line_sender_column_name __pyx_v_c_name; + size_t __pyx_v_col_index; + int __pyx_r; + __Pyx_RefNannyDeclarations + size_t __pyx_t_1; + size_t __pyx_t_2; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_resolve_col_names", 0); + + /* "src/questdb/pandas_helpers.pxi":183 + * cdef line_sender_column_name c_name + * cdef size_t col_index + * for col_index in range(symbol_indices.size): # <<<<<<<<<<<<<< + * col_index = symbol_indices.d[col_index] + * str_to_column_name(b, data.columns[col_index], &c_name) + */ + __pyx_t_1 = __pyx_v_symbol_indices->size; + __pyx_t_2 = __pyx_t_1; + for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { + __pyx_v_col_index = __pyx_t_3; + + /* "src/questdb/pandas_helpers.pxi":184 + * cdef size_t col_index + * for col_index in range(symbol_indices.size): + * col_index = symbol_indices.d[col_index] # <<<<<<<<<<<<<< + * str_to_column_name(b, data.columns[col_index], &c_name) + * column_name_vec_push(symbol_names_out, c_name) + */ + __pyx_v_col_index = (__pyx_v_symbol_indices->d[__pyx_v_col_index]); + + /* "src/questdb/pandas_helpers.pxi":185 + * for col_index in range(symbol_indices.size): + * col_index = symbol_indices.d[col_index] + * str_to_column_name(b, data.columns[col_index], &c_name) # <<<<<<<<<<<<<< + * column_name_vec_push(symbol_names_out, c_name) + * for col_index in range(field_indices.size): + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 185, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 185, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (!(likely(PyUnicode_CheckExact(__pyx_t_5))||((__pyx_t_5) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_5)->tp_name), 0))) __PYX_ERR(2, 185, __pyx_L1_error) + __pyx_t_6 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_v_b, ((PyObject*)__pyx_t_5), (&__pyx_v_c_name)); if (unlikely(__pyx_t_6 == ((int)0))) __PYX_ERR(2, 185, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "src/questdb/pandas_helpers.pxi":186 + * col_index = symbol_indices.d[col_index] + * str_to_column_name(b, data.columns[col_index], &c_name) + * column_name_vec_push(symbol_names_out, c_name) # <<<<<<<<<<<<<< + * for col_index in range(field_indices.size): + * col_index = field_indices.d[col_index] + */ + __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_v_symbol_names_out, __pyx_v_c_name); + } + + /* "src/questdb/pandas_helpers.pxi":187 + * str_to_column_name(b, data.columns[col_index], &c_name) + * column_name_vec_push(symbol_names_out, c_name) + * for col_index in range(field_indices.size): # <<<<<<<<<<<<<< + * col_index = field_indices.d[col_index] + * str_to_column_name(b, data.columns[col_index], &c_name) + */ + __pyx_t_1 = __pyx_v_field_indices->size; + __pyx_t_2 = __pyx_t_1; + for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { + __pyx_v_col_index = __pyx_t_3; + + /* "src/questdb/pandas_helpers.pxi":188 + * column_name_vec_push(symbol_names_out, c_name) + * for col_index in range(field_indices.size): + * col_index = field_indices.d[col_index] # <<<<<<<<<<<<<< + * str_to_column_name(b, data.columns[col_index], &c_name) + * column_name_vec_push(field_names_out, c_name) + */ + __pyx_v_col_index = (__pyx_v_field_indices->d[__pyx_v_col_index]); + + /* "src/questdb/pandas_helpers.pxi":189 + * for col_index in range(field_indices.size): + * col_index = field_indices.d[col_index] + * str_to_column_name(b, data.columns[col_index], &c_name) # <<<<<<<<<<<<<< + * column_name_vec_push(field_names_out, c_name) + * return True + */ + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_5, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (!(likely(PyUnicode_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 189, __pyx_L1_error) + __pyx_t_6 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_v_b, ((PyObject*)__pyx_t_4), (&__pyx_v_c_name)); if (unlikely(__pyx_t_6 == ((int)0))) __PYX_ERR(2, 189, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "src/questdb/pandas_helpers.pxi":190 + * col_index = field_indices.d[col_index] + * str_to_column_name(b, data.columns[col_index], &c_name) + * column_name_vec_push(field_names_out, c_name) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_v_field_names_out, __pyx_v_c_name); + } + + /* "src/questdb/pandas_helpers.pxi":191 + * str_to_column_name(b, data.columns[col_index], &c_name) + * column_name_vec_push(field_names_out, c_name) + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":174 + * + * + * cdef bint _pandas_resolve_col_names( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * object data, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("questdb.ingress._pandas_resolve_col_names", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":194 + * + * + * cdef bint _bind_col_index( # <<<<<<<<<<<<<< + * str arg_name, int col_num, size_t col_count, + * size_t* col_index) except False: + */ + +static int __pyx_f_7questdb_7ingress__bind_col_index(PyObject *__pyx_v_arg_name, int __pyx_v_col_num, size_t __pyx_v_col_count, size_t *__pyx_v_col_index) { + int __pyx_v_bad; + int __pyx_v_orig_col_num; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + Py_ssize_t __pyx_t_4; + Py_UCS4 __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_bind_col_index", 0); + + /* "src/questdb/pandas_helpers.pxi":202 + * positive indicies. + * """ + * cdef bint bad = False # <<<<<<<<<<<<<< + * cdef int orig_col_num = col_num + * if col_num < 0: + */ + __pyx_v_bad = 0; + + /* "src/questdb/pandas_helpers.pxi":203 + * """ + * cdef bint bad = False + * cdef int orig_col_num = col_num # <<<<<<<<<<<<<< + * if col_num < 0: + * col_num += col_count # Try convert negative offsets to positive ones. + */ + __pyx_v_orig_col_num = __pyx_v_col_num; + + /* "src/questdb/pandas_helpers.pxi":204 + * cdef bint bad = False + * cdef int orig_col_num = col_num + * if col_num < 0: # <<<<<<<<<<<<<< + * col_num += col_count # Try convert negative offsets to positive ones. + * if col_num < 0: + */ + __pyx_t_1 = ((__pyx_v_col_num < 0) != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":205 + * cdef int orig_col_num = col_num + * if col_num < 0: + * col_num += col_count # Try convert negative offsets to positive ones. # <<<<<<<<<<<<<< + * if col_num < 0: + * bad = True + */ + __pyx_v_col_num = (__pyx_v_col_num + __pyx_v_col_count); + + /* "src/questdb/pandas_helpers.pxi":204 + * cdef bint bad = False + * cdef int orig_col_num = col_num + * if col_num < 0: # <<<<<<<<<<<<<< + * col_num += col_count # Try convert negative offsets to positive ones. + * if col_num < 0: + */ + } + + /* "src/questdb/pandas_helpers.pxi":206 + * if col_num < 0: + * col_num += col_count # Try convert negative offsets to positive ones. + * if col_num < 0: # <<<<<<<<<<<<<< + * bad = True + * if (not bad) and (col_num >= col_count): + */ + __pyx_t_1 = ((__pyx_v_col_num < 0) != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":207 + * col_num += col_count # Try convert negative offsets to positive ones. + * if col_num < 0: + * bad = True # <<<<<<<<<<<<<< + * if (not bad) and (col_num >= col_count): + * bad = True + */ + __pyx_v_bad = 1; + + /* "src/questdb/pandas_helpers.pxi":206 + * if col_num < 0: + * col_num += col_count # Try convert negative offsets to positive ones. + * if col_num < 0: # <<<<<<<<<<<<<< + * bad = True + * if (not bad) and (col_num >= col_count): + */ + } + + /* "src/questdb/pandas_helpers.pxi":208 + * if col_num < 0: + * bad = True + * if (not bad) and (col_num >= col_count): # <<<<<<<<<<<<<< + * bad = True + * if bad: + */ + __pyx_t_2 = ((!(__pyx_v_bad != 0)) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_2 = ((((size_t)__pyx_v_col_num) >= __pyx_v_col_count) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L6_bool_binop_done:; + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":209 + * bad = True + * if (not bad) and (col_num >= col_count): + * bad = True # <<<<<<<<<<<<<< + * if bad: + * raise IndexError( + */ + __pyx_v_bad = 1; + + /* "src/questdb/pandas_helpers.pxi":208 + * if col_num < 0: + * bad = True + * if (not bad) and (col_num >= col_count): # <<<<<<<<<<<<<< + * bad = True + * if bad: + */ + } + + /* "src/questdb/pandas_helpers.pxi":210 + * if (not bad) and (col_num >= col_count): + * bad = True + * if bad: # <<<<<<<<<<<<<< + * raise IndexError( + * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') + */ + __pyx_t_1 = (__pyx_v_bad != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":212 + * if bad: + * raise IndexError( + * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') # <<<<<<<<<<<<<< + * col_index[0] = col_num + * return True + */ + __pyx_t_3 = PyTuple_New(5); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_Bad_argument); + __pyx_t_4 += 14; + __Pyx_GIVEREF(__pyx_kp_u_Bad_argument); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Bad_argument); + __pyx_t_6 = __Pyx_PyUnicode_Unicode(__pyx_v_arg_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__5); + __pyx_t_4 += 3; + __Pyx_GIVEREF(__pyx_kp_u__5); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__5); + __pyx_t_6 = __Pyx_PyUnicode_From_int(__pyx_v_orig_col_num, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u_index_out_of_range); + __pyx_t_4 += 19; + __Pyx_GIVEREF(__pyx_kp_u_index_out_of_range); + PyTuple_SET_ITEM(__pyx_t_3, 4, __pyx_kp_u_index_out_of_range); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 5, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":211 + * bad = True + * if bad: + * raise IndexError( # <<<<<<<<<<<<<< + * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') + * col_index[0] = col_num + */ + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IndexError, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 211, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 211, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":210 + * if (not bad) and (col_num >= col_count): + * bad = True + * if bad: # <<<<<<<<<<<<<< + * raise IndexError( + * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') + */ + } + + /* "src/questdb/pandas_helpers.pxi":213 + * raise IndexError( + * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') + * col_index[0] = col_num # <<<<<<<<<<<<<< + * return True + * + */ + (__pyx_v_col_index[0]) = ((size_t)__pyx_v_col_num); + + /* "src/questdb/pandas_helpers.pxi":214 + * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') + * col_index[0] = col_num + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":194 + * + * + * cdef bint _bind_col_index( # <<<<<<<<<<<<<< + * str arg_name, int col_num, size_t col_count, + * size_t* col_index) except False: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("questdb.ingress._bind_col_index", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":217 + * + * + * cdef object _pandas_column_is_str(object data, int col_index): # <<<<<<<<<<<<<< + * """ + * Return True if the column at `col_index` is a string column. + */ + +static PyObject *__pyx_f_7questdb_7ingress__pandas_column_is_str(PyObject *__pyx_v_data, int __pyx_v_col_index) { + PyObject *__pyx_v_col_kind = 0; + PyObject *__pyx_v_col = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_t_4; + Py_ssize_t __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_column_is_str", 0); + + /* "src/questdb/pandas_helpers.pxi":224 + * cdef str col_kind + * cdef object col + * col_kind = data.dtypes[col_index].kind # <<<<<<<<<<<<<< + * if col_kind == 'S': # string, string[pyarrow] + * return True + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_col_index, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_kind); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 224, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 224, __pyx_L1_error) + __pyx_v_col_kind = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "src/questdb/pandas_helpers.pxi":225 + * cdef object col + * col_kind = data.dtypes[col_index].kind + * if col_kind == 'S': # string, string[pyarrow] # <<<<<<<<<<<<<< + * return True + * elif col_kind == 'O': # object + */ + __pyx_t_3 = (__Pyx_PyUnicode_Equals(__pyx_v_col_kind, __pyx_n_u_S, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(2, 225, __pyx_L1_error) + __pyx_t_4 = (__pyx_t_3 != 0); + if (__pyx_t_4) { + + /* "src/questdb/pandas_helpers.pxi":226 + * col_kind = data.dtypes[col_index].kind + * if col_kind == 'S': # string, string[pyarrow] + * return True # <<<<<<<<<<<<<< + * elif col_kind == 'O': # object + * if len(data.index) == 0: + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_True); + __pyx_r = Py_True; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":225 + * cdef object col + * col_kind = data.dtypes[col_index].kind + * if col_kind == 'S': # string, string[pyarrow] # <<<<<<<<<<<<<< + * return True + * elif col_kind == 'O': # object + */ + } + + /* "src/questdb/pandas_helpers.pxi":227 + * if col_kind == 'S': # string, string[pyarrow] + * return True + * elif col_kind == 'O': # object # <<<<<<<<<<<<<< + * if len(data.index) == 0: + * return True + */ + __pyx_t_4 = (__Pyx_PyUnicode_Equals(__pyx_v_col_kind, __pyx_n_u_O, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 227, __pyx_L1_error) + __pyx_t_3 = (__pyx_t_4 != 0); + if (__pyx_t_3) { + + /* "src/questdb/pandas_helpers.pxi":228 + * return True + * elif col_kind == 'O': # object + * if len(data.index) == 0: # <<<<<<<<<<<<<< + * return True + * else: + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 228, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(2, 228, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_3 = ((__pyx_t_5 == 0) != 0); + if (__pyx_t_3) { + + /* "src/questdb/pandas_helpers.pxi":229 + * elif col_kind == 'O': # object + * if len(data.index) == 0: + * return True # <<<<<<<<<<<<<< + * else: + * # We only check the first element and hope for the rest. + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_True); + __pyx_r = Py_True; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":228 + * return True + * elif col_kind == 'O': # object + * if len(data.index) == 0: # <<<<<<<<<<<<<< + * return True + * else: + */ + } + + /* "src/questdb/pandas_helpers.pxi":233 + * # We only check the first element and hope for the rest. + * # We also accept None as a null value. + * col = data.iloc[0, col_index] # <<<<<<<<<<<<<< + * return (col is None) or isinstance(col, str) + * else: + */ + /*else*/ { + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_iloc); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 233, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_col_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 233, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 233, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_int_0); + __Pyx_GIVEREF(__pyx_int_0); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_int_0); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2); + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 233, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_col = __pyx_t_2; + __pyx_t_2 = 0; + + /* "src/questdb/pandas_helpers.pxi":234 + * # We also accept None as a null value. + * col = data.iloc[0, col_index] + * return (col is None) or isinstance(col, str) # <<<<<<<<<<<<<< + * else: + * return False + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = (__pyx_v_col == Py_None); + if (!__pyx_t_3) { + } else { + __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 234, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_3 = PyUnicode_Check(__pyx_v_col); + __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 234, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = __pyx_t_6; + __pyx_t_6 = 0; + __pyx_L5_bool_binop_done:; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + } + + /* "src/questdb/pandas_helpers.pxi":227 + * if col_kind == 'S': # string, string[pyarrow] + * return True + * elif col_kind == 'O': # object # <<<<<<<<<<<<<< + * if len(data.index) == 0: + * return True + */ + } + + /* "src/questdb/pandas_helpers.pxi":236 + * return (col is None) or isinstance(col, str) + * else: + * return False # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_False); + __pyx_r = Py_False; + goto __pyx_L0; + } + + /* "src/questdb/pandas_helpers.pxi":217 + * + * + * cdef object _pandas_column_is_str(object data, int col_index): # <<<<<<<<<<<<<< + * """ + * Return True if the column at `col_index` is a string column. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("questdb.ingress._pandas_column_is_str", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_col_kind); + __Pyx_XDECREF(__pyx_v_col); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":239 + * + * + * cdef object _pandas_check_column_is_str( # <<<<<<<<<<<<<< + * object data, size_t col_index, str err_msg_prefix, object col_name): + * cdef str col_kind + */ + +static PyObject *__pyx_f_7questdb_7ingress__pandas_check_column_is_str(PyObject *__pyx_v_data, size_t __pyx_v_col_index, PyObject *__pyx_v_err_msg_prefix, PyObject *__pyx_v_col_name) { + PyObject *__pyx_v_col_kind = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_t_4; + Py_ssize_t __pyx_t_5; + Py_UCS4 __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_check_column_is_str", 0); + + /* "src/questdb/pandas_helpers.pxi":242 + * object data, size_t col_index, str err_msg_prefix, object col_name): + * cdef str col_kind + * col_kind = data.dtypes[col_index].kind # <<<<<<<<<<<<<< + * if col_kind in 'SO': + * if not _pandas_column_is_str(data, col_index): + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_kind); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 242, __pyx_L1_error) + __pyx_v_col_kind = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "src/questdb/pandas_helpers.pxi":243 + * cdef str col_kind + * col_kind = data.dtypes[col_index].kind + * if col_kind in 'SO': # <<<<<<<<<<<<<< + * if not _pandas_column_is_str(data, col_index): + * raise TypeError( + */ + __pyx_t_3 = (__Pyx_PyUnicode_ContainsTF(__pyx_v_col_kind, __pyx_n_u_SO, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(2, 243, __pyx_L1_error) + __pyx_t_4 = (__pyx_t_3 != 0); + if (likely(__pyx_t_4)) { + + /* "src/questdb/pandas_helpers.pxi":244 + * col_kind = data.dtypes[col_index].kind + * if col_kind in 'SO': + * if not _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< + * raise TypeError( + * err_msg_prefix + + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_column_is_str(__pyx_v_data, __pyx_v_col_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 244, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_3 = ((!__pyx_t_4) != 0); + if (unlikely(__pyx_t_3)) { + + /* "src/questdb/pandas_helpers.pxi":246 + * if not _pandas_column_is_str(data, col_index): + * raise TypeError( + * err_msg_prefix + # <<<<<<<<<<<<<< + * 'Found non-string value ' + + * f'in column {col_name!r}.') + */ + __pyx_t_1 = __Pyx_PyUnicode_ConcatSafe(__pyx_v_err_msg_prefix, __pyx_kp_u_Found_non_string_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "src/questdb/pandas_helpers.pxi":248 + * err_msg_prefix + + * 'Found non-string value ' + + * f'in column {col_name!r}.') # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = 0; + __pyx_t_6 = 127; + __Pyx_INCREF(__pyx_kp_u_in_column); + __pyx_t_5 += 10; + __Pyx_GIVEREF(__pyx_kp_u_in_column); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_in_column); + __pyx_t_7 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_col_name), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6; + __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_INCREF(__pyx_kp_u__6); + __pyx_t_5 += 1; + __Pyx_GIVEREF(__pyx_kp_u__6); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); + __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "src/questdb/pandas_helpers.pxi":247 + * raise TypeError( + * err_msg_prefix + + * 'Found non-string value ' + # <<<<<<<<<<<<<< + * f'in column {col_name!r}.') + * else: + */ + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 247, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "src/questdb/pandas_helpers.pxi":245 + * if col_kind in 'SO': + * if not _pandas_column_is_str(data, col_index): + * raise TypeError( # <<<<<<<<<<<<<< + * err_msg_prefix + + * 'Found non-string value ' + + */ + __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_7, 0, 0, 0); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __PYX_ERR(2, 245, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":244 + * col_kind = data.dtypes[col_index].kind + * if col_kind in 'SO': + * if not _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< + * raise TypeError( + * err_msg_prefix + + */ + } + + /* "src/questdb/pandas_helpers.pxi":243 + * cdef str col_kind + * col_kind = data.dtypes[col_index].kind + * if col_kind in 'SO': # <<<<<<<<<<<<<< + * if not _pandas_column_is_str(data, col_index): + * raise TypeError( + */ + goto __pyx_L3; + } + + /* "src/questdb/pandas_helpers.pxi":250 + * f'in column {col_name!r}.') + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * err_msg_prefix + + * f'Bad dtype `{data.dtypes[col_index]}` for the ' + + */ + /*else*/ { + + /* "src/questdb/pandas_helpers.pxi":252 + * raise TypeError( + * err_msg_prefix + + * f'Bad dtype `{data.dtypes[col_index]}` for the ' + # <<<<<<<<<<<<<< + * f'{col_name!r} column: Must be a strings column.') + * + */ + __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_5 = 0; + __pyx_t_6 = 127; + __Pyx_INCREF(__pyx_kp_u_Bad_dtype); + __pyx_t_5 += 11; + __Pyx_GIVEREF(__pyx_kp_u_Bad_dtype); + PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_kp_u_Bad_dtype); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_6; + __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_2); + __pyx_t_2 = 0; + __Pyx_INCREF(__pyx_kp_u_for_the); + __pyx_t_5 += 10; + __Pyx_GIVEREF(__pyx_kp_u_for_the); + PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_kp_u_for_the); + __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_7, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "src/questdb/pandas_helpers.pxi":251 + * else: + * raise TypeError( + * err_msg_prefix + # <<<<<<<<<<<<<< + * f'Bad dtype `{data.dtypes[col_index]}` for the ' + + * f'{col_name!r} column: Must be a strings column.') + */ + __pyx_t_7 = __Pyx_PyUnicode_ConcatSafe(__pyx_v_err_msg_prefix, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "src/questdb/pandas_helpers.pxi":253 + * err_msg_prefix + + * f'Bad dtype `{data.dtypes[col_index]}` for the ' + + * f'{col_name!r} column: Must be a strings column.') # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_2 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_col_name), __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 253, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_kp_u_column_Must_be_a_strings_column); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 253, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "src/questdb/pandas_helpers.pxi":252 + * raise TypeError( + * err_msg_prefix + + * f'Bad dtype `{data.dtypes[col_index]}` for the ' + # <<<<<<<<<<<<<< + * f'{col_name!r} column: Must be a strings column.') + * + */ + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "src/questdb/pandas_helpers.pxi":250 + * f'in column {col_name!r}.') + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * err_msg_prefix + + * f'Bad dtype `{data.dtypes[col_index]}` for the ' + + */ + __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 250, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(2, 250, __pyx_L1_error) + } + __pyx_L3:; + + /* "src/questdb/pandas_helpers.pxi":239 + * + * + * cdef object _pandas_check_column_is_str( # <<<<<<<<<<<<<< + * object data, size_t col_index, str err_msg_prefix, object col_name): + * cdef str col_kind + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress._pandas_check_column_is_str", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_col_kind); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":256 + * + * + * cdef int _pandas_resolve_symbols( # <<<<<<<<<<<<<< + * object data, + * ssize_t table_name_col, + */ + +static int __pyx_f_7questdb_7ingress__pandas_resolve_symbols(PyObject *__pyx_v_data, Py_ssize_t __pyx_v_table_name_col, Py_ssize_t __pyx_v_at_col, PyObject *__pyx_v_symbols, size_t __pyx_v_col_count, __pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_symbol_indices_out) { + size_t __pyx_v_col_index; + PyObject *__pyx_v_symbol = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + size_t __pyx_t_3; + size_t __pyx_t_4; + size_t __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + Py_ssize_t __pyx_t_8; + PyObject *(*__pyx_t_9)(PyObject *); + PyObject *__pyx_t_10 = NULL; + int __pyx_t_11; + PyObject *__pyx_t_12 = NULL; + Py_ssize_t __pyx_t_13; + Py_UCS4 __pyx_t_14; + PyObject *__pyx_t_15 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_resolve_symbols", 0); + + /* "src/questdb/pandas_helpers.pxi":267 + * Returns the length of the vec. + * """ + * cdef size_t col_index = 0 # <<<<<<<<<<<<<< + * cdef object symbol + * if symbols is False: + */ + __pyx_v_col_index = 0; + + /* "src/questdb/pandas_helpers.pxi":269 + * cdef size_t col_index = 0 + * cdef object symbol + * if symbols is False: # <<<<<<<<<<<<<< + * return 0 + * elif symbols is True: + */ + __pyx_t_1 = (__pyx_v_symbols == Py_False); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":270 + * cdef object symbol + * if symbols is False: + * return 0 # <<<<<<<<<<<<<< + * elif symbols is True: + * for col_index in range(col_count): + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":269 + * cdef size_t col_index = 0 + * cdef object symbol + * if symbols is False: # <<<<<<<<<<<<<< + * return 0 + * elif symbols is True: + */ + } + + /* "src/questdb/pandas_helpers.pxi":271 + * if symbols is False: + * return 0 + * elif symbols is True: # <<<<<<<<<<<<<< + * for col_index in range(col_count): + * if _pandas_column_is_str(data, col_index): + */ + __pyx_t_2 = (__pyx_v_symbols == Py_True); + __pyx_t_1 = (__pyx_t_2 != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":272 + * return 0 + * elif symbols is True: + * for col_index in range(col_count): # <<<<<<<<<<<<<< + * if _pandas_column_is_str(data, col_index): + * size_t_vec_push(symbol_indices_out, col_index) + */ + __pyx_t_3 = __pyx_v_col_count; + __pyx_t_4 = __pyx_t_3; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_col_index = __pyx_t_5; + + /* "src/questdb/pandas_helpers.pxi":273 + * elif symbols is True: + * for col_index in range(col_count): + * if _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< + * size_t_vec_push(symbol_indices_out, col_index) + * return 0 + */ + __pyx_t_6 = __pyx_f_7questdb_7ingress__pandas_column_is_str(__pyx_v_data, __pyx_v_col_index); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 273, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 273, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":274 + * for col_index in range(col_count): + * if _pandas_column_is_str(data, col_index): + * size_t_vec_push(symbol_indices_out, col_index) # <<<<<<<<<<<<<< + * return 0 + * else: + */ + __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_v_symbol_indices_out, __pyx_v_col_index); + + /* "src/questdb/pandas_helpers.pxi":273 + * elif symbols is True: + * for col_index in range(col_count): + * if _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< + * size_t_vec_push(symbol_indices_out, col_index) + * return 0 + */ + } + } + + /* "src/questdb/pandas_helpers.pxi":275 + * if _pandas_column_is_str(data, col_index): + * size_t_vec_push(symbol_indices_out, col_index) + * return 0 # <<<<<<<<<<<<<< + * else: + * if not isinstance(symbols, (tuple, list)): + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":271 + * if symbols is False: + * return 0 + * elif symbols is True: # <<<<<<<<<<<<<< + * for col_index in range(col_count): + * if _pandas_column_is_str(data, col_index): + */ + } + + /* "src/questdb/pandas_helpers.pxi":277 + * return 0 + * else: + * if not isinstance(symbols, (tuple, list)): # <<<<<<<<<<<<<< + * raise TypeError( + * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + */ + /*else*/ { + __pyx_t_2 = PyTuple_Check(__pyx_v_symbols); + __pyx_t_7 = (__pyx_t_2 != 0); + if (!__pyx_t_7) { + } else { + __pyx_t_1 = __pyx_t_7; + goto __pyx_L8_bool_binop_done; + } + __pyx_t_7 = PyList_Check(__pyx_v_symbols); + __pyx_t_2 = (__pyx_t_7 != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L8_bool_binop_done:; + __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); + if (unlikely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":278 + * else: + * if not isinstance(symbols, (tuple, list)): + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + * 'of column names (str) or indices (int).') + */ + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(2, 278, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":277 + * return 0 + * else: + * if not isinstance(symbols, (tuple, list)): # <<<<<<<<<<<<<< + * raise TypeError( + * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + */ + } + + /* "src/questdb/pandas_helpers.pxi":281 + * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + * 'of column names (str) or indices (int).') + * for symbol in symbols: # <<<<<<<<<<<<<< + * if isinstance(symbol, str): + * _pandas_get_loc(data, symbol, 'symbols', &col_index) + */ + if (likely(PyList_CheckExact(__pyx_v_symbols)) || PyTuple_CheckExact(__pyx_v_symbols)) { + __pyx_t_6 = __pyx_v_symbols; __Pyx_INCREF(__pyx_t_6); __pyx_t_8 = 0; + __pyx_t_9 = NULL; + } else { + __pyx_t_8 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_v_symbols); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_9 = Py_TYPE(__pyx_t_6)->tp_iternext; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 281, __pyx_L1_error) + } + for (;;) { + if (likely(!__pyx_t_9)) { + if (likely(PyList_CheckExact(__pyx_t_6))) { + if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_6)) break; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_10 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_10); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(2, 281, __pyx_L1_error) + #else + __pyx_t_10 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + #endif + } else { + if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_6)) break; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_10); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(2, 281, __pyx_L1_error) + #else + __pyx_t_10 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 281, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + #endif + } + } else { + __pyx_t_10 = __pyx_t_9(__pyx_t_6); + if (unlikely(!__pyx_t_10)) { + PyObject* exc_type = PyErr_Occurred(); + if (exc_type) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); + else __PYX_ERR(2, 281, __pyx_L1_error) + } + break; + } + __Pyx_GOTREF(__pyx_t_10); + } + __Pyx_XDECREF_SET(__pyx_v_symbol, __pyx_t_10); + __pyx_t_10 = 0; + + /* "src/questdb/pandas_helpers.pxi":282 + * 'of column names (str) or indices (int).') + * for symbol in symbols: + * if isinstance(symbol, str): # <<<<<<<<<<<<<< + * _pandas_get_loc(data, symbol, 'symbols', &col_index) + * elif isinstance(symbol, int): + */ + __pyx_t_2 = PyUnicode_Check(__pyx_v_symbol); + __pyx_t_1 = (__pyx_t_2 != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":283 + * for symbol in symbols: + * if isinstance(symbol, str): + * _pandas_get_loc(data, symbol, 'symbols', &col_index) # <<<<<<<<<<<<<< + * elif isinstance(symbol, int): + * _bind_col_index('symbol', symbol, col_count, &col_index) + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_symbol))||((__pyx_v_symbol) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_symbol)->tp_name), 0))) __PYX_ERR(2, 283, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_get_loc(__pyx_v_data, ((PyObject*)__pyx_v_symbol), __pyx_n_u_symbols, (&__pyx_v_col_index)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 283, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":282 + * 'of column names (str) or indices (int).') + * for symbol in symbols: + * if isinstance(symbol, str): # <<<<<<<<<<<<<< + * _pandas_get_loc(data, symbol, 'symbols', &col_index) + * elif isinstance(symbol, int): + */ + goto __pyx_L12; + } + + /* "src/questdb/pandas_helpers.pxi":284 + * if isinstance(symbol, str): + * _pandas_get_loc(data, symbol, 'symbols', &col_index) + * elif isinstance(symbol, int): # <<<<<<<<<<<<<< + * _bind_col_index('symbol', symbol, col_count, &col_index) + * else: + */ + __pyx_t_1 = PyInt_Check(__pyx_v_symbol); + __pyx_t_2 = (__pyx_t_1 != 0); + if (likely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":285 + * _pandas_get_loc(data, symbol, 'symbols', &col_index) + * elif isinstance(symbol, int): + * _bind_col_index('symbol', symbol, col_count, &col_index) # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_symbol); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 285, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress__bind_col_index(__pyx_n_u_symbol, __pyx_t_11, __pyx_v_col_count, (&__pyx_v_col_index)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 285, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":284 + * if isinstance(symbol, str): + * _pandas_get_loc(data, symbol, 'symbols', &col_index) + * elif isinstance(symbol, int): # <<<<<<<<<<<<<< + * _bind_col_index('symbol', symbol, col_count, &col_index) + * else: + */ + goto __pyx_L12; + } + + /* "src/questdb/pandas_helpers.pxi":287 + * _bind_col_index('symbol', symbol, col_count, &col_index) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `symbols`: Elements must ' + + * 'be a column name (str) or index (int).') + */ + /*else*/ { + __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_Raise(__pyx_t_10, 0, 0, 0); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __PYX_ERR(2, 287, __pyx_L1_error) + } + __pyx_L12:; + + /* "src/questdb/pandas_helpers.pxi":290 + * f'Bad argument `symbols`: Elements must ' + + * 'be a column name (str) or index (int).') + * if (table_name_col >= 0) and (col_index == table_name_col): # <<<<<<<<<<<<<< + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the same column ' + + */ + __pyx_t_1 = ((__pyx_v_table_name_col >= 0) != 0); + if (__pyx_t_1) { + } else { + __pyx_t_2 = __pyx_t_1; + goto __pyx_L14_bool_binop_done; + } + __pyx_t_1 = ((__pyx_v_col_index == ((size_t)__pyx_v_table_name_col)) != 0); + __pyx_t_2 = __pyx_t_1; + __pyx_L14_bool_binop_done:; + if (unlikely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":293 + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the same column ' + + * f'{symbol!r} as both the table_name and as a symbol.') # <<<<<<<<<<<<<< + * if (at_col >= 0) and (col_index == at_col): + * raise ValueError( + */ + __pyx_t_10 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_symbol), __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 293, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_12 = __Pyx_PyUnicode_Concat(__pyx_t_10, __pyx_kp_u_as_both_the_table_name_and_as_a); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 293, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "src/questdb/pandas_helpers.pxi":292 + * if (table_name_col >= 0) and (col_index == table_name_col): + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the same column ' + # <<<<<<<<<<<<<< + * f'{symbol!r} as both the table_name and as a symbol.') + * if (at_col >= 0) and (col_index == at_col): + */ + __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_argument_symbols_Cannot_use, __pyx_t_12); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 292, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + + /* "src/questdb/pandas_helpers.pxi":291 + * 'be a column name (str) or index (int).') + * if (table_name_col >= 0) and (col_index == table_name_col): + * raise ValueError( # <<<<<<<<<<<<<< + * f'Bad argument `symbols`: Cannot use the same column ' + + * f'{symbol!r} as both the table_name and as a symbol.') + */ + __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_10); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 291, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_Raise(__pyx_t_12, 0, 0, 0); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __PYX_ERR(2, 291, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":290 + * f'Bad argument `symbols`: Elements must ' + + * 'be a column name (str) or index (int).') + * if (table_name_col >= 0) and (col_index == table_name_col): # <<<<<<<<<<<<<< + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the same column ' + + */ + } + + /* "src/questdb/pandas_helpers.pxi":294 + * f'Bad argument `symbols`: Cannot use the same column ' + + * f'{symbol!r} as both the table_name and as a symbol.') + * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the `at` column ' + + */ + __pyx_t_1 = ((__pyx_v_at_col >= 0) != 0); + if (__pyx_t_1) { + } else { + __pyx_t_2 = __pyx_t_1; + goto __pyx_L17_bool_binop_done; + } + __pyx_t_1 = ((__pyx_v_col_index == ((size_t)__pyx_v_at_col)) != 0); + __pyx_t_2 = __pyx_t_1; + __pyx_L17_bool_binop_done:; + if (unlikely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":297 + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the `at` column ' + + * f'({data.columns[at_col]!r}) as a symbol column.') # <<<<<<<<<<<<<< + * _pandas_check_column_is_str( + * data, + */ + __pyx_t_12 = PyTuple_New(3); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_13 = 0; + __pyx_t_14 = 127; + __Pyx_INCREF(__pyx_kp_u__9); + __pyx_t_13 += 1; + __Pyx_GIVEREF(__pyx_kp_u__9); + PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_kp_u__9); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_10, __pyx_v_at_col, Py_ssize_t, 1, PyInt_FromSsize_t, 0, 1, 1); if (unlikely(!__pyx_t_15)) __PYX_ERR(2, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_15); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_15), __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; + __pyx_t_14 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) > __pyx_t_14) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) : __pyx_t_14; + __pyx_t_13 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_10); + PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_10); + __pyx_t_10 = 0; + __Pyx_INCREF(__pyx_kp_u_as_a_symbol_column); + __pyx_t_13 += 21; + __Pyx_GIVEREF(__pyx_kp_u_as_a_symbol_column); + PyTuple_SET_ITEM(__pyx_t_12, 2, __pyx_kp_u_as_a_symbol_column); + __pyx_t_10 = __Pyx_PyUnicode_Join(__pyx_t_12, 3, __pyx_t_13, __pyx_t_14); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + + /* "src/questdb/pandas_helpers.pxi":296 + * if (at_col >= 0) and (col_index == at_col): + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the `at` column ' + # <<<<<<<<<<<<<< + * f'({data.columns[at_col]!r}) as a symbol column.') + * _pandas_check_column_is_str( + */ + __pyx_t_12 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_argument_symbols_Cannot_use_2, __pyx_t_10); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 296, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "src/questdb/pandas_helpers.pxi":295 + * f'{symbol!r} as both the table_name and as a symbol.') + * if (at_col >= 0) and (col_index == at_col): + * raise ValueError( # <<<<<<<<<<<<<< + * f'Bad argument `symbols`: Cannot use the `at` column ' + + * f'({data.columns[at_col]!r}) as a symbol column.') + */ + __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_12); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_Raise(__pyx_t_10, 0, 0, 0); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __PYX_ERR(2, 295, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":294 + * f'Bad argument `symbols`: Cannot use the same column ' + + * f'{symbol!r} as both the table_name and as a symbol.') + * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< + * raise ValueError( + * f'Bad argument `symbols`: Cannot use the `at` column ' + + */ + } + + /* "src/questdb/pandas_helpers.pxi":298 + * f'Bad argument `symbols`: Cannot use the `at` column ' + + * f'({data.columns[at_col]!r}) as a symbol column.') + * _pandas_check_column_is_str( # <<<<<<<<<<<<<< + * data, + * col_index, + */ + __pyx_t_10 = __pyx_f_7questdb_7ingress__pandas_check_column_is_str(__pyx_v_data, __pyx_v_col_index, __pyx_kp_u_Bad_element_in_argument_symbols, __pyx_v_symbol); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "src/questdb/pandas_helpers.pxi":303 + * 'Bad element in argument `symbols`: ', + * symbol) + * size_t_vec_push(symbol_indices_out, col_index) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_v_symbol_indices_out, __pyx_v_col_index); + + /* "src/questdb/pandas_helpers.pxi":281 + * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + * 'of column names (str) or indices (int).') + * for symbol in symbols: # <<<<<<<<<<<<<< + * if isinstance(symbol, str): + * _pandas_get_loc(data, symbol, 'symbols', &col_index) + */ + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "src/questdb/pandas_helpers.pxi":304 + * symbol) + * size_t_vec_push(symbol_indices_out, col_index) + * return 0 # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 0; + goto __pyx_L0; + } + + /* "src/questdb/pandas_helpers.pxi":256 + * + * + * cdef int _pandas_resolve_symbols( # <<<<<<<<<<<<<< + * object data, + * ssize_t table_name_col, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_15); + __Pyx_AddTraceback("questdb.ingress._pandas_resolve_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_symbol); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":307 + * + * + * cdef bint _pandas_get_loc( # <<<<<<<<<<<<<< + * object data, str col_name, str arg_name, + * size_t* col_index_out) except False: + */ + +static int __pyx_f_7questdb_7ingress__pandas_get_loc(PyObject *__pyx_v_data, PyObject *__pyx_v_col_name, PyObject *__pyx_v_arg_name, size_t *__pyx_v_col_index_out) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + size_t __pyx_t_7; + int __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + Py_ssize_t __pyx_t_10; + Py_UCS4 __pyx_t_11; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_get_loc", 0); + + /* "src/questdb/pandas_helpers.pxi":313 + * Return the column index for `col_name`. + * """ + * try: # <<<<<<<<<<<<<< + * col_index_out[0] = data.columns.get_loc(col_name) + * return True + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "src/questdb/pandas_helpers.pxi":314 + * """ + * try: + * col_index_out[0] = data.columns.get_loc(col_name) # <<<<<<<<<<<<<< + * return True + * except KeyError: + */ + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 314, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_get_loc); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 314, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + } + } + __pyx_t_4 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_5, __pyx_v_col_name) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_col_name); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 314, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_4); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 314, __pyx_L3_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + (__pyx_v_col_index_out[0]) = __pyx_t_7; + + /* "src/questdb/pandas_helpers.pxi":315 + * try: + * col_index_out[0] = data.columns.get_loc(col_name) + * return True # <<<<<<<<<<<<<< + * except KeyError: + * raise KeyError( + */ + __pyx_r = 1; + goto __pyx_L7_try_return; + + /* "src/questdb/pandas_helpers.pxi":313 + * Return the column index for `col_name`. + * """ + * try: # <<<<<<<<<<<<<< + * col_index_out[0] = data.columns.get_loc(col_name) + * return True + */ + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "src/questdb/pandas_helpers.pxi":316 + * col_index_out[0] = data.columns.get_loc(col_name) + * return True + * except KeyError: # <<<<<<<<<<<<<< + * raise KeyError( + * f'Bad argument `{arg_name}`: ' + + */ + __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_8) { + __Pyx_AddTraceback("questdb.ingress._pandas_get_loc", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_5) < 0) __PYX_ERR(2, 316, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_5); + + /* "src/questdb/pandas_helpers.pxi":318 + * except KeyError: + * raise KeyError( + * f'Bad argument `{arg_name}`: ' + # <<<<<<<<<<<<<< + * f'Column {col_name!r} not found in the dataframe.') + * + */ + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 318, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = 0; + __pyx_t_11 = 127; + __Pyx_INCREF(__pyx_kp_u_Bad_argument); + __pyx_t_10 += 14; + __Pyx_GIVEREF(__pyx_kp_u_Bad_argument); + PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_Bad_argument); + __pyx_t_12 = __Pyx_PyUnicode_Unicode(__pyx_v_arg_name); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 318, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_12) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_12) : __pyx_t_11; + __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_12); + __Pyx_GIVEREF(__pyx_t_12); + PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_12); + __pyx_t_12 = 0; + __Pyx_INCREF(__pyx_kp_u__5); + __pyx_t_10 += 3; + __Pyx_GIVEREF(__pyx_kp_u__5); + PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u__5); + __pyx_t_12 = __Pyx_PyUnicode_Join(__pyx_t_9, 3, __pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 318, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "src/questdb/pandas_helpers.pxi":319 + * raise KeyError( + * f'Bad argument `{arg_name}`: ' + + * f'Column {col_name!r} not found in the dataframe.') # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 319, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = 0; + __pyx_t_11 = 127; + __Pyx_INCREF(__pyx_kp_u_Column); + __pyx_t_10 += 7; + __Pyx_GIVEREF(__pyx_kp_u_Column); + PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_Column); + __pyx_t_13 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_col_name), __pyx_empty_unicode); if (unlikely(!__pyx_t_13)) __PYX_ERR(2, 319, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_13); + __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_13) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_13) : __pyx_t_11; + __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_13); + __Pyx_GIVEREF(__pyx_t_13); + PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_13); + __pyx_t_13 = 0; + __Pyx_INCREF(__pyx_kp_u_not_found_in_the_dataframe); + __pyx_t_10 += 28; + __Pyx_GIVEREF(__pyx_kp_u_not_found_in_the_dataframe); + PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u_not_found_in_the_dataframe); + __pyx_t_13 = __Pyx_PyUnicode_Join(__pyx_t_9, 3, __pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_13)) __PYX_ERR(2, 319, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "src/questdb/pandas_helpers.pxi":318 + * except KeyError: + * raise KeyError( + * f'Bad argument `{arg_name}`: ' + # <<<<<<<<<<<<<< + * f'Column {col_name!r} not found in the dataframe.') + * + */ + __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 318, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + + /* "src/questdb/pandas_helpers.pxi":317 + * return True + * except KeyError: + * raise KeyError( # <<<<<<<<<<<<<< + * f'Bad argument `{arg_name}`: ' + + * f'Column {col_name!r} not found in the dataframe.') + */ + __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_9); if (unlikely(!__pyx_t_13)) __PYX_ERR(2, 317, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_Raise(__pyx_t_13, 0, 0, 0); + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + __PYX_ERR(2, 317, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "src/questdb/pandas_helpers.pxi":313 + * Return the column index for `col_name`. + * """ + * try: # <<<<<<<<<<<<<< + * col_index_out[0] = data.columns.get_loc(col_name) + * return True + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L7_try_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + } + + /* "src/questdb/pandas_helpers.pxi":307 + * + * + * cdef bint _pandas_get_loc( # <<<<<<<<<<<<<< + * object data, str col_name, str arg_name, + * size_t* col_index_out) except False: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("questdb.ingress._pandas_get_loc", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":322 + * + * + * cdef ssize_t _pandas_resolve_at( # <<<<<<<<<<<<<< + * object data, + * object at, + */ + +static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_at(PyObject *__pyx_v_data, PyObject *__pyx_v_at, size_t __pyx_v_col_count, int64_t *__pyx_v_at_value_out) { + size_t __pyx_v_col_index; + PyObject *__pyx_v_dtype = 0; + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int64_t __pyx_t_4; + int __pyx_t_5; + Py_ssize_t __pyx_t_6; + Py_UCS4 __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_resolve_at", 0); + + /* "src/questdb/pandas_helpers.pxi":329 + * cdef size_t col_index + * cdef object dtype + * if at is None: # <<<<<<<<<<<<<< + * at_value_out[0] = 0 # Special value for `at_now`. + * return -1 + */ + __pyx_t_1 = (__pyx_v_at == Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":330 + * cdef object dtype + * if at is None: + * at_value_out[0] = 0 # Special value for `at_now`. # <<<<<<<<<<<<<< + * return -1 + * elif isinstance(at, TimestampNanos): + */ + (__pyx_v_at_value_out[0]) = 0; + + /* "src/questdb/pandas_helpers.pxi":331 + * if at is None: + * at_value_out[0] = 0 # Special value for `at_now`. + * return -1 # <<<<<<<<<<<<<< + * elif isinstance(at, TimestampNanos): + * at_value_out[0] = at._value + */ + __pyx_r = -1L; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":329 + * cdef size_t col_index + * cdef object dtype + * if at is None: # <<<<<<<<<<<<<< + * at_value_out[0] = 0 # Special value for `at_now`. + * return -1 + */ + } + + /* "src/questdb/pandas_helpers.pxi":332 + * at_value_out[0] = 0 # Special value for `at_now`. + * return -1 + * elif isinstance(at, TimestampNanos): # <<<<<<<<<<<<<< + * at_value_out[0] = at._value + * return -1 + */ + __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_at, __pyx_ptype_7questdb_7ingress_TimestampNanos); + __pyx_t_1 = (__pyx_t_2 != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":333 + * return -1 + * elif isinstance(at, TimestampNanos): + * at_value_out[0] = at._value # <<<<<<<<<<<<<< + * return -1 + * elif isinstance(at, datetime): + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_at, __pyx_n_s_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 333, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyInt_As_int64_t(__pyx_t_3); if (unlikely((__pyx_t_4 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(2, 333, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + (__pyx_v_at_value_out[0]) = __pyx_t_4; + + /* "src/questdb/pandas_helpers.pxi":334 + * elif isinstance(at, TimestampNanos): + * at_value_out[0] = at._value + * return -1 # <<<<<<<<<<<<<< + * elif isinstance(at, datetime): + * at_value_out[0] = datetime_to_nanos(at) + */ + __pyx_r = -1L; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":332 + * at_value_out[0] = 0 # Special value for `at_now`. + * return -1 + * elif isinstance(at, TimestampNanos): # <<<<<<<<<<<<<< + * at_value_out[0] = at._value + * return -1 + */ + } + + /* "src/questdb/pandas_helpers.pxi":335 + * at_value_out[0] = at._value + * return -1 + * elif isinstance(at, datetime): # <<<<<<<<<<<<<< + * at_value_out[0] = datetime_to_nanos(at) + * return -1 + */ + __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_at, __pyx_ptype_7cpython_8datetime_datetime); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "src/questdb/pandas_helpers.pxi":336 + * return -1 + * elif isinstance(at, datetime): + * at_value_out[0] = datetime_to_nanos(at) # <<<<<<<<<<<<<< + * return -1 + * elif isinstance(at, str): + */ + if (!(likely(((__pyx_v_at) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_at, __pyx_ptype_7cpython_8datetime_datetime))))) __PYX_ERR(2, 336, __pyx_L1_error) + (__pyx_v_at_value_out[0]) = __pyx_f_7questdb_7ingress_datetime_to_nanos(((PyDateTime_DateTime *)__pyx_v_at)); + + /* "src/questdb/pandas_helpers.pxi":337 + * elif isinstance(at, datetime): + * at_value_out[0] = datetime_to_nanos(at) + * return -1 # <<<<<<<<<<<<<< + * elif isinstance(at, str): + * _pandas_get_loc(data, at, 'at', &col_index) + */ + __pyx_r = -1L; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":335 + * at_value_out[0] = at._value + * return -1 + * elif isinstance(at, datetime): # <<<<<<<<<<<<<< + * at_value_out[0] = datetime_to_nanos(at) + * return -1 + */ + } + + /* "src/questdb/pandas_helpers.pxi":338 + * at_value_out[0] = datetime_to_nanos(at) + * return -1 + * elif isinstance(at, str): # <<<<<<<<<<<<<< + * _pandas_get_loc(data, at, 'at', &col_index) + * elif isinstance(at, int): + */ + __pyx_t_2 = PyUnicode_Check(__pyx_v_at); + __pyx_t_1 = (__pyx_t_2 != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":339 + * return -1 + * elif isinstance(at, str): + * _pandas_get_loc(data, at, 'at', &col_index) # <<<<<<<<<<<<<< + * elif isinstance(at, int): + * _bind_col_index('at', at, col_count, &col_index) + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_at))||((__pyx_v_at) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_at)->tp_name), 0))) __PYX_ERR(2, 339, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_get_loc(__pyx_v_data, ((PyObject*)__pyx_v_at), __pyx_n_u_at, (&__pyx_v_col_index)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 339, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":338 + * at_value_out[0] = datetime_to_nanos(at) + * return -1 + * elif isinstance(at, str): # <<<<<<<<<<<<<< + * _pandas_get_loc(data, at, 'at', &col_index) + * elif isinstance(at, int): + */ + goto __pyx_L3; + } + + /* "src/questdb/pandas_helpers.pxi":340 + * elif isinstance(at, str): + * _pandas_get_loc(data, at, 'at', &col_index) + * elif isinstance(at, int): # <<<<<<<<<<<<<< + * _bind_col_index('at', at, col_count, &col_index) + * else: + */ + __pyx_t_1 = PyInt_Check(__pyx_v_at); + __pyx_t_2 = (__pyx_t_1 != 0); + if (likely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":341 + * _pandas_get_loc(data, at, 'at', &col_index) + * elif isinstance(at, int): + * _bind_col_index('at', at, col_count, &col_index) # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_v_at); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 341, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress__bind_col_index(__pyx_n_u_at, __pyx_t_5, __pyx_v_col_count, (&__pyx_v_col_index)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 341, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":340 + * elif isinstance(at, str): + * _pandas_get_loc(data, at, 'at', &col_index) + * elif isinstance(at, int): # <<<<<<<<<<<<<< + * _bind_col_index('at', at, col_count, &col_index) + * else: + */ + goto __pyx_L3; + } + + /* "src/questdb/pandas_helpers.pxi":343 + * _bind_col_index('at', at, col_count, &col_index) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `at`: Unsupported type {type(at)}. ' + + * 'Must be one of: None, TimestampNanos, datetime, ' + + */ + /*else*/ { + + /* "src/questdb/pandas_helpers.pxi":344 + * else: + * raise TypeError( + * f'Bad argument `at`: Unsupported type {type(at)}. ' + # <<<<<<<<<<<<<< + * 'Must be one of: None, TimestampNanos, datetime, ' + + * 'int (column index), str (colum name)') + */ + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = 0; + __pyx_t_7 = 127; + __Pyx_INCREF(__pyx_kp_u_Bad_argument_at_Unsupported_type); + __pyx_t_6 += 36; + __Pyx_GIVEREF(__pyx_kp_u_Bad_argument_at_Unsupported_type); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Bad_argument_at_Unsupported_type); + __pyx_t_8 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_at)), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_7; + __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_INCREF(__pyx_kp_u__10); + __pyx_t_6 += 2; + __Pyx_GIVEREF(__pyx_kp_u__10); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__10); + __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_8, __pyx_kp_u_Must_be_one_of_None_TimestampNan); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "src/questdb/pandas_helpers.pxi":345 + * raise TypeError( + * f'Bad argument `at`: Unsupported type {type(at)}. ' + + * 'Must be one of: None, TimestampNanos, datetime, ' + # <<<<<<<<<<<<<< + * 'int (column index), str (colum name)') + * dtype = data.dtypes[col_index] + */ + __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_kp_u_int_column_index_str_colum_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 345, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":343 + * _bind_col_index('at', at, col_count, &col_index) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `at`: Unsupported type {type(at)}. ' + + * 'Must be one of: None, TimestampNanos, datetime, ' + + */ + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 343, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 343, __pyx_L1_error) + } + __pyx_L3:; + + /* "src/questdb/pandas_helpers.pxi":347 + * 'Must be one of: None, TimestampNanos, datetime, ' + + * 'int (column index), str (colum name)') + * dtype = data.dtypes[col_index] # <<<<<<<<<<<<<< + * if _pandas_is_supported_datetime(dtype): + * at_value_out[0] = 0 + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 347, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_3, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 347, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_dtype = __pyx_t_8; + __pyx_t_8 = 0; + + /* "src/questdb/pandas_helpers.pxi":348 + * 'int (column index), str (colum name)') + * dtype = data.dtypes[col_index] + * if _pandas_is_supported_datetime(dtype): # <<<<<<<<<<<<<< + * at_value_out[0] = 0 + * return col_index + */ + __pyx_t_8 = __pyx_f_7questdb_7ingress__pandas_is_supported_datetime(__pyx_v_dtype); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 348, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 348, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (likely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":349 + * dtype = data.dtypes[col_index] + * if _pandas_is_supported_datetime(dtype): + * at_value_out[0] = 0 # <<<<<<<<<<<<<< + * return col_index + * else: + */ + (__pyx_v_at_value_out[0]) = 0; + + /* "src/questdb/pandas_helpers.pxi":350 + * if _pandas_is_supported_datetime(dtype): + * at_value_out[0] = 0 + * return col_index # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + __pyx_r = __pyx_v_col_index; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":348 + * 'int (column index), str (colum name)') + * dtype = data.dtypes[col_index] + * if _pandas_is_supported_datetime(dtype): # <<<<<<<<<<<<<< + * at_value_out[0] = 0 + * return col_index + */ + } + + /* "src/questdb/pandas_helpers.pxi":352 + * return col_index + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `at`: Bad dtype `{dtype}` ' + + * f'for the {at!r} column: Must be a datetime64[ns] column.') + */ + /*else*/ { + + /* "src/questdb/pandas_helpers.pxi":353 + * else: + * raise TypeError( + * f'Bad argument `at`: Bad dtype `{dtype}` ' + # <<<<<<<<<<<<<< + * f'for the {at!r} column: Must be a datetime64[ns] column.') + * + */ + __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 353, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = 0; + __pyx_t_7 = 127; + __Pyx_INCREF(__pyx_kp_u_Bad_argument_at_Bad_dtype); + __pyx_t_6 += 30; + __Pyx_GIVEREF(__pyx_kp_u_Bad_argument_at_Bad_dtype); + PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_Bad_argument_at_Bad_dtype); + __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_v_dtype, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 353, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) : __pyx_t_7; + __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_3); + __pyx_t_3 = 0; + __Pyx_INCREF(__pyx_kp_u__11); + __pyx_t_6 += 2; + __Pyx_GIVEREF(__pyx_kp_u__11); + PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u__11); + __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 353, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "src/questdb/pandas_helpers.pxi":354 + * raise TypeError( + * f'Bad argument `at`: Bad dtype `{dtype}` ' + + * f'for the {at!r} column: Must be a datetime64[ns] column.') # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 354, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = 0; + __pyx_t_7 = 127; + __Pyx_INCREF(__pyx_kp_u_for_the_2); + __pyx_t_6 += 8; + __Pyx_GIVEREF(__pyx_kp_u_for_the_2); + PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_for_the_2); + __pyx_t_9 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_at), __pyx_empty_unicode); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 354, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) : __pyx_t_7; + __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_9); + __pyx_t_9 = 0; + __Pyx_INCREF(__pyx_kp_u_column_Must_be_a_datetime64_ns); + __pyx_t_6 += 41; + __Pyx_GIVEREF(__pyx_kp_u_column_Must_be_a_datetime64_ns); + PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u_column_Must_be_a_datetime64_ns); + __pyx_t_9 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 354, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "src/questdb/pandas_helpers.pxi":353 + * else: + * raise TypeError( + * f'Bad argument `at`: Bad dtype `{dtype}` ' + # <<<<<<<<<<<<<< + * f'for the {at!r} column: Must be a datetime64[ns] column.') + * + */ + __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_t_9); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 353, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "src/questdb/pandas_helpers.pxi":352 + * return col_index + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `at`: Bad dtype `{dtype}` ' + + * f'for the {at!r} column: Must be a datetime64[ns] column.') + */ + __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 352, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_Raise(__pyx_t_9, 0, 0, 0); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __PYX_ERR(2, 352, __pyx_L1_error) + } + + /* "src/questdb/pandas_helpers.pxi":322 + * + * + * cdef ssize_t _pandas_resolve_at( # <<<<<<<<<<<<<< + * object data, + * object at, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("questdb.ingress._pandas_resolve_at", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -2L; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_dtype); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":357 + * + * + * cdef object _pandas_is_supported_datetime(object dtype): # <<<<<<<<<<<<<< + * # We currently only accept datetime64[ns] columns. + * return ( + */ + +static PyObject *__pyx_f_7questdb_7ingress__pandas_is_supported_datetime(PyObject *__pyx_v_dtype) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_is_supported_datetime", 0); + + /* "src/questdb/pandas_helpers.pxi":359 + * cdef object _pandas_is_supported_datetime(object dtype): + * # We currently only accept datetime64[ns] columns. + * return ( # <<<<<<<<<<<<<< + * (dtype.kind == 'M') and + * (dtype.itemsize == 8) and + */ + __Pyx_XDECREF(__pyx_r); + + /* "src/questdb/pandas_helpers.pxi":360 + * # We currently only accept datetime64[ns] columns. + * return ( + * (dtype.kind == 'M') and # <<<<<<<<<<<<<< + * (dtype.itemsize == 8) and + * (dtype.byteorder == '=') and + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 360, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_n_u_M, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 360, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 360, __pyx_L1_error) + if (__pyx_t_4) { + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + __Pyx_INCREF(__pyx_t_3); + __pyx_t_1 = __pyx_t_3; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L3_bool_binop_done; + } + + /* "src/questdb/pandas_helpers.pxi":361 + * return ( + * (dtype.kind == 'M') and + * (dtype.itemsize == 8) and # <<<<<<<<<<<<<< + * (dtype.byteorder == '=') and + * (dtype.alignment == 8) and + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyInt_EqObjC(__pyx_t_3, __pyx_int_8, 8, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 361, __pyx_L1_error) + if (__pyx_t_4) { + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = __pyx_t_2; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L3_bool_binop_done; + } + + /* "src/questdb/pandas_helpers.pxi":362 + * (dtype.kind == 'M') and + * (dtype.itemsize == 8) and + * (dtype.byteorder == '=') and # <<<<<<<<<<<<<< + * (dtype.alignment == 8) and + * (not dtype.hasobject)) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_byteorder); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 362, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_kp_u__12, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 362, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 362, __pyx_L1_error) + if (__pyx_t_4) { + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + __Pyx_INCREF(__pyx_t_3); + __pyx_t_1 = __pyx_t_3; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L3_bool_binop_done; + } + + /* "src/questdb/pandas_helpers.pxi":363 + * (dtype.itemsize == 8) and + * (dtype.byteorder == '=') and + * (dtype.alignment == 8) and # <<<<<<<<<<<<<< + * (not dtype.hasobject)) + * + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_alignment); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 363, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyInt_EqObjC(__pyx_t_3, __pyx_int_8, 8, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 363, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 363, __pyx_L1_error) + if (__pyx_t_4) { + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + } else { + __Pyx_INCREF(__pyx_t_2); + __pyx_t_1 = __pyx_t_2; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L3_bool_binop_done; + } + + /* "src/questdb/pandas_helpers.pxi":364 + * (dtype.byteorder == '=') and + * (dtype.alignment == 8) and + * (not dtype.hasobject)) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_hasobject); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 364, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 364, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_5 = (!__pyx_t_4); + __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 364, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __pyx_t_2; + __pyx_t_2 = 0; + __pyx_L3_bool_binop_done:; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":357 + * + * + * cdef object _pandas_is_supported_datetime(object dtype): # <<<<<<<<<<<<<< + * # We currently only accept datetime64[ns] columns. + * return ( + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress._pandas_is_supported_datetime", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":370 + * + * + * cdef char _str_to_char(str field, str s) except 0: # <<<<<<<<<<<<<< + * cdef int res + * if len(s) != 1: + */ + +static char __pyx_f_7questdb_7ingress__str_to_char(PyObject *__pyx_v_field, PyObject *__pyx_v_s) { + int __pyx_v_res; + char __pyx_r; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + Py_UCS4 __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + long __pyx_t_6; + int __pyx_t_7; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_str_to_char", 0); + + /* "src/questdb/pandas_helpers.pxi":372 + * cdef char _str_to_char(str field, str s) except 0: + * cdef int res + * if len(s) != 1: # <<<<<<<<<<<<<< + * raise ValueError( + * f'dtype.{field}: Expected a single character, got {s!r}') + */ + if (unlikely(__pyx_v_s == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(2, 372, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_PyUnicode_GET_LENGTH(__pyx_v_s); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(2, 372, __pyx_L1_error) + __pyx_t_2 = ((__pyx_t_1 != 1) != 0); + if (unlikely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":374 + * if len(s) != 1: + * raise ValueError( + * f'dtype.{field}: Expected a single character, got {s!r}') # <<<<<<<<<<<<<< + * res = ord(s) + * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. + */ + __pyx_t_3 = PyTuple_New(4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = 0; + __pyx_t_4 = 127; + __Pyx_INCREF(__pyx_kp_u_dtype); + __pyx_t_1 += 6; + __Pyx_GIVEREF(__pyx_kp_u_dtype); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_dtype); + __pyx_t_5 = __Pyx_PyUnicode_Unicode(__pyx_v_field); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; + __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5); + __pyx_t_5 = 0; + __Pyx_INCREF(__pyx_kp_u_Expected_a_single_character_got); + __pyx_t_1 += 35; + __Pyx_GIVEREF(__pyx_kp_u_Expected_a_single_character_got); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u_Expected_a_single_character_got); + __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_s), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; + __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_3, 4, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":373 + * cdef int res + * if len(s) != 1: + * raise ValueError( # <<<<<<<<<<<<<< + * f'dtype.{field}: Expected a single character, got {s!r}') + * res = ord(s) + */ + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 373, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 373, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":372 + * cdef char _str_to_char(str field, str s) except 0: + * cdef int res + * if len(s) != 1: # <<<<<<<<<<<<<< + * raise ValueError( + * f'dtype.{field}: Expected a single character, got {s!r}') + */ + } + + /* "src/questdb/pandas_helpers.pxi":375 + * raise ValueError( + * f'dtype.{field}: Expected a single character, got {s!r}') + * res = ord(s) # <<<<<<<<<<<<<< + * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. + * raise ValueError( + */ + __pyx_t_6 = __Pyx_PyObject_Ord(__pyx_v_s); if (unlikely(__pyx_t_6 == ((long)(long)(Py_UCS4)-1))) __PYX_ERR(2, 375, __pyx_L1_error) + __pyx_v_res = __pyx_t_6; + + /* "src/questdb/pandas_helpers.pxi":376 + * f'dtype.{field}: Expected a single character, got {s!r}') + * res = ord(s) + * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. # <<<<<<<<<<<<<< + * raise ValueError( + * f'dtype.{field}: Character out of ASCII range, got {s!r}') + */ + __pyx_t_7 = ((__pyx_v_res <= 0) != 0); + if (!__pyx_t_7) { + } else { + __pyx_t_2 = __pyx_t_7; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_7 = ((__pyx_v_res > 0x7F) != 0); + __pyx_t_2 = __pyx_t_7; + __pyx_L5_bool_binop_done:; + if (unlikely(__pyx_t_2)) { + + /* "src/questdb/pandas_helpers.pxi":378 + * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. + * raise ValueError( + * f'dtype.{field}: Character out of ASCII range, got {s!r}') # <<<<<<<<<<<<<< + * return res + * + */ + __pyx_t_3 = PyTuple_New(4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = 0; + __pyx_t_4 = 127; + __Pyx_INCREF(__pyx_kp_u_dtype); + __pyx_t_1 += 6; + __Pyx_GIVEREF(__pyx_kp_u_dtype); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_dtype); + __pyx_t_5 = __Pyx_PyUnicode_Unicode(__pyx_v_field); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; + __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5); + __pyx_t_5 = 0; + __Pyx_INCREF(__pyx_kp_u_Character_out_of_ASCII_range_go); + __pyx_t_1 += 36; + __Pyx_GIVEREF(__pyx_kp_u_Character_out_of_ASCII_range_go); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u_Character_out_of_ASCII_range_go); + __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_s), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; + __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_3, 4, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":377 + * res = ord(s) + * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. + * raise ValueError( # <<<<<<<<<<<<<< + * f'dtype.{field}: Character out of ASCII range, got {s!r}') + * return res + */ + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 377, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 377, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":376 + * f'dtype.{field}: Expected a single character, got {s!r}') + * res = ord(s) + * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. # <<<<<<<<<<<<<< + * raise ValueError( + * f'dtype.{field}: Character out of ASCII range, got {s!r}') + */ + } + + /* "src/questdb/pandas_helpers.pxi":379 + * raise ValueError( + * f'dtype.{field}: Character out of ASCII range, got {s!r}') + * return res # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = ((char)__pyx_v_res); + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":370 + * + * + * cdef char _str_to_char(str field, str s) except 0: # <<<<<<<<<<<<<< + * cdef int res + * if len(s) != 1: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("questdb.ingress._str_to_char", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":382 + * + * + * cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: # <<<<<<<<<<<<<< + * """ + * Parse a numpy dtype and return a dtype_t. + */ + +static int __pyx_f_7questdb_7ingress__pandas_parse_dtype(PyObject *__pyx_v_np_dtype, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype_out) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + char __pyx_t_3; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_parse_dtype", 0); + + /* "src/questdb/pandas_helpers.pxi":386 + * Parse a numpy dtype and return a dtype_t. + * """ + * dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) # <<<<<<<<<<<<<< + * dtype_out.kind = _str_to_char('kind', np_dtype.kind) + * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) + */ + __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_alignment, __pyx_int_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 386, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 386, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_dtype_out->alignment = __pyx_t_2; + + /* "src/questdb/pandas_helpers.pxi":387 + * """ + * dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) + * dtype_out.kind = _str_to_char('kind', np_dtype.kind) # <<<<<<<<<<<<<< + * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) + * dtype_out.byteorder = _str_to_char( + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_np_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 387, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 387, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7questdb_7ingress__str_to_char(__pyx_n_u_kind, ((PyObject*)__pyx_t_1)); if (unlikely(__pyx_t_3 == ((char)0))) __PYX_ERR(2, 387, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_dtype_out->kind = __pyx_t_3; + + /* "src/questdb/pandas_helpers.pxi":388 + * dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) + * dtype_out.kind = _str_to_char('kind', np_dtype.kind) + * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) # <<<<<<<<<<<<<< + * dtype_out.byteorder = _str_to_char( + * 'byteorder', getattr(np_dtype, 'byteorder', '=')) + */ + __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_itemsize, __pyx_int_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 388, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 388, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_dtype_out->itemsize = __pyx_t_2; + + /* "src/questdb/pandas_helpers.pxi":390 + * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) + * dtype_out.byteorder = _str_to_char( + * 'byteorder', getattr(np_dtype, 'byteorder', '=')) # <<<<<<<<<<<<<< + * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) + * return True + */ + __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_byteorder, __pyx_kp_u__12); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 390, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 390, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":389 + * dtype_out.kind = _str_to_char('kind', np_dtype.kind) + * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) + * dtype_out.byteorder = _str_to_char( # <<<<<<<<<<<<<< + * 'byteorder', getattr(np_dtype, 'byteorder', '=')) + * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress__str_to_char(__pyx_n_u_byteorder, ((PyObject*)__pyx_t_1)); if (unlikely(__pyx_t_3 == ((char)0))) __PYX_ERR(2, 389, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_dtype_out->byteorder = __pyx_t_3; + + /* "src/questdb/pandas_helpers.pxi":391 + * dtype_out.byteorder = _str_to_char( + * 'byteorder', getattr(np_dtype, 'byteorder', '=')) + * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_hasobject, Py_False); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 391, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 391, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_dtype_out->hasobject = __pyx_t_4; + + /* "src/questdb/pandas_helpers.pxi":392 + * 'byteorder', getattr(np_dtype, 'byteorder', '=')) + * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":382 + * + * + * cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: # <<<<<<<<<<<<<< + * """ + * Parse a numpy dtype and return a dtype_t. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress._pandas_parse_dtype", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":395 + * + * + * cdef bint _pandas_resolve_dtypes( # <<<<<<<<<<<<<< + * object data, size_t col_count, dtype_t* dtypes_out) except False: + * cdef size_t col_index + */ + +static int __pyx_f_7questdb_7ingress__pandas_resolve_dtypes(PyObject *__pyx_v_data, size_t __pyx_v_col_count, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes_out) { + size_t __pyx_v_col_index; + int __pyx_r; + __Pyx_RefNannyDeclarations + size_t __pyx_t_1; + size_t __pyx_t_2; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_resolve_dtypes", 0); + + /* "src/questdb/pandas_helpers.pxi":398 + * object data, size_t col_count, dtype_t* dtypes_out) except False: + * cdef size_t col_index + * for col_index in range(col_count): # <<<<<<<<<<<<<< + * _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) + * return True + */ + __pyx_t_1 = __pyx_v_col_count; + __pyx_t_2 = __pyx_t_1; + for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { + __pyx_v_col_index = __pyx_t_3; + + /* "src/questdb/pandas_helpers.pxi":399 + * cdef size_t col_index + * for col_index in range(col_count): + * _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 399, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 399, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __pyx_f_7questdb_7ingress__pandas_parse_dtype(__pyx_t_5, (&(__pyx_v_dtypes_out[__pyx_v_col_index]))); if (unlikely(__pyx_t_6 == ((int)0))) __PYX_ERR(2, 399, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } + + /* "src/questdb/pandas_helpers.pxi":400 + * for col_index in range(col_count): + * _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":395 + * + * + * cdef bint _pandas_resolve_dtypes( # <<<<<<<<<<<<<< + * object data, size_t col_count, dtype_t* dtypes_out) except False: + * cdef size_t col_index + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("questdb.ingress._pandas_resolve_dtypes", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":403 + * + * + * cdef bint _pandas_resolve_col_buffers( # <<<<<<<<<<<<<< + * object data, size_t col_count, const dtype_t* dtypes, + * Py_buffer* col_buffers, size_t* set_buf_count) except False: + */ + +static int __pyx_f_7questdb_7ingress__pandas_resolve_col_buffers(PyObject *__pyx_v_data, size_t __pyx_v_col_count, struct __pyx_t_7questdb_7ingress_dtype_t const *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, size_t *__pyx_v_set_buf_count) { + size_t __pyx_v_col_index; + PyObject *__pyx_v_nparr = 0; + Py_buffer *__pyx_v_view; + CYTHON_UNUSED struct __pyx_t_7questdb_7ingress_dtype_t const *__pyx_v_dtype; + int __pyx_r; + __Pyx_RefNannyDeclarations + size_t __pyx_t_1; + size_t __pyx_t_2; + size_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + long __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_resolve_col_buffers", 0); + + /* "src/questdb/pandas_helpers.pxi":417 + * cdef Py_buffer* view + * cdef const dtype_t* dtype + * for col_index in range(col_count): # <<<<<<<<<<<<<< + * nparr = data.iloc[:, col_index].to_numpy() + * view = &col_buffers[col_index] + */ + __pyx_t_1 = __pyx_v_col_count; + __pyx_t_2 = __pyx_t_1; + for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { + __pyx_v_col_index = __pyx_t_3; + + /* "src/questdb/pandas_helpers.pxi":418 + * cdef const dtype_t* dtype + * for col_index in range(col_count): + * nparr = data.iloc[:, col_index].to_numpy() # <<<<<<<<<<<<<< + * view = &col_buffers[col_index] + * dtype = &dtypes[col_index] + */ + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_iloc); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyInt_FromSize_t(__pyx_v_col_index); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_slice__13); + __Pyx_GIVEREF(__pyx_slice__13); + PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_slice__13); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_to_numpy); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallNoArg(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF_SET(__pyx_v_nparr, __pyx_t_4); + __pyx_t_4 = 0; + + /* "src/questdb/pandas_helpers.pxi":419 + * for col_index in range(col_count): + * nparr = data.iloc[:, col_index].to_numpy() + * view = &col_buffers[col_index] # <<<<<<<<<<<<<< + * dtype = &dtypes[col_index] + * if not PyObject_CheckBuffer(nparr): + */ + __pyx_v_view = (&(__pyx_v_col_buffers[__pyx_v_col_index])); + + /* "src/questdb/pandas_helpers.pxi":420 + * nparr = data.iloc[:, col_index].to_numpy() + * view = &col_buffers[col_index] + * dtype = &dtypes[col_index] # <<<<<<<<<<<<<< + * if not PyObject_CheckBuffer(nparr): + * raise TypeError( + */ + __pyx_v_dtype = (&(__pyx_v_dtypes[__pyx_v_col_index])); + + /* "src/questdb/pandas_helpers.pxi":421 + * view = &col_buffers[col_index] + * dtype = &dtypes[col_index] + * if not PyObject_CheckBuffer(nparr): # <<<<<<<<<<<<<< + * raise TypeError( + * f'Bad column: Expected a numpy array, got {nparr!r}') + */ + __pyx_t_8 = ((!(PyObject_CheckBuffer(__pyx_v_nparr) != 0)) != 0); + if (unlikely(__pyx_t_8)) { + + /* "src/questdb/pandas_helpers.pxi":423 + * if not PyObject_CheckBuffer(nparr): + * raise TypeError( + * f'Bad column: Expected a numpy array, got {nparr!r}') # <<<<<<<<<<<<<< + * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) + * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. + */ + __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_nparr), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 423, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_column_Expected_a_numpy_arra, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 423, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "src/questdb/pandas_helpers.pxi":422 + * dtype = &dtypes[col_index] + * if not PyObject_CheckBuffer(nparr): + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad column: Expected a numpy array, got {nparr!r}') + * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) + */ + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 422, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(2, 422, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":421 + * view = &col_buffers[col_index] + * dtype = &dtypes[col_index] + * if not PyObject_CheckBuffer(nparr): # <<<<<<<<<<<<<< + * raise TypeError( + * f'Bad column: Expected a numpy array, got {nparr!r}') + */ + } + + /* "src/questdb/pandas_helpers.pxi":424 + * raise TypeError( + * f'Bad column: Expected a numpy array, got {nparr!r}') + * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) # <<<<<<<<<<<<<< + * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. + * set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. + */ + __pyx_t_9 = PyObject_GetBuffer(__pyx_v_nparr, __pyx_v_view, PyBUF_STRIDES); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 424, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":426 + * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) + * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. + * set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_10 = 0; + (__pyx_v_set_buf_count[__pyx_t_10]) = ((__pyx_v_set_buf_count[__pyx_t_10]) + 1); + } + + /* "src/questdb/pandas_helpers.pxi":427 + * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. + * set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":403 + * + * + * cdef bint _pandas_resolve_col_buffers( # <<<<<<<<<<<<<< + * object data, size_t col_count, const dtype_t* dtypes, + * Py_buffer* col_buffers, size_t* set_buf_count) except False: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress._pandas_resolve_col_buffers", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_nparr); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":430 + * + * + * cdef inline const void* _pandas_get_cell( # <<<<<<<<<<<<<< + * Py_buffer* col_buffer, size_t row_index): + * return col_buffer.buf + (row_index * col_buffer.strides[0]) + */ + +static CYTHON_INLINE void const *__pyx_f_7questdb_7ingress__pandas_get_cell(Py_buffer *__pyx_v_col_buffer, size_t __pyx_v_row_index) { + void const *__pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_pandas_get_cell", 0); + + /* "src/questdb/pandas_helpers.pxi":432 + * cdef inline const void* _pandas_get_cell( + * Py_buffer* col_buffer, size_t row_index): + * return col_buffer.buf + (row_index * col_buffer.strides[0]) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = (__pyx_v_col_buffer->buf + (((Py_ssize_t)__pyx_v_row_index) * (__pyx_v_col_buffer->strides[0]))); + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":430 + * + * + * cdef inline const void* _pandas_get_cell( # <<<<<<<<<<<<<< + * Py_buffer* col_buffer, size_t row_index): + * return col_buffer.buf + (row_index * col_buffer.strides[0]) + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":439 + * + * + * cdef bint _pandas_get_str_cell( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * dtype_t* dtype, + */ + +static int __pyx_f_7questdb_7ingress__pandas_get_str_cell(struct qdb_pystr_buf *__pyx_v_b, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype, Py_buffer *__pyx_v_col_buffer, size_t __pyx_v_row_index, int *__pyx_v_is_null_out, struct line_sender_utf8 *__pyx_v_utf8_out) { + void const *__pyx_v_cell; + PyObject *__pyx_v_obj = 0; + PyObject *__pyx_v_e = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + Py_ssize_t __pyx_t_12; + Py_UCS4 __pyx_t_13; + PyObject *__pyx_t_14 = NULL; + int __pyx_t_15; + char const *__pyx_t_16; + PyObject *__pyx_t_17 = NULL; + PyObject *__pyx_t_18 = NULL; + PyObject *__pyx_t_19 = NULL; + PyObject *__pyx_t_20 = NULL; + PyObject *__pyx_t_21 = NULL; + PyObject *__pyx_t_22 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_get_str_cell", 0); + + /* "src/questdb/pandas_helpers.pxi":446 + * bint* is_null_out, + * line_sender_utf8* utf8_out) except False: + * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) # <<<<<<<<<<<<<< + * cdef object obj + * if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: + */ + __pyx_v_cell = __pyx_f_7questdb_7ingress__pandas_get_cell(__pyx_v_col_buffer, __pyx_v_row_index); + + /* "src/questdb/pandas_helpers.pxi":448 + * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + * cdef object obj + * if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: # <<<<<<<<<<<<<< + * # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. + * # TODO: Improve error messaging. Error message should include the column name. + */ + __pyx_t_1 = ((__pyx_v_dtype->kind == __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_OBJECT) != 0); + if (likely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":451 + * # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. + * # TODO: Improve error messaging. Error message should include the column name. + * obj = ((cell)[0]) # <<<<<<<<<<<<<< + * if (obj is None) or (obj is _PANDAS_NA): + * is_null_out[0] = True + */ + __pyx_t_2 = ((PyObject *)(((PyObject **)__pyx_v_cell)[0])); + __Pyx_INCREF(__pyx_t_2); + __pyx_v_obj = __pyx_t_2; + __pyx_t_2 = 0; + + /* "src/questdb/pandas_helpers.pxi":452 + * # TODO: Improve error messaging. Error message should include the column name. + * obj = ((cell)[0]) + * if (obj is None) or (obj is _PANDAS_NA): # <<<<<<<<<<<<<< + * is_null_out[0] = True + * else: + */ + __pyx_t_3 = (__pyx_v_obj == Py_None); + __pyx_t_4 = (__pyx_t_3 != 0); + if (!__pyx_t_4) { + } else { + __pyx_t_1 = __pyx_t_4; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_4 = (__pyx_v_obj == __pyx_v_7questdb_7ingress__PANDAS_NA); + __pyx_t_3 = (__pyx_t_4 != 0); + __pyx_t_1 = __pyx_t_3; + __pyx_L5_bool_binop_done:; + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":453 + * obj = ((cell)[0]) + * if (obj is None) or (obj is _PANDAS_NA): + * is_null_out[0] = True # <<<<<<<<<<<<<< + * else: + * is_null_out[0] = False + */ + (__pyx_v_is_null_out[0]) = 1; + + /* "src/questdb/pandas_helpers.pxi":452 + * # TODO: Improve error messaging. Error message should include the column name. + * obj = ((cell)[0]) + * if (obj is None) or (obj is _PANDAS_NA): # <<<<<<<<<<<<<< + * is_null_out[0] = True + * else: + */ + goto __pyx_L4; + } + + /* "src/questdb/pandas_helpers.pxi":455 + * is_null_out[0] = True + * else: + * is_null_out[0] = False # <<<<<<<<<<<<<< + * try: + * str_to_utf8(b, obj, utf8_out) + */ + /*else*/ { + (__pyx_v_is_null_out[0]) = 0; + + /* "src/questdb/pandas_helpers.pxi":456 + * else: + * is_null_out[0] = False + * try: # <<<<<<<<<<<<<< + * str_to_utf8(b, obj, utf8_out) + * except TypeError as e: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + /*try:*/ { + + /* "src/questdb/pandas_helpers.pxi":457 + * is_null_out[0] = False + * try: + * str_to_utf8(b, obj, utf8_out) # <<<<<<<<<<<<<< + * except TypeError as e: + * raise TypeError( + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_obj))||((__pyx_v_obj) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_obj)->tp_name), 0))) __PYX_ERR(2, 457, __pyx_L7_error) + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, ((PyObject*)__pyx_v_obj), __pyx_v_utf8_out); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 457, __pyx_L7_error) + + /* "src/questdb/pandas_helpers.pxi":456 + * else: + * is_null_out[0] = False + * try: # <<<<<<<<<<<<<< + * str_to_utf8(b, obj, utf8_out) + * except TypeError as e: + */ + } + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L12_try_end; + __pyx_L7_error:; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "src/questdb/pandas_helpers.pxi":458 + * try: + * str_to_utf8(b, obj, utf8_out) + * except TypeError as e: # <<<<<<<<<<<<<< + * raise TypeError( + * 'Bad column: Expected a string, ' + + */ + __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); + if (__pyx_t_8) { + __Pyx_AddTraceback("questdb.ingress._pandas_get_str_cell", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(2, 458, __pyx_L9_except_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_t_9); + __Pyx_GOTREF(__pyx_t_10); + __Pyx_INCREF(__pyx_t_9); + __pyx_v_e = __pyx_t_9; + /*try:*/ { + + /* "src/questdb/pandas_helpers.pxi":461 + * raise TypeError( + * 'Bad column: Expected a string, ' + + * f'got {obj!r} ({type(obj)!r})') from e # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + __pyx_t_11 = PyTuple_New(5); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 461, __pyx_L18_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_12 = 0; + __pyx_t_13 = 127; + __Pyx_INCREF(__pyx_kp_u_got); + __pyx_t_12 += 4; + __Pyx_GIVEREF(__pyx_kp_u_got); + PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_kp_u_got); + __pyx_t_14 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_obj), __pyx_empty_unicode); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 461, __pyx_L18_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) : __pyx_t_13; + __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_14); + __Pyx_GIVEREF(__pyx_t_14); + PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_14); + __pyx_t_14 = 0; + __Pyx_INCREF(__pyx_kp_u__14); + __pyx_t_12 += 2; + __Pyx_GIVEREF(__pyx_kp_u__14); + PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_kp_u__14); + __pyx_t_14 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(((PyObject *)Py_TYPE(__pyx_v_obj))), __pyx_empty_unicode); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 461, __pyx_L18_error) + __Pyx_GOTREF(__pyx_t_14); + __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) : __pyx_t_13; + __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_14); + __Pyx_GIVEREF(__pyx_t_14); + PyTuple_SET_ITEM(__pyx_t_11, 3, __pyx_t_14); + __pyx_t_14 = 0; + __Pyx_INCREF(__pyx_kp_u__15); + __pyx_t_12 += 1; + __Pyx_GIVEREF(__pyx_kp_u__15); + PyTuple_SET_ITEM(__pyx_t_11, 4, __pyx_kp_u__15); + __pyx_t_14 = __Pyx_PyUnicode_Join(__pyx_t_11, 5, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 461, __pyx_L18_error) + __Pyx_GOTREF(__pyx_t_14); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "src/questdb/pandas_helpers.pxi":460 + * except TypeError as e: + * raise TypeError( + * 'Bad column: Expected a string, ' + # <<<<<<<<<<<<<< + * f'got {obj!r} ({type(obj)!r})') from e + * else: + */ + __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_column_Expected_a_string, __pyx_t_14); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 460, __pyx_L18_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + + /* "src/questdb/pandas_helpers.pxi":459 + * str_to_utf8(b, obj, utf8_out) + * except TypeError as e: + * raise TypeError( # <<<<<<<<<<<<<< + * 'Bad column: Expected a string, ' + + * f'got {obj!r} ({type(obj)!r})') from e + */ + __pyx_t_14 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_11); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 459, __pyx_L18_error) + __Pyx_GOTREF(__pyx_t_14); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "src/questdb/pandas_helpers.pxi":461 + * raise TypeError( + * 'Bad column: Expected a string, ' + + * f'got {obj!r} ({type(obj)!r})') from e # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + __Pyx_Raise(__pyx_t_14, 0, 0, __pyx_v_e); + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __PYX_ERR(2, 459, __pyx_L18_error) + } + + /* "src/questdb/pandas_helpers.pxi":458 + * try: + * str_to_utf8(b, obj, utf8_out) + * except TypeError as e: # <<<<<<<<<<<<<< + * raise TypeError( + * 'Bad column: Expected a string, ' + + */ + /*finally:*/ { + __pyx_L18_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_20, &__pyx_t_21, &__pyx_t_22); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19) < 0)) __Pyx_ErrFetch(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19); + __Pyx_XGOTREF(__pyx_t_17); + __Pyx_XGOTREF(__pyx_t_18); + __Pyx_XGOTREF(__pyx_t_19); + __Pyx_XGOTREF(__pyx_t_20); + __Pyx_XGOTREF(__pyx_t_21); + __Pyx_XGOTREF(__pyx_t_22); + __pyx_t_8 = __pyx_lineno; __pyx_t_15 = __pyx_clineno; __pyx_t_16 = __pyx_filename; + { + __Pyx_DECREF(__pyx_v_e); + __pyx_v_e = NULL; + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_20); + __Pyx_XGIVEREF(__pyx_t_21); + __Pyx_XGIVEREF(__pyx_t_22); + __Pyx_ExceptionReset(__pyx_t_20, __pyx_t_21, __pyx_t_22); + } + __Pyx_XGIVEREF(__pyx_t_17); + __Pyx_XGIVEREF(__pyx_t_18); + __Pyx_XGIVEREF(__pyx_t_19); + __Pyx_ErrRestore(__pyx_t_17, __pyx_t_18, __pyx_t_19); + __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; + __pyx_lineno = __pyx_t_8; __pyx_clineno = __pyx_t_15; __pyx_filename = __pyx_t_16; + goto __pyx_L9_except_error; + } + } + } + goto __pyx_L9_except_error; + __pyx_L9_except_error:; + + /* "src/questdb/pandas_helpers.pxi":456 + * else: + * is_null_out[0] = False + * try: # <<<<<<<<<<<<<< + * str_to_utf8(b, obj, utf8_out) + * except TypeError as e: + */ + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_XGIVEREF(__pyx_t_7); + __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_6, __pyx_t_7); + goto __pyx_L1_error; + __pyx_L12_try_end:; + } + } + __pyx_L4:; + + /* "src/questdb/pandas_helpers.pxi":448 + * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + * cdef object obj + * if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: # <<<<<<<<<<<<<< + * # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. + * # TODO: Improve error messaging. Error message should include the column name. + */ + goto __pyx_L3; + } + + /* "src/questdb/pandas_helpers.pxi":463 + * f'got {obj!r} ({type(obj)!r})') from e + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. + * return True + */ + /*else*/ { + + /* "src/questdb/pandas_helpers.pxi":464 + * else: + * raise TypeError( + * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_10 = __Pyx_PyUnicode_From_char(__pyx_v_dtype->kind, 0, ' ', 'd'); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 464, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_kp_u_NOT_YET_IMPLEMENTED_Kind, __pyx_t_10); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 464, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "src/questdb/pandas_helpers.pxi":463 + * f'got {obj!r} ({type(obj)!r})') from e + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. + * return True + */ + __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 463, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_Raise(__pyx_t_10, 0, 0, 0); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __PYX_ERR(2, 463, __pyx_L1_error) + } + __pyx_L3:; + + /* "src/questdb/pandas_helpers.pxi":465 + * raise TypeError( + * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":439 + * + * + * cdef bint _pandas_get_str_cell( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * dtype_t* dtype, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_14); + __Pyx_AddTraceback("questdb.ingress._pandas_get_str_cell", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_obj); + __Pyx_XDECREF(__pyx_v_e); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":468 + * + * + * cdef int64_t _pandas_get_timestamp_cell( # <<<<<<<<<<<<<< + * dtype_t* dtype, + * Py_buffer* col_buffer, + */ + +static int64_t __pyx_f_7questdb_7ingress__pandas_get_timestamp_cell(CYTHON_UNUSED struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype, Py_buffer *__pyx_v_col_buffer, size_t __pyx_v_row_index) { + void const *__pyx_v_cell; + int64_t __pyx_v_res; + int64_t __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_get_timestamp_cell", 0); + + /* "src/questdb/pandas_helpers.pxi":473 + * size_t row_index) except -1: + * # Note: Type is pre-validated by `_pandas_is_supported_datetime`. + * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) # <<<<<<<<<<<<<< + * cdef int64_t res = (cell)[0] + * if res < 0: + */ + __pyx_v_cell = __pyx_f_7questdb_7ingress__pandas_get_cell(__pyx_v_col_buffer, __pyx_v_row_index); + + /* "src/questdb/pandas_helpers.pxi":474 + * # Note: Type is pre-validated by `_pandas_is_supported_datetime`. + * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + * cdef int64_t res = (cell)[0] # <<<<<<<<<<<<<< + * if res < 0: + * # TODO [amunra]: Improve error messaging. Add column name. + */ + __pyx_v_res = (((int64_t *)__pyx_v_cell)[0]); + + /* "src/questdb/pandas_helpers.pxi":475 + * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + * cdef int64_t res = (cell)[0] + * if res < 0: # <<<<<<<<<<<<<< + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( + */ + __pyx_t_1 = ((__pyx_v_res < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":478 + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( + * f'Bad value: Negative timestamp, got {res}') # <<<<<<<<<<<<<< + * return res + * + */ + __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_res); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 478, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 478, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_value_Negative_timestamp_got, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 478, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "src/questdb/pandas_helpers.pxi":477 + * if res < 0: + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( # <<<<<<<<<<<<<< + * f'Bad value: Negative timestamp, got {res}') + * return res + */ + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 477, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 477, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":475 + * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) + * cdef int64_t res = (cell)[0] + * if res < 0: # <<<<<<<<<<<<<< + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( + */ + } + + /* "src/questdb/pandas_helpers.pxi":479 + * raise ValueError( + * f'Bad value: Negative timestamp, got {res}') + * return res # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_res; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":468 + * + * + * cdef int64_t _pandas_get_timestamp_cell( # <<<<<<<<<<<<<< + * dtype_t* dtype, + * Py_buffer* col_buffer, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress._pandas_get_timestamp_cell", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1L; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":482 + * + * + * cdef bint _pandas_row_table_name( # <<<<<<<<<<<<<< + * line_sender_buffer* impl, + * qdb_pystr_buf* b, + */ + +static int __pyx_f_7questdb_7ingress__pandas_row_table_name(struct line_sender_buffer *__pyx_v_impl, struct qdb_pystr_buf *__pyx_v_b, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, Py_ssize_t __pyx_v_name_col, size_t __pyx_v_row_index, struct line_sender_table_name __pyx_v_c_table_name) { + struct line_sender_error *__pyx_v_err; + int __pyx_v_is_null; + struct line_sender_utf8 __pyx_v_utf8; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + Py_UCS4 __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_row_table_name", 0); + + /* "src/questdb/pandas_helpers.pxi":490 + * size_t row_index, + * line_sender_table_name c_table_name) except False: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef bint is_null = False + * cdef line_sender_utf8 utf8 + */ + __pyx_v_err = NULL; + + /* "src/questdb/pandas_helpers.pxi":491 + * line_sender_table_name c_table_name) except False: + * cdef line_sender_error* err = NULL + * cdef bint is_null = False # <<<<<<<<<<<<<< + * cdef line_sender_utf8 utf8 + * if name_col >= 0: + */ + __pyx_v_is_null = 0; + + /* "src/questdb/pandas_helpers.pxi":493 + * cdef bint is_null = False + * cdef line_sender_utf8 utf8 + * if name_col >= 0: # <<<<<<<<<<<<<< + * _pandas_get_str_cell( + * b, + */ + __pyx_t_1 = ((__pyx_v_name_col >= 0) != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":494 + * cdef line_sender_utf8 utf8 + * if name_col >= 0: + * _pandas_get_str_cell( # <<<<<<<<<<<<<< + * b, + * &dtypes[name_col], + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_get_str_cell(__pyx_v_b, (&(__pyx_v_dtypes[((size_t)__pyx_v_name_col)])), (&(__pyx_v_col_buffers[((size_t)__pyx_v_name_col)])), __pyx_v_row_index, (&__pyx_v_is_null), (&__pyx_v_utf8)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 494, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":501 + * &is_null, + * &utf8) + * if is_null: # <<<<<<<<<<<<<< + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( + */ + __pyx_t_1 = (__pyx_v_is_null != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":504 + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( + * f'Bad value: `None` table name value at row {row_index}.') # <<<<<<<<<<<<<< + * if not line_sender_table_name_init( + * &c_table_name, utf8.len, utf8.buf, &err): + */ + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 504, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = 0; + __pyx_t_4 = 127; + __Pyx_INCREF(__pyx_kp_u_Bad_value_None_table_name_value); + __pyx_t_3 += 42; + __Pyx_GIVEREF(__pyx_kp_u_Bad_value_None_table_name_value); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_Bad_value_None_table_name_value); + __pyx_t_5 = __Pyx_PyUnicode_From_size_t(__pyx_v_row_index, 0, ' ', 'd'); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 504, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_3 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5); + __pyx_t_5 = 0; + __Pyx_INCREF(__pyx_kp_u__6); + __pyx_t_3 += 1; + __Pyx_GIVEREF(__pyx_kp_u__6); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); + __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 504, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "src/questdb/pandas_helpers.pxi":503 + * if is_null: + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( # <<<<<<<<<<<<<< + * f'Bad value: `None` table name value at row {row_index}.') + * if not line_sender_table_name_init( + */ + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 503, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(2, 503, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":501 + * &is_null, + * &utf8) + * if is_null: # <<<<<<<<<<<<<< + * # TODO [amunra]: Improve error messaging. Add column name. + * raise ValueError( + */ + } + + /* "src/questdb/pandas_helpers.pxi":505 + * raise ValueError( + * f'Bad value: `None` table name value at row {row_index}.') + * if not line_sender_table_name_init( # <<<<<<<<<<<<<< + * &c_table_name, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = ((!(line_sender_table_name_init((&__pyx_v_c_table_name), __pyx_v_utf8.len, __pyx_v_utf8.buf, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":507 + * if not line_sender_table_name_init( + * &c_table_name, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * if not line_sender_buffer_table(impl, c_table_name, &err): + * raise c_err_to_py(err) + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 507, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(2, 507, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":505 + * raise ValueError( + * f'Bad value: `None` table name value at row {row_index}.') + * if not line_sender_table_name_init( # <<<<<<<<<<<<<< + * &c_table_name, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + */ + } + + /* "src/questdb/pandas_helpers.pxi":493 + * cdef bint is_null = False + * cdef line_sender_utf8 utf8 + * if name_col >= 0: # <<<<<<<<<<<<<< + * _pandas_get_str_cell( + * b, + */ + } + + /* "src/questdb/pandas_helpers.pxi":508 + * &c_table_name, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + * if not line_sender_buffer_table(impl, c_table_name, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + __pyx_t_1 = ((!(line_sender_buffer_table(__pyx_v_impl, __pyx_v_c_table_name, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":509 + * raise c_err_to_py(err) + * if not line_sender_buffer_table(impl, c_table_name, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 509, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(2, 509, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":508 + * &c_table_name, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + * if not line_sender_buffer_table(impl, c_table_name, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + } + + /* "src/questdb/pandas_helpers.pxi":510 + * if not line_sender_buffer_table(impl, c_table_name, &err): + * raise c_err_to_py(err) + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":482 + * + * + * cdef bint _pandas_row_table_name( # <<<<<<<<<<<<<< + * line_sender_buffer* impl, + * qdb_pystr_buf* b, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("questdb.ingress._pandas_row_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":513 + * + * + * cdef bint _pandas_row_symbols( # <<<<<<<<<<<<<< + * line_sender_buffer* impl, + * qdb_pystr_buf* b, + */ + +static int __pyx_f_7questdb_7ingress__pandas_row_symbols(struct line_sender_buffer *__pyx_v_impl, struct qdb_pystr_buf *__pyx_v_b, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, size_t __pyx_v_row_index, __pyx_t_7questdb_7ingress_column_name_vec const *__pyx_v_symbol_names, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_symbol_indices) { + struct line_sender_error *__pyx_v_err; + size_t __pyx_v_sym_index; + size_t __pyx_v_col_index; + struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype; + Py_buffer *__pyx_v_col_buffer; + struct line_sender_column_name __pyx_v_col_name; + struct line_sender_utf8 __pyx_v_symbol; + int __pyx_v_is_null; + int __pyx_r; + __Pyx_RefNannyDeclarations + size_t __pyx_t_1; + size_t __pyx_t_2; + size_t __pyx_t_3; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_row_symbols", 0); + + /* "src/questdb/pandas_helpers.pxi":521 + * const column_name_vec* symbol_names, + * const size_t_vec* symbol_indices) except False: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef size_t sym_index + * cdef size_t col_index + */ + __pyx_v_err = NULL; + + /* "src/questdb/pandas_helpers.pxi":528 + * cdef line_sender_column_name col_name + * cdef line_sender_utf8 symbol + * cdef bint is_null = False # <<<<<<<<<<<<<< + * for sym_index in range(symbol_indices.size): + * col_name = symbol_names.d[sym_index] + */ + __pyx_v_is_null = 0; + + /* "src/questdb/pandas_helpers.pxi":529 + * cdef line_sender_utf8 symbol + * cdef bint is_null = False + * for sym_index in range(symbol_indices.size): # <<<<<<<<<<<<<< + * col_name = symbol_names.d[sym_index] + * col_index = symbol_indices.d[sym_index] + */ + __pyx_t_1 = __pyx_v_symbol_indices->size; + __pyx_t_2 = __pyx_t_1; + for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { + __pyx_v_sym_index = __pyx_t_3; + + /* "src/questdb/pandas_helpers.pxi":530 + * cdef bint is_null = False + * for sym_index in range(symbol_indices.size): + * col_name = symbol_names.d[sym_index] # <<<<<<<<<<<<<< + * col_index = symbol_indices.d[sym_index] + * col_buffer = &col_buffers[col_index] + */ + __pyx_v_col_name = (__pyx_v_symbol_names->d[__pyx_v_sym_index]); + + /* "src/questdb/pandas_helpers.pxi":531 + * for sym_index in range(symbol_indices.size): + * col_name = symbol_names.d[sym_index] + * col_index = symbol_indices.d[sym_index] # <<<<<<<<<<<<<< + * col_buffer = &col_buffers[col_index] + * dtype = &dtypes[col_index] + */ + __pyx_v_col_index = (__pyx_v_symbol_indices->d[__pyx_v_sym_index]); + + /* "src/questdb/pandas_helpers.pxi":532 + * col_name = symbol_names.d[sym_index] + * col_index = symbol_indices.d[sym_index] + * col_buffer = &col_buffers[col_index] # <<<<<<<<<<<<<< + * dtype = &dtypes[col_index] + * _pandas_get_str_cell( + */ + __pyx_v_col_buffer = (&(__pyx_v_col_buffers[__pyx_v_col_index])); + + /* "src/questdb/pandas_helpers.pxi":533 + * col_index = symbol_indices.d[sym_index] + * col_buffer = &col_buffers[col_index] + * dtype = &dtypes[col_index] # <<<<<<<<<<<<<< + * _pandas_get_str_cell( + * b, + */ + __pyx_v_dtype = (&(__pyx_v_dtypes[__pyx_v_col_index])); + + /* "src/questdb/pandas_helpers.pxi":534 + * col_buffer = &col_buffers[col_index] + * dtype = &dtypes[col_index] + * _pandas_get_str_cell( # <<<<<<<<<<<<<< + * b, + * dtype, + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress__pandas_get_str_cell(__pyx_v_b, __pyx_v_dtype, __pyx_v_col_buffer, __pyx_v_row_index, (&__pyx_v_is_null), (&__pyx_v_symbol)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(2, 534, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":541 + * &is_null, + * &symbol) + * if not is_null: # <<<<<<<<<<<<<< + * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): + * raise c_err_to_py(err) + */ + __pyx_t_4 = ((!(__pyx_v_is_null != 0)) != 0); + if (__pyx_t_4) { + + /* "src/questdb/pandas_helpers.pxi":542 + * &symbol) + * if not is_null: + * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + __pyx_t_4 = ((!(line_sender_buffer_symbol(__pyx_v_impl, __pyx_v_col_name, __pyx_v_symbol, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_4)) { + + /* "src/questdb/pandas_helpers.pxi":543 + * if not is_null: + * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 543, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_Raise(__pyx_t_5, 0, 0, 0); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __PYX_ERR(2, 543, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":542 + * &symbol) + * if not is_null: + * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + } + + /* "src/questdb/pandas_helpers.pxi":541 + * &is_null, + * &symbol) + * if not is_null: # <<<<<<<<<<<<<< + * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): + * raise c_err_to_py(err) + */ + } + } + + /* "src/questdb/pandas_helpers.pxi":544 + * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): + * raise c_err_to_py(err) + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":513 + * + * + * cdef bint _pandas_row_symbols( # <<<<<<<<<<<<<< + * line_sender_buffer* impl, + * qdb_pystr_buf* b, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("questdb.ingress._pandas_row_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "src/questdb/pandas_helpers.pxi":547 + * + * + * cdef bint _pandas_row_at( # <<<<<<<<<<<<<< + * line_sender_buffer* impl, + * dtype_t* dtypes, + */ + +static int __pyx_f_7questdb_7ingress__pandas_row_at(struct line_sender_buffer *__pyx_v_impl, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, size_t __pyx_v_row_index, Py_ssize_t __pyx_v_at_col, int64_t __pyx_v_at_value) { + struct line_sender_error *__pyx_v_err; + Py_buffer *__pyx_v_col_buffer; + struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int64_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas_row_at", 0); + + /* "src/questdb/pandas_helpers.pxi":554 + * ssize_t at_col, + * int64_t at_value) except False: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef Py_buffer* col_buffer + * cdef dtype_t* dtype + */ + __pyx_v_err = NULL; + + /* "src/questdb/pandas_helpers.pxi":557 + * cdef Py_buffer* col_buffer + * cdef dtype_t* dtype + * if at_col >= 0: # <<<<<<<<<<<<<< + * col_buffer = &col_buffers[at_col] + * dtype = &dtypes[at_col] + */ + __pyx_t_1 = ((__pyx_v_at_col >= 0) != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":558 + * cdef dtype_t* dtype + * if at_col >= 0: + * col_buffer = &col_buffers[at_col] # <<<<<<<<<<<<<< + * dtype = &dtypes[at_col] + * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + */ + __pyx_v_col_buffer = (&(__pyx_v_col_buffers[((size_t)__pyx_v_at_col)])); + + /* "src/questdb/pandas_helpers.pxi":559 + * if at_col >= 0: + * col_buffer = &col_buffers[at_col] + * dtype = &dtypes[at_col] # <<<<<<<<<<<<<< + * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + * if at_value > 0: + */ + __pyx_v_dtype = (&(__pyx_v_dtypes[((size_t)__pyx_v_at_col)])); + + /* "src/questdb/pandas_helpers.pxi":560 + * col_buffer = &col_buffers[at_col] + * dtype = &dtypes[at_col] + * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) # <<<<<<<<<<<<<< + * if at_value > 0: + * if not line_sender_buffer_at(impl, at_value, &err): + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress__pandas_get_timestamp_cell(__pyx_v_dtype, __pyx_v_col_buffer, __pyx_v_row_index); if (unlikely(__pyx_t_2 == ((int64_t)-1L))) __PYX_ERR(2, 560, __pyx_L1_error) + __pyx_v_at_value = __pyx_t_2; + + /* "src/questdb/pandas_helpers.pxi":557 + * cdef Py_buffer* col_buffer + * cdef dtype_t* dtype + * if at_col >= 0: # <<<<<<<<<<<<<< + * col_buffer = &col_buffers[at_col] + * dtype = &dtypes[at_col] + */ + } + + /* "src/questdb/pandas_helpers.pxi":561 + * dtype = &dtypes[at_col] + * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + * if at_value > 0: # <<<<<<<<<<<<<< + * if not line_sender_buffer_at(impl, at_value, &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = ((__pyx_v_at_value > 0) != 0); + if (__pyx_t_1) { + + /* "src/questdb/pandas_helpers.pxi":562 + * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + * if at_value > 0: + * if not line_sender_buffer_at(impl, at_value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * else: + */ + __pyx_t_1 = ((!(line_sender_buffer_at(__pyx_v_impl, __pyx_v_at_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":563 + * if at_value > 0: + * if not line_sender_buffer_at(impl, at_value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * else: + * if not line_sender_buffer_at_now(impl, &err): + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 563, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 563, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":562 + * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + * if at_value > 0: + * if not line_sender_buffer_at(impl, at_value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * else: + */ + } + + /* "src/questdb/pandas_helpers.pxi":561 + * dtype = &dtypes[at_col] + * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) + * if at_value > 0: # <<<<<<<<<<<<<< + * if not line_sender_buffer_at(impl, at_value, &err): + * raise c_err_to_py(err) + */ + goto __pyx_L4; + } + + /* "src/questdb/pandas_helpers.pxi":565 + * raise c_err_to_py(err) + * else: + * if not line_sender_buffer_at_now(impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + /*else*/ { + __pyx_t_1 = ((!(line_sender_buffer_at_now(__pyx_v_impl, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "src/questdb/pandas_helpers.pxi":566 + * else: + * if not line_sender_buffer_at_now(impl, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return True + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 566, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(2, 566, __pyx_L1_error) + + /* "src/questdb/pandas_helpers.pxi":565 + * raise c_err_to_py(err) + * else: + * if not line_sender_buffer_at_now(impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + } + } + __pyx_L4:; + + /* "src/questdb/pandas_helpers.pxi":567 + * if not line_sender_buffer_at_now(impl, &err): + * raise c_err_to_py(err) + * return True # <<<<<<<<<<<<<< + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "src/questdb/pandas_helpers.pxi":547 + * + * + * cdef bint _pandas_row_at( # <<<<<<<<<<<<<< + * line_sender_buffer* impl, + * dtype_t* dtypes, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress._pandas_row_at", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":73 + * TlsError = line_sender_error_tls_error + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """Return the name of the enum.""" + * return self.name + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_16IngressErrorCode_1__str__(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ +static char __pyx_doc_7questdb_7ingress_16IngressErrorCode___str__[] = "Return the name of the enum."; +static PyMethodDef __pyx_mdef_7questdb_7ingress_16IngressErrorCode_1__str__ = {"__str__", (PyCFunction)__pyx_pw_7questdb_7ingress_16IngressErrorCode_1__str__, METH_O, __pyx_doc_7questdb_7ingress_16IngressErrorCode___str__}; +static PyObject *__pyx_pw_7questdb_7ingress_16IngressErrorCode_1__str__(PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_16IngressErrorCode___str__(__pyx_self, ((PyObject *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_16IngressErrorCode___str__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__str__", 0); + + /* "questdb/ingress.pyx":75 + * def __str__(self) -> str: + * """Return the name of the enum.""" + * return self.name # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 75, __pyx_L1_error) + __pyx_r = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":73 + * TlsError = line_sender_error_tls_error + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """Return the name of the enum.""" + * return self.name + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.IngressErrorCode.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":80 + * class IngressError(Exception): + * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" + * def __init__(self, code, msg): # <<<<<<<<<<<<<< + * super().__init__(msg) + * self._code = code + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_12IngressError_1__init__ = {"__init__", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_12IngressError_1__init__, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_self = 0; + PyObject *__pyx_v_code = 0; + PyObject *__pyx_v_msg = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_code,&__pyx_n_s_msg,0}; + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_code)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); __PYX_ERR(0, 80, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_msg)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); __PYX_ERR(0, 80, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 80, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v_self = values[0]; + __pyx_v_code = values[1]; + __pyx_v_msg = values[2]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 80, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.IngressError.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7questdb_7ingress_12IngressError___init__(__pyx_self, __pyx_v_self, __pyx_v_code, __pyx_v_msg); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_12IngressError___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_code, PyObject *__pyx_v_msg) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "questdb/ingress.pyx":81 + * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" + * def __init__(self, code, msg): + * super().__init__(msg) # <<<<<<<<<<<<<< + * self._code = code + * + */ + __pyx_t_2 = __Pyx_CyFunction_GetClassObj(__pyx_self); + if (!__pyx_t_2) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 81, __pyx_L1_error) } + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); + __Pyx_INCREF(__pyx_v_self); + __Pyx_GIVEREF(__pyx_v_self); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self); + __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_2)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_v_msg) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_msg); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":82 + * def __init__(self, code, msg): + * super().__init__(msg) + * self._code = code # <<<<<<<<<<<<<< + * + * @property + */ + if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_code_2, __pyx_v_code) < 0) __PYX_ERR(0, 82, __pyx_L1_error) + + /* "questdb/ingress.pyx":80 + * class IngressError(Exception): + * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" + * def __init__(self, code, msg): # <<<<<<<<<<<<<< + * super().__init__(msg) + * self._code = code + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress.IngressError.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":85 + * + * @property + * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< + * """Return the error code.""" + * return self._code + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_3code(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ +static char __pyx_doc_7questdb_7ingress_12IngressError_2code[] = "Return the error code."; +static PyMethodDef __pyx_mdef_7questdb_7ingress_12IngressError_3code = {"code", (PyCFunction)__pyx_pw_7questdb_7ingress_12IngressError_3code, METH_O, __pyx_doc_7questdb_7ingress_12IngressError_2code}; +static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_3code(PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("code (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_12IngressError_2code(__pyx_self, ((PyObject *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_12IngressError_2code(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("code", 0); + + /* "questdb/ingress.pyx":87 + * def code(self) -> IngressErrorCode: + * """Return the error code.""" + * return self._code # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_code_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":85 + * + * @property + * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< + * """Return the error code.""" + * return self._code + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.IngressError.code", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":90 + * + * + * cdef inline object c_err_code_to_py(line_sender_error_code code): # <<<<<<<<<<<<<< + * if code == line_sender_error_could_not_resolve_addr: + * return IngressErrorCode.CouldNotResolveAddr + */ + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_code_to_py(enum line_sender_error_code __pyx_v_code) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("c_err_code_to_py", 0); + + /* "questdb/ingress.pyx":91 + * + * cdef inline object c_err_code_to_py(line_sender_error_code code): + * if code == line_sender_error_could_not_resolve_addr: # <<<<<<<<<<<<<< + * return IngressErrorCode.CouldNotResolveAddr + * elif code == line_sender_error_invalid_api_call: + */ + switch (__pyx_v_code) { + case line_sender_error_could_not_resolve_addr: + + /* "questdb/ingress.pyx":92 + * cdef inline object c_err_code_to_py(line_sender_error_code code): + * if code == line_sender_error_could_not_resolve_addr: + * return IngressErrorCode.CouldNotResolveAddr # <<<<<<<<<<<<<< + * elif code == line_sender_error_invalid_api_call: + * return IngressErrorCode.InvalidApiCall + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CouldNotResolveAddr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 92, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":91 + * + * cdef inline object c_err_code_to_py(line_sender_error_code code): + * if code == line_sender_error_could_not_resolve_addr: # <<<<<<<<<<<<<< + * return IngressErrorCode.CouldNotResolveAddr + * elif code == line_sender_error_invalid_api_call: + */ + break; + case line_sender_error_invalid_api_call: + + /* "questdb/ingress.pyx":94 + * return IngressErrorCode.CouldNotResolveAddr + * elif code == line_sender_error_invalid_api_call: + * return IngressErrorCode.InvalidApiCall # <<<<<<<<<<<<<< + * elif code == line_sender_error_socket_error: + * return IngressErrorCode.SocketError + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 94, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_InvalidApiCall); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":93 + * if code == line_sender_error_could_not_resolve_addr: + * return IngressErrorCode.CouldNotResolveAddr + * elif code == line_sender_error_invalid_api_call: # <<<<<<<<<<<<<< + * return IngressErrorCode.InvalidApiCall + * elif code == line_sender_error_socket_error: + */ + break; + case line_sender_error_socket_error: + + /* "questdb/ingress.pyx":96 + * return IngressErrorCode.InvalidApiCall + * elif code == line_sender_error_socket_error: + * return IngressErrorCode.SocketError # <<<<<<<<<<<<<< + * elif code == line_sender_error_invalid_utf8: + * return IngressErrorCode.InvalidUtf8 + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SocketError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 96, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":95 + * elif code == line_sender_error_invalid_api_call: + * return IngressErrorCode.InvalidApiCall + * elif code == line_sender_error_socket_error: # <<<<<<<<<<<<<< + * return IngressErrorCode.SocketError + * elif code == line_sender_error_invalid_utf8: + */ + break; + case line_sender_error_invalid_utf8: + + /* "questdb/ingress.pyx":98 + * return IngressErrorCode.SocketError + * elif code == line_sender_error_invalid_utf8: + * return IngressErrorCode.InvalidUtf8 # <<<<<<<<<<<<<< + * elif code == line_sender_error_invalid_name: + * return IngressErrorCode.InvalidName + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_InvalidUtf8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":97 + * elif code == line_sender_error_socket_error: + * return IngressErrorCode.SocketError + * elif code == line_sender_error_invalid_utf8: # <<<<<<<<<<<<<< + * return IngressErrorCode.InvalidUtf8 + * elif code == line_sender_error_invalid_name: + */ + break; + case line_sender_error_invalid_name: + + /* "questdb/ingress.pyx":100 + * return IngressErrorCode.InvalidUtf8 + * elif code == line_sender_error_invalid_name: + * return IngressErrorCode.InvalidName # <<<<<<<<<<<<<< + * elif code == line_sender_error_invalid_timestamp: + * return IngressErrorCode.InvalidTimestamp + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_InvalidName); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 100, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":99 + * elif code == line_sender_error_invalid_utf8: + * return IngressErrorCode.InvalidUtf8 + * elif code == line_sender_error_invalid_name: # <<<<<<<<<<<<<< + * return IngressErrorCode.InvalidName + * elif code == line_sender_error_invalid_timestamp: + */ + break; + case line_sender_error_invalid_timestamp: + + /* "questdb/ingress.pyx":102 + * return IngressErrorCode.InvalidName + * elif code == line_sender_error_invalid_timestamp: + * return IngressErrorCode.InvalidTimestamp # <<<<<<<<<<<<<< + * elif code == line_sender_error_auth_error: + * return IngressErrorCode.AuthError + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_InvalidTimestamp); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":101 + * elif code == line_sender_error_invalid_name: + * return IngressErrorCode.InvalidName + * elif code == line_sender_error_invalid_timestamp: # <<<<<<<<<<<<<< + * return IngressErrorCode.InvalidTimestamp + * elif code == line_sender_error_auth_error: + */ + break; + case line_sender_error_auth_error: + + /* "questdb/ingress.pyx":104 + * return IngressErrorCode.InvalidTimestamp + * elif code == line_sender_error_auth_error: + * return IngressErrorCode.AuthError # <<<<<<<<<<<<<< + * elif code == line_sender_error_tls_error: + * return IngressErrorCode.TlsError + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AuthError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":103 + * elif code == line_sender_error_invalid_timestamp: + * return IngressErrorCode.InvalidTimestamp + * elif code == line_sender_error_auth_error: # <<<<<<<<<<<<<< + * return IngressErrorCode.AuthError + * elif code == line_sender_error_tls_error: + */ + break; + case line_sender_error_tls_error: + + /* "questdb/ingress.pyx":106 + * return IngressErrorCode.AuthError + * elif code == line_sender_error_tls_error: + * return IngressErrorCode.TlsError # <<<<<<<<<<<<<< + * else: + * raise ValueError('Internal error converting error code.') + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_TlsError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":105 + * elif code == line_sender_error_auth_error: + * return IngressErrorCode.AuthError + * elif code == line_sender_error_tls_error: # <<<<<<<<<<<<<< + * return IngressErrorCode.TlsError + * else: + */ + break; + default: + + /* "questdb/ingress.pyx":108 + * return IngressErrorCode.TlsError + * else: + * raise ValueError('Internal error converting error code.') # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 108, __pyx_L1_error) + break; + } + + /* "questdb/ingress.pyx":90 + * + * + * cdef inline object c_err_code_to_py(line_sender_error_code code): # <<<<<<<<<<<<<< + * if code == line_sender_error_could_not_resolve_addr: + * return IngressErrorCode.CouldNotResolveAddr + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.c_err_code_to_py", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":111 + * + * + * cdef inline object c_err_to_code_and_msg(line_sender_error* err): # <<<<<<<<<<<<<< + * """Construct a ``SenderError`` from a C error, which will be freed.""" + * cdef line_sender_error_code code = line_sender_error_get_code(err) + */ + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_code_and_msg(struct line_sender_error *__pyx_v_err) { + enum line_sender_error_code __pyx_v_code; + size_t __pyx_v_c_len; + char const *__pyx_v_c_msg; + PyObject *__pyx_v_py_msg = 0; + PyObject *__pyx_v_py_code = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_t_3; + char const *__pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("c_err_to_code_and_msg", 0); + + /* "questdb/ingress.pyx":113 + * cdef inline object c_err_to_code_and_msg(line_sender_error* err): + * """Construct a ``SenderError`` from a C error, which will be freed.""" + * cdef line_sender_error_code code = line_sender_error_get_code(err) # <<<<<<<<<<<<<< + * cdef size_t c_len = 0 + * cdef const char* c_msg = line_sender_error_msg(err, &c_len) + */ + __pyx_v_code = line_sender_error_get_code(__pyx_v_err); + + /* "questdb/ingress.pyx":114 + * """Construct a ``SenderError`` from a C error, which will be freed.""" + * cdef line_sender_error_code code = line_sender_error_get_code(err) + * cdef size_t c_len = 0 # <<<<<<<<<<<<<< + * cdef const char* c_msg = line_sender_error_msg(err, &c_len) + * cdef object py_err + */ + __pyx_v_c_len = 0; + + /* "questdb/ingress.pyx":115 + * cdef line_sender_error_code code = line_sender_error_get_code(err) + * cdef size_t c_len = 0 + * cdef const char* c_msg = line_sender_error_msg(err, &c_len) # <<<<<<<<<<<<<< + * cdef object py_err + * cdef object py_msg + */ + __pyx_v_c_msg = line_sender_error_msg(__pyx_v_err, (&__pyx_v_c_len)); + + /* "questdb/ingress.pyx":119 + * cdef object py_msg + * cdef object py_code + * try: # <<<<<<<<<<<<<< + * py_code = c_err_code_to_py(code) + * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) + */ + /*try:*/ { + + /* "questdb/ingress.pyx":120 + * cdef object py_code + * try: + * py_code = c_err_code_to_py(code) # <<<<<<<<<<<<<< + * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) + * return (py_code, py_msg) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_code_to_py(__pyx_v_code); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 120, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_py_code = __pyx_t_1; + __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":121 + * try: + * py_code = c_err_code_to_py(code) + * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) # <<<<<<<<<<<<<< + * return (py_code, py_msg) + * finally: + */ + __pyx_t_1 = PyUnicode_FromStringAndSize(__pyx_v_c_msg, ((Py_ssize_t)__pyx_v_c_len)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 121, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_py_msg = __pyx_t_1; + __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":122 + * py_code = c_err_code_to_py(code) + * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) + * return (py_code, py_msg) # <<<<<<<<<<<<<< + * finally: + * line_sender_error_free(err) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 122, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_py_code); + __Pyx_GIVEREF(__pyx_v_py_code); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_py_code); + __Pyx_INCREF(__pyx_v_py_msg); + __Pyx_GIVEREF(__pyx_v_py_msg); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_py_msg); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L3_return; + } + + /* "questdb/ingress.pyx":124 + * return (py_code, py_msg) + * finally: + * line_sender_error_free(err) # <<<<<<<<<<<<<< + * + * + */ + /*finally:*/ { + __pyx_L4_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0)) __Pyx_ErrFetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_9); + __Pyx_XGOTREF(__pyx_t_10); + __pyx_t_2 = __pyx_lineno; __pyx_t_3 = __pyx_clineno; __pyx_t_4 = __pyx_filename; + { + line_sender_error_free(__pyx_v_err); + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_8); + __Pyx_XGIVEREF(__pyx_t_9); + __Pyx_XGIVEREF(__pyx_t_10); + __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); + } + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_XGIVEREF(__pyx_t_7); + __Pyx_ErrRestore(__pyx_t_5, __pyx_t_6, __pyx_t_7); + __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; + __pyx_lineno = __pyx_t_2; __pyx_clineno = __pyx_t_3; __pyx_filename = __pyx_t_4; + goto __pyx_L1_error; + } + __pyx_L3_return: { + __pyx_t_10 = __pyx_r; + __pyx_r = 0; + line_sender_error_free(__pyx_v_err); + __pyx_r = __pyx_t_10; + __pyx_t_10 = 0; + goto __pyx_L0; + } + } + + /* "questdb/ingress.pyx":111 + * + * + * cdef inline object c_err_to_code_and_msg(line_sender_error* err): # <<<<<<<<<<<<<< + * """Construct a ``SenderError`` from a C error, which will be freed.""" + * cdef line_sender_error_code code = line_sender_error_get_code(err) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.c_err_to_code_and_msg", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_py_msg); + __Pyx_XDECREF(__pyx_v_py_code); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":127 + * + * + * cdef inline object c_err_to_py(line_sender_error* err): # <<<<<<<<<<<<<< + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) + */ + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py(struct line_sender_error *__pyx_v_err) { + PyObject *__pyx_v_tup = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("c_err_to_py", 0); + + /* "questdb/ingress.pyx":129 + * cdef inline object c_err_to_py(line_sender_error* err): + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) # <<<<<<<<<<<<<< + * return IngressError(tup[0], tup[1]) + * + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_to_code_and_msg(__pyx_v_err); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_tup = __pyx_t_1; + __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":130 + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) + * return IngressError(tup[0], tup[1]) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_tup, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_tup, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + __pyx_t_6 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } else + #endif + { + __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__pyx_t_5) { + __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL; + } + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4); + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":127 + * + * + * cdef inline object c_err_to_py(line_sender_error* err): # <<<<<<<<<<<<<< + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress.c_err_to_py", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_tup); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":133 + * + * + * cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): # <<<<<<<<<<<<<< + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) + */ + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py_fmt(struct line_sender_error *__pyx_v_err, PyObject *__pyx_v_fmt) { + PyObject *__pyx_v_tup = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("c_err_to_py_fmt", 0); + + /* "questdb/ingress.pyx":135 + * cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) # <<<<<<<<<<<<<< + * return IngressError(tup[0], fmt.format(tup[1])) + * + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_to_code_and_msg(__pyx_v_err); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 135, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_tup = __pyx_t_1; + __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":136 + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) + * return IngressError(tup[0], fmt.format(tup[1])) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_tup, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_tup, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PyUnicode_Type_format, __pyx_v_fmt, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + __pyx_t_6 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else + #endif + { + __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__pyx_t_4) { + __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL; + } + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_5); + __pyx_t_3 = 0; + __pyx_t_5 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":133 + * + * + * cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): # <<<<<<<<<<<<<< + * """Construct an ``IngressError`` from a C error, which will be freed.""" + * cdef object tup = c_err_to_code_and_msg(err) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress.c_err_to_py_fmt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_tup); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":139 + * + * + * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): # <<<<<<<<<<<<<< + * return IngressError( + * IngressErrorCode.InvalidUtf8, + */ + +static PyObject *__pyx_f_7questdb_7ingress__utf8_decode_error(PyObject *__pyx_v_string, uint32_t __pyx_v_bad_codepoint) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + Py_ssize_t __pyx_t_5; + Py_UCS4 __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_utf8_decode_error", 0); + + /* "questdb/ingress.pyx":140 + * + * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): + * return IngressError( # <<<<<<<<<<<<<< + * IngressErrorCode.InvalidUtf8, + * f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "questdb/ingress.pyx":141 + * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): + * return IngressError( + * IngressErrorCode.InvalidUtf8, # <<<<<<<<<<<<<< + * f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + + * 'Cannot be encoded as UTF-8.') + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_InvalidUtf8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":142 + * return IngressError( + * IngressErrorCode.InvalidUtf8, + * f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + # <<<<<<<<<<<<<< + * 'Cannot be encoded as UTF-8.') + * + */ + __pyx_t_3 = PyTuple_New(5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = 0; + __pyx_t_6 = 127; + __Pyx_INCREF(__pyx_kp_u_Invalid_codepoint_0x); + __pyx_t_5 += 20; + __Pyx_GIVEREF(__pyx_kp_u_Invalid_codepoint_0x); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Invalid_codepoint_0x); + __pyx_t_7 = __Pyx_PyInt_From_uint32_t(__pyx_v_bad_codepoint); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyObject_Format(__pyx_t_7, __pyx_n_u_x); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_6; + __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_INCREF(__pyx_kp_u_in_string); + __pyx_t_5 += 11; + __Pyx_GIVEREF(__pyx_kp_u_in_string); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u_in_string); + __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_string), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_6; + __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_INCREF(__pyx_kp_u__17); + __pyx_t_5 += 2; + __Pyx_GIVEREF(__pyx_kp_u__17); + PyTuple_SET_ITEM(__pyx_t_3, 4, __pyx_kp_u__17); + __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_3, 5, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_8, __pyx_kp_u_Cannot_be_encoded_as_UTF_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_8 = NULL; + __pyx_t_9 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_9 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_8, __pyx_t_4, __pyx_t_3}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_8, __pyx_t_4, __pyx_t_3}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else + #endif + { + __pyx_t_7 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__pyx_t_8) { + __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8); __pyx_t_8 = NULL; + } + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_9, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_9, __pyx_t_3); + __pyx_t_4 = 0; + __pyx_t_3 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":139 + * + * + * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): # <<<<<<<<<<<<<< + * return IngressError( + * IngressErrorCode.InvalidUtf8, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("questdb.ingress._utf8_decode_error", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":146 + * + * + * cdef bint str_to_utf8( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * str string, + */ + +static int __pyx_f_7questdb_7ingress_str_to_utf8(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_string, struct line_sender_utf8 *__pyx_v_utf8_out) { + size_t __pyx_v_count; + int __pyx_v_kind; + uint32_t __pyx_v_bad_codepoint; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + Py_ssize_t __pyx_t_4; + Py_UCS4 __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("str_to_utf8", 0); + + /* "questdb/ingress.pyx":160 + * cdef size_t count + * cdef int kind + * cdef uint32_t bad_codepoint = 0 # <<<<<<<<<<<<<< + * PyUnicode_READY(string) + * count = (PyUnicode_GET_LENGTH(string)) + */ + __pyx_v_bad_codepoint = 0; + + /* "questdb/ingress.pyx":161 + * cdef int kind + * cdef uint32_t bad_codepoint = 0 + * PyUnicode_READY(string) # <<<<<<<<<<<<<< + * count = (PyUnicode_GET_LENGTH(string)) + * + */ + __pyx_t_1 = PyUnicode_READY(__pyx_v_string); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 161, __pyx_L1_error) + + /* "questdb/ingress.pyx":162 + * cdef uint32_t bad_codepoint = 0 + * PyUnicode_READY(string) + * count = (PyUnicode_GET_LENGTH(string)) # <<<<<<<<<<<<<< + * + * # We optimize the common case of ASCII strings. + */ + __pyx_v_count = ((size_t)PyUnicode_GET_LENGTH(__pyx_v_string)); + + /* "questdb/ingress.pyx":167 + * # This avoid memory allocations and copies altogether. + * # We get away with this because ASCII is a subset of UTF-8. + * if PyUnicode_IS_COMPACT_ASCII(string): # <<<<<<<<<<<<<< + * utf8_out.len = count + * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) + */ + __pyx_t_2 = (PyUnicode_IS_COMPACT_ASCII(__pyx_v_string) != 0); + if (__pyx_t_2) { + + /* "questdb/ingress.pyx":168 + * # We get away with this because ASCII is a subset of UTF-8. + * if PyUnicode_IS_COMPACT_ASCII(string): + * utf8_out.len = count # <<<<<<<<<<<<<< + * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) + * return True + */ + __pyx_v_utf8_out->len = __pyx_v_count; + + /* "questdb/ingress.pyx":169 + * if PyUnicode_IS_COMPACT_ASCII(string): + * utf8_out.len = count + * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_v_utf8_out->buf = ((char const *)PyUnicode_1BYTE_DATA(__pyx_v_string)); + + /* "questdb/ingress.pyx":170 + * utf8_out.len = count + * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) + * return True # <<<<<<<<<<<<<< + * + * kind = PyUnicode_KIND(string) + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "questdb/ingress.pyx":167 + * # This avoid memory allocations and copies altogether. + * # We get away with this because ASCII is a subset of UTF-8. + * if PyUnicode_IS_COMPACT_ASCII(string): # <<<<<<<<<<<<<< + * utf8_out.len = count + * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) + */ + } + + /* "questdb/ingress.pyx":172 + * return True + * + * kind = PyUnicode_KIND(string) # <<<<<<<<<<<<<< + * if kind == PyUnicode_1BYTE_KIND: + * # No error handling for UCS1: All code points translate into valid UTF8. + */ + __pyx_v_kind = PyUnicode_KIND(__pyx_v_string); + + /* "questdb/ingress.pyx":173 + * + * kind = PyUnicode_KIND(string) + * if kind == PyUnicode_1BYTE_KIND: # <<<<<<<<<<<<<< + * # No error handling for UCS1: All code points translate into valid UTF8. + * qdb_ucs1_to_utf8( + */ + switch (__pyx_v_kind) { + case PyUnicode_1BYTE_KIND: + + /* "questdb/ingress.pyx":175 + * if kind == PyUnicode_1BYTE_KIND: + * # No error handling for UCS1: All code points translate into valid UTF8. + * qdb_ucs1_to_utf8( # <<<<<<<<<<<<<< + * b, + * count, + */ + qdb_ucs1_to_utf8(__pyx_v_b, __pyx_v_count, PyUnicode_1BYTE_DATA(__pyx_v_string), (&__pyx_v_utf8_out->len), (&__pyx_v_utf8_out->buf)); + + /* "questdb/ingress.pyx":173 + * + * kind = PyUnicode_KIND(string) + * if kind == PyUnicode_1BYTE_KIND: # <<<<<<<<<<<<<< + * # No error handling for UCS1: All code points translate into valid UTF8. + * qdb_ucs1_to_utf8( + */ + break; + case PyUnicode_2BYTE_KIND: + + /* "questdb/ingress.pyx":182 + * &utf8_out.buf) + * elif kind == PyUnicode_2BYTE_KIND: + * if not qdb_ucs2_to_utf8( # <<<<<<<<<<<<<< + * b, + * count, + */ + __pyx_t_2 = ((!(qdb_ucs2_to_utf8(__pyx_v_b, __pyx_v_count, PyUnicode_2BYTE_DATA(__pyx_v_string), (&__pyx_v_utf8_out->len), (&__pyx_v_utf8_out->buf), (&__pyx_v_bad_codepoint)) != 0)) != 0); + if (unlikely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":189 + * &utf8_out.buf, + * &bad_codepoint): + * raise _utf8_decode_error(string, bad_codepoint) # <<<<<<<<<<<<<< + * elif kind == PyUnicode_4BYTE_KIND: + * if not qdb_ucs4_to_utf8( + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress__utf8_decode_error(__pyx_v_string, __pyx_v_bad_codepoint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 189, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 189, __pyx_L1_error) + + /* "questdb/ingress.pyx":182 + * &utf8_out.buf) + * elif kind == PyUnicode_2BYTE_KIND: + * if not qdb_ucs2_to_utf8( # <<<<<<<<<<<<<< + * b, + * count, + */ + } + + /* "questdb/ingress.pyx":181 + * &utf8_out.len, + * &utf8_out.buf) + * elif kind == PyUnicode_2BYTE_KIND: # <<<<<<<<<<<<<< + * if not qdb_ucs2_to_utf8( + * b, + */ + break; + case PyUnicode_4BYTE_KIND: + + /* "questdb/ingress.pyx":191 + * raise _utf8_decode_error(string, bad_codepoint) + * elif kind == PyUnicode_4BYTE_KIND: + * if not qdb_ucs4_to_utf8( # <<<<<<<<<<<<<< + * b, + * count, + */ + __pyx_t_2 = ((!(qdb_ucs4_to_utf8(__pyx_v_b, __pyx_v_count, ((uint32_t const *)PyUnicode_4BYTE_DATA(__pyx_v_string)), (&__pyx_v_utf8_out->len), (&__pyx_v_utf8_out->buf), (&__pyx_v_bad_codepoint)) != 0)) != 0); + if (unlikely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":203 + * &utf8_out.buf, + * &bad_codepoint): + * raise _utf8_decode_error(string, bad_codepoint) # <<<<<<<<<<<<<< + * else: + * raise ValueError(f'Unknown UCS kind: {kind}.') + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress__utf8_decode_error(__pyx_v_string, __pyx_v_bad_codepoint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 203, __pyx_L1_error) + + /* "questdb/ingress.pyx":191 + * raise _utf8_decode_error(string, bad_codepoint) + * elif kind == PyUnicode_4BYTE_KIND: + * if not qdb_ucs4_to_utf8( # <<<<<<<<<<<<<< + * b, + * count, + */ + } + + /* "questdb/ingress.pyx":190 + * &bad_codepoint): + * raise _utf8_decode_error(string, bad_codepoint) + * elif kind == PyUnicode_4BYTE_KIND: # <<<<<<<<<<<<<< + * if not qdb_ucs4_to_utf8( + * b, + */ + break; + default: + + /* "questdb/ingress.pyx":205 + * raise _utf8_decode_error(string, bad_codepoint) + * else: + * raise ValueError(f'Unknown UCS kind: {kind}.') # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 205, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_Unknown_UCS_kind); + __pyx_t_4 += 18; + __Pyx_GIVEREF(__pyx_kp_u_Unknown_UCS_kind); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Unknown_UCS_kind); + __pyx_t_6 = __Pyx_PyUnicode_From_int(__pyx_v_kind, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 205, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__6); + __pyx_t_4 += 1; + __Pyx_GIVEREF(__pyx_kp_u__6); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__6); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 205, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 205, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 205, __pyx_L1_error) + break; + } + + /* "questdb/ingress.pyx":206 + * else: + * raise ValueError(f'Unknown UCS kind: {kind}.') + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "questdb/ingress.pyx":146 + * + * + * cdef bint str_to_utf8( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * str string, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("questdb.ingress.str_to_utf8", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":209 + * + * + * cdef bint str_to_table_name( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * str string, + */ + +static int __pyx_f_7questdb_7ingress_str_to_table_name(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_string, struct line_sender_table_name *__pyx_v_name_out) { + struct line_sender_error *__pyx_v_err; + struct line_sender_utf8 __pyx_v_utf8; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("str_to_table_name", 0); + + /* "questdb/ingress.pyx":217 + * Also see `str_to_utf8`. + * """ + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":219 + * cdef line_sender_error* err = NULL + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) # <<<<<<<<<<<<<< + * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_string, (&__pyx_v_utf8)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 219, __pyx_L1_error) + + /* "questdb/ingress.pyx":220 + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) + * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + __pyx_t_1 = ((!(line_sender_table_name_init(__pyx_v_name_out, __pyx_v_utf8.len, __pyx_v_utf8.buf, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":221 + * str_to_utf8(b, string, &utf8) + * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 221, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 221, __pyx_L1_error) + + /* "questdb/ingress.pyx":220 + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) + * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + } + + /* "questdb/ingress.pyx":222 + * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "questdb/ingress.pyx":209 + * + * + * cdef bint str_to_table_name( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * str string, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.str_to_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":225 + * + * + * cdef bint str_to_column_name( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * str string, + */ + +static int __pyx_f_7questdb_7ingress_str_to_column_name(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_string, struct line_sender_column_name *__pyx_v_name_out) { + struct line_sender_error *__pyx_v_err; + struct line_sender_utf8 __pyx_v_utf8; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("str_to_column_name", 0); + + /* "questdb/ingress.pyx":233 + * Also see `str_to_utf8`. + * """ + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":235 + * cdef line_sender_error* err = NULL + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) # <<<<<<<<<<<<<< + * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_string, (&__pyx_v_utf8)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 235, __pyx_L1_error) + + /* "questdb/ingress.pyx":236 + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) + * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + __pyx_t_1 = ((!(line_sender_column_name_init(__pyx_v_name_out, __pyx_v_utf8.len, __pyx_v_utf8.buf, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":237 + * str_to_utf8(b, string, &utf8) + * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return True + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 237, __pyx_L1_error) + + /* "questdb/ingress.pyx":236 + * cdef line_sender_utf8 utf8 + * str_to_utf8(b, string, &utf8) + * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return True + */ + } + + /* "questdb/ingress.pyx":238 + * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): + * raise c_err_to_py(err) + * return True # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 1; + goto __pyx_L0; + + /* "questdb/ingress.pyx":225 + * + * + * cdef bint str_to_column_name( # <<<<<<<<<<<<<< + * qdb_pystr_buf* b, + * str string, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.str_to_column_name", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":241 + * + * + * cdef int64_t datetime_to_micros(datetime dt): # <<<<<<<<<<<<<< + * """ + * Convert a `datetime.datetime` to microseconds since the epoch. + */ + +static int64_t __pyx_f_7questdb_7ingress_datetime_to_micros(PyDateTime_DateTime *__pyx_v_dt) { + int64_t __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int64_t __pyx_t_4; + int64_t __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("datetime_to_micros", 0); + + /* "questdb/ingress.pyx":246 + * """ + * return ( + * (dt.timestamp()) * # <<<<<<<<<<<<<< + * (1000000) + + * (dt.microsecond)) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_timestamp); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 246, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyInt_As_int64_t(__pyx_t_1); if (unlikely((__pyx_t_4 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 246, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":248 + * (dt.timestamp()) * + * (1000000) + + * (dt.microsecond)) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_microsecond); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 248, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_1); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 248, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":247 + * return ( + * (dt.timestamp()) * + * (1000000) + # <<<<<<<<<<<<<< + * (dt.microsecond)) + * + */ + __pyx_r = ((((int64_t)__pyx_t_4) * ((int64_t)0xF4240)) + ((int64_t)__pyx_t_5)); + goto __pyx_L0; + + /* "questdb/ingress.pyx":241 + * + * + * cdef int64_t datetime_to_micros(datetime dt): # <<<<<<<<<<<<<< + * """ + * Convert a `datetime.datetime` to microseconds since the epoch. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_WriteUnraisable("questdb.ingress.datetime_to_micros", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":251 + * + * + * cdef int64_t datetime_to_nanos(datetime dt): # <<<<<<<<<<<<<< + * """ + * Convert a `datetime.datetime` to nanoseconds since the epoch. + */ + +static int64_t __pyx_f_7questdb_7ingress_datetime_to_nanos(PyDateTime_DateTime *__pyx_v_dt) { + int64_t __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int64_t __pyx_t_4; + int64_t __pyx_t_5; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("datetime_to_nanos", 0); + + /* "questdb/ingress.pyx":256 + * """ + * return ( + * (dt.timestamp()) * # <<<<<<<<<<<<<< + * (1000000000) + + * (dt.microsecond * 1000)) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_timestamp); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 256, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 256, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_4 = __Pyx_PyInt_As_int64_t(__pyx_t_1); if (unlikely((__pyx_t_4 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 256, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":258 + * (dt.timestamp()) * + * (1000000000) + + * (dt.microsecond * 1000)) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_microsecond); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 258, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_int_1000); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 258, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 258, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":257 + * return ( + * (dt.timestamp()) * + * (1000000000) + # <<<<<<<<<<<<<< + * (dt.microsecond * 1000)) + * + */ + __pyx_r = ((((int64_t)__pyx_t_4) * ((int64_t)0x3B9ACA00)) + ((int64_t)__pyx_t_5)); + goto __pyx_L0; + + /* "questdb/ingress.pyx":251 + * + * + * cdef int64_t datetime_to_nanos(datetime dt): # <<<<<<<<<<<<<< + * """ + * Convert a `datetime.datetime` to nanoseconds since the epoch. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_WriteUnraisable("questdb.ingress.datetime_to_nanos", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":292 + * cdef int64_t _value + * + * def __cinit__(self, value: int): # <<<<<<<<<<<<<< + * if value < 0: + * raise ValueError('value must positive integer.') + */ + +/* Python wrapper */ +static int __pyx_pw_7questdb_7ingress_15TimestampMicros_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7questdb_7ingress_15TimestampMicros_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_value = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_value_2,0}; + PyObject* values[1] = {0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_value_2)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 292, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + } + __pyx_v_value = values[0]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 292, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros___cinit__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self), __pyx_v_value); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7questdb_7ingress_15TimestampMicros___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, PyObject *__pyx_v_value) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int64_t __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__cinit__", 0); + + /* "questdb/ingress.pyx":293 + * + * def __cinit__(self, value: int): + * if value < 0: # <<<<<<<<<<<<<< + * raise ValueError('value must positive integer.') + * self._value = value + */ + __pyx_t_1 = PyObject_RichCompare(__pyx_v_value, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 293, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 293, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":294 + * def __cinit__(self, value: int): + * if value < 0: + * raise ValueError('value must positive integer.') # <<<<<<<<<<<<<< + * self._value = value + * + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 294, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 294, __pyx_L1_error) + + /* "questdb/ingress.pyx":293 + * + * def __cinit__(self, value: int): + * if value < 0: # <<<<<<<<<<<<<< + * raise ValueError('value must positive integer.') + * self._value = value + */ + } + + /* "questdb/ingress.pyx":295 + * if value < 0: + * raise ValueError('value must positive integer.') + * self._value = value # <<<<<<<<<<<<<< + * + * @classmethod + */ + __pyx_t_3 = __Pyx_PyInt_As_int64_t(__pyx_v_value); if (unlikely((__pyx_t_3 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 295, __pyx_L1_error) + __pyx_v_self->_value = __pyx_t_3; + + /* "questdb/ingress.pyx":292 + * cdef int64_t _value + * + * def __cinit__(self, value: int): # <<<<<<<<<<<<<< + * if value < 0: + * raise ValueError('value must positive integer.') + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":298 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt); /*proto*/ +static char __pyx_doc_7questdb_7ingress_15TimestampMicros_2from_datetime[] = "\n Construct a ``TimestampMicros`` from a ``datetime.datetime`` object.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_15TimestampMicros_3from_datetime = {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_15TimestampMicros_2from_datetime}; +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt) { + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("from_datetime (wrapper)", 0); + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime, 1, "dt", 0))) __PYX_ERR(0, 298, __pyx_L1_error) + __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_2from_datetime(((PyTypeObject*)__pyx_v_cls), ((PyDateTime_DateTime *)__pyx_v_dt)); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("from_datetime", 0); + + /* "questdb/ingress.pyx":302 + * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. + * """ + * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< + * raise TypeError('dt must be a datetime object.') + * return cls(datetime_to_micros(dt)) + */ + __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime); + __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); + if (unlikely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":303 + * """ + * if not isinstance(dt, datetime): + * raise TypeError('dt must be a datetime object.') # <<<<<<<<<<<<<< + * return cls(datetime_to_micros(dt)) + * + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 303, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 303, __pyx_L1_error) + + /* "questdb/ingress.pyx":302 + * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. + * """ + * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< + * raise TypeError('dt must be a datetime object.') + * return cls(datetime_to_micros(dt)) + */ + } + + /* "questdb/ingress.pyx":304 + * if not isinstance(dt, datetime): + * raise TypeError('dt must be a datetime object.') + * return cls(datetime_to_micros(dt)) # <<<<<<<<<<<<<< + * + * @property + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_f_7questdb_7ingress_datetime_to_micros(__pyx_v_dt)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 304, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_v_cls), __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 304, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":298 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("questdb.ingress.TimestampMicros.from_datetime", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":307 + * + * @property + * def value(self) -> int: # <<<<<<<<<<<<<< + * """Number of microseconds.""" + * return self._value + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5value_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5value_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_5value___get__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "questdb/ingress.pyx":309 + * def value(self) -> int: + * """Number of microseconds.""" + * return self._value # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 309, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":307 + * + * @property + * def value(self) -> int: # <<<<<<<<<<<<<< + * """Number of microseconds.""" + * return self._value + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampMicros.value.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_15TimestampMicros_5__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__, METH_NOARGS, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_4__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_15TimestampMicros_7__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__, METH_O, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_6__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":343 + * cdef int64_t _value + * + * def __cinit__(self, value: int): # <<<<<<<<<<<<<< + * if value < 0: + * raise ValueError('value must positive integer.') + */ + +/* Python wrapper */ +static int __pyx_pw_7questdb_7ingress_14TimestampNanos_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7questdb_7ingress_14TimestampNanos_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_value = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_value_2,0}; + PyObject* values[1] = {0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_value_2)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 343, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + } + __pyx_v_value = values[0]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 343, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos___cinit__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self), __pyx_v_value); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7questdb_7ingress_14TimestampNanos___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, PyObject *__pyx_v_value) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int64_t __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__cinit__", 0); + + /* "questdb/ingress.pyx":344 + * + * def __cinit__(self, value: int): + * if value < 0: # <<<<<<<<<<<<<< + * raise ValueError('value must positive integer.') + * self._value = value + */ + __pyx_t_1 = PyObject_RichCompare(__pyx_v_value, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 344, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 344, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":345 + * def __cinit__(self, value: int): + * if value < 0: + * raise ValueError('value must positive integer.') # <<<<<<<<<<<<<< + * self._value = value + * + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 345, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 345, __pyx_L1_error) + + /* "questdb/ingress.pyx":344 + * + * def __cinit__(self, value: int): + * if value < 0: # <<<<<<<<<<<<<< + * raise ValueError('value must positive integer.') + * self._value = value + */ + } + + /* "questdb/ingress.pyx":346 + * if value < 0: + * raise ValueError('value must positive integer.') + * self._value = value # <<<<<<<<<<<<<< + * + * @classmethod + */ + __pyx_t_3 = __Pyx_PyInt_As_int64_t(__pyx_v_value); if (unlikely((__pyx_t_3 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 346, __pyx_L1_error) + __pyx_v_self->_value = __pyx_t_3; + + /* "questdb/ingress.pyx":343 + * cdef int64_t _value + * + * def __cinit__(self, value: int): # <<<<<<<<<<<<<< + * if value < 0: + * raise ValueError('value must positive integer.') + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":349 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt); /*proto*/ +static char __pyx_doc_7questdb_7ingress_14TimestampNanos_2from_datetime[] = "\n Construct a ``TimestampNanos`` from a ``datetime.datetime`` object.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_14TimestampNanos_3from_datetime = {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_14TimestampNanos_2from_datetime}; +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt) { + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("from_datetime (wrapper)", 0); + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime, 1, "dt", 0))) __PYX_ERR(0, 349, __pyx_L1_error) + __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_2from_datetime(((PyTypeObject*)__pyx_v_cls), ((PyDateTime_DateTime *)__pyx_v_dt)); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("from_datetime", 0); + + /* "questdb/ingress.pyx":353 + * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. + * """ + * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< + * raise TypeError('dt must be a datetime object.') + * return cls(datetime_to_nanos(dt)) + */ + __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime); + __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); + if (unlikely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":354 + * """ + * if not isinstance(dt, datetime): + * raise TypeError('dt must be a datetime object.') # <<<<<<<<<<<<<< + * return cls(datetime_to_nanos(dt)) + * + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 354, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 354, __pyx_L1_error) + + /* "questdb/ingress.pyx":353 + * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. + * """ + * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< + * raise TypeError('dt must be a datetime object.') + * return cls(datetime_to_nanos(dt)) + */ + } + + /* "questdb/ingress.pyx":355 + * if not isinstance(dt, datetime): + * raise TypeError('dt must be a datetime object.') + * return cls(datetime_to_nanos(dt)) # <<<<<<<<<<<<<< + * + * @property + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_f_7questdb_7ingress_datetime_to_nanos(__pyx_v_dt)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_v_cls), __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 355, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":349 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("questdb.ingress.TimestampNanos.from_datetime", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":358 + * + * @property + * def value(self) -> int: # <<<<<<<<<<<<<< + * """Number of nanoseconds.""" + * return self._value + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5value_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5value_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_5value___get__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "questdb/ingress.pyx":360 + * def value(self) -> int: + * """Number of nanoseconds.""" + * return self._value # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 360, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":358 + * + * @property + * def value(self) -> int: # <<<<<<<<<<<<<< + * """Number of nanoseconds.""" + * return self._value + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampNanos.value.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_14TimestampNanos_5__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__, METH_NOARGS, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_4__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_14TimestampNanos_7__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__, METH_O, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_6__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":363 + * + * + * cdef _check_is_pandas_dataframe(data): # <<<<<<<<<<<<<< + * exp_mod = 'pandas.core.frame' + * exp_name = 'DataFrame' + */ + +static PyObject *__pyx_f_7questdb_7ingress__check_is_pandas_dataframe(PyObject *__pyx_v_data) { + PyObject *__pyx_v_exp_mod = NULL; + PyObject *__pyx_v_exp_name = NULL; + PyTypeObject *__pyx_v_t = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + Py_ssize_t __pyx_t_4; + Py_UCS4 __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_check_is_pandas_dataframe", 0); + + /* "questdb/ingress.pyx":364 + * + * cdef _check_is_pandas_dataframe(data): + * exp_mod = 'pandas.core.frame' # <<<<<<<<<<<<<< + * exp_name = 'DataFrame' + * t = type(data) + */ + __Pyx_INCREF(__pyx_kp_u_pandas_core_frame); + __pyx_v_exp_mod = __pyx_kp_u_pandas_core_frame; + + /* "questdb/ingress.pyx":365 + * cdef _check_is_pandas_dataframe(data): + * exp_mod = 'pandas.core.frame' + * exp_name = 'DataFrame' # <<<<<<<<<<<<<< + * t = type(data) + * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): + */ + __Pyx_INCREF(__pyx_n_u_DataFrame); + __pyx_v_exp_name = __pyx_n_u_DataFrame; + + /* "questdb/ingress.pyx":366 + * exp_mod = 'pandas.core.frame' + * exp_name = 'DataFrame' + * t = type(data) # <<<<<<<<<<<<<< + * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): + * raise TypeError( + */ + __Pyx_INCREF(((PyObject *)Py_TYPE(__pyx_v_data))); + __pyx_v_t = ((PyTypeObject*)((PyObject *)Py_TYPE(__pyx_v_data))); + + /* "questdb/ingress.pyx":367 + * exp_name = 'DataFrame' + * t = type(data) + * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): # <<<<<<<<<<<<<< + * raise TypeError( + * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_module); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 367, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = (__Pyx_PyUnicode_Equals(__pyx_t_2, __pyx_v_exp_mod, Py_NE)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 367, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (!__pyx_t_3) { + } else { + __pyx_t_1 = __pyx_t_3; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_qualname); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 367, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = (__Pyx_PyUnicode_Equals(__pyx_t_2, __pyx_v_exp_name, Py_NE)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 367, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_1 = __pyx_t_3; + __pyx_L4_bool_binop_done:; + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":369 + * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): + * raise TypeError( + * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + # <<<<<<<<<<<<<< + * f'not {t.__module__}.{t.__qualname__}.') + * + */ + __pyx_t_2 = PyTuple_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 369, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_Bad_argument_data_Expected); + __pyx_t_4 += 30; + __Pyx_GIVEREF(__pyx_kp_u_Bad_argument_data_Expected); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_Bad_argument_data_Expected); + __Pyx_INCREF(__pyx_v_exp_mod); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_mod) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_mod) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_exp_mod); + __Pyx_GIVEREF(__pyx_v_exp_mod); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_exp_mod); + __Pyx_INCREF(__pyx_kp_u__6); + __pyx_t_4 += 1; + __Pyx_GIVEREF(__pyx_kp_u__6); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); + __Pyx_INCREF(__pyx_v_exp_name); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_name) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_name) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_exp_name); + __Pyx_GIVEREF(__pyx_v_exp_name); + PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_v_exp_name); + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_kp_u__24); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 5, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 369, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":370 + * raise TypeError( + * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + + * f'not {t.__module__}.{t.__qualname__}.') # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_2 = PyTuple_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_not); + __pyx_t_4 += 4; + __Pyx_GIVEREF(__pyx_kp_u_not); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_not); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_module); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_8); + __pyx_t_8 = 0; + __Pyx_INCREF(__pyx_kp_u__6); + __pyx_t_4 += 1; + __Pyx_GIVEREF(__pyx_kp_u__6); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_qualname); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_INCREF(__pyx_kp_u__6); + __pyx_t_4 += 1; + __Pyx_GIVEREF(__pyx_kp_u__6); + PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_kp_u__6); + __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_2, 5, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":369 + * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): + * raise TypeError( + * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + # <<<<<<<<<<<<<< + * f'not {t.__module__}.{t.__qualname__}.') + * + */ + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 369, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":368 + * t = type(data) + * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + + * f'not {t.__module__}.{t.__qualname__}.') + */ + __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 368, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_7, 0, 0, 0); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __PYX_ERR(0, 368, __pyx_L1_error) + + /* "questdb/ingress.pyx":367 + * exp_name = 'DataFrame' + * t = type(data) + * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): # <<<<<<<<<<<<<< + * raise TypeError( + * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + + */ + } + + /* "questdb/ingress.pyx":363 + * + * + * cdef _check_is_pandas_dataframe(data): # <<<<<<<<<<<<<< + * exp_mod = 'pandas.core.frame' + * exp_name = 'DataFrame' + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("questdb.ingress._check_is_pandas_dataframe", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_exp_mod); + __Pyx_XDECREF(__pyx_v_exp_name); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":377 + * + * + * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: # <<<<<<<<<<<<<< + * if sender._auto_flush_enabled: + * if len(buffer) >= sender._auto_flush_watermark: + */ + +static int __pyx_f_7questdb_7ingress_may_flush_on_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer, struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_sender) { + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + struct __pyx_opt_args_7questdb_7ingress_6Sender_flush __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("may_flush_on_row_complete", 0); + + /* "questdb/ingress.pyx":378 + * + * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: + * if sender._auto_flush_enabled: # <<<<<<<<<<<<<< + * if len(buffer) >= sender._auto_flush_watermark: + * sender.flush(buffer) + */ + __pyx_t_1 = (__pyx_v_sender->_auto_flush_enabled != 0); + if (__pyx_t_1) { + + /* "questdb/ingress.pyx":379 + * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: + * if sender._auto_flush_enabled: + * if len(buffer) >= sender._auto_flush_watermark: # <<<<<<<<<<<<<< + * sender.flush(buffer) + * + */ + __pyx_t_2 = PyObject_Length(((PyObject *)__pyx_v_buffer)); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 379, __pyx_L1_error) + __pyx_t_1 = ((__pyx_t_2 >= __pyx_v_sender->_auto_flush_watermark) != 0); + if (__pyx_t_1) { + + /* "questdb/ingress.pyx":380 + * if sender._auto_flush_enabled: + * if len(buffer) >= sender._auto_flush_watermark: + * sender.flush(buffer) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_4.__pyx_n = 1; + __pyx_t_4.buffer = __pyx_v_buffer; + __pyx_t_3 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_sender->__pyx_vtab)->flush(__pyx_v_sender, 0, &__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 380, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":379 + * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: + * if sender._auto_flush_enabled: + * if len(buffer) >= sender._auto_flush_watermark: # <<<<<<<<<<<<<< + * sender.flush(buffer) + * + */ + } + + /* "questdb/ingress.pyx":378 + * + * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: + * if sender._auto_flush_enabled: # <<<<<<<<<<<<<< + * if len(buffer) >= sender._auto_flush_watermark: + * sender.flush(buffer) + */ + } + + /* "questdb/ingress.pyx":377 + * + * + * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: # <<<<<<<<<<<<<< + * if sender._auto_flush_enabled: + * if len(buffer) >= sender._auto_flush_watermark: + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress.may_flush_on_row_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":453 + * cdef object _row_complete_sender + * + * def __cinit__(self, init_capacity: int=65536, max_name_len: int=127): # <<<<<<<<<<<<<< + * """ + * Create a new buffer with the an initial capacity and max name length. + */ + +/* Python wrapper */ +static int __pyx_pw_7questdb_7ingress_6Buffer_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7questdb_7ingress_6Buffer_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_init_capacity = 0; + PyObject *__pyx_v_max_name_len = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_init_capacity,&__pyx_n_s_max_name_len,0}; + PyObject* values[2] = {0,0}; + values[0] = ((PyObject *)__pyx_int_65536); + values[1] = ((PyObject *)__pyx_int_127); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_init_capacity); + if (value) { values[0] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 1: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_name_len); + if (value) { values[1] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 453, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_init_capacity = values[0]; + __pyx_v_max_name_len = values[1]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 453, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Buffer.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer___cinit__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), __pyx_v_init_capacity, __pyx_v_max_name_len); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7questdb_7ingress_6Buffer___cinit__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_init_capacity, PyObject *__pyx_v_max_name_len) { + int __pyx_r; + __Pyx_RefNannyDeclarations + size_t __pyx_t_1; + size_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__cinit__", 0); + + /* "questdb/ingress.pyx":459 + * :param int max_name_len: Maximum length of a table or column name. + * """ + * self._cinit_impl(init_capacity, max_name_len) # <<<<<<<<<<<<<< + * + * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): + */ + __pyx_t_1 = __Pyx_PyInt_As_size_t(__pyx_v_init_capacity); if (unlikely((__pyx_t_1 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 459, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyInt_As_size_t(__pyx_v_max_name_len); if (unlikely((__pyx_t_2 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 459, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__cinit_impl(__pyx_v_self, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":453 + * cdef object _row_complete_sender + * + * def __cinit__(self, init_capacity: int=65536, max_name_len: int=127): # <<<<<<<<<<<<<< + * """ + * Create a new buffer with the an initial capacity and max name length. + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress.Buffer.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":461 + * self._cinit_impl(init_capacity, max_name_len) + * + * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): # <<<<<<<<<<<<<< + * self._impl = line_sender_buffer_with_max_name_len(max_name_len) + * self._b = qdb_pystr_buf_new() + */ + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__cinit_impl(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, size_t __pyx_v_init_capacity, size_t __pyx_v_max_name_len) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_cinit_impl", 0); + + /* "questdb/ingress.pyx":462 + * + * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): + * self._impl = line_sender_buffer_with_max_name_len(max_name_len) # <<<<<<<<<<<<<< + * self._b = qdb_pystr_buf_new() + * line_sender_buffer_reserve(self._impl, init_capacity) + */ + __pyx_v_self->_impl = line_sender_buffer_with_max_name_len(__pyx_v_max_name_len); + + /* "questdb/ingress.pyx":463 + * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): + * self._impl = line_sender_buffer_with_max_name_len(max_name_len) + * self._b = qdb_pystr_buf_new() # <<<<<<<<<<<<<< + * line_sender_buffer_reserve(self._impl, init_capacity) + * self._init_capacity = init_capacity + */ + __pyx_v_self->_b = qdb_pystr_buf_new(); + + /* "questdb/ingress.pyx":464 + * self._impl = line_sender_buffer_with_max_name_len(max_name_len) + * self._b = qdb_pystr_buf_new() + * line_sender_buffer_reserve(self._impl, init_capacity) # <<<<<<<<<<<<<< + * self._init_capacity = init_capacity + * self._max_name_len = max_name_len + */ + line_sender_buffer_reserve(__pyx_v_self->_impl, __pyx_v_init_capacity); + + /* "questdb/ingress.pyx":465 + * self._b = qdb_pystr_buf_new() + * line_sender_buffer_reserve(self._impl, init_capacity) + * self._init_capacity = init_capacity # <<<<<<<<<<<<<< + * self._max_name_len = max_name_len + * self._row_complete_sender = None + */ + __pyx_v_self->_init_capacity = __pyx_v_init_capacity; + + /* "questdb/ingress.pyx":466 + * line_sender_buffer_reserve(self._impl, init_capacity) + * self._init_capacity = init_capacity + * self._max_name_len = max_name_len # <<<<<<<<<<<<<< + * self._row_complete_sender = None + * + */ + __pyx_v_self->_max_name_len = __pyx_v_max_name_len; + + /* "questdb/ingress.pyx":467 + * self._init_capacity = init_capacity + * self._max_name_len = max_name_len + * self._row_complete_sender = None # <<<<<<<<<<<<<< + * + * def __dealloc__(self): + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_row_complete_sender); + __Pyx_DECREF(__pyx_v_self->_row_complete_sender); + __pyx_v_self->_row_complete_sender = Py_None; + + /* "questdb/ingress.pyx":461 + * self._cinit_impl(init_capacity, max_name_len) + * + * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): # <<<<<<<<<<<<<< + * self._impl = line_sender_buffer_with_max_name_len(max_name_len) + * self._b = qdb_pystr_buf_new() + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":469 + * self._row_complete_sender = None + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * self._row_complete_sender = None + * qdb_pystr_buf_free(self._b) + */ + +/* Python wrapper */ +static void __pyx_pw_7questdb_7ingress_6Buffer_3__dealloc__(PyObject *__pyx_v_self); /*proto*/ +static void __pyx_pw_7questdb_7ingress_6Buffer_3__dealloc__(PyObject *__pyx_v_self) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); + __pyx_pf_7questdb_7ingress_6Buffer_2__dealloc__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_7questdb_7ingress_6Buffer_2__dealloc__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__", 0); + + /* "questdb/ingress.pyx":470 + * + * def __dealloc__(self): + * self._row_complete_sender = None # <<<<<<<<<<<<<< + * qdb_pystr_buf_free(self._b) + * line_sender_buffer_free(self._impl) + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_row_complete_sender); + __Pyx_DECREF(__pyx_v_self->_row_complete_sender); + __pyx_v_self->_row_complete_sender = Py_None; + + /* "questdb/ingress.pyx":471 + * def __dealloc__(self): + * self._row_complete_sender = None + * qdb_pystr_buf_free(self._b) # <<<<<<<<<<<<<< + * line_sender_buffer_free(self._impl) + * + */ + qdb_pystr_buf_free(__pyx_v_self->_b); + + /* "questdb/ingress.pyx":472 + * self._row_complete_sender = None + * qdb_pystr_buf_free(self._b) + * line_sender_buffer_free(self._impl) # <<<<<<<<<<<<<< + * + * @property + */ + line_sender_buffer_free(__pyx_v_self->_impl); + + /* "questdb/ingress.pyx":469 + * self._row_complete_sender = None + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * self._row_complete_sender = None + * qdb_pystr_buf_free(self._b) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "questdb/ingress.pyx":475 + * + * @property + * def init_capacity(self) -> int: # <<<<<<<<<<<<<< + * """ + * The initial capacity of the buffer when first created. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13init_capacity_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13init_capacity_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_13init_capacity___get__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "questdb/ingress.pyx":481 + * This may grow over time, see ``capacity()``. + * """ + * return self._init_capacity # <<<<<<<<<<<<<< + * + * @property + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_init_capacity); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 481, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":475 + * + * @property + * def init_capacity(self) -> int: # <<<<<<<<<<<<<< + * """ + * The initial capacity of the buffer when first created. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer.init_capacity.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":489 + * + * @property + * def max_name_len(self) -> int: # <<<<<<<<<<<<<< + * """Maximum length of a table or column name.""" + * return self._max_name_len + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_12max_name_len_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_12max_name_len_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_12max_name_len___get__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "questdb/ingress.pyx":491 + * def max_name_len(self) -> int: + * """Maximum length of a table or column name.""" + * return self._max_name_len # <<<<<<<<<<<<<< + * + * def reserve(self, additional: int): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_max_name_len); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 491, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":489 + * + * @property + * def max_name_len(self) -> int: # <<<<<<<<<<<<<< + * """Maximum length of a table or column name.""" + * return self._max_name_len + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer.max_name_len.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":493 + * return self._max_name_len + * + * def reserve(self, additional: int): # <<<<<<<<<<<<<< + * """ + * Ensure the buffer has at least `additional` bytes of future capacity. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_5reserve(PyObject *__pyx_v_self, PyObject *__pyx_v_additional); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Buffer_4reserve[] = "\n Ensure the buffer has at least `additional` bytes of future capacity.\n\n :param int additional: Additional bytes to reserve.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_5reserve = {"reserve", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_5reserve, METH_O, __pyx_doc_7questdb_7ingress_6Buffer_4reserve}; +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_5reserve(PyObject *__pyx_v_self, PyObject *__pyx_v_additional) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("reserve (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_4reserve(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), ((PyObject *)__pyx_v_additional)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_4reserve(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_additional) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + size_t __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("reserve", 0); + + /* "questdb/ingress.pyx":499 + * :param int additional: Additional bytes to reserve. + * """ + * if additional < 0: # <<<<<<<<<<<<<< + * raise ValueError('additional must be non-negative.') + * line_sender_buffer_reserve(self._impl, additional) + */ + __pyx_t_1 = PyObject_RichCompare(__pyx_v_additional, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 499, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 499, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":500 + * """ + * if additional < 0: + * raise ValueError('additional must be non-negative.') # <<<<<<<<<<<<<< + * line_sender_buffer_reserve(self._impl, additional) + * + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 500, __pyx_L1_error) + + /* "questdb/ingress.pyx":499 + * :param int additional: Additional bytes to reserve. + * """ + * if additional < 0: # <<<<<<<<<<<<<< + * raise ValueError('additional must be non-negative.') + * line_sender_buffer_reserve(self._impl, additional) + */ + } + + /* "questdb/ingress.pyx":501 + * if additional < 0: + * raise ValueError('additional must be non-negative.') + * line_sender_buffer_reserve(self._impl, additional) # <<<<<<<<<<<<<< + * + * def capacity(self) -> int: + */ + __pyx_t_3 = __Pyx_PyInt_As_size_t(__pyx_v_additional); if (unlikely((__pyx_t_3 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 501, __pyx_L1_error) + line_sender_buffer_reserve(__pyx_v_self->_impl, __pyx_t_3); + + /* "questdb/ingress.pyx":493 + * return self._max_name_len + * + * def reserve(self, additional: int): # <<<<<<<<<<<<<< + * """ + * Ensure the buffer has at least `additional` bytes of future capacity. + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer.reserve", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":503 + * line_sender_buffer_reserve(self._impl, additional) + * + * def capacity(self) -> int: # <<<<<<<<<<<<<< + * """The current buffer capacity.""" + * return line_sender_buffer_capacity(self._impl) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_7capacity(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Buffer_6capacity[] = "The current buffer capacity."; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_7capacity = {"capacity", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_7capacity, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_6capacity}; +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_7capacity(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("capacity (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_6capacity(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_6capacity(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("capacity", 0); + + /* "questdb/ingress.pyx":505 + * def capacity(self) -> int: + * """The current buffer capacity.""" + * return line_sender_buffer_capacity(self._impl) # <<<<<<<<<<<<<< + * + * def clear(self): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_FromSize_t(line_sender_buffer_capacity(__pyx_v_self->_impl)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 505, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":503 + * line_sender_buffer_reserve(self._impl, additional) + * + * def capacity(self) -> int: # <<<<<<<<<<<<<< + * """The current buffer capacity.""" + * return line_sender_buffer_capacity(self._impl) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer.capacity", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":507 + * return line_sender_buffer_capacity(self._impl) + * + * def clear(self): # <<<<<<<<<<<<<< + * """ + * Reset the buffer. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_9clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Buffer_8clear[] = "\n Reset the buffer.\n\n Note that flushing a buffer will (unless otherwise specified)\n also automatically clear it.\n\n This method is designed to be called only in conjunction with\n ``sender.flush(buffer, clear=False)``.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_9clear = {"clear", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_9clear, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_8clear}; +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_9clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("clear (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_8clear(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_8clear(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("clear", 0); + + /* "questdb/ingress.pyx":517 + * ``sender.flush(buffer, clear=False)``. + * """ + * line_sender_buffer_clear(self._impl) # <<<<<<<<<<<<<< + * qdb_pystr_buf_clear(self._b) + * + */ + line_sender_buffer_clear(__pyx_v_self->_impl); + + /* "questdb/ingress.pyx":518 + * """ + * line_sender_buffer_clear(self._impl) + * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< + * + * def __len__(self) -> int: + */ + qdb_pystr_buf_clear(__pyx_v_self->_b); + + /* "questdb/ingress.pyx":507 + * return line_sender_buffer_capacity(self._impl) + * + * def clear(self): # <<<<<<<<<<<<<< + * """ + * Reset the buffer. + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":520 + * qdb_pystr_buf_clear(self._b) + * + * def __len__(self) -> int: # <<<<<<<<<<<<<< + * """ + * The current number of bytes currently in the buffer. + */ + +/* Python wrapper */ +static Py_ssize_t __pyx_pw_7questdb_7ingress_6Buffer_11__len__(PyObject *__pyx_v_self); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Buffer_10__len__[] = "\n The current number of bytes currently in the buffer.\n\n Equivalent (but cheaper) to ``len(str(sender))``.\n "; +#if CYTHON_UPDATE_DESCRIPTOR_DOC +struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__; +#endif +static Py_ssize_t __pyx_pw_7questdb_7ingress_6Buffer_11__len__(PyObject *__pyx_v_self) { + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_10__len__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static Py_ssize_t __pyx_pf_7questdb_7ingress_6Buffer_10__len__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__len__", 0); + + /* "questdb/ingress.pyx":526 + * Equivalent (but cheaper) to ``len(str(sender))``. + * """ + * return line_sender_buffer_size(self._impl) # <<<<<<<<<<<<<< + * + * def __str__(self) -> str: + */ + __pyx_r = line_sender_buffer_size(__pyx_v_self->_impl); + goto __pyx_L0; + + /* "questdb/ingress.pyx":520 + * qdb_pystr_buf_clear(self._b) + * + * def __len__(self) -> int: # <<<<<<<<<<<<<< + * """ + * The current number of bytes currently in the buffer. + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":528 + * return line_sender_buffer_size(self._impl) + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """Return the constructed buffer as a string. Use for debugging.""" + * return self._to_str() + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13__str__(PyObject *__pyx_v_self); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Buffer_12__str__[] = "Return the constructed buffer as a string. Use for debugging."; +#if CYTHON_UPDATE_DESCRIPTOR_DOC +struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__; +#endif +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13__str__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_12__str__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12__str__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__str__", 0); + + /* "questdb/ingress.pyx":530 + * def __str__(self) -> str: + * """Return the constructed buffer as a string. Use for debugging.""" + * return self._to_str() # <<<<<<<<<<<<<< + * + * cdef inline object _to_str(self): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__to_str(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 530, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":528 + * return line_sender_buffer_size(self._impl) + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """Return the constructed buffer as a string. Use for debugging.""" + * return self._to_str() + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":532 + * return self._to_str() + * + * cdef inline object _to_str(self): # <<<<<<<<<<<<<< + * cdef size_t size = 0 + * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) + */ + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__to_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + size_t __pyx_v_size; + char const *__pyx_v_utf8; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_to_str", 0); + + /* "questdb/ingress.pyx":533 + * + * cdef inline object _to_str(self): + * cdef size_t size = 0 # <<<<<<<<<<<<<< + * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) + * return PyUnicode_FromStringAndSize(utf8, size) + */ + __pyx_v_size = 0; + + /* "questdb/ingress.pyx":534 + * cdef inline object _to_str(self): + * cdef size_t size = 0 + * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) # <<<<<<<<<<<<<< + * return PyUnicode_FromStringAndSize(utf8, size) + * + */ + __pyx_v_utf8 = line_sender_buffer_peek(__pyx_v_self->_impl, (&__pyx_v_size)); + + /* "questdb/ingress.pyx":535 + * cdef size_t size = 0 + * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) + * return PyUnicode_FromStringAndSize(utf8, size) # <<<<<<<<<<<<<< + * + * cdef inline int _set_marker(self) except -1: + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyUnicode_FromStringAndSize(__pyx_v_utf8, ((Py_ssize_t)__pyx_v_size)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 535, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":532 + * return self._to_str() + * + * cdef inline object _to_str(self): # <<<<<<<<<<<<<< + * cdef size_t size = 0 + * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer._to_str", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":537 + * return PyUnicode_FromStringAndSize(utf8, size) + * + * cdef inline int _set_marker(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_set_marker(self._impl, &err): + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__set_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_set_marker", 0); + + /* "questdb/ingress.pyx":538 + * + * cdef inline int _set_marker(self) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_set_marker(self._impl, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":539 + * cdef inline int _set_marker(self) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_set_marker(self._impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * + */ + __pyx_t_1 = ((!(line_sender_buffer_set_marker(__pyx_v_self->_impl, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":540 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_set_marker(self._impl, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * + * cdef inline int _rewind_to_marker(self) except -1: + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 540, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 540, __pyx_L1_error) + + /* "questdb/ingress.pyx":539 + * cdef inline int _set_marker(self) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_set_marker(self._impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * + */ + } + + /* "questdb/ingress.pyx":537 + * return PyUnicode_FromStringAndSize(utf8, size) + * + * cdef inline int _set_marker(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_set_marker(self._impl, &err): + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._set_marker", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":542 + * raise c_err_to_py(err) + * + * cdef inline int _rewind_to_marker(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_rewind_to_marker(self._impl, &err): + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_rewind_to_marker", 0); + + /* "questdb/ingress.pyx":543 + * + * cdef inline int _rewind_to_marker(self) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_rewind_to_marker(self._impl, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":544 + * cdef inline int _rewind_to_marker(self) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_rewind_to_marker(self._impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * + */ + __pyx_t_1 = ((!(line_sender_buffer_rewind_to_marker(__pyx_v_self->_impl, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":545 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_rewind_to_marker(self._impl, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * + * cdef inline _clear_marker(self): + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 545, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 545, __pyx_L1_error) + + /* "questdb/ingress.pyx":544 + * cdef inline int _rewind_to_marker(self) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_rewind_to_marker(self._impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * + */ + } + + /* "questdb/ingress.pyx":542 + * raise c_err_to_py(err) + * + * cdef inline int _rewind_to_marker(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_rewind_to_marker(self._impl, &err): + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._rewind_to_marker", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":547 + * raise c_err_to_py(err) + * + * cdef inline _clear_marker(self): # <<<<<<<<<<<<<< + * line_sender_buffer_clear_marker(self._impl) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__clear_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_clear_marker", 0); + + /* "questdb/ingress.pyx":548 + * + * cdef inline _clear_marker(self): + * line_sender_buffer_clear_marker(self._impl) # <<<<<<<<<<<<<< + * + * cdef inline int _table(self, str table_name) except -1: + */ + line_sender_buffer_clear_marker(__pyx_v_self->_impl); + + /* "questdb/ingress.pyx":547 + * raise c_err_to_py(err) + * + * cdef inline _clear_marker(self): # <<<<<<<<<<<<<< + * line_sender_buffer_clear_marker(self._impl) + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":550 + * line_sender_buffer_clear_marker(self._impl) + * + * cdef inline int _table(self, str table_name) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * cdef line_sender_table_name c_table_name + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__table(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name) { + struct line_sender_error *__pyx_v_err; + struct line_sender_table_name __pyx_v_c_table_name; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_table", 0); + + /* "questdb/ingress.pyx":551 + * + * cdef inline int _table(self, str table_name) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef line_sender_table_name c_table_name + * str_to_table_name(self._cleared_b(), table_name, &c_table_name) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":553 + * cdef line_sender_error* err = NULL + * cdef line_sender_table_name c_table_name + * str_to_table_name(self._cleared_b(), table_name, &c_table_name) # <<<<<<<<<<<<<< + * if not line_sender_buffer_table(self._impl, c_table_name, &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_table_name(__pyx_f_7questdb_7ingress_6Buffer__cleared_b(__pyx_v_self), __pyx_v_table_name, (&__pyx_v_c_table_name)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 553, __pyx_L1_error) + + /* "questdb/ingress.pyx":554 + * cdef line_sender_table_name c_table_name + * str_to_table_name(self._cleared_b(), table_name, &c_table_name) + * if not line_sender_buffer_table(self._impl, c_table_name, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_table(__pyx_v_self->_impl, __pyx_v_c_table_name, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":555 + * str_to_table_name(self._cleared_b(), table_name, &c_table_name) + * if not line_sender_buffer_table(self._impl, c_table_name, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 555, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 555, __pyx_L1_error) + + /* "questdb/ingress.pyx":554 + * cdef line_sender_table_name c_table_name + * str_to_table_name(self._cleared_b(), table_name, &c_table_name) + * if not line_sender_buffer_table(self._impl, c_table_name, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":556 + * if not line_sender_buffer_table(self._impl, c_table_name, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline qdb_pystr_buf* _cleared_b(self): + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":550 + * line_sender_buffer_clear_marker(self._impl) + * + * cdef inline int _table(self, str table_name) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * cdef line_sender_table_name c_table_name + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._table", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":558 + * return 0 + * + * cdef inline qdb_pystr_buf* _cleared_b(self): # <<<<<<<<<<<<<< + * qdb_pystr_buf_clear(self._b) + * return self._b + */ + +static CYTHON_INLINE struct qdb_pystr_buf *__pyx_f_7questdb_7ingress_6Buffer__cleared_b(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + struct qdb_pystr_buf *__pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_cleared_b", 0); + + /* "questdb/ingress.pyx":559 + * + * cdef inline qdb_pystr_buf* _cleared_b(self): + * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< + * return self._b + * + */ + qdb_pystr_buf_clear(__pyx_v_self->_b); + + /* "questdb/ingress.pyx":560 + * cdef inline qdb_pystr_buf* _cleared_b(self): + * qdb_pystr_buf_clear(self._b) + * return self._b # <<<<<<<<<<<<<< + * + * cdef inline int _symbol(self, str name, str value) except -1: + */ + __pyx_r = __pyx_v_self->_b; + goto __pyx_L0; + + /* "questdb/ingress.pyx":558 + * return 0 + * + * cdef inline qdb_pystr_buf* _cleared_b(self): # <<<<<<<<<<<<<< + * qdb_pystr_buf_clear(self._b) + * return self._b + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":562 + * return self._b + * + * cdef inline int _symbol(self, str name, str value) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * cdef line_sender_column_name c_name + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__symbol(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value) { + struct line_sender_error *__pyx_v_err; + struct line_sender_column_name __pyx_v_c_name; + struct line_sender_utf8 __pyx_v_c_value; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_symbol", 0); + + /* "questdb/ingress.pyx":563 + * + * cdef inline int _symbol(self, str name, str value) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef line_sender_column_name c_name + * cdef line_sender_utf8 c_value + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":566 + * cdef line_sender_column_name c_name + * cdef line_sender_utf8 c_value + * str_to_column_name(self._cleared_b(), name, &c_name) # <<<<<<<<<<<<<< + * str_to_utf8(self._b, value, &c_value) + * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_f_7questdb_7ingress_6Buffer__cleared_b(__pyx_v_self), __pyx_v_name, (&__pyx_v_c_name)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 566, __pyx_L1_error) + + /* "questdb/ingress.pyx":567 + * cdef line_sender_utf8 c_value + * str_to_column_name(self._cleared_b(), name, &c_name) + * str_to_utf8(self._b, value, &c_value) # <<<<<<<<<<<<<< + * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_self->_b, __pyx_v_value, (&__pyx_v_c_value)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 567, __pyx_L1_error) + + /* "questdb/ingress.pyx":568 + * str_to_column_name(self._cleared_b(), name, &c_name) + * str_to_utf8(self._b, value, &c_value) + * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_symbol(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_c_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":569 + * str_to_utf8(self._b, value, &c_value) + * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 569, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 569, __pyx_L1_error) + + /* "questdb/ingress.pyx":568 + * str_to_column_name(self._cleared_b(), name, &c_name) + * str_to_utf8(self._b, value, &c_value) + * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":570 + * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _column_bool( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":562 + * return self._b + * + * cdef inline int _symbol(self, str name, str value) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * cdef line_sender_column_name c_name + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._symbol", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":572 + * return 0 + * + * cdef inline int _column_bool( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, bint value) except -1: + * cdef line_sender_error* err = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_bool(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int __pyx_v_value) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_column_bool", 0); + + /* "questdb/ingress.pyx":574 + * cdef inline int _column_bool( + * self, line_sender_column_name c_name, bint value) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":575 + * self, line_sender_column_name c_name, bint value) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_column_bool(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":576 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 576, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 576, __pyx_L1_error) + + /* "questdb/ingress.pyx":575 + * self, line_sender_column_name c_name, bint value) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":577 + * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _column_i64( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":572 + * return 0 + * + * cdef inline int _column_bool( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, bint value) except -1: + * cdef line_sender_error* err = NULL + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._column_bool", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":579 + * return 0 + * + * cdef inline int _column_i64( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, int64_t value) except -1: + * cdef line_sender_error* err = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_i64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int64_t __pyx_v_value) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_column_i64", 0); + + /* "questdb/ingress.pyx":581 + * cdef inline int _column_i64( + * self, line_sender_column_name c_name, int64_t value) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":582 + * self, line_sender_column_name c_name, int64_t value) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_column_i64(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":583 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 583, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 583, __pyx_L1_error) + + /* "questdb/ingress.pyx":582 + * self, line_sender_column_name c_name, int64_t value) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":584 + * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _column_f64( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":579 + * return 0 + * + * cdef inline int _column_i64( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, int64_t value) except -1: + * cdef line_sender_error* err = NULL + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._column_i64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":586 + * return 0 + * + * cdef inline int _column_f64( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, double value) except -1: + * cdef line_sender_error* err = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_f64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, double __pyx_v_value) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_column_f64", 0); + + /* "questdb/ingress.pyx":588 + * cdef inline int _column_f64( + * self, line_sender_column_name c_name, double value) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":589 + * self, line_sender_column_name c_name, double value) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_column_f64(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":590 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 590, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 590, __pyx_L1_error) + + /* "questdb/ingress.pyx":589 + * self, line_sender_column_name c_name, double value) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":591 + * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _column_str( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":586 + * return 0 + * + * cdef inline int _column_f64( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, double value) except -1: + * cdef line_sender_error* err = NULL + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._column_f64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":593 + * return 0 + * + * cdef inline int _column_str( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, str value) except -1: + * cdef line_sender_error* err = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyObject *__pyx_v_value) { + struct line_sender_error *__pyx_v_err; + struct line_sender_utf8 __pyx_v_c_value; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_column_str", 0); + + /* "questdb/ingress.pyx":595 + * cdef inline int _column_str( + * self, line_sender_column_name c_name, str value) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef line_sender_utf8 c_value + * str_to_utf8(self._b, value, &c_value) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":597 + * cdef line_sender_error* err = NULL + * cdef line_sender_utf8 c_value + * str_to_utf8(self._b, value, &c_value) # <<<<<<<<<<<<<< + * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_self->_b, __pyx_v_value, (&__pyx_v_c_value)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 597, __pyx_L1_error) + + /* "questdb/ingress.pyx":598 + * cdef line_sender_utf8 c_value + * str_to_utf8(self._b, value, &c_value) + * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_column_str(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_c_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":599 + * str_to_utf8(self._b, value, &c_value) + * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 599, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 599, __pyx_L1_error) + + /* "questdb/ingress.pyx":598 + * cdef line_sender_utf8 c_value + * str_to_utf8(self._b, value, &c_value) + * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":600 + * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _column_ts( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":593 + * return 0 + * + * cdef inline int _column_str( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, str value) except -1: + * cdef line_sender_error* err = NULL + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._column_str", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":602 + * return 0 + * + * cdef inline int _column_ts( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, TimestampMicros ts) except -1: + * cdef line_sender_error* err = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_ts) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_column_ts", 0); + + /* "questdb/ingress.pyx":604 + * cdef inline int _column_ts( + * self, line_sender_column_name c_name, TimestampMicros ts) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":605 + * self, line_sender_column_name c_name, TimestampMicros ts) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_column_ts(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_ts->_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":606 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 606, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 606, __pyx_L1_error) + + /* "questdb/ingress.pyx":605 + * self, line_sender_column_name c_name, TimestampMicros ts) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":607 + * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _column_dt( + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":602 + * return 0 + * + * cdef inline int _column_ts( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, TimestampMicros ts) except -1: + * cdef line_sender_error* err = NULL + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._column_ts", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":609 + * return 0 + * + * cdef inline int _column_dt( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, datetime dt) except -1: + * cdef line_sender_error* err = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyDateTime_DateTime *__pyx_v_dt) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_column_dt", 0); + + /* "questdb/ingress.pyx":611 + * cdef inline int _column_dt( + * self, line_sender_column_name c_name, datetime dt) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_column_ts( + * self._impl, c_name, datetime_to_micros(dt), &err): + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":612 + * self, line_sender_column_name c_name, datetime dt) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_ts( # <<<<<<<<<<<<<< + * self._impl, c_name, datetime_to_micros(dt), &err): + * raise c_err_to_py(err) + */ + __pyx_t_1 = ((!(line_sender_buffer_column_ts(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_f_7questdb_7ingress_datetime_to_micros(__pyx_v_dt), (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":614 + * if not line_sender_buffer_column_ts( + * self._impl, c_name, datetime_to_micros(dt), &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 614, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 614, __pyx_L1_error) + + /* "questdb/ingress.pyx":612 + * self, line_sender_column_name c_name, datetime dt) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_column_ts( # <<<<<<<<<<<<<< + * self._impl, c_name, datetime_to_micros(dt), &err): + * raise c_err_to_py(err) + */ + } + + /* "questdb/ingress.pyx":615 + * self._impl, c_name, datetime_to_micros(dt), &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _column(self, str name, object value) except -1: + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":609 + * return 0 + * + * cdef inline int _column_dt( # <<<<<<<<<<<<<< + * self, line_sender_column_name c_name, datetime dt) except -1: + * cdef line_sender_error* err = NULL + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._column_dt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":617 + * return 0 + * + * cdef inline int _column(self, str name, object value) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_column_name c_name + * str_to_column_name(self._cleared_b(), name, &c_name) + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value) { + struct line_sender_column_name __pyx_v_c_name; + PyObject *__pyx_v_valid = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + int64_t __pyx_t_3; + double __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + Py_ssize_t __pyx_t_7; + Py_UCS4 __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_column", 0); + + /* "questdb/ingress.pyx":619 + * cdef inline int _column(self, str name, object value) except -1: + * cdef line_sender_column_name c_name + * str_to_column_name(self._cleared_b(), name, &c_name) # <<<<<<<<<<<<<< + * if PyBool_Check(value): + * return self._column_bool(c_name, value) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_f_7questdb_7ingress_6Buffer__cleared_b(__pyx_v_self), __pyx_v_name, (&__pyx_v_c_name)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 619, __pyx_L1_error) + + /* "questdb/ingress.pyx":620 + * cdef line_sender_column_name c_name + * str_to_column_name(self._cleared_b(), name, &c_name) + * if PyBool_Check(value): # <<<<<<<<<<<<<< + * return self._column_bool(c_name, value) + * elif PyInt_Check(value): + */ + __pyx_t_1 = (PyBool_Check(__pyx_v_value) != 0); + if (__pyx_t_1) { + + /* "questdb/ingress.pyx":621 + * str_to_column_name(self._cleared_b(), name, &c_name) + * if PyBool_Check(value): + * return self._column_bool(c_name, value) # <<<<<<<<<<<<<< + * elif PyInt_Check(value): + * return self._column_i64(c_name, value) + */ + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 621, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_bool(__pyx_v_self, __pyx_v_c_name, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 621, __pyx_L1_error) + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "questdb/ingress.pyx":620 + * cdef line_sender_column_name c_name + * str_to_column_name(self._cleared_b(), name, &c_name) + * if PyBool_Check(value): # <<<<<<<<<<<<<< + * return self._column_bool(c_name, value) + * elif PyInt_Check(value): + */ + } + + /* "questdb/ingress.pyx":622 + * if PyBool_Check(value): + * return self._column_bool(c_name, value) + * elif PyInt_Check(value): # <<<<<<<<<<<<<< + * return self._column_i64(c_name, value) + * elif PyFloat_Check(value): + */ + __pyx_t_1 = (PyInt_Check(__pyx_v_value) != 0); + if (__pyx_t_1) { + + /* "questdb/ingress.pyx":623 + * return self._column_bool(c_name, value) + * elif PyInt_Check(value): + * return self._column_i64(c_name, value) # <<<<<<<<<<<<<< + * elif PyFloat_Check(value): + * return self._column_f64(c_name, value) + */ + __pyx_t_3 = __Pyx_PyInt_As_int64_t(__pyx_v_value); if (unlikely((__pyx_t_3 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 623, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_i64(__pyx_v_self, __pyx_v_c_name, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 623, __pyx_L1_error) + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "questdb/ingress.pyx":622 + * if PyBool_Check(value): + * return self._column_bool(c_name, value) + * elif PyInt_Check(value): # <<<<<<<<<<<<<< + * return self._column_i64(c_name, value) + * elif PyFloat_Check(value): + */ + } + + /* "questdb/ingress.pyx":624 + * elif PyInt_Check(value): + * return self._column_i64(c_name, value) + * elif PyFloat_Check(value): # <<<<<<<<<<<<<< + * return self._column_f64(c_name, value) + * elif PyUnicode_Check(value): + */ + __pyx_t_1 = (PyFloat_Check(__pyx_v_value) != 0); + if (__pyx_t_1) { + + /* "questdb/ingress.pyx":625 + * return self._column_i64(c_name, value) + * elif PyFloat_Check(value): + * return self._column_f64(c_name, value) # <<<<<<<<<<<<<< + * elif PyUnicode_Check(value): + * return self._column_str(c_name, value) + */ + __pyx_t_4 = __pyx_PyFloat_AsDouble(__pyx_v_value); if (unlikely((__pyx_t_4 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 625, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_f64(__pyx_v_self, __pyx_v_c_name, __pyx_t_4); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 625, __pyx_L1_error) + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "questdb/ingress.pyx":624 + * elif PyInt_Check(value): + * return self._column_i64(c_name, value) + * elif PyFloat_Check(value): # <<<<<<<<<<<<<< + * return self._column_f64(c_name, value) + * elif PyUnicode_Check(value): + */ + } + + /* "questdb/ingress.pyx":626 + * elif PyFloat_Check(value): + * return self._column_f64(c_name, value) + * elif PyUnicode_Check(value): # <<<<<<<<<<<<<< + * return self._column_str(c_name, value) + * elif isinstance(value, TimestampMicros): + */ + __pyx_t_1 = (PyUnicode_Check(__pyx_v_value) != 0); + if (__pyx_t_1) { + + /* "questdb/ingress.pyx":627 + * return self._column_f64(c_name, value) + * elif PyUnicode_Check(value): + * return self._column_str(c_name, value) # <<<<<<<<<<<<<< + * elif isinstance(value, TimestampMicros): + * return self._column_ts(c_name, value) + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_value))||((__pyx_v_value) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_value)->tp_name), 0))) __PYX_ERR(0, 627, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_str(__pyx_v_self, __pyx_v_c_name, ((PyObject*)__pyx_v_value)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 627, __pyx_L1_error) + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "questdb/ingress.pyx":626 + * elif PyFloat_Check(value): + * return self._column_f64(c_name, value) + * elif PyUnicode_Check(value): # <<<<<<<<<<<<<< + * return self._column_str(c_name, value) + * elif isinstance(value, TimestampMicros): + */ + } + + /* "questdb/ingress.pyx":628 + * elif PyUnicode_Check(value): + * return self._column_str(c_name, value) + * elif isinstance(value, TimestampMicros): # <<<<<<<<<<<<<< + * return self._column_ts(c_name, value) + * elif isinstance(value, datetime): + */ + __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_value, __pyx_ptype_7questdb_7ingress_TimestampMicros); + __pyx_t_5 = (__pyx_t_1 != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":629 + * return self._column_str(c_name, value) + * elif isinstance(value, TimestampMicros): + * return self._column_ts(c_name, value) # <<<<<<<<<<<<<< + * elif isinstance(value, datetime): + * return self._column_dt(c_name, value) + */ + if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_7questdb_7ingress_TimestampMicros))))) __PYX_ERR(0, 629, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_ts(__pyx_v_self, __pyx_v_c_name, ((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_value)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 629, __pyx_L1_error) + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "questdb/ingress.pyx":628 + * elif PyUnicode_Check(value): + * return self._column_str(c_name, value) + * elif isinstance(value, TimestampMicros): # <<<<<<<<<<<<<< + * return self._column_ts(c_name, value) + * elif isinstance(value, datetime): + */ + } + + /* "questdb/ingress.pyx":630 + * elif isinstance(value, TimestampMicros): + * return self._column_ts(c_name, value) + * elif isinstance(value, datetime): # <<<<<<<<<<<<<< + * return self._column_dt(c_name, value) + * else: + */ + __pyx_t_5 = __Pyx_TypeCheck(__pyx_v_value, __pyx_ptype_7cpython_8datetime_datetime); + __pyx_t_1 = (__pyx_t_5 != 0); + if (likely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":631 + * return self._column_ts(c_name, value) + * elif isinstance(value, datetime): + * return self._column_dt(c_name, value) # <<<<<<<<<<<<<< + * else: + * valid = ', '.join(( + */ + if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_7cpython_8datetime_datetime))))) __PYX_ERR(0, 631, __pyx_L1_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_dt(__pyx_v_self, __pyx_v_c_name, ((PyDateTime_DateTime *)__pyx_v_value)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 631, __pyx_L1_error) + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "questdb/ingress.pyx":630 + * elif isinstance(value, TimestampMicros): + * return self._column_ts(c_name, value) + * elif isinstance(value, datetime): # <<<<<<<<<<<<<< + * return self._column_dt(c_name, value) + * else: + */ + } + + /* "questdb/ingress.pyx":633 + * return self._column_dt(c_name, value) + * else: + * valid = ', '.join(( # <<<<<<<<<<<<<< + * 'bool', + * 'int', + */ + /*else*/ { + + /* "questdb/ingress.pyx":634 + * else: + * valid = ', '.join(( + * 'bool', # <<<<<<<<<<<<<< + * 'int', + * 'float', + */ + __pyx_t_6 = PyUnicode_Join(__pyx_kp_u__24, __pyx_tuple__26); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 633, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_v_valid = ((PyObject*)__pyx_t_6); + __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":641 + * 'datetime.datetime')) + * raise TypeError( + * f'Unsupported type: {type(value)}. Must be one of: {valid}') # <<<<<<<<<<<<<< + * + * cdef inline int _may_trigger_row_complete(self) except -1: + */ + __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 641, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = 0; + __pyx_t_8 = 127; + __Pyx_INCREF(__pyx_kp_u_Unsupported_type); + __pyx_t_7 += 18; + __Pyx_GIVEREF(__pyx_kp_u_Unsupported_type); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_Unsupported_type); + __pyx_t_9 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_value)), __pyx_empty_unicode); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 641, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) : __pyx_t_8; + __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_9); + __pyx_t_9 = 0; + __Pyx_INCREF(__pyx_kp_u_Must_be_one_of); + __pyx_t_7 += 18; + __Pyx_GIVEREF(__pyx_kp_u_Must_be_one_of); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u_Must_be_one_of); + __pyx_t_9 = __Pyx_PyUnicode_Unicode(__pyx_v_valid); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 641, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) : __pyx_t_8; + __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_9); + __pyx_t_9 = 0; + __pyx_t_9 = __Pyx_PyUnicode_Join(__pyx_t_6, 4, __pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 641, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":640 + * 'TimestampMicros', + * 'datetime.datetime')) + * raise TypeError( # <<<<<<<<<<<<<< + * f'Unsupported type: {type(value)}. Must be one of: {valid}') + * + */ + __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_9); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 640, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(0, 640, __pyx_L1_error) + } + + /* "questdb/ingress.pyx":617 + * return 0 + * + * cdef inline int _column(self, str name, object value) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_column_name c_name + * str_to_column_name(self._cleared_b(), name, &c_name) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("questdb.ingress.Buffer._column", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_valid); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":643 + * f'Unsupported type: {type(value)}. Must be one of: {valid}') + * + * cdef inline int _may_trigger_row_complete(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * cdef PyObject* sender = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + CYTHON_UNUSED struct line_sender_error *__pyx_v_err; + PyObject *__pyx_v_sender; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_may_trigger_row_complete", 0); + + /* "questdb/ingress.pyx":644 + * + * cdef inline int _may_trigger_row_complete(self) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef PyObject* sender = NULL + * if self._row_complete_sender != None: + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":645 + * cdef inline int _may_trigger_row_complete(self) except -1: + * cdef line_sender_error* err = NULL + * cdef PyObject* sender = NULL # <<<<<<<<<<<<<< + * if self._row_complete_sender != None: + * sender = PyWeakref_GetObject(self._row_complete_sender) + */ + __pyx_v_sender = NULL; + + /* "questdb/ingress.pyx":646 + * cdef line_sender_error* err = NULL + * cdef PyObject* sender = NULL + * if self._row_complete_sender != None: # <<<<<<<<<<<<<< + * sender = PyWeakref_GetObject(self._row_complete_sender) + * if sender != NULL: + */ + __pyx_t_1 = PyObject_RichCompare(__pyx_v_self->_row_complete_sender, Py_None, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 646, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 646, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_2) { + + /* "questdb/ingress.pyx":647 + * cdef PyObject* sender = NULL + * if self._row_complete_sender != None: + * sender = PyWeakref_GetObject(self._row_complete_sender) # <<<<<<<<<<<<<< + * if sender != NULL: + * may_flush_on_row_complete(self, sender) + */ + __pyx_t_1 = __pyx_v_self->_row_complete_sender; + __Pyx_INCREF(__pyx_t_1); + __pyx_t_3 = PyWeakref_GetObject(__pyx_t_1); if (unlikely(__pyx_t_3 == ((PyObject *)NULL))) __PYX_ERR(0, 647, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_sender = __pyx_t_3; + + /* "questdb/ingress.pyx":648 + * if self._row_complete_sender != None: + * sender = PyWeakref_GetObject(self._row_complete_sender) + * if sender != NULL: # <<<<<<<<<<<<<< + * may_flush_on_row_complete(self, sender) + * + */ + __pyx_t_2 = ((__pyx_v_sender != NULL) != 0); + if (__pyx_t_2) { + + /* "questdb/ingress.pyx":649 + * sender = PyWeakref_GetObject(self._row_complete_sender) + * if sender != NULL: + * may_flush_on_row_complete(self, sender) # <<<<<<<<<<<<<< + * + * cdef inline int _at_ts(self, TimestampNanos ts) except -1: + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_may_flush_on_row_complete(__pyx_v_self, ((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_sender)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 649, __pyx_L1_error) + + /* "questdb/ingress.pyx":648 + * if self._row_complete_sender != None: + * sender = PyWeakref_GetObject(self._row_complete_sender) + * if sender != NULL: # <<<<<<<<<<<<<< + * may_flush_on_row_complete(self, sender) + * + */ + } + + /* "questdb/ingress.pyx":646 + * cdef line_sender_error* err = NULL + * cdef PyObject* sender = NULL + * if self._row_complete_sender != None: # <<<<<<<<<<<<<< + * sender = PyWeakref_GetObject(self._row_complete_sender) + * if sender != NULL: + */ + } + + /* "questdb/ingress.pyx":643 + * f'Unsupported type: {type(value)}. Must be one of: {valid}') + * + * cdef inline int _may_trigger_row_complete(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * cdef PyObject* sender = NULL + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer._may_trigger_row_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":651 + * may_flush_on_row_complete(self, sender) + * + * cdef inline int _at_ts(self, TimestampNanos ts) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, ts._value, &err): + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_ts) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_at_ts", 0); + + /* "questdb/ingress.pyx":652 + * + * cdef inline int _at_ts(self, TimestampNanos ts) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_at(self._impl, ts._value, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":653 + * cdef inline int _at_ts(self, TimestampNanos ts) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, ts._value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_at(__pyx_v_self->_impl, __pyx_v_ts->_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":654 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, ts._value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 654, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 654, __pyx_L1_error) + + /* "questdb/ingress.pyx":653 + * cdef inline int _at_ts(self, TimestampNanos ts) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, ts._value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":655 + * if not line_sender_buffer_at(self._impl, ts._value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _at_dt(self, datetime dt) except -1: + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":651 + * may_flush_on_row_complete(self, sender) + * + * cdef inline int _at_ts(self, TimestampNanos ts) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, ts._value, &err): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._at_ts", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":657 + * return 0 + * + * cdef inline int _at_dt(self, datetime dt) except -1: # <<<<<<<<<<<<<< + * cdef int64_t value = datetime_to_nanos(dt) + * cdef line_sender_error* err = NULL + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyDateTime_DateTime *__pyx_v_dt) { + int64_t __pyx_v_value; + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_at_dt", 0); + + /* "questdb/ingress.pyx":658 + * + * cdef inline int _at_dt(self, datetime dt) except -1: + * cdef int64_t value = datetime_to_nanos(dt) # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, value, &err): + */ + __pyx_v_value = __pyx_f_7questdb_7ingress_datetime_to_nanos(__pyx_v_dt); + + /* "questdb/ingress.pyx":659 + * cdef inline int _at_dt(self, datetime dt) except -1: + * cdef int64_t value = datetime_to_nanos(dt) + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_at(self._impl, value, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":660 + * cdef int64_t value = datetime_to_nanos(dt) + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_at(__pyx_v_self->_impl, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":661 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, value, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 661, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 661, __pyx_L1_error) + + /* "questdb/ingress.pyx":660 + * cdef int64_t value = datetime_to_nanos(dt) + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at(self._impl, value, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":662 + * if not line_sender_buffer_at(self._impl, value, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _at_now(self) except -1: + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":657 + * return 0 + * + * cdef inline int _at_dt(self, datetime dt) except -1: # <<<<<<<<<<<<<< + * cdef int64_t value = datetime_to_nanos(dt) + * cdef line_sender_error* err = NULL + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._at_dt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":664 + * return 0 + * + * cdef inline int _at_now(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at_now(self._impl, &err): + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_now(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + struct line_sender_error *__pyx_v_err; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_at_now", 0); + + /* "questdb/ingress.pyx":665 + * + * cdef inline int _at_now(self) except -1: + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if not line_sender_buffer_at_now(self._impl, &err): + * raise c_err_to_py(err) + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":666 + * cdef inline int _at_now(self) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at_now(self._impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + __pyx_t_1 = ((!(line_sender_buffer_at_now(__pyx_v_self->_impl, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":667 + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at_now(self._impl, &err): + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 667, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 667, __pyx_L1_error) + + /* "questdb/ingress.pyx":666 + * cdef inline int _at_now(self) except -1: + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at_now(self._impl, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * return 0 + */ + } + + /* "questdb/ingress.pyx":668 + * if not line_sender_buffer_at_now(self._impl, &err): + * raise c_err_to_py(err) + * return 0 # <<<<<<<<<<<<<< + * + * cdef inline int _at(self, object ts) except -1: + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":664 + * return 0 + * + * cdef inline int _at_now(self) except -1: # <<<<<<<<<<<<<< + * cdef line_sender_error* err = NULL + * if not line_sender_buffer_at_now(self._impl, &err): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Buffer._at_now", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":670 + * return 0 + * + * cdef inline int _at(self, object ts) except -1: # <<<<<<<<<<<<<< + * if ts is None: + * return self._at_now() + */ + +static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_ts) { + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + Py_ssize_t __pyx_t_5; + Py_UCS4 __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_at", 0); + + /* "questdb/ingress.pyx":671 + * + * cdef inline int _at(self, object ts) except -1: + * if ts is None: # <<<<<<<<<<<<<< + * return self._at_now() + * elif isinstance(ts, TimestampNanos): + */ + __pyx_t_1 = (__pyx_v_ts == Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "questdb/ingress.pyx":672 + * cdef inline int _at(self, object ts) except -1: + * if ts is None: + * return self._at_now() # <<<<<<<<<<<<<< + * elif isinstance(ts, TimestampNanos): + * return self._at_ts(ts) + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__at_now(__pyx_v_self); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 672, __pyx_L1_error) + __pyx_r = __pyx_t_3; + goto __pyx_L0; + + /* "questdb/ingress.pyx":671 + * + * cdef inline int _at(self, object ts) except -1: + * if ts is None: # <<<<<<<<<<<<<< + * return self._at_now() + * elif isinstance(ts, TimestampNanos): + */ + } + + /* "questdb/ingress.pyx":673 + * if ts is None: + * return self._at_now() + * elif isinstance(ts, TimestampNanos): # <<<<<<<<<<<<<< + * return self._at_ts(ts) + * elif isinstance(ts, datetime): + */ + __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_ts, __pyx_ptype_7questdb_7ingress_TimestampNanos); + __pyx_t_1 = (__pyx_t_2 != 0); + if (__pyx_t_1) { + + /* "questdb/ingress.pyx":674 + * return self._at_now() + * elif isinstance(ts, TimestampNanos): + * return self._at_ts(ts) # <<<<<<<<<<<<<< + * elif isinstance(ts, datetime): + * return self._at_dt(ts) + */ + if (!(likely(((__pyx_v_ts) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_ts, __pyx_ptype_7questdb_7ingress_TimestampNanos))))) __PYX_ERR(0, 674, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__at_ts(__pyx_v_self, ((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_ts)); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 674, __pyx_L1_error) + __pyx_r = __pyx_t_3; + goto __pyx_L0; + + /* "questdb/ingress.pyx":673 + * if ts is None: + * return self._at_now() + * elif isinstance(ts, TimestampNanos): # <<<<<<<<<<<<<< + * return self._at_ts(ts) + * elif isinstance(ts, datetime): + */ + } + + /* "questdb/ingress.pyx":675 + * elif isinstance(ts, TimestampNanos): + * return self._at_ts(ts) + * elif isinstance(ts, datetime): # <<<<<<<<<<<<<< + * return self._at_dt(ts) + * else: + */ + __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_ts, __pyx_ptype_7cpython_8datetime_datetime); + __pyx_t_2 = (__pyx_t_1 != 0); + if (likely(__pyx_t_2)) { + + /* "questdb/ingress.pyx":676 + * return self._at_ts(ts) + * elif isinstance(ts, datetime): + * return self._at_dt(ts) # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + if (!(likely(((__pyx_v_ts) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_ts, __pyx_ptype_7cpython_8datetime_datetime))))) __PYX_ERR(0, 676, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__at_dt(__pyx_v_self, ((PyDateTime_DateTime *)__pyx_v_ts)); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 676, __pyx_L1_error) + __pyx_r = __pyx_t_3; + goto __pyx_L0; + + /* "questdb/ingress.pyx":675 + * elif isinstance(ts, TimestampNanos): + * return self._at_ts(ts) + * elif isinstance(ts, datetime): # <<<<<<<<<<<<<< + * return self._at_dt(ts) + * else: + */ + } + + /* "questdb/ingress.pyx":678 + * return self._at_dt(ts) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Unsupported type: {type(ts)}. Must be one of: ' + + * 'TimestampNanos, datetime, None') + */ + /*else*/ { + + /* "questdb/ingress.pyx":679 + * else: + * raise TypeError( + * f'Unsupported type: {type(ts)}. Must be one of: ' + # <<<<<<<<<<<<<< + * 'TimestampNanos, datetime, None') + * + */ + __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = 0; + __pyx_t_6 = 127; + __Pyx_INCREF(__pyx_kp_u_Unsupported_type); + __pyx_t_5 += 18; + __Pyx_GIVEREF(__pyx_kp_u_Unsupported_type); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_kp_u_Unsupported_type); + __pyx_t_7 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_ts)), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 679, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6; + __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_INCREF(__pyx_kp_u_Must_be_one_of); + __pyx_t_5 += 18; + __Pyx_GIVEREF(__pyx_kp_u_Must_be_one_of); + PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_kp_u_Must_be_one_of); + __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_4, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 679, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_kp_u_TimestampNanos_datetime_None); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":678 + * return self._at_dt(ts) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Unsupported type: {type(ts)}. Must be one of: ' + + * 'TimestampNanos, datetime, None') + */ + __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 678, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_7, 0, 0, 0); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __PYX_ERR(0, 678, __pyx_L1_error) + } + + /* "questdb/ingress.pyx":670 + * return 0 + * + * cdef inline int _at(self, object ts) except -1: # <<<<<<<<<<<<<< + * if ts is None: + * return self._at_now() + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress.Buffer._at", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":682 + * 'TimestampNanos, datetime, None') + * + * cdef int _row( # <<<<<<<<<<<<<< + * self, + * str table_name, + */ + +static int __pyx_f_7questdb_7ingress_6Buffer__row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args) { + + /* "questdb/ingress.pyx":685 + * self, + * str table_name, + * dict symbols=None, # <<<<<<<<<<<<<< + * dict columns=None, + * object at=None) except -1: + */ + PyObject *__pyx_v_symbols = ((PyObject*)Py_None); + + /* "questdb/ingress.pyx":686 + * str table_name, + * dict symbols=None, + * dict columns=None, # <<<<<<<<<<<<<< + * object at=None) except -1: + * """ + */ + PyObject *__pyx_v_columns = ((PyObject*)Py_None); + + /* "questdb/ingress.pyx":687 + * dict symbols=None, + * dict columns=None, + * object at=None) except -1: # <<<<<<<<<<<<<< + * """ + * Add a row to the buffer. + */ + PyObject *__pyx_v_at = ((PyObject *)Py_None); + int __pyx_v_wrote_fields; + PyObject *__pyx_v_name = NULL; + PyObject *__pyx_v_value = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + Py_ssize_t __pyx_t_8; + Py_ssize_t __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + int __pyx_t_12; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_row", 0); + if (__pyx_optional_args) { + if (__pyx_optional_args->__pyx_n > 0) { + __pyx_v_symbols = __pyx_optional_args->symbols; + if (__pyx_optional_args->__pyx_n > 1) { + __pyx_v_columns = __pyx_optional_args->columns; + if (__pyx_optional_args->__pyx_n > 2) { + __pyx_v_at = __pyx_optional_args->at; + } + } + } + } + + /* "questdb/ingress.pyx":691 + * Add a row to the buffer. + * """ + * cdef bint wrote_fields = False # <<<<<<<<<<<<<< + * self._set_marker() + * try: + */ + __pyx_v_wrote_fields = 0; + + /* "questdb/ingress.pyx":692 + * """ + * cdef bint wrote_fields = False + * self._set_marker() # <<<<<<<<<<<<<< + * try: + * self._table(table_name) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__set_marker(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 692, __pyx_L1_error) + + /* "questdb/ingress.pyx":693 + * cdef bint wrote_fields = False + * self._set_marker() + * try: # <<<<<<<<<<<<<< + * self._table(table_name) + * if symbols is not None: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "questdb/ingress.pyx":694 + * self._set_marker() + * try: + * self._table(table_name) # <<<<<<<<<<<<<< + * if symbols is not None: + * for name, value in symbols.items(): + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__table(__pyx_v_self, __pyx_v_table_name); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 694, __pyx_L3_error) + + /* "questdb/ingress.pyx":695 + * try: + * self._table(table_name) + * if symbols is not None: # <<<<<<<<<<<<<< + * for name, value in symbols.items(): + * if value is not None: + */ + __pyx_t_5 = (__pyx_v_symbols != ((PyObject*)Py_None)); + __pyx_t_6 = (__pyx_t_5 != 0); + if (__pyx_t_6) { + + /* "questdb/ingress.pyx":696 + * self._table(table_name) + * if symbols is not None: + * for name, value in symbols.items(): # <<<<<<<<<<<<<< + * if value is not None: + * self._symbol(name, value) + */ + __pyx_t_8 = 0; + if (unlikely(__pyx_v_symbols == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items"); + __PYX_ERR(0, 696, __pyx_L3_error) + } + __pyx_t_10 = __Pyx_dict_iterator(__pyx_v_symbols, 1, __pyx_n_s_items, (&__pyx_t_9), (&__pyx_t_1)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 696, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_7); + __pyx_t_7 = __pyx_t_10; + __pyx_t_10 = 0; + while (1) { + __pyx_t_12 = __Pyx_dict_iter_next(__pyx_t_7, __pyx_t_9, &__pyx_t_8, &__pyx_t_10, &__pyx_t_11, NULL, __pyx_t_1); + if (unlikely(__pyx_t_12 == 0)) break; + if (unlikely(__pyx_t_12 == -1)) __PYX_ERR(0, 696, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GOTREF(__pyx_t_11); + __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_10); + __pyx_t_10 = 0; + __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_11); + __pyx_t_11 = 0; + + /* "questdb/ingress.pyx":697 + * if symbols is not None: + * for name, value in symbols.items(): + * if value is not None: # <<<<<<<<<<<<<< + * self._symbol(name, value) + * wrote_fields = True + */ + __pyx_t_6 = (__pyx_v_value != Py_None); + __pyx_t_5 = (__pyx_t_6 != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":698 + * for name, value in symbols.items(): + * if value is not None: + * self._symbol(name, value) # <<<<<<<<<<<<<< + * wrote_fields = True + * if columns is not None: + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_name))||((__pyx_v_name) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_name)->tp_name), 0))) __PYX_ERR(0, 698, __pyx_L3_error) + if (!(likely(PyUnicode_CheckExact(__pyx_v_value))||((__pyx_v_value) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_value)->tp_name), 0))) __PYX_ERR(0, 698, __pyx_L3_error) + __pyx_t_12 = __pyx_f_7questdb_7ingress_6Buffer__symbol(__pyx_v_self, ((PyObject*)__pyx_v_name), ((PyObject*)__pyx_v_value)); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 698, __pyx_L3_error) + + /* "questdb/ingress.pyx":699 + * if value is not None: + * self._symbol(name, value) + * wrote_fields = True # <<<<<<<<<<<<<< + * if columns is not None: + * for name, value in columns.items(): + */ + __pyx_v_wrote_fields = 1; + + /* "questdb/ingress.pyx":697 + * if symbols is not None: + * for name, value in symbols.items(): + * if value is not None: # <<<<<<<<<<<<<< + * self._symbol(name, value) + * wrote_fields = True + */ + } + } + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":695 + * try: + * self._table(table_name) + * if symbols is not None: # <<<<<<<<<<<<<< + * for name, value in symbols.items(): + * if value is not None: + */ + } + + /* "questdb/ingress.pyx":700 + * self._symbol(name, value) + * wrote_fields = True + * if columns is not None: # <<<<<<<<<<<<<< + * for name, value in columns.items(): + * if value is not None: + */ + __pyx_t_5 = (__pyx_v_columns != ((PyObject*)Py_None)); + __pyx_t_6 = (__pyx_t_5 != 0); + if (__pyx_t_6) { + + /* "questdb/ingress.pyx":701 + * wrote_fields = True + * if columns is not None: + * for name, value in columns.items(): # <<<<<<<<<<<<<< + * if value is not None: + * self._column(name, value) + */ + __pyx_t_9 = 0; + if (unlikely(__pyx_v_columns == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items"); + __PYX_ERR(0, 701, __pyx_L3_error) + } + __pyx_t_11 = __Pyx_dict_iterator(__pyx_v_columns, 1, __pyx_n_s_items, (&__pyx_t_8), (&__pyx_t_1)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 701, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_7); + __pyx_t_7 = __pyx_t_11; + __pyx_t_11 = 0; + while (1) { + __pyx_t_12 = __Pyx_dict_iter_next(__pyx_t_7, __pyx_t_8, &__pyx_t_9, &__pyx_t_11, &__pyx_t_10, NULL, __pyx_t_1); + if (unlikely(__pyx_t_12 == 0)) break; + if (unlikely(__pyx_t_12 == -1)) __PYX_ERR(0, 701, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_t_10); + __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_10); + __pyx_t_10 = 0; + + /* "questdb/ingress.pyx":702 + * if columns is not None: + * for name, value in columns.items(): + * if value is not None: # <<<<<<<<<<<<<< + * self._column(name, value) + * wrote_fields = True + */ + __pyx_t_6 = (__pyx_v_value != Py_None); + __pyx_t_5 = (__pyx_t_6 != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":703 + * for name, value in columns.items(): + * if value is not None: + * self._column(name, value) # <<<<<<<<<<<<<< + * wrote_fields = True + * if wrote_fields: + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_name))||((__pyx_v_name) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_name)->tp_name), 0))) __PYX_ERR(0, 703, __pyx_L3_error) + __pyx_t_12 = __pyx_f_7questdb_7ingress_6Buffer__column(__pyx_v_self, ((PyObject*)__pyx_v_name), __pyx_v_value); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 703, __pyx_L3_error) + + /* "questdb/ingress.pyx":704 + * if value is not None: + * self._column(name, value) + * wrote_fields = True # <<<<<<<<<<<<<< + * if wrote_fields: + * self._at(at) + */ + __pyx_v_wrote_fields = 1; + + /* "questdb/ingress.pyx":702 + * if columns is not None: + * for name, value in columns.items(): + * if value is not None: # <<<<<<<<<<<<<< + * self._column(name, value) + * wrote_fields = True + */ + } + } + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":700 + * self._symbol(name, value) + * wrote_fields = True + * if columns is not None: # <<<<<<<<<<<<<< + * for name, value in columns.items(): + * if value is not None: + */ + } + + /* "questdb/ingress.pyx":705 + * self._column(name, value) + * wrote_fields = True + * if wrote_fields: # <<<<<<<<<<<<<< + * self._at(at) + * self._clear_marker() + */ + __pyx_t_5 = (__pyx_v_wrote_fields != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":706 + * wrote_fields = True + * if wrote_fields: + * self._at(at) # <<<<<<<<<<<<<< + * self._clear_marker() + * else: + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__at(__pyx_v_self, __pyx_v_at); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 706, __pyx_L3_error) + + /* "questdb/ingress.pyx":707 + * if wrote_fields: + * self._at(at) + * self._clear_marker() # <<<<<<<<<<<<<< + * else: + * self._rewind_to_marker() + */ + __pyx_t_7 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 707, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":705 + * self._column(name, value) + * wrote_fields = True + * if wrote_fields: # <<<<<<<<<<<<<< + * self._at(at) + * self._clear_marker() + */ + goto __pyx_L17; + } + + /* "questdb/ingress.pyx":709 + * self._clear_marker() + * else: + * self._rewind_to_marker() # <<<<<<<<<<<<<< + * except: + * self._rewind_to_marker() + */ + /*else*/ { + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 709, __pyx_L3_error) + } + __pyx_L17:; + + /* "questdb/ingress.pyx":693 + * cdef bint wrote_fields = False + * self._set_marker() + * try: # <<<<<<<<<<<<<< + * self._table(table_name) + * if symbols is not None: + */ + } + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":710 + * else: + * self._rewind_to_marker() + * except: # <<<<<<<<<<<<<< + * self._rewind_to_marker() + * raise + */ + /*except:*/ { + __Pyx_AddTraceback("questdb.ingress.Buffer._row", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_10, &__pyx_t_11) < 0) __PYX_ERR(0, 710, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GOTREF(__pyx_t_11); + + /* "questdb/ingress.pyx":711 + * self._rewind_to_marker() + * except: + * self._rewind_to_marker() # <<<<<<<<<<<<<< + * raise + * if wrote_fields: + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 711, __pyx_L5_except_error) + + /* "questdb/ingress.pyx":712 + * except: + * self._rewind_to_marker() + * raise # <<<<<<<<<<<<<< + * if wrote_fields: + * self._may_trigger_row_complete() + */ + __Pyx_GIVEREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_10); + __Pyx_XGIVEREF(__pyx_t_11); + __Pyx_ErrRestoreWithState(__pyx_t_7, __pyx_t_10, __pyx_t_11); + __pyx_t_7 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; + __PYX_ERR(0, 712, __pyx_L5_except_error) + } + __pyx_L5_except_error:; + + /* "questdb/ingress.pyx":693 + * cdef bint wrote_fields = False + * self._set_marker() + * try: # <<<<<<<<<<<<<< + * self._table(table_name) + * if symbols is not None: + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "questdb/ingress.pyx":713 + * self._rewind_to_marker() + * raise + * if wrote_fields: # <<<<<<<<<<<<<< + * self._may_trigger_row_complete() + * + */ + __pyx_t_5 = (__pyx_v_wrote_fields != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":714 + * raise + * if wrote_fields: + * self._may_trigger_row_complete() # <<<<<<<<<<<<<< + * + * def row( + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 714, __pyx_L1_error) + + /* "questdb/ingress.pyx":713 + * self._rewind_to_marker() + * raise + * if wrote_fields: # <<<<<<<<<<<<<< + * self._may_trigger_row_complete() + * + */ + } + + /* "questdb/ingress.pyx":682 + * 'TimestampNanos, datetime, None') + * + * cdef int _row( # <<<<<<<<<<<<<< + * self, + * str table_name, + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("questdb.ingress.Buffer._row", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_name); + __Pyx_XDECREF(__pyx_v_value); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":716 + * self._may_trigger_row_complete() + * + * def row( # <<<<<<<<<<<<<< + * self, + * table_name: str, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_15row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Buffer_14row[] = "\n Add a single row (line) to the buffer.\n\n .. code-block:: python\n\n # All fields specified.\n buffer.row(\n 'table_name',\n symbols={'sym1': 'abc', 'sym2': 'def', 'sym3': None},\n columns={\n 'col1': True,\n 'col2': 123,\n 'col3': 3.14,\n 'col4': 'xyz',\n 'col5': TimestampMicros(123456789),\n 'col6': datetime(2019, 1, 1, 12, 0, 0),\n 'col7': None},\n at=TimestampNanos(123456789))\n\n # Only symbols specified. Designated timestamp assigned by the db.\n buffer.row(\n 'table_name',\n symbols={'sym1': 'abc', 'sym2': 'def'})\n\n # Float columns and timestamp specified as `datetime.datetime`.\n # Pay special attention to the timezone, which if unspecified is\n # assumed to be the local timezone (and not UTC).\n buffer.row(\n 'sensor data',\n columns={\n 'temperature': 24.5,\n 'humidity': 0.5},\n at=datetime.datetime.utcnow())\n\n\n Python strings passed as values to ``symbols`` are going to be encoded\n as the ``SYMBOL`` type in QuestDB, whilst Python strings passed as\n values to ``columns`` are going to be encoded as the ``STRING`` type.\n\n Refer to the\n `QuestDB documentation `_ to\n understand the difference between the ``SYMBOL`` and ``STRING`` types\n (TL;DR: symbols are interned strings).\n\n Column values can be specified with Python types directly and map as so:\n\n .. list-table::\n :header-rows: 1\n\n * - Python type\n - Serialized as ILP type\n * - ``bool``\n - `BOOLEAN `_\n * - ``int``\n - `INTEGER `_\n * - ``float``\n - `FLOAT `_\n * - ``str``\n - `STRING `_\n * - ``datetime.datetime`` and ``TimestampMicros``\n - `TIMESTAMP `_\n * - ``None``\n - *Column is skipped and not serialized.*\n\n If the destination table was already created, then the columns types\n will be cast to the types of the existing columns whenever possible\n (Refer to the QuestDB documentation pages linked above).\n\n :param table_name: The name of the table to which the row belongs.\n :param symbols: A dictionary of symbol column names to ``str`` values.\n As a convenience, you can also pass a ``None`` value which will\n have the same effect as skipping the key: If the column already\n existed, it will be recorded as ``NULL``, otherwise it will not be\n created.\n :param columns: A dictionary of column names to ``bool``, ``int``,\n ``float``, ``str``, ``TimestampMicros`` or ``datetime`` values.\n As a convenience, you can also pass a ``None`` value which will\n have the same effect as skipping the key: If the column already\n existed, it will be recorded as ``NULL``, otherwise it will not be\n created.\n :param at: The timestamp of the row. If ``None``, timestamp is assigned\n by the server. If ``datetime``, the timestamp is converted to\n nanoseconds. A nanosecond unix epoch timestamp can be passed\n explicitly as a ``TimestampNanos`` object.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_15row = {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_15row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_14row}; +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_15row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_table_name = 0; + PyObject *__pyx_v_symbols = 0; + PyObject *__pyx_v_columns = 0; + PyObject *__pyx_v_at = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("row (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_table_name,&__pyx_n_s_symbols,&__pyx_n_s_columns,&__pyx_n_s_at,0}; + PyObject* values[4] = {0,0,0,0}; + + /* "questdb/ingress.pyx":720 + * table_name: str, + * *, + * symbols: Optional[Dict[str, Optional[str]]]=None, # <<<<<<<<<<<<<< + * columns: Optional[Dict[ + * str, + */ + values[1] = ((PyObject *)Py_None); + + /* "questdb/ingress.pyx":724 + * str, + * Union[None, bool, int, float, str, TimestampMicros, datetime]] + * ]=None, # <<<<<<<<<<<<<< + * at: Union[None, TimestampNanos, datetime]=None): + * """ + */ + values[2] = ((PyObject *)Py_None); + + /* "questdb/ingress.pyx":725 + * Union[None, bool, int, float, str, TimestampMicros, datetime]] + * ]=None, + * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< + * """ + * Add a single row (line) to the buffer. + */ + values[3] = ((PyObject *)Py_None); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_table_name)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + } + if (kw_args > 0 && likely(kw_args <= 3)) { + Py_ssize_t index; + for (index = 1; index < 4 && kw_args > 0; index++) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); + if (value) { values[index] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "row") < 0)) __PYX_ERR(0, 716, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + } + __pyx_v_table_name = ((PyObject*)values[0]); + __pyx_v_symbols = values[1]; + __pyx_v_columns = values[2]; + __pyx_v_at = values[3]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("row", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 716, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Buffer.row", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_table_name), (&PyUnicode_Type), 1, "table_name", 1))) __PYX_ERR(0, 718, __pyx_L1_error) + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_14row(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), __pyx_v_table_name, __pyx_v_symbols, __pyx_v_columns, __pyx_v_at); + + /* "questdb/ingress.pyx":716 + * self._may_trigger_row_complete() + * + * def row( # <<<<<<<<<<<<<< + * self, + * table_name: str, + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_14row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + struct __pyx_opt_args_7questdb_7ingress_6Buffer__row __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("row", 0); + + /* "questdb/ingress.pyx":811 + * explicitly as a ``TimestampNanos`` object. + * """ + * self._row(table_name, symbols, columns, at) # <<<<<<<<<<<<<< + * return self + * + */ + if (!(likely(PyDict_CheckExact(__pyx_v_symbols))||((__pyx_v_symbols) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "dict", Py_TYPE(__pyx_v_symbols)->tp_name), 0))) __PYX_ERR(0, 811, __pyx_L1_error) + if (!(likely(PyDict_CheckExact(__pyx_v_columns))||((__pyx_v_columns) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "dict", Py_TYPE(__pyx_v_columns)->tp_name), 0))) __PYX_ERR(0, 811, __pyx_L1_error) + __pyx_t_2.__pyx_n = 3; + __pyx_t_2.symbols = ((PyObject*)__pyx_v_symbols); + __pyx_t_2.columns = ((PyObject*)__pyx_v_columns); + __pyx_t_2.at = __pyx_v_at; + __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Buffer *)__pyx_v_self->__pyx_vtab)->_row(__pyx_v_self, __pyx_v_table_name, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 811, __pyx_L1_error) + + /* "questdb/ingress.pyx":812 + * """ + * self._row(table_name, symbols, columns, at) + * return self # <<<<<<<<<<<<<< + * + * # def tabular( + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __pyx_r = ((PyObject *)__pyx_v_self); + goto __pyx_L0; + + /* "questdb/ingress.pyx":716 + * self._may_trigger_row_complete() + * + * def row( # <<<<<<<<<<<<<< + * self, + * table_name: str, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("questdb.ingress.Buffer.row", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":978 + * # raise ValueError('nyi') + * + * cdef bint _pandas( # <<<<<<<<<<<<<< + * self, + * object data, + */ + +static int __pyx_f_7questdb_7ingress_6Buffer__pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, CYTHON_UNUSED int __pyx_v_sort) { + size_t __pyx_v_col_count; + Py_ssize_t __pyx_v_name_col; + struct line_sender_table_name __pyx_v_c_table_name; + __pyx_t_7questdb_7ingress_size_t_vec __pyx_v_symbol_indices; + __pyx_t_7questdb_7ingress_size_t_vec __pyx_v_field_indices; + Py_ssize_t __pyx_v_at_col; + int64_t __pyx_v_at_value; + __pyx_t_7questdb_7ingress_column_name_vec __pyx_v_symbol_names; + __pyx_t_7questdb_7ingress_column_name_vec __pyx_v_field_names; + struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes; + size_t __pyx_v_set_buf_count; + Py_buffer *__pyx_v_col_buffers; + size_t __pyx_v_col_index; + struct qdb_pystr_pos __pyx_v_str_buf_marker; + size_t __pyx_v_row_count; + PyObject *__pyx_v_sys = NULL; + size_t __pyx_v_row_index; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + Py_UCS4 __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + size_t __pyx_t_12; + size_t __pyx_t_13; + size_t __pyx_t_14; + PyObject *__pyx_t_15 = NULL; + PyObject *__pyx_t_16 = NULL; + PyObject *__pyx_t_17 = NULL; + int __pyx_t_18; + char const *__pyx_t_19; + PyObject *__pyx_t_20 = NULL; + PyObject *__pyx_t_21 = NULL; + PyObject *__pyx_t_22 = NULL; + int __pyx_t_23; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_pandas", 0); + + /* "questdb/ingress.pyx":994 + * cdef ssize_t name_col + * cdef line_sender_table_name c_table_name + * cdef size_t_vec symbol_indices = size_t_vec_new() # <<<<<<<<<<<<<< + * cdef size_t_vec field_indices = size_t_vec_new() + * cdef ssize_t at_col + */ + __pyx_v_symbol_indices = __pyx_f_7questdb_7ingress_size_t_vec_new(); + + /* "questdb/ingress.pyx":995 + * cdef line_sender_table_name c_table_name + * cdef size_t_vec symbol_indices = size_t_vec_new() + * cdef size_t_vec field_indices = size_t_vec_new() # <<<<<<<<<<<<<< + * cdef ssize_t at_col + * cdef int64_t at_value = 0 + */ + __pyx_v_field_indices = __pyx_f_7questdb_7ingress_size_t_vec_new(); + + /* "questdb/ingress.pyx":997 + * cdef size_t_vec field_indices = size_t_vec_new() + * cdef ssize_t at_col + * cdef int64_t at_value = 0 # <<<<<<<<<<<<<< + * cdef column_name_vec symbol_names = column_name_vec_new() + * cdef column_name_vec field_names = column_name_vec_new() + */ + __pyx_v_at_value = 0; + + /* "questdb/ingress.pyx":998 + * cdef ssize_t at_col + * cdef int64_t at_value = 0 + * cdef column_name_vec symbol_names = column_name_vec_new() # <<<<<<<<<<<<<< + * cdef column_name_vec field_names = column_name_vec_new() + * cdef dtype_t* dtypes = NULL + */ + __pyx_v_symbol_names = __pyx_f_7questdb_7ingress_column_name_vec_new(); + + /* "questdb/ingress.pyx":999 + * cdef int64_t at_value = 0 + * cdef column_name_vec symbol_names = column_name_vec_new() + * cdef column_name_vec field_names = column_name_vec_new() # <<<<<<<<<<<<<< + * cdef dtype_t* dtypes = NULL + * cdef size_t set_buf_count = 0 + */ + __pyx_v_field_names = __pyx_f_7questdb_7ingress_column_name_vec_new(); + + /* "questdb/ingress.pyx":1000 + * cdef column_name_vec symbol_names = column_name_vec_new() + * cdef column_name_vec field_names = column_name_vec_new() + * cdef dtype_t* dtypes = NULL # <<<<<<<<<<<<<< + * cdef size_t set_buf_count = 0 + * cdef Py_buffer* col_buffers = NULL + */ + __pyx_v_dtypes = NULL; + + /* "questdb/ingress.pyx":1001 + * cdef column_name_vec field_names = column_name_vec_new() + * cdef dtype_t* dtypes = NULL + * cdef size_t set_buf_count = 0 # <<<<<<<<<<<<<< + * cdef Py_buffer* col_buffers = NULL + * cdef size_t col_index + */ + __pyx_v_set_buf_count = 0; + + /* "questdb/ingress.pyx":1002 + * cdef dtype_t* dtypes = NULL + * cdef size_t set_buf_count = 0 + * cdef Py_buffer* col_buffers = NULL # <<<<<<<<<<<<<< + * cdef size_t col_index + * cdef qdb_pystr_pos str_buf_marker + */ + __pyx_v_col_buffers = NULL; + + /* "questdb/ingress.pyx":1007 + * cdef size_t row_count + * cdef Py_buffer* cur_col + * _pandas_may_set_na_type() # <<<<<<<<<<<<<< + * try: + * _check_is_pandas_dataframe(data) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_may_set_na_type(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1007, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1008 + * cdef Py_buffer* cur_col + * _pandas_may_set_na_type() + * try: # <<<<<<<<<<<<<< + * _check_is_pandas_dataframe(data) + * col_count = len(data.columns) + */ + /*try:*/ { + + /* "questdb/ingress.pyx":1009 + * _pandas_may_set_na_type() + * try: + * _check_is_pandas_dataframe(data) # <<<<<<<<<<<<<< + * col_count = len(data.columns) + * qdb_pystr_buf_clear(self._b) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress__check_is_pandas_dataframe(__pyx_v_data); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1009, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1010 + * try: + * _check_is_pandas_dataframe(data) + * col_count = len(data.columns) # <<<<<<<<<<<<<< + * qdb_pystr_buf_clear(self._b) + * name_col = _pandas_resolve_table_name( + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1010, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1010, __pyx_L4_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_col_count = __pyx_t_2; + + /* "questdb/ingress.pyx":1011 + * _check_is_pandas_dataframe(data) + * col_count = len(data.columns) + * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< + * name_col = _pandas_resolve_table_name( + * self._b, + */ + qdb_pystr_buf_clear(__pyx_v_self->_b); + + /* "questdb/ingress.pyx":1012 + * col_count = len(data.columns) + * qdb_pystr_buf_clear(self._b) + * name_col = _pandas_resolve_table_name( # <<<<<<<<<<<<<< + * self._b, + * data, table_name, table_name_col, col_count, &c_table_name) + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress__pandas_resolve_table_name(__pyx_v_self->_b, __pyx_v_data, __pyx_v_table_name, __pyx_v_table_name_col, __pyx_v_col_count, (&__pyx_v_c_table_name)); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-2L))) __PYX_ERR(0, 1012, __pyx_L4_error) + __pyx_v_name_col = __pyx_t_3; + + /* "questdb/ingress.pyx":1015 + * self._b, + * data, table_name, table_name_col, col_count, &c_table_name) + * at_col = _pandas_resolve_at(data, at, col_count, &at_value) # <<<<<<<<<<<<<< + * _pandas_resolve_symbols( + * data, name_col, at_col, symbols, col_count, &symbol_indices) + */ + __pyx_t_3 = __pyx_f_7questdb_7ingress__pandas_resolve_at(__pyx_v_data, __pyx_v_at, __pyx_v_col_count, (&__pyx_v_at_value)); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-2L))) __PYX_ERR(0, 1015, __pyx_L4_error) + __pyx_v_at_col = __pyx_t_3; + + /* "questdb/ingress.pyx":1016 + * data, table_name, table_name_col, col_count, &c_table_name) + * at_col = _pandas_resolve_at(data, at, col_count, &at_value) + * _pandas_resolve_symbols( # <<<<<<<<<<<<<< + * data, name_col, at_col, symbols, col_count, &symbol_indices) + * _pandas_resolve_fields( + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress__pandas_resolve_symbols(__pyx_v_data, __pyx_v_name_col, __pyx_v_at_col, __pyx_v_symbols, __pyx_v_col_count, (&__pyx_v_symbol_indices)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1016, __pyx_L4_error) + + /* "questdb/ingress.pyx":1018 + * _pandas_resolve_symbols( + * data, name_col, at_col, symbols, col_count, &symbol_indices) + * _pandas_resolve_fields( # <<<<<<<<<<<<<< + * name_col, &symbol_indices, at_col, col_count, &field_indices) + * _pandas_resolve_col_names( + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress__pandas_resolve_fields(__pyx_v_name_col, (&__pyx_v_symbol_indices), __pyx_v_at_col, __pyx_v_col_count, (&__pyx_v_field_indices)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1018, __pyx_L4_error) + + /* "questdb/ingress.pyx":1020 + * _pandas_resolve_fields( + * name_col, &symbol_indices, at_col, col_count, &field_indices) + * _pandas_resolve_col_names( # <<<<<<<<<<<<<< + * self._b, + * data, &symbol_indices, &field_indices, + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_resolve_col_names(__pyx_v_self->_b, __pyx_v_data, (&__pyx_v_symbol_indices), (&__pyx_v_field_indices), (&__pyx_v_symbol_names), (&__pyx_v_field_names)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1020, __pyx_L4_error) + + /* "questdb/ingress.pyx":1024 + * data, &symbol_indices, &field_indices, + * &symbol_names, &field_names) + * dtypes = calloc(col_count, sizeof(dtype_t)) # <<<<<<<<<<<<<< + * _pandas_resolve_dtypes(data, col_count, dtypes) + * col_buffers = calloc(col_count, sizeof(Py_buffer)) + */ + __pyx_v_dtypes = ((struct __pyx_t_7questdb_7ingress_dtype_t *)calloc(__pyx_v_col_count, (sizeof(struct __pyx_t_7questdb_7ingress_dtype_t)))); + + /* "questdb/ingress.pyx":1025 + * &symbol_names, &field_names) + * dtypes = calloc(col_count, sizeof(dtype_t)) + * _pandas_resolve_dtypes(data, col_count, dtypes) # <<<<<<<<<<<<<< + * col_buffers = calloc(col_count, sizeof(Py_buffer)) + * _pandas_resolve_col_buffers( + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_resolve_dtypes(__pyx_v_data, __pyx_v_col_count, __pyx_v_dtypes); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1025, __pyx_L4_error) + + /* "questdb/ingress.pyx":1026 + * dtypes = calloc(col_count, sizeof(dtype_t)) + * _pandas_resolve_dtypes(data, col_count, dtypes) + * col_buffers = calloc(col_count, sizeof(Py_buffer)) # <<<<<<<<<<<<<< + * _pandas_resolve_col_buffers( + * data, col_count, dtypes, col_buffers, &set_buf_count) + */ + __pyx_v_col_buffers = ((Py_buffer *)calloc(__pyx_v_col_count, (sizeof(Py_buffer)))); + + /* "questdb/ingress.pyx":1027 + * _pandas_resolve_dtypes(data, col_count, dtypes) + * col_buffers = calloc(col_count, sizeof(Py_buffer)) + * _pandas_resolve_col_buffers( # <<<<<<<<<<<<<< + * data, col_count, dtypes, col_buffers, &set_buf_count) + * + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_resolve_col_buffers(__pyx_v_data, __pyx_v_col_count, __pyx_v_dtypes, __pyx_v_col_buffers, (&__pyx_v_set_buf_count)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1027, __pyx_L4_error) + + /* "questdb/ingress.pyx":1033 + * # Instead of clearing it (which would clear the headers' memory) + * # we will truncate (rewind) back to this position. + * str_buf_marker = qdb_pystr_buf_tell(self._b) # <<<<<<<<<<<<<< + * + * import sys + */ + __pyx_v_str_buf_marker = qdb_pystr_buf_tell(__pyx_v_self->_b); + + /* "questdb/ingress.pyx":1035 + * str_buf_marker = qdb_pystr_buf_tell(self._b) + * + * import sys # <<<<<<<<<<<<<< + * sys.stderr.write('_pandas :: (A) ' + + * f'name_col: {name_col}, ' + + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1035, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_sys = __pyx_t_1; + __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1036 + * + * import sys + * sys.stderr.write('_pandas :: (A) ' + # <<<<<<<<<<<<<< + * f'name_col: {name_col}, ' + + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + */ + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_sys, __pyx_n_s_stderr); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1036, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_write); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1036, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1037 + * import sys + * sys.stderr.write('_pandas :: (A) ' + + * f'name_col: {name_col}, ' + # <<<<<<<<<<<<<< + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + * f'at_col: {at_col}, ' + + */ + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1037, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = 0; + __pyx_t_8 = 127; + __Pyx_INCREF(__pyx_kp_u_name_col); + __pyx_t_2 += 10; + __Pyx_GIVEREF(__pyx_kp_u_name_col); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_name_col); + __pyx_t_9 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_name_col, 0, ' ', 'd'); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1037, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_9); + __pyx_t_9 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_2 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); + __pyx_t_9 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1037, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1036 + * + * import sys + * sys.stderr.write('_pandas :: (A) ' + # <<<<<<<<<<<<<< + * f'name_col: {name_col}, ' + + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + */ + __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_pandas_A, __pyx_t_9); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1036, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "questdb/ingress.pyx":1038 + * sys.stderr.write('_pandas :: (A) ' + + * f'name_col: {name_col}, ' + + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + # <<<<<<<<<<<<<< + * f'at_col: {at_col}, ' + + * f'at_value: {at_value}, ' + + */ + __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1038, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_2 = 0; + __pyx_t_8 = 127; + __Pyx_INCREF(__pyx_kp_u_symbol_indices); + __pyx_t_2 += 16; + __Pyx_GIVEREF(__pyx_kp_u_symbol_indices); + PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_symbol_indices); + __pyx_t_10 = __pyx_f_7questdb_7ingress_size_t_vec_str((&__pyx_v_symbol_indices)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1038, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_PyUnicode_Unicode(__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1038, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) : __pyx_t_8; + __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_2 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u__24); + __pyx_t_11 = __Pyx_PyUnicode_Join(__pyx_t_9, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1038, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "questdb/ingress.pyx":1037 + * import sys + * sys.stderr.write('_pandas :: (A) ' + + * f'name_col: {name_col}, ' + # <<<<<<<<<<<<<< + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + * f'at_col: {at_col}, ' + + */ + __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_11); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1037, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "questdb/ingress.pyx":1039 + * f'name_col: {name_col}, ' + + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + * f'at_col: {at_col}, ' + # <<<<<<<<<<<<<< + * f'at_value: {at_value}, ' + + * f'field_indices: {size_t_vec_str(&field_indices)}' + + */ + __pyx_t_11 = PyTuple_New(3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1039, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_2 = 0; + __pyx_t_8 = 127; + __Pyx_INCREF(__pyx_kp_u_at_col); + __pyx_t_2 += 8; + __Pyx_GIVEREF(__pyx_kp_u_at_col); + PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_kp_u_at_col); + __pyx_t_6 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_at_col, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1039, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_2 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_kp_u__24); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_11, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1039, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "questdb/ingress.pyx":1038 + * sys.stderr.write('_pandas :: (A) ' + + * f'name_col: {name_col}, ' + + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + # <<<<<<<<<<<<<< + * f'at_col: {at_col}, ' + + * f'at_value: {at_value}, ' + + */ + __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_t_9, __pyx_t_6); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1038, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1040 + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + * f'at_col: {at_col}, ' + + * f'at_value: {at_value}, ' + # <<<<<<<<<<<<<< + * f'field_indices: {size_t_vec_str(&field_indices)}' + + * '\n') + */ + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1040, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = 0; + __pyx_t_8 = 127; + __Pyx_INCREF(__pyx_kp_u_at_value); + __pyx_t_2 += 10; + __Pyx_GIVEREF(__pyx_kp_u_at_value); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_at_value); + __pyx_t_9 = __Pyx_PyInt_From_int64_t(__pyx_v_at_value); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1040, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_t_9, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1040, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) : __pyx_t_8; + __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_10); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_10); + __pyx_t_10 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_2 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); + __pyx_t_10 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1040, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1039 + * f'name_col: {name_col}, ' + + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + * f'at_col: {at_col}, ' + # <<<<<<<<<<<<<< + * f'at_value: {at_value}, ' + + * f'field_indices: {size_t_vec_str(&field_indices)}' + + */ + __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_11, __pyx_t_10); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1039, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "questdb/ingress.pyx":1041 + * f'at_col: {at_col}, ' + + * f'at_value: {at_value}, ' + + * f'field_indices: {size_t_vec_str(&field_indices)}' + # <<<<<<<<<<<<<< + * '\n') + * row_count = len(data) + */ + __pyx_t_10 = __pyx_f_7questdb_7ingress_size_t_vec_str((&__pyx_v_field_indices)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1041, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_PyUnicode_Unicode(__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1041, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_kp_u_field_indices, __pyx_t_11); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1041, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "questdb/ingress.pyx":1040 + * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + * f'at_col: {at_col}, ' + + * f'at_value: {at_value}, ' + # <<<<<<<<<<<<<< + * f'field_indices: {size_t_vec_str(&field_indices)}' + + * '\n') + */ + __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1040, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "questdb/ingress.pyx":1041 + * f'at_col: {at_col}, ' + + * f'at_value: {at_value}, ' + + * f'field_indices: {size_t_vec_str(&field_indices)}' + # <<<<<<<<<<<<<< + * '\n') + * row_count = len(data) + */ + __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_t_11, __pyx_kp_u__27); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1041, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __pyx_t_11 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_11)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_1 = (__pyx_t_11) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_11, __pyx_t_10) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1036, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1043 + * f'field_indices: {size_t_vec_str(&field_indices)}' + + * '\n') + * row_count = len(data) # <<<<<<<<<<<<<< + * self._clear_marker() + * for row_index in range(row_count): + */ + __pyx_t_2 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1043, __pyx_L4_error) + __pyx_v_row_count = __pyx_t_2; + + /* "questdb/ingress.pyx":1044 + * '\n') + * row_count = len(data) + * self._clear_marker() # <<<<<<<<<<<<<< + * for row_index in range(row_count): + * qdb_pystr_buf_truncate(self._b, str_buf_marker) + */ + __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1044, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1045 + * row_count = len(data) + * self._clear_marker() + * for row_index in range(row_count): # <<<<<<<<<<<<<< + * qdb_pystr_buf_truncate(self._b, str_buf_marker) + * try: + */ + __pyx_t_12 = __pyx_v_row_count; + __pyx_t_13 = __pyx_t_12; + for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { + __pyx_v_row_index = __pyx_t_14; + + /* "questdb/ingress.pyx":1046 + * self._clear_marker() + * for row_index in range(row_count): + * qdb_pystr_buf_truncate(self._b, str_buf_marker) # <<<<<<<<<<<<<< + * try: + * self._set_marker() + */ + qdb_pystr_buf_truncate(__pyx_v_self->_b, __pyx_v_str_buf_marker); + + /* "questdb/ingress.pyx":1047 + * for row_index in range(row_count): + * qdb_pystr_buf_truncate(self._b, str_buf_marker) + * try: # <<<<<<<<<<<<<< + * self._set_marker() + * _pandas_row_table_name( + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_15, &__pyx_t_16, &__pyx_t_17); + __Pyx_XGOTREF(__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_16); + __Pyx_XGOTREF(__pyx_t_17); + /*try:*/ { + + /* "questdb/ingress.pyx":1048 + * qdb_pystr_buf_truncate(self._b, str_buf_marker) + * try: + * self._set_marker() # <<<<<<<<<<<<<< + * _pandas_row_table_name( + * self._impl, + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_6Buffer__set_marker(__pyx_v_self); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1048, __pyx_L8_error) + + /* "questdb/ingress.pyx":1049 + * try: + * self._set_marker() + * _pandas_row_table_name( # <<<<<<<<<<<<<< + * self._impl, + * self._b, + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_row_table_name(__pyx_v_self->_impl, __pyx_v_self->_b, __pyx_v_dtypes, __pyx_v_col_buffers, __pyx_v_name_col, __pyx_v_row_index, __pyx_v_c_table_name); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1049, __pyx_L8_error) + + /* "questdb/ingress.pyx":1057 + * row_index, + * c_table_name) + * _pandas_row_symbols( # <<<<<<<<<<<<<< + * self._impl, + * self._b, + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_row_symbols(__pyx_v_self->_impl, __pyx_v_self->_b, __pyx_v_dtypes, __pyx_v_col_buffers, __pyx_v_row_index, (&__pyx_v_symbol_names), (&__pyx_v_symbol_indices)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1057, __pyx_L8_error) + + /* "questdb/ingress.pyx":1066 + * &symbol_indices) + * # _pandas_row_fields(...) # TODO [amunra]: implement + * _pandas_row_at( # <<<<<<<<<<<<<< + * self._impl, + * dtypes, + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_row_at(__pyx_v_self->_impl, __pyx_v_dtypes, __pyx_v_col_buffers, __pyx_v_row_index, __pyx_v_at_col, __pyx_v_at_value); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1066, __pyx_L8_error) + + /* "questdb/ingress.pyx":1047 + * for row_index in range(row_count): + * qdb_pystr_buf_truncate(self._b, str_buf_marker) + * try: # <<<<<<<<<<<<<< + * self._set_marker() + * _pandas_row_table_name( + */ + } + __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; + __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; + __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; + goto __pyx_L15_try_end; + __pyx_L8_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "questdb/ingress.pyx":1073 + * at_col, + * at_value) + * except: # <<<<<<<<<<<<<< + * self._rewind_to_marker() + * raise + */ + /*except:*/ { + __Pyx_AddTraceback("questdb.ingress.Buffer._pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_7, &__pyx_t_10) < 0) __PYX_ERR(0, 1073, __pyx_L10_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_10); + + /* "questdb/ingress.pyx":1074 + * at_value) + * except: + * self._rewind_to_marker() # <<<<<<<<<<<<<< + * raise + * return True + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(__pyx_v_self); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1074, __pyx_L10_except_error) + + /* "questdb/ingress.pyx":1075 + * except: + * self._rewind_to_marker() + * raise # <<<<<<<<<<<<<< + * return True + * finally: + */ + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_7); + __Pyx_XGIVEREF(__pyx_t_10); + __Pyx_ErrRestoreWithState(__pyx_t_1, __pyx_t_7, __pyx_t_10); + __pyx_t_1 = 0; __pyx_t_7 = 0; __pyx_t_10 = 0; + __PYX_ERR(0, 1075, __pyx_L10_except_error) + } + __pyx_L10_except_error:; + + /* "questdb/ingress.pyx":1047 + * for row_index in range(row_count): + * qdb_pystr_buf_truncate(self._b, str_buf_marker) + * try: # <<<<<<<<<<<<<< + * self._set_marker() + * _pandas_row_table_name( + */ + __Pyx_XGIVEREF(__pyx_t_15); + __Pyx_XGIVEREF(__pyx_t_16); + __Pyx_XGIVEREF(__pyx_t_17); + __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_16, __pyx_t_17); + goto __pyx_L4_error; + __pyx_L15_try_end:; + } + } + + /* "questdb/ingress.pyx":1076 + * self._rewind_to_marker() + * raise + * return True # <<<<<<<<<<<<<< + * finally: + * self._clear_marker() + */ + __pyx_r = 1; + goto __pyx_L3_return; + } + + /* "questdb/ingress.pyx":1078 + * return True + * finally: + * self._clear_marker() # <<<<<<<<<<<<<< + * if col_buffers != NULL: + * for col_index in range(set_buf_count): + */ + /*finally:*/ { + __pyx_L4_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_17 = 0; __pyx_t_16 = 0; __pyx_t_15 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_20, &__pyx_t_21, &__pyx_t_22); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_17, &__pyx_t_16, &__pyx_t_15) < 0)) __Pyx_ErrFetch(&__pyx_t_17, &__pyx_t_16, &__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_17); + __Pyx_XGOTREF(__pyx_t_16); + __Pyx_XGOTREF(__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_20); + __Pyx_XGOTREF(__pyx_t_21); + __Pyx_XGOTREF(__pyx_t_22); + __pyx_t_4 = __pyx_lineno; __pyx_t_18 = __pyx_clineno; __pyx_t_19 = __pyx_filename; + { + __pyx_t_10 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1078, __pyx_L19_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "questdb/ingress.pyx":1079 + * finally: + * self._clear_marker() + * if col_buffers != NULL: # <<<<<<<<<<<<<< + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) + */ + __pyx_t_5 = ((__pyx_v_col_buffers != NULL) != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":1080 + * self._clear_marker() + * if col_buffers != NULL: + * for col_index in range(set_buf_count): # <<<<<<<<<<<<<< + * PyBuffer_Release(&col_buffers[col_index]) + * free(col_buffers) + */ + __pyx_t_12 = __pyx_v_set_buf_count; + __pyx_t_13 = __pyx_t_12; + for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { + __pyx_v_col_index = __pyx_t_14; + + /* "questdb/ingress.pyx":1081 + * if col_buffers != NULL: + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) # <<<<<<<<<<<<<< + * free(col_buffers) + * free(dtypes) + */ + PyBuffer_Release((&(__pyx_v_col_buffers[__pyx_v_col_index]))); + } + + /* "questdb/ingress.pyx":1082 + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) + * free(col_buffers) # <<<<<<<<<<<<<< + * free(dtypes) + * column_name_vec_free(&field_names) + */ + free(__pyx_v_col_buffers); + + /* "questdb/ingress.pyx":1079 + * finally: + * self._clear_marker() + * if col_buffers != NULL: # <<<<<<<<<<<<<< + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) + */ + } + + /* "questdb/ingress.pyx":1083 + * PyBuffer_Release(&col_buffers[col_index]) + * free(col_buffers) + * free(dtypes) # <<<<<<<<<<<<<< + * column_name_vec_free(&field_names) + * column_name_vec_free(&symbol_names) + */ + free(__pyx_v_dtypes); + + /* "questdb/ingress.pyx":1084 + * free(col_buffers) + * free(dtypes) + * column_name_vec_free(&field_names) # <<<<<<<<<<<<<< + * column_name_vec_free(&symbol_names) + * size_t_vec_free(&field_indices) + */ + __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_field_names)); + + /* "questdb/ingress.pyx":1085 + * free(dtypes) + * column_name_vec_free(&field_names) + * column_name_vec_free(&symbol_names) # <<<<<<<<<<<<<< + * size_t_vec_free(&field_indices) + * size_t_vec_free(&symbol_indices) + */ + __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_symbol_names)); + + /* "questdb/ingress.pyx":1086 + * column_name_vec_free(&field_names) + * column_name_vec_free(&symbol_names) + * size_t_vec_free(&field_indices) # <<<<<<<<<<<<<< + * size_t_vec_free(&symbol_indices) + * qdb_pystr_buf_clear(self._b) + */ + __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_field_indices)); + + /* "questdb/ingress.pyx":1087 + * column_name_vec_free(&symbol_names) + * size_t_vec_free(&field_indices) + * size_t_vec_free(&symbol_indices) # <<<<<<<<<<<<<< + * qdb_pystr_buf_clear(self._b) + * + */ + __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_symbol_indices)); + + /* "questdb/ingress.pyx":1088 + * size_t_vec_free(&field_indices) + * size_t_vec_free(&symbol_indices) + * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< + * + * def pandas( + */ + qdb_pystr_buf_clear(__pyx_v_self->_b); + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_20); + __Pyx_XGIVEREF(__pyx_t_21); + __Pyx_XGIVEREF(__pyx_t_22); + __Pyx_ExceptionReset(__pyx_t_20, __pyx_t_21, __pyx_t_22); + } + __Pyx_XGIVEREF(__pyx_t_17); + __Pyx_XGIVEREF(__pyx_t_16); + __Pyx_XGIVEREF(__pyx_t_15); + __Pyx_ErrRestore(__pyx_t_17, __pyx_t_16, __pyx_t_15); + __pyx_t_17 = 0; __pyx_t_16 = 0; __pyx_t_15 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; + __pyx_lineno = __pyx_t_4; __pyx_clineno = __pyx_t_18; __pyx_filename = __pyx_t_19; + goto __pyx_L1_error; + __pyx_L19_error:; + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_20); + __Pyx_XGIVEREF(__pyx_t_21); + __Pyx_XGIVEREF(__pyx_t_22); + __Pyx_ExceptionReset(__pyx_t_20, __pyx_t_21, __pyx_t_22); + } + __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; + __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; + __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; + __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; + goto __pyx_L1_error; + } + __pyx_L3_return: { + __pyx_t_5 = __pyx_r; + + /* "questdb/ingress.pyx":1078 + * return True + * finally: + * self._clear_marker() # <<<<<<<<<<<<<< + * if col_buffers != NULL: + * for col_index in range(set_buf_count): + */ + __pyx_t_10 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1078, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + + /* "questdb/ingress.pyx":1079 + * finally: + * self._clear_marker() + * if col_buffers != NULL: # <<<<<<<<<<<<<< + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) + */ + __pyx_t_23 = ((__pyx_v_col_buffers != NULL) != 0); + if (__pyx_t_23) { + + /* "questdb/ingress.pyx":1080 + * self._clear_marker() + * if col_buffers != NULL: + * for col_index in range(set_buf_count): # <<<<<<<<<<<<<< + * PyBuffer_Release(&col_buffers[col_index]) + * free(col_buffers) + */ + __pyx_t_12 = __pyx_v_set_buf_count; + __pyx_t_13 = __pyx_t_12; + for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { + __pyx_v_col_index = __pyx_t_14; + + /* "questdb/ingress.pyx":1081 + * if col_buffers != NULL: + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) # <<<<<<<<<<<<<< + * free(col_buffers) + * free(dtypes) + */ + PyBuffer_Release((&(__pyx_v_col_buffers[__pyx_v_col_index]))); + } + + /* "questdb/ingress.pyx":1082 + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) + * free(col_buffers) # <<<<<<<<<<<<<< + * free(dtypes) + * column_name_vec_free(&field_names) + */ + free(__pyx_v_col_buffers); + + /* "questdb/ingress.pyx":1079 + * finally: + * self._clear_marker() + * if col_buffers != NULL: # <<<<<<<<<<<<<< + * for col_index in range(set_buf_count): + * PyBuffer_Release(&col_buffers[col_index]) + */ + } + + /* "questdb/ingress.pyx":1083 + * PyBuffer_Release(&col_buffers[col_index]) + * free(col_buffers) + * free(dtypes) # <<<<<<<<<<<<<< + * column_name_vec_free(&field_names) + * column_name_vec_free(&symbol_names) + */ + free(__pyx_v_dtypes); + + /* "questdb/ingress.pyx":1084 + * free(col_buffers) + * free(dtypes) + * column_name_vec_free(&field_names) # <<<<<<<<<<<<<< + * column_name_vec_free(&symbol_names) + * size_t_vec_free(&field_indices) + */ + __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_field_names)); + + /* "questdb/ingress.pyx":1085 + * free(dtypes) + * column_name_vec_free(&field_names) + * column_name_vec_free(&symbol_names) # <<<<<<<<<<<<<< + * size_t_vec_free(&field_indices) + * size_t_vec_free(&symbol_indices) + */ + __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_symbol_names)); + + /* "questdb/ingress.pyx":1086 + * column_name_vec_free(&field_names) + * column_name_vec_free(&symbol_names) + * size_t_vec_free(&field_indices) # <<<<<<<<<<<<<< + * size_t_vec_free(&symbol_indices) + * qdb_pystr_buf_clear(self._b) + */ + __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_field_indices)); + + /* "questdb/ingress.pyx":1087 + * column_name_vec_free(&symbol_names) + * size_t_vec_free(&field_indices) + * size_t_vec_free(&symbol_indices) # <<<<<<<<<<<<<< + * qdb_pystr_buf_clear(self._b) + * + */ + __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_symbol_indices)); + + /* "questdb/ingress.pyx":1088 + * size_t_vec_free(&field_indices) + * size_t_vec_free(&symbol_indices) + * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< + * + * def pandas( + */ + qdb_pystr_buf_clear(__pyx_v_self->_b); + __pyx_r = __pyx_t_5; + goto __pyx_L0; + } + } + + /* "questdb/ingress.pyx":978 + * # raise ValueError('nyi') + * + * cdef bint _pandas( # <<<<<<<<<<<<<< + * self, + * object data, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("questdb.ingress.Buffer._pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_sys); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1090 + * qdb_pystr_buf_clear(self._b) + * + * def pandas( # <<<<<<<<<<<<<< + * self, + * data, # : pd.DataFrame + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_17pandas(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Buffer_16pandas[] = "\n Add a pandas DataFrame to the buffer.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_17pandas = {"pandas", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_17pandas, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_16pandas}; +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_17pandas(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_data = 0; + PyObject *__pyx_v_table_name = 0; + PyObject *__pyx_v_table_name_col = 0; + PyObject *__pyx_v_symbols = 0; + PyObject *__pyx_v_at = 0; + PyBoolObject *__pyx_v_sort = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("pandas (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_table_name,&__pyx_n_s_table_name_col,&__pyx_n_s_symbols,&__pyx_n_s_at,&__pyx_n_s_sort,0}; + PyObject* values[6] = {0,0,0,0,0,0}; + + /* "questdb/ingress.pyx":1094 + * data, # : pd.DataFrame + * *, + * table_name: Optional[str] = None, # <<<<<<<<<<<<<< + * table_name_col: Union[None, int, str] = None, + * symbols: Union[bool, List[int], List[str]] = False, + */ + values[1] = ((PyObject *)Py_None); + + /* "questdb/ingress.pyx":1095 + * *, + * table_name: Optional[str] = None, + * table_name_col: Union[None, int, str] = None, # <<<<<<<<<<<<<< + * symbols: Union[bool, List[int], List[str]] = False, + * at: Union[None, int, str, TimestampNanos, datetime] = None, + */ + values[2] = ((PyObject *)Py_None); + + /* "questdb/ingress.pyx":1096 + * table_name: Optional[str] = None, + * table_name_col: Union[None, int, str] = None, + * symbols: Union[bool, List[int], List[str]] = False, # <<<<<<<<<<<<<< + * at: Union[None, int, str, TimestampNanos, datetime] = None, + * sort: bool = True): + */ + values[3] = ((PyObject *)Py_False); + + /* "questdb/ingress.pyx":1097 + * table_name_col: Union[None, int, str] = None, + * symbols: Union[bool, List[int], List[str]] = False, + * at: Union[None, int, str, TimestampNanos, datetime] = None, # <<<<<<<<<<<<<< + * sort: bool = True): + * """ + */ + values[4] = ((PyObject *)Py_None); + + /* "questdb/ingress.pyx":1098 + * symbols: Union[bool, List[int], List[str]] = False, + * at: Union[None, int, str, TimestampNanos, datetime] = None, + * sort: bool = True): # <<<<<<<<<<<<<< + * """ + * Add a pandas DataFrame to the buffer. + */ + values[5] = (PyObject *)((PyBoolObject *)Py_True); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + } + if (kw_args > 0 && likely(kw_args <= 5)) { + Py_ssize_t index; + for (index = 1; index < 6 && kw_args > 0; index++) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); + if (value) { values[index] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "pandas") < 0)) __PYX_ERR(0, 1090, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + } + __pyx_v_data = values[0]; + __pyx_v_table_name = values[1]; + __pyx_v_table_name_col = values[2]; + __pyx_v_symbols = values[3]; + __pyx_v_at = values[4]; + __pyx_v_sort = ((PyBoolObject *)values[5]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("pandas", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1090, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Buffer.pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sort), __pyx_ptype_7cpython_4bool_bool, 1, "sort", 0))) __PYX_ERR(0, 1098, __pyx_L1_error) + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_16pandas(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), __pyx_v_data, __pyx_v_table_name, __pyx_v_table_name_col, __pyx_v_symbols, __pyx_v_at, __pyx_v_sort); + + /* "questdb/ingress.pyx":1090 + * qdb_pystr_buf_clear(self._b) + * + * def pandas( # <<<<<<<<<<<<<< + * self, + * data, # : pd.DataFrame + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_16pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, PyBoolObject *__pyx_v_sort) { + PyObject *__pyx_v_sys = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + Py_ssize_t __pyx_t_4; + Py_UCS4 __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("pandas", 0); + + /* "questdb/ingress.pyx":1104 + * # See https://cython.readthedocs.io/en/latest/src/userguide/ + * # numpy_tutorial.html#numpy-tutorial + * import sys # <<<<<<<<<<<<<< + * sys.stderr.write('pandas :: (A) ' + + * f'table_name: {table_name}, ' + + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_sys = __pyx_t_1; + __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1105 + * # numpy_tutorial.html#numpy-tutorial + * import sys + * sys.stderr.write('pandas :: (A) ' + # <<<<<<<<<<<<<< + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_sys, __pyx_n_s_stderr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1105, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_write); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1105, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1106 + * import sys + * sys.stderr.write('pandas :: (A) ' + + * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + */ + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_table_name_2); + __pyx_t_4 += 12; + __Pyx_GIVEREF(__pyx_kp_u_table_name_2); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_table_name_2); + __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__24); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1105 + * # numpy_tutorial.html#numpy-tutorial + * import sys + * sys.stderr.write('pandas :: (A) ' + # <<<<<<<<<<<<<< + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + */ + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_pandas_A_2, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1105, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1107 + * sys.stderr.write('pandas :: (A) ' + + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + */ + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_table_name_col_2); + __pyx_t_4 += 16; + __Pyx_GIVEREF(__pyx_kp_u_table_name_col_2); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_table_name_col_2); + __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); + __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1106 + * import sys + * sys.stderr.write('pandas :: (A) ' + + * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + */ + __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":1108 + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< + * f'at: {at}, ' + + * f'sort: {sort}' + + */ + __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_symbols_2); + __pyx_t_4 += 9; + __Pyx_GIVEREF(__pyx_kp_u_symbols_2); + PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_kp_u_symbols_2); + __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_symbols, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_2); + __pyx_t_2 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_kp_u__24); + __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_7, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":1107 + * sys.stderr.write('pandas :: (A) ' + + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + */ + __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1109 + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + # <<<<<<<<<<<<<< + * f'sort: {sort}' + + * '\n') + */ + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_at_2); + __pyx_t_4 += 4; + __Pyx_GIVEREF(__pyx_kp_u_at_2); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_at_2); + __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_at, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__24); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1108 + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< + * f'at: {at}, ' + + * f'sort: {sort}' + + */ + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1110 + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + * f'sort: {sort}' + # <<<<<<<<<<<<<< + * '\n') + * self._pandas(data, table_name, table_name_col, symbols, at, sort) + */ + __pyx_t_6 = __Pyx_PyObject_FormatSimple(((PyObject *)__pyx_v_sort), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_sort_2, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1109 + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + # <<<<<<<<<<<<<< + * f'sort: {sort}' + + * '\n') + */ + __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":1110 + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + * f'sort: {sort}' + # <<<<<<<<<<<<<< + * '\n') + * self._pandas(data, table_name, table_name_col, symbols, at, sort) + */ + __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_kp_u__27); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + __pyx_t_1 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_6, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_7); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1105, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1112 + * f'sort: {sort}' + + * '\n') + * self._pandas(data, table_name, table_name_col, symbols, at, sort) # <<<<<<<<<<<<<< + * sys.stderr.write('pandas :: (B) ' + + * f'table_name: {table_name}, ' + + */ + __pyx_t_8 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_sort)); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1112, __pyx_L1_error) + __pyx_t_9 = ((struct __pyx_vtabstruct_7questdb_7ingress_Buffer *)__pyx_v_self->__pyx_vtab)->_pandas(__pyx_v_self, __pyx_v_data, __pyx_v_table_name, __pyx_v_table_name_col, __pyx_v_symbols, __pyx_v_at, __pyx_t_8); if (unlikely(__pyx_t_9 == ((int)0))) __PYX_ERR(0, 1112, __pyx_L1_error) + + /* "questdb/ingress.pyx":1113 + * '\n') + * self._pandas(data, table_name, table_name_col, symbols, at, sort) + * sys.stderr.write('pandas :: (B) ' + # <<<<<<<<<<<<<< + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_sys, __pyx_n_s_stderr); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_write); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":1114 + * self._pandas(data, table_name, table_name_col, symbols, at, sort) + * sys.stderr.write('pandas :: (B) ' + + * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + */ + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_table_name_2); + __pyx_t_4 += 12; + __Pyx_GIVEREF(__pyx_kp_u_table_name_2); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_table_name_2); + __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__24); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":1113 + * '\n') + * self._pandas(data, table_name, table_name_col, symbols, at, sort) + * sys.stderr.write('pandas :: (B) ' + # <<<<<<<<<<<<<< + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + */ + __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_kp_u_pandas_B, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1115 + * sys.stderr.write('pandas :: (B) ' + + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + */ + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_table_name_col_2); + __pyx_t_4 += 16; + __Pyx_GIVEREF(__pyx_kp_u_table_name_col_2); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_table_name_col_2); + __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2); + __pyx_t_2 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); + __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1114 + * self._pandas(data, table_name, table_name_col, symbols, at, sort) + * sys.stderr.write('pandas :: (B) ' + + * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + */ + __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1116 + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< + * f'at: {at}, ' + + * f'sort: {sort}' + + */ + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_symbols_2); + __pyx_t_4 += 9; + __Pyx_GIVEREF(__pyx_kp_u_symbols_2); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_symbols_2); + __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_v_symbols, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3); + __pyx_t_3 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__24); + __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1115 + * sys.stderr.write('pandas :: (B) ' + + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + */ + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":1117 + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + # <<<<<<<<<<<<<< + * f'sort: {sort}' + + * '\n') + */ + __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1117, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = 0; + __pyx_t_5 = 127; + __Pyx_INCREF(__pyx_kp_u_at_2); + __pyx_t_4 += 4; + __Pyx_GIVEREF(__pyx_kp_u_at_2); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_at_2); + __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_at, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1117, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; + __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_INCREF(__pyx_kp_u__24); + __pyx_t_4 += 2; + __Pyx_GIVEREF(__pyx_kp_u__24); + PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__24); + __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1117, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":1116 + * f'table_name: {table_name}, ' + + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< + * f'at: {at}, ' + + * f'sort: {sort}' + + */ + __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1118 + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + * f'sort: {sort}' + # <<<<<<<<<<<<<< + * '\n') + * + */ + __pyx_t_6 = __Pyx_PyObject_FormatSimple(((PyObject *)__pyx_v_sort), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_sort_2, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1117 + * f'table_name_col: {table_name_col}, ' + + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + # <<<<<<<<<<<<<< + * f'sort: {sort}' + + * '\n') + */ + __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1117, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1118 + * f'symbols: {symbols}, ' + + * f'at: {at}, ' + + * f'sort: {sort}' + # <<<<<<<<<<<<<< + * '\n') + * + */ + __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_kp_u__27); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1118, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_1 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_6, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1090 + * qdb_pystr_buf_clear(self._b) + * + * def pandas( # <<<<<<<<<<<<<< + * self, + * data, # : pd.DataFrame + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress.Buffer.pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_sys); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_19__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__, METH_NOARGS, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_18__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_18__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_21__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__, METH_O, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_20__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_20__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Buffer.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1266 + * cdef size_t _max_name_len + * + * def __cinit__( # <<<<<<<<<<<<<< + * self, + * str host, + */ + +/* Python wrapper */ +static int __pyx_pw_7questdb_7ingress_6Sender_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7questdb_7ingress_6Sender_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_host = 0; + PyObject *__pyx_v_port = 0; + PyObject *__pyx_v_interface = 0; + PyObject *__pyx_v_auth = 0; + PyObject *__pyx_v_tls = 0; + uint64_t __pyx_v_read_timeout; + uint64_t __pyx_v_init_capacity; + uint64_t __pyx_v_max_name_len; + PyObject *__pyx_v_auto_flush = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_host,&__pyx_n_s_port,&__pyx_n_s_interface,&__pyx_n_s_auth,&__pyx_n_s_tls,&__pyx_n_s_read_timeout,&__pyx_n_s_init_capacity,&__pyx_n_s_max_name_len,&__pyx_n_s_auto_flush,0}; + PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; + + /* "questdb/ingress.pyx":1271 + * object port, + * *, + * str interface=None, # <<<<<<<<<<<<<< + * tuple auth=None, + * object tls=False, + */ + values[2] = ((PyObject*)Py_None); + + /* "questdb/ingress.pyx":1272 + * *, + * str interface=None, + * tuple auth=None, # <<<<<<<<<<<<<< + * object tls=False, + * uint64_t read_timeout=15000, + */ + values[3] = ((PyObject*)Py_None); + + /* "questdb/ingress.pyx":1273 + * str interface=None, + * tuple auth=None, + * object tls=False, # <<<<<<<<<<<<<< + * uint64_t read_timeout=15000, + * uint64_t init_capacity=65536, # 64KiB + */ + values[4] = ((PyObject *)Py_False); + values[8] = ((PyObject *)__pyx_int_64512); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_host)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_port)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); __PYX_ERR(0, 1266, __pyx_L3_error) + } + } + if (kw_args > 0 && likely(kw_args <= 7)) { + Py_ssize_t index; + for (index = 2; index < 9 && kw_args > 0; index++) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); + if (value) { values[index] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 1266, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_host = ((PyObject*)values[0]); + __pyx_v_port = values[1]; + __pyx_v_interface = ((PyObject*)values[2]); + __pyx_v_auth = ((PyObject*)values[3]); + __pyx_v_tls = values[4]; + if (values[5]) { + __pyx_v_read_timeout = __Pyx_PyInt_As_uint64_t(values[5]); if (unlikely((__pyx_v_read_timeout == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1274, __pyx_L3_error) + } else { + __pyx_v_read_timeout = ((uint64_t)0x3A98); + } + if (values[6]) { + __pyx_v_init_capacity = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_init_capacity == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1275, __pyx_L3_error) + } else { + __pyx_v_init_capacity = ((uint64_t)0x10000); + } + if (values[7]) { + __pyx_v_max_name_len = __Pyx_PyInt_As_uint64_t(values[7]); if (unlikely((__pyx_v_max_name_len == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1276, __pyx_L3_error) + } else { + __pyx_v_max_name_len = ((uint64_t)0x7F); + } + __pyx_v_auto_flush = values[8]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1266, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Sender.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_host), (&PyUnicode_Type), 1, "host", 1))) __PYX_ERR(0, 1268, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_interface), (&PyUnicode_Type), 1, "interface", 1))) __PYX_ERR(0, 1271, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_auth), (&PyTuple_Type), 1, "auth", 1))) __PYX_ERR(0, 1272, __pyx_L1_error) + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender___cinit__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_host, __pyx_v_port, __pyx_v_interface, __pyx_v_auth, __pyx_v_tls, __pyx_v_read_timeout, __pyx_v_init_capacity, __pyx_v_max_name_len, __pyx_v_auto_flush); + + /* "questdb/ingress.pyx":1266 + * cdef size_t _max_name_len + * + * def __cinit__( # <<<<<<<<<<<<<< + * self, + * str host, + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7questdb_7ingress_6Sender___cinit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_host, PyObject *__pyx_v_port, PyObject *__pyx_v_interface, PyObject *__pyx_v_auth, PyObject *__pyx_v_tls, uint64_t __pyx_v_read_timeout, uint64_t __pyx_v_init_capacity, uint64_t __pyx_v_max_name_len, PyObject *__pyx_v_auto_flush) { + CYTHON_UNUSED struct line_sender_error *__pyx_v_err; + struct line_sender_utf8 __pyx_v_host_utf8; + PyObject *__pyx_v_port_str = 0; + struct line_sender_utf8 __pyx_v_port_utf8; + struct line_sender_utf8 __pyx_v_interface_utf8; + PyObject *__pyx_v_a_key_id = 0; + struct line_sender_utf8 __pyx_v_a_key_id_utf8; + PyObject *__pyx_v_a_priv_key = 0; + struct line_sender_utf8 __pyx_v_a_priv_key_utf8; + PyObject *__pyx_v_a_pub_key_x = 0; + struct line_sender_utf8 __pyx_v_a_pub_key_x_utf8; + PyObject *__pyx_v_a_pub_key_y = 0; + struct line_sender_utf8 __pyx_v_a_pub_key_y_utf8; + struct line_sender_utf8 __pyx_v_ca_utf8; + struct qdb_pystr_buf *__pyx_v_b; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + struct qdb_pystr_buf *__pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + Py_ssize_t __pyx_t_8; + Py_ssize_t __pyx_t_9; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__cinit__", 0); + __Pyx_INCREF(__pyx_v_tls); + + /* "questdb/ingress.pyx":1278 + * uint64_t max_name_len=127, + * object auto_flush=64512): # 63KiB + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * + * cdef line_sender_utf8 host_utf8 + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":1308 + * cdef qdb_pystr_buf* b + * + * self._opts = NULL # <<<<<<<<<<<<<< + * self._impl = NULL + * + */ + __pyx_v_self->_opts = NULL; + + /* "questdb/ingress.pyx":1309 + * + * self._opts = NULL + * self._impl = NULL # <<<<<<<<<<<<<< + * + * self._init_capacity = init_capacity + */ + __pyx_v_self->_impl = NULL; + + /* "questdb/ingress.pyx":1311 + * self._impl = NULL + * + * self._init_capacity = init_capacity # <<<<<<<<<<<<<< + * self._max_name_len = max_name_len + * + */ + __pyx_v_self->_init_capacity = __pyx_v_init_capacity; + + /* "questdb/ingress.pyx":1312 + * + * self._init_capacity = init_capacity + * self._max_name_len = max_name_len # <<<<<<<<<<<<<< + * + * self._buffer = Buffer( + */ + __pyx_v_self->_max_name_len = __pyx_v_max_name_len; + + /* "questdb/ingress.pyx":1315 + * + * self._buffer = Buffer( + * init_capacity=init_capacity, # <<<<<<<<<<<<<< + * max_name_len=max_name_len) + * + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1315, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_v_init_capacity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1315, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_init_capacity, __pyx_t_2) < 0) __PYX_ERR(0, 1315, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1316 + * self._buffer = Buffer( + * init_capacity=init_capacity, + * max_name_len=max_name_len) # <<<<<<<<<<<<<< + * + * b = self._buffer._b + */ + __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_v_max_name_len); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1316, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_max_name_len, __pyx_t_2) < 0) __PYX_ERR(0, 1315, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1314 + * self._max_name_len = max_name_len + * + * self._buffer = Buffer( # <<<<<<<<<<<<<< + * init_capacity=init_capacity, + * max_name_len=max_name_len) + */ + __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer), __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1314, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->_buffer); + __Pyx_DECREF(((PyObject *)__pyx_v_self->_buffer)); + __pyx_v_self->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_t_2); + __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1318 + * max_name_len=max_name_len) + * + * b = self._buffer._b # <<<<<<<<<<<<<< + * + * if PyInt_Check(port): + */ + __pyx_t_3 = __pyx_v_self->_buffer->_b; + __pyx_v_b = __pyx_t_3; + + /* "questdb/ingress.pyx":1320 + * b = self._buffer._b + * + * if PyInt_Check(port): # <<<<<<<<<<<<<< + * port_str = str(port) + * elif PyUnicode_Check(port): + */ + __pyx_t_4 = (PyInt_Check(__pyx_v_port) != 0); + if (__pyx_t_4) { + + /* "questdb/ingress.pyx":1321 + * + * if PyInt_Check(port): + * port_str = str(port) # <<<<<<<<<<<<<< + * elif PyUnicode_Check(port): + * port_str = port + */ + __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_port); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1321, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_port_str = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1320 + * b = self._buffer._b + * + * if PyInt_Check(port): # <<<<<<<<<<<<<< + * port_str = str(port) + * elif PyUnicode_Check(port): + */ + goto __pyx_L3; + } + + /* "questdb/ingress.pyx":1322 + * if PyInt_Check(port): + * port_str = str(port) + * elif PyUnicode_Check(port): # <<<<<<<<<<<<<< + * port_str = port + * else: + */ + __pyx_t_4 = (PyUnicode_Check(__pyx_v_port) != 0); + if (likely(__pyx_t_4)) { + + /* "questdb/ingress.pyx":1323 + * port_str = str(port) + * elif PyUnicode_Check(port): + * port_str = port # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_port))||((__pyx_v_port) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_port)->tp_name), 0))) __PYX_ERR(0, 1323, __pyx_L1_error) + __pyx_t_2 = __pyx_v_port; + __Pyx_INCREF(__pyx_t_2); + __pyx_v_port_str = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1322 + * if PyInt_Check(port): + * port_str = str(port) + * elif PyUnicode_Check(port): # <<<<<<<<<<<<<< + * port_str = port + * else: + */ + goto __pyx_L3; + } + + /* "questdb/ingress.pyx":1325 + * port_str = port + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'port must be an integer or a string, not {type(port)}') + * + */ + /*else*/ { + + /* "questdb/ingress.pyx":1326 + * else: + * raise TypeError( + * f'port must be an integer or a string, not {type(port)}') # <<<<<<<<<<<<<< + * + * str_to_utf8(b, host, &host_utf8) + */ + __pyx_t_2 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_port)), __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_kp_u_port_must_be_an_integer_or_a_str, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1326, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1325 + * port_str = port + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'port must be an integer or a string, not {type(port)}') + * + */ + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1325, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 1325, __pyx_L1_error) + } + __pyx_L3:; + + /* "questdb/ingress.pyx":1328 + * f'port must be an integer or a string, not {type(port)}') + * + * str_to_utf8(b, host, &host_utf8) # <<<<<<<<<<<<<< + * str_to_utf8(b, port_str, &port_utf8) + * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_host, (&__pyx_v_host_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1328, __pyx_L1_error) + + /* "questdb/ingress.pyx":1329 + * + * str_to_utf8(b, host, &host_utf8) + * str_to_utf8(b, port_str, &port_utf8) # <<<<<<<<<<<<<< + * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) + * + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_port_str, (&__pyx_v_port_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1329, __pyx_L1_error) + + /* "questdb/ingress.pyx":1330 + * str_to_utf8(b, host, &host_utf8) + * str_to_utf8(b, port_str, &port_utf8) + * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) # <<<<<<<<<<<<<< + * + * if interface is not None: + */ + __pyx_v_self->_opts = line_sender_opts_new_service(__pyx_v_host_utf8, __pyx_v_port_utf8); + + /* "questdb/ingress.pyx":1332 + * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) + * + * if interface is not None: # <<<<<<<<<<<<<< + * str_to_utf8(b, interface, &interface_utf8) + * line_sender_opts_net_interface(self._opts, interface_utf8) + */ + __pyx_t_4 = (__pyx_v_interface != ((PyObject*)Py_None)); + __pyx_t_5 = (__pyx_t_4 != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":1333 + * + * if interface is not None: + * str_to_utf8(b, interface, &interface_utf8) # <<<<<<<<<<<<<< + * line_sender_opts_net_interface(self._opts, interface_utf8) + * + */ + __pyx_t_5 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_interface, (&__pyx_v_interface_utf8)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1333, __pyx_L1_error) + + /* "questdb/ingress.pyx":1334 + * if interface is not None: + * str_to_utf8(b, interface, &interface_utf8) + * line_sender_opts_net_interface(self._opts, interface_utf8) # <<<<<<<<<<<<<< + * + * if auth is not None: + */ + line_sender_opts_net_interface(__pyx_v_self->_opts, __pyx_v_interface_utf8); + + /* "questdb/ingress.pyx":1332 + * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) + * + * if interface is not None: # <<<<<<<<<<<<<< + * str_to_utf8(b, interface, &interface_utf8) + * line_sender_opts_net_interface(self._opts, interface_utf8) + */ + } + + /* "questdb/ingress.pyx":1336 + * line_sender_opts_net_interface(self._opts, interface_utf8) + * + * if auth is not None: # <<<<<<<<<<<<<< + * (a_key_id, + * a_priv_key, + */ + __pyx_t_5 = (__pyx_v_auth != ((PyObject*)Py_None)); + __pyx_t_4 = (__pyx_t_5 != 0); + if (__pyx_t_4) { + + /* "questdb/ingress.pyx":1340 + * a_priv_key, + * a_pub_key_x, + * a_pub_key_y) = auth # <<<<<<<<<<<<<< + * str_to_utf8(b, a_key_id, &a_key_id_utf8) + * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) + */ + if (likely(__pyx_v_auth != Py_None)) { + PyObject* sequence = __pyx_v_auth; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 4)) { + if (size > 4) __Pyx_RaiseTooManyValuesError(4); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 1337, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 2); + __pyx_t_7 = PyTuple_GET_ITEM(sequence, 3); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_7); + #else + { + Py_ssize_t i; + PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_1,&__pyx_t_6,&__pyx_t_7}; + for (i=0; i < 4; i++) { + PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 1337, __pyx_L1_error) + __Pyx_GOTREF(item); + *(temps[i]) = item; + } + } + #endif + } else { + __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(0, 1337, __pyx_L1_error) + } + + /* "questdb/ingress.pyx":1337 + * + * if auth is not None: + * (a_key_id, # <<<<<<<<<<<<<< + * a_priv_key, + * a_pub_key_x, + */ + if (!(likely(PyUnicode_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) + if (!(likely(PyUnicode_CheckExact(__pyx_t_6))||((__pyx_t_6) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_6)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) + if (!(likely(PyUnicode_CheckExact(__pyx_t_7))||((__pyx_t_7) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_7)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) + __pyx_v_a_key_id = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + __pyx_v_a_priv_key = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + __pyx_v_a_pub_key_x = ((PyObject*)__pyx_t_6); + __pyx_t_6 = 0; + __pyx_v_a_pub_key_y = ((PyObject*)__pyx_t_7); + __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":1341 + * a_pub_key_x, + * a_pub_key_y) = auth + * str_to_utf8(b, a_key_id, &a_key_id_utf8) # <<<<<<<<<<<<<< + * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) + * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_key_id, (&__pyx_v_a_key_id_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1341, __pyx_L1_error) + + /* "questdb/ingress.pyx":1342 + * a_pub_key_y) = auth + * str_to_utf8(b, a_key_id, &a_key_id_utf8) + * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) # <<<<<<<<<<<<<< + * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) + * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_priv_key, (&__pyx_v_a_priv_key_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1342, __pyx_L1_error) + + /* "questdb/ingress.pyx":1343 + * str_to_utf8(b, a_key_id, &a_key_id_utf8) + * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) + * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) # <<<<<<<<<<<<<< + * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) + * line_sender_opts_auth( + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_pub_key_x, (&__pyx_v_a_pub_key_x_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1343, __pyx_L1_error) + + /* "questdb/ingress.pyx":1344 + * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) + * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) + * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) # <<<<<<<<<<<<<< + * line_sender_opts_auth( + * self._opts, + */ + __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_pub_key_y, (&__pyx_v_a_pub_key_y_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1344, __pyx_L1_error) + + /* "questdb/ingress.pyx":1345 + * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) + * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) + * line_sender_opts_auth( # <<<<<<<<<<<<<< + * self._opts, + * a_key_id_utf8, + */ + line_sender_opts_auth(__pyx_v_self->_opts, __pyx_v_a_key_id_utf8, __pyx_v_a_priv_key_utf8, __pyx_v_a_pub_key_x_utf8, __pyx_v_a_pub_key_y_utf8); + + /* "questdb/ingress.pyx":1336 + * line_sender_opts_net_interface(self._opts, interface_utf8) + * + * if auth is not None: # <<<<<<<<<<<<<< + * (a_key_id, + * a_priv_key, + */ + } + + /* "questdb/ingress.pyx":1352 + * a_pub_key_y_utf8) + * + * if tls: # <<<<<<<<<<<<<< + * if tls is True: + * line_sender_opts_tls(self._opts) + */ + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_tls); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1352, __pyx_L1_error) + if (__pyx_t_4) { + + /* "questdb/ingress.pyx":1353 + * + * if tls: + * if tls is True: # <<<<<<<<<<<<<< + * line_sender_opts_tls(self._opts) + * elif isinstance(tls, str): + */ + __pyx_t_4 = (__pyx_v_tls == Py_True); + __pyx_t_5 = (__pyx_t_4 != 0); + if (__pyx_t_5) { + + /* "questdb/ingress.pyx":1354 + * if tls: + * if tls is True: + * line_sender_opts_tls(self._opts) # <<<<<<<<<<<<<< + * elif isinstance(tls, str): + * if tls == 'insecure_skip_verify': + */ + line_sender_opts_tls(__pyx_v_self->_opts); + + /* "questdb/ingress.pyx":1353 + * + * if tls: + * if tls is True: # <<<<<<<<<<<<<< + * line_sender_opts_tls(self._opts) + * elif isinstance(tls, str): + */ + goto __pyx_L7; + } + + /* "questdb/ingress.pyx":1355 + * if tls is True: + * line_sender_opts_tls(self._opts) + * elif isinstance(tls, str): # <<<<<<<<<<<<<< + * if tls == 'insecure_skip_verify': + * line_sender_opts_tls_insecure_skip_verify(self._opts) + */ + __pyx_t_5 = PyUnicode_Check(__pyx_v_tls); + __pyx_t_4 = (__pyx_t_5 != 0); + if (__pyx_t_4) { + + /* "questdb/ingress.pyx":1356 + * line_sender_opts_tls(self._opts) + * elif isinstance(tls, str): + * if tls == 'insecure_skip_verify': # <<<<<<<<<<<<<< + * line_sender_opts_tls_insecure_skip_verify(self._opts) + * else: + */ + __pyx_t_4 = (__Pyx_PyUnicode_Equals(__pyx_v_tls, __pyx_n_u_insecure_skip_verify, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1356, __pyx_L1_error) + if (__pyx_t_4) { + + /* "questdb/ingress.pyx":1357 + * elif isinstance(tls, str): + * if tls == 'insecure_skip_verify': + * line_sender_opts_tls_insecure_skip_verify(self._opts) # <<<<<<<<<<<<<< + * else: + * str_to_utf8(b, tls, &ca_utf8) + */ + line_sender_opts_tls_insecure_skip_verify(__pyx_v_self->_opts); + + /* "questdb/ingress.pyx":1356 + * line_sender_opts_tls(self._opts) + * elif isinstance(tls, str): + * if tls == 'insecure_skip_verify': # <<<<<<<<<<<<<< + * line_sender_opts_tls_insecure_skip_verify(self._opts) + * else: + */ + goto __pyx_L8; + } + + /* "questdb/ingress.pyx":1359 + * line_sender_opts_tls_insecure_skip_verify(self._opts) + * else: + * str_to_utf8(b, tls, &ca_utf8) # <<<<<<<<<<<<<< + * line_sender_opts_tls_ca(self._opts, ca_utf8) + * elif isinstance(tls, pathlib.Path): + */ + /*else*/ { + if (!(likely(PyUnicode_CheckExact(__pyx_v_tls))||((__pyx_v_tls) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_tls)->tp_name), 0))) __PYX_ERR(0, 1359, __pyx_L1_error) + __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, ((PyObject*)__pyx_v_tls), (&__pyx_v_ca_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1359, __pyx_L1_error) + + /* "questdb/ingress.pyx":1360 + * else: + * str_to_utf8(b, tls, &ca_utf8) + * line_sender_opts_tls_ca(self._opts, ca_utf8) # <<<<<<<<<<<<<< + * elif isinstance(tls, pathlib.Path): + * tls = str(tls) + */ + line_sender_opts_tls_ca(__pyx_v_self->_opts, __pyx_v_ca_utf8); + } + __pyx_L8:; + + /* "questdb/ingress.pyx":1355 + * if tls is True: + * line_sender_opts_tls(self._opts) + * elif isinstance(tls, str): # <<<<<<<<<<<<<< + * if tls == 'insecure_skip_verify': + * line_sender_opts_tls_insecure_skip_verify(self._opts) + */ + goto __pyx_L7; + } + + /* "questdb/ingress.pyx":1361 + * str_to_utf8(b, tls, &ca_utf8) + * line_sender_opts_tls_ca(self._opts, ca_utf8) + * elif isinstance(tls, pathlib.Path): # <<<<<<<<<<<<<< + * tls = str(tls) + * str_to_utf8(b, tls, &ca_utf8) + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_Path); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1361, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_4 = PyObject_IsInstance(__pyx_v_tls, __pyx_t_6); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1361, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_5 = (__pyx_t_4 != 0); + if (likely(__pyx_t_5)) { + + /* "questdb/ingress.pyx":1362 + * line_sender_opts_tls_ca(self._opts, ca_utf8) + * elif isinstance(tls, pathlib.Path): + * tls = str(tls) # <<<<<<<<<<<<<< + * str_to_utf8(b, tls, &ca_utf8) + * line_sender_opts_tls_ca(self._opts, ca_utf8) + */ + __pyx_t_6 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_tls); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1362, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF_SET(__pyx_v_tls, __pyx_t_6); + __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1363 + * elif isinstance(tls, pathlib.Path): + * tls = str(tls) + * str_to_utf8(b, tls, &ca_utf8) # <<<<<<<<<<<<<< + * line_sender_opts_tls_ca(self._opts, ca_utf8) + * else: + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_tls))||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_tls)->tp_name), 0))) __PYX_ERR(0, 1363, __pyx_L1_error) + __pyx_t_5 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, ((PyObject*)__pyx_v_tls), (&__pyx_v_ca_utf8)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1363, __pyx_L1_error) + + /* "questdb/ingress.pyx":1364 + * tls = str(tls) + * str_to_utf8(b, tls, &ca_utf8) + * line_sender_opts_tls_ca(self._opts, ca_utf8) # <<<<<<<<<<<<<< + * else: + * raise TypeError( + */ + line_sender_opts_tls_ca(__pyx_v_self->_opts, __pyx_v_ca_utf8); + + /* "questdb/ingress.pyx":1361 + * str_to_utf8(b, tls, &ca_utf8) + * line_sender_opts_tls_ca(self._opts, ca_utf8) + * elif isinstance(tls, pathlib.Path): # <<<<<<<<<<<<<< + * tls = str(tls) + * str_to_utf8(b, tls, &ca_utf8) + */ + goto __pyx_L7; + } + + /* "questdb/ingress.pyx":1366 + * line_sender_opts_tls_ca(self._opts, ca_utf8) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * 'tls must be a bool, a path or string pointing to CA file ' + * f'or "insecure_skip_verify", not {type(tls)}') + */ + /*else*/ { + + /* "questdb/ingress.pyx":1368 + * raise TypeError( + * 'tls must be a bool, a path or string pointing to CA file ' + * f'or "insecure_skip_verify", not {type(tls)}') # <<<<<<<<<<<<<< + * + * if read_timeout is not None: + */ + __pyx_t_6 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_tls)), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1368, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "questdb/ingress.pyx":1367 + * else: + * raise TypeError( + * 'tls must be a bool, a path or string pointing to CA file ' # <<<<<<<<<<<<<< + * f'or "insecure_skip_verify", not {type(tls)}') + * + */ + __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_tls_must_be_a_bool_a_path_or_str, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1367, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1366 + * line_sender_opts_tls_ca(self._opts, ca_utf8) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * 'tls must be a bool, a path or string pointing to CA file ' + * f'or "insecure_skip_verify", not {type(tls)}') + */ + __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1366, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(0, 1366, __pyx_L1_error) + } + __pyx_L7:; + + /* "questdb/ingress.pyx":1352 + * a_pub_key_y_utf8) + * + * if tls: # <<<<<<<<<<<<<< + * if tls is True: + * line_sender_opts_tls(self._opts) + */ + } + + /* "questdb/ingress.pyx":1370 + * f'or "insecure_skip_verify", not {type(tls)}') + * + * if read_timeout is not None: # <<<<<<<<<<<<<< + * line_sender_opts_read_timeout(self._opts, read_timeout) + * + */ + __pyx_t_6 = __Pyx_PyInt_From_uint64_t(__pyx_v_read_timeout); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1370, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = (__pyx_t_6 != Py_None); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_4 = (__pyx_t_5 != 0); + if (__pyx_t_4) { + + /* "questdb/ingress.pyx":1371 + * + * if read_timeout is not None: + * line_sender_opts_read_timeout(self._opts, read_timeout) # <<<<<<<<<<<<<< + * + * self._auto_flush_enabled = not not auto_flush + */ + line_sender_opts_read_timeout(__pyx_v_self->_opts, __pyx_v_read_timeout); + + /* "questdb/ingress.pyx":1370 + * f'or "insecure_skip_verify", not {type(tls)}') + * + * if read_timeout is not None: # <<<<<<<<<<<<<< + * line_sender_opts_read_timeout(self._opts, read_timeout) + * + */ + } + + /* "questdb/ingress.pyx":1373 + * line_sender_opts_read_timeout(self._opts, read_timeout) + * + * self._auto_flush_enabled = not not auto_flush # <<<<<<<<<<<<<< + * self._auto_flush_watermark = int(auto_flush) \ + * if self._auto_flush_enabled else 0 + */ + __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_auto_flush); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1373, __pyx_L1_error) + __pyx_v_self->_auto_flush_enabled = (!((!__pyx_t_4) != 0)); + + /* "questdb/ingress.pyx":1375 + * self._auto_flush_enabled = not not auto_flush + * self._auto_flush_watermark = int(auto_flush) \ + * if self._auto_flush_enabled else 0 # <<<<<<<<<<<<<< + * if self._auto_flush_watermark < 0: + * raise ValueError( + */ + if ((__pyx_v_self->_auto_flush_enabled != 0)) { + + /* "questdb/ingress.pyx":1374 + * + * self._auto_flush_enabled = not not auto_flush + * self._auto_flush_watermark = int(auto_flush) \ # <<<<<<<<<<<<<< + * if self._auto_flush_enabled else 0 + * if self._auto_flush_watermark < 0: + */ + __pyx_t_6 = __Pyx_PyNumber_Int(__pyx_v_auto_flush); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1374, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_9 = PyInt_AsSsize_t(__pyx_t_6); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1374, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_8 = __pyx_t_9; + } else { + __pyx_t_8 = 0; + } + __pyx_v_self->_auto_flush_watermark = __pyx_t_8; + + /* "questdb/ingress.pyx":1376 + * self._auto_flush_watermark = int(auto_flush) \ + * if self._auto_flush_enabled else 0 + * if self._auto_flush_watermark < 0: # <<<<<<<<<<<<<< + * raise ValueError( + * 'auto_flush_watermark must be >= 0, ' + */ + __pyx_t_4 = ((__pyx_v_self->_auto_flush_watermark < 0) != 0); + if (unlikely(__pyx_t_4)) { + + /* "questdb/ingress.pyx":1379 + * raise ValueError( + * 'auto_flush_watermark must be >= 0, ' + * f'not {self._auto_flush_watermark}') # <<<<<<<<<<<<<< + * + * qdb_pystr_buf_clear(b) + */ + __pyx_t_6 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_self->_auto_flush_watermark, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1379, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "questdb/ingress.pyx":1378 + * if self._auto_flush_watermark < 0: + * raise ValueError( + * 'auto_flush_watermark must be >= 0, ' # <<<<<<<<<<<<<< + * f'not {self._auto_flush_watermark}') + * + */ + __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_auto_flush_watermark_must_be_0_n, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1378, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1377 + * if self._auto_flush_enabled else 0 + * if self._auto_flush_watermark < 0: + * raise ValueError( # <<<<<<<<<<<<<< + * 'auto_flush_watermark must be >= 0, ' + * f'not {self._auto_flush_watermark}') + */ + __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1377, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(0, 1377, __pyx_L1_error) + + /* "questdb/ingress.pyx":1376 + * self._auto_flush_watermark = int(auto_flush) \ + * if self._auto_flush_enabled else 0 + * if self._auto_flush_watermark < 0: # <<<<<<<<<<<<<< + * raise ValueError( + * 'auto_flush_watermark must be >= 0, ' + */ + } + + /* "questdb/ingress.pyx":1381 + * f'not {self._auto_flush_watermark}') + * + * qdb_pystr_buf_clear(b) # <<<<<<<<<<<<<< + * + * def new_buffer(self): + */ + qdb_pystr_buf_clear(__pyx_v_b); + + /* "questdb/ingress.pyx":1266 + * cdef size_t _max_name_len + * + * def __cinit__( # <<<<<<<<<<<<<< + * self, + * str host, + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress.Sender.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_port_str); + __Pyx_XDECREF(__pyx_v_a_key_id); + __Pyx_XDECREF(__pyx_v_a_priv_key); + __Pyx_XDECREF(__pyx_v_a_pub_key_x); + __Pyx_XDECREF(__pyx_v_a_pub_key_y); + __Pyx_XDECREF(__pyx_v_tls); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1383 + * qdb_pystr_buf_clear(b) + * + * def new_buffer(self): # <<<<<<<<<<<<<< + * """ + * Make a new configured buffer. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_3new_buffer(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_2new_buffer[] = "\n Make a new configured buffer.\n\n The buffer is set up with the configured `init_capacity` and\n `max_name_len`.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_3new_buffer = {"new_buffer", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_3new_buffer, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_2new_buffer}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_3new_buffer(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("new_buffer (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_2new_buffer(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_2new_buffer(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("new_buffer", 0); + + /* "questdb/ingress.pyx":1390 + * `max_name_len`. + * """ + * return Buffer( # <<<<<<<<<<<<<< + * init_capacity=self._init_capacity, + * max_name_len=self._max_name_len) + */ + __Pyx_XDECREF(__pyx_r); + + /* "questdb/ingress.pyx":1391 + * """ + * return Buffer( + * init_capacity=self._init_capacity, # <<<<<<<<<<<<<< + * max_name_len=self._max_name_len) + * + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1391, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_init_capacity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1391, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_init_capacity, __pyx_t_2) < 0) __PYX_ERR(0, 1391, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1392 + * return Buffer( + * init_capacity=self._init_capacity, + * max_name_len=self._max_name_len) # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_max_name_len); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1392, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_max_name_len, __pyx_t_2) < 0) __PYX_ERR(0, 1391, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1390 + * `max_name_len`. + * """ + * return Buffer( # <<<<<<<<<<<<<< + * init_capacity=self._init_capacity, + * max_name_len=self._max_name_len) + */ + __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer), __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1390, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":1383 + * qdb_pystr_buf_clear(b) + * + * def new_buffer(self): # <<<<<<<<<<<<<< + * """ + * Make a new configured buffer. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Sender.new_buffer", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1395 + * + * @property + * def init_capacity(self) -> int: # <<<<<<<<<<<<<< + * """The initial capacity of the sender's internal buffer.""" + * return self._init_capacity + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13init_capacity_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13init_capacity_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_13init_capacity___get__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "questdb/ingress.pyx":1397 + * def init_capacity(self) -> int: + * """The initial capacity of the sender's internal buffer.""" + * return self._init_capacity # <<<<<<<<<<<<<< + * + * @property + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_init_capacity); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1397, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":1395 + * + * @property + * def init_capacity(self) -> int: # <<<<<<<<<<<<<< + * """The initial capacity of the sender's internal buffer.""" + * return self._init_capacity + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.init_capacity.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1400 + * + * @property + * def max_name_len(self) -> int: # <<<<<<<<<<<<<< + * """Maximum length of a table or column name.""" + * return self._max_name_len + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_12max_name_len_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_12max_name_len_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_12max_name_len___get__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "questdb/ingress.pyx":1402 + * def max_name_len(self) -> int: + * """Maximum length of a table or column name.""" + * return self._max_name_len # <<<<<<<<<<<<<< + * + * def connect(self): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_max_name_len); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1402, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":1400 + * + * @property + * def max_name_len(self) -> int: # <<<<<<<<<<<<<< + * """Maximum length of a table or column name.""" + * return self._max_name_len + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.max_name_len.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1404 + * return self._max_name_len + * + * def connect(self): # <<<<<<<<<<<<<< + * """ + * Connect to the QuestDB server. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_5connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_4connect[] = "\n Connect to the QuestDB server.\n\n This method is synchronous and will block until the connection is\n established.\n\n If the connection is set up with authentication and/or TLS, this\n method will return only *after* the handshake(s) is/are complete.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_5connect = {"connect", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_5connect, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_4connect}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_5connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("connect (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_4connect(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_4connect(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + struct line_sender_error *__pyx_v_err; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("connect", 0); + + /* "questdb/ingress.pyx":1414 + * method will return only *after* the handshake(s) is/are complete. + * """ + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * if self._opts == NULL: + * raise IngressError( + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":1415 + * """ + * cdef line_sender_error* err = NULL + * if self._opts == NULL: # <<<<<<<<<<<<<< + * raise IngressError( + * IngressErrorCode.InvalidApiCall, + */ + __pyx_t_1 = ((__pyx_v_self->_opts == NULL) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":1416 + * cdef line_sender_error* err = NULL + * if self._opts == NULL: + * raise IngressError( # <<<<<<<<<<<<<< + * IngressErrorCode.InvalidApiCall, + * 'connect() can\'t be called after close().') + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "questdb/ingress.pyx":1417 + * if self._opts == NULL: + * raise IngressError( + * IngressErrorCode.InvalidApiCall, # <<<<<<<<<<<<<< + * 'connect() can\'t be called after close().') + * self._impl = line_sender_connect(self._opts, &err) + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_InvalidApiCall); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + __pyx_t_6 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_6 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_3)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_5, __pyx_kp_u_connect_can_t_be_called_after_cl}; + __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_5, __pyx_kp_u_connect_can_t_be_called_after_cl}; + __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else + #endif + { + __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__pyx_t_4) { + __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL; + } + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_5); + __Pyx_INCREF(__pyx_kp_u_connect_can_t_be_called_after_cl); + __Pyx_GIVEREF(__pyx_kp_u_connect_can_t_be_called_after_cl); + PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_kp_u_connect_can_t_be_called_after_cl); + __pyx_t_5 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1416, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 1416, __pyx_L1_error) + + /* "questdb/ingress.pyx":1415 + * """ + * cdef line_sender_error* err = NULL + * if self._opts == NULL: # <<<<<<<<<<<<<< + * raise IngressError( + * IngressErrorCode.InvalidApiCall, + */ + } + + /* "questdb/ingress.pyx":1419 + * IngressErrorCode.InvalidApiCall, + * 'connect() can\'t be called after close().') + * self._impl = line_sender_connect(self._opts, &err) # <<<<<<<<<<<<<< + * if self._impl == NULL: + * raise c_err_to_py(err) + */ + __pyx_v_self->_impl = line_sender_connect(__pyx_v_self->_opts, (&__pyx_v_err)); + + /* "questdb/ingress.pyx":1420 + * 'connect() can\'t be called after close().') + * self._impl = line_sender_connect(self._opts, &err) + * if self._impl == NULL: # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * line_sender_opts_free(self._opts) + */ + __pyx_t_1 = ((__pyx_v_self->_impl == NULL) != 0); + if (unlikely(__pyx_t_1)) { + + /* "questdb/ingress.pyx":1421 + * self._impl = line_sender_connect(self._opts, &err) + * if self._impl == NULL: + * raise c_err_to_py(err) # <<<<<<<<<<<<<< + * line_sender_opts_free(self._opts) + * self._opts = NULL + */ + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1421, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 1421, __pyx_L1_error) + + /* "questdb/ingress.pyx":1420 + * 'connect() can\'t be called after close().') + * self._impl = line_sender_connect(self._opts, &err) + * if self._impl == NULL: # <<<<<<<<<<<<<< + * raise c_err_to_py(err) + * line_sender_opts_free(self._opts) + */ + } + + /* "questdb/ingress.pyx":1422 + * if self._impl == NULL: + * raise c_err_to_py(err) + * line_sender_opts_free(self._opts) # <<<<<<<<<<<<<< + * self._opts = NULL + * + */ + line_sender_opts_free(__pyx_v_self->_opts); + + /* "questdb/ingress.pyx":1423 + * raise c_err_to_py(err) + * line_sender_opts_free(self._opts) + * self._opts = NULL # <<<<<<<<<<<<<< + * + * # Request callbacks when rows are complete. + */ + __pyx_v_self->_opts = NULL; + + /* "questdb/ingress.pyx":1426 + * + * # Request callbacks when rows are complete. + * if self._buffer is not None: # <<<<<<<<<<<<<< + * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) + * + */ + __pyx_t_1 = (((PyObject *)__pyx_v_self->_buffer) != Py_None); + __pyx_t_8 = (__pyx_t_1 != 0); + if (__pyx_t_8) { + + /* "questdb/ingress.pyx":1427 + * # Request callbacks when rows are complete. + * if self._buffer is not None: + * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) # <<<<<<<<<<<<<< + * + * def __enter__(self) -> Sender: + */ + __pyx_t_2 = PyWeakref_NewRef(((PyObject *)__pyx_v_self), Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1427, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->_buffer->_row_complete_sender); + __Pyx_DECREF(__pyx_v_self->_buffer->_row_complete_sender); + __pyx_v_self->_buffer->_row_complete_sender = __pyx_t_2; + __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1426 + * + * # Request callbacks when rows are complete. + * if self._buffer is not None: # <<<<<<<<<<<<<< + * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) + * + */ + } + + /* "questdb/ingress.pyx":1404 + * return self._max_name_len + * + * def connect(self): # <<<<<<<<<<<<<< + * """ + * Connect to the QuestDB server. + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress.Sender.connect", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1429 + * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) + * + * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< + * """Call :func:`Sender.connect` at the start of a ``with`` block.""" + * self.connect() + */ + +/* Python wrapper */ +static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pw_7questdb_7ingress_6Sender_7__enter__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_6__enter__[] = "Call :func:`Sender.connect` at the start of a ``with`` block."; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_7__enter__ = {"__enter__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_7__enter__, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_6__enter__}; +static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pw_7questdb_7ingress_6Sender_7__enter__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + struct __pyx_obj_7questdb_7ingress_Sender *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__enter__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_6__enter__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pf_7questdb_7ingress_6Sender_6__enter__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + struct __pyx_obj_7questdb_7ingress_Sender *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__enter__", 0); + + /* "questdb/ingress.pyx":1431 + * def __enter__(self) -> Sender: + * """Call :func:`Sender.connect` at the start of a ``with`` block.""" + * self.connect() # <<<<<<<<<<<<<< + * return self + * + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_connect); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1431, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1431, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1432 + * """Call :func:`Sender.connect` at the start of a ``with`` block.""" + * self.connect() + * return self # <<<<<<<<<<<<<< + * + * def __str__(self) -> str: + */ + __Pyx_XDECREF(((PyObject *)__pyx_r)); + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __pyx_r = __pyx_v_self; + goto __pyx_L0; + + /* "questdb/ingress.pyx":1429 + * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) + * + * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< + * """Call :func:`Sender.connect` at the start of a ``with`` block.""" + * self.connect() + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("questdb.ingress.Sender.__enter__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF((PyObject *)__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1434 + * return self + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """ + * Inspect the contents of the internal buffer. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_9__str__(PyObject *__pyx_v_self); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_8__str__[] = "\n Inspect the contents of the internal buffer.\n\n The ``str`` value returned represents the unsent data.\n\n Also see :func:`Sender.__len__`.\n "; +#if CYTHON_UPDATE_DESCRIPTOR_DOC +struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__; +#endif +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_9__str__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_8__str__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_8__str__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__str__", 0); + + /* "questdb/ingress.pyx":1442 + * Also see :func:`Sender.__len__`. + * """ + * return str(self._buffer) # <<<<<<<<<<<<<< + * + * def __len__(self) -> int: + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), ((PyObject *)__pyx_v_self->_buffer)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1442, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "questdb/ingress.pyx":1434 + * return self + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """ + * Inspect the contents of the internal buffer. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1444 + * return str(self._buffer) + * + * def __len__(self) -> int: # <<<<<<<<<<<<<< + * """ + * Number of bytes of unsent data in the internal buffer. + */ + +/* Python wrapper */ +static Py_ssize_t __pyx_pw_7questdb_7ingress_6Sender_11__len__(PyObject *__pyx_v_self); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_10__len__[] = "\n Number of bytes of unsent data in the internal buffer.\n\n Equivalent (but cheaper) to ``len(str(sender))``.\n "; +#if CYTHON_UPDATE_DESCRIPTOR_DOC +struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__; +#endif +static Py_ssize_t __pyx_pw_7questdb_7ingress_6Sender_11__len__(PyObject *__pyx_v_self) { + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_10__len__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static Py_ssize_t __pyx_pf_7questdb_7ingress_6Sender_10__len__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__len__", 0); + + /* "questdb/ingress.pyx":1450 + * Equivalent (but cheaper) to ``len(str(sender))``. + * """ + * return len(self._buffer) # <<<<<<<<<<<<<< + * + * def row(self, + */ + __pyx_t_1 = ((PyObject *)__pyx_v_self->_buffer); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1450, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "questdb/ingress.pyx":1444 + * return str(self._buffer) + * + * def __len__(self) -> int: # <<<<<<<<<<<<<< + * """ + * Number of bytes of unsent data in the internal buffer. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1452 + * return len(self._buffer) + * + * def row(self, # <<<<<<<<<<<<<< + * table_name: str, + * *, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_12row[] = "\n Write a row to the internal buffer.\n\n This may be sent automatically depending on the ``auto_flush`` setting\n in the constructor.\n\n Refer to the :func:`Buffer.row` documentation for details on arguments.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_13row = {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_13row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_12row}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_table_name = 0; + PyObject *__pyx_v_symbols = 0; + PyObject *__pyx_v_columns = 0; + PyObject *__pyx_v_at = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("row (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_table_name,&__pyx_n_s_symbols,&__pyx_n_s_columns,&__pyx_n_s_at,0}; + PyObject* values[4] = {0,0,0,0}; + + /* "questdb/ingress.pyx":1455 + * table_name: str, + * *, + * symbols: Optional[Dict[str, str]]=None, # <<<<<<<<<<<<<< + * columns: Optional[Dict[ + * str, + */ + values[1] = ((PyObject *)Py_None); + + /* "questdb/ingress.pyx":1458 + * columns: Optional[Dict[ + * str, + * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, # <<<<<<<<<<<<<< + * at: Union[None, TimestampNanos, datetime]=None): + * """ + */ + values[2] = ((PyObject *)Py_None); + + /* "questdb/ingress.pyx":1459 + * str, + * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, + * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< + * """ + * Write a row to the internal buffer. + */ + values[3] = ((PyObject *)Py_None); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_table_name)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + } + if (kw_args > 0 && likely(kw_args <= 3)) { + Py_ssize_t index; + for (index = 1; index < 4 && kw_args > 0; index++) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); + if (value) { values[index] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "row") < 0)) __PYX_ERR(0, 1452, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + } + __pyx_v_table_name = ((PyObject*)values[0]); + __pyx_v_symbols = values[1]; + __pyx_v_columns = values[2]; + __pyx_v_at = values[3]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("row", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1452, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Sender.row", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_table_name), (&PyUnicode_Type), 1, "table_name", 1))) __PYX_ERR(0, 1453, __pyx_L1_error) + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_12row(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_table_name, __pyx_v_symbols, __pyx_v_columns, __pyx_v_at); + + /* "questdb/ingress.pyx":1452 + * return len(self._buffer) + * + * def row(self, # <<<<<<<<<<<<<< + * table_name: str, + * *, + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12row(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("row", 0); + + /* "questdb/ingress.pyx":1468 + * Refer to the :func:`Buffer.row` documentation for details on arguments. + * """ + * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) # <<<<<<<<<<<<<< + * + * cpdef flush(self, Buffer buffer=None, bint clear=True): + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self->_buffer), __pyx_n_s_row); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1468, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1468, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_table_name); + __Pyx_GIVEREF(__pyx_v_table_name); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_table_name); + __pyx_t_3 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1468, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_symbols, __pyx_v_symbols) < 0) __PYX_ERR(0, 1468, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_columns, __pyx_v_columns) < 0) __PYX_ERR(0, 1468, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_at, __pyx_v_at) < 0) __PYX_ERR(0, 1468, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1468, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":1452 + * return len(self._buffer) + * + * def row(self, # <<<<<<<<<<<<<< + * table_name: str, + * *, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("questdb.ingress.Sender.row", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1470 + * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) + * + * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< + * """ + * If called with no arguments, immediately flushes the internal buffer. + */ + +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_15flush(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress_6Sender_flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args) { + struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); + int __pyx_v_clear = ((int)1); + struct line_sender_error *__pyx_v_err; + struct line_sender_buffer *__pyx_v_c_buf; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + struct line_sender_buffer *__pyx_t_11; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("flush", 0); + if (__pyx_optional_args) { + if (__pyx_optional_args->__pyx_n > 0) { + __pyx_v_buffer = __pyx_optional_args->buffer; + if (__pyx_optional_args->__pyx_n > 1) { + __pyx_v_clear = __pyx_optional_args->clear; + } + } + } + /* Check if called by wrapper */ + if (unlikely(__pyx_skip_dispatch)) ; + /* Check if overridden in Python */ + else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) { + #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS + static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; + if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) { + PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); + #endif + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flush); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7questdb_7ingress_6Sender_15flush)) { + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_clear); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL; + __pyx_t_6 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_6 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_4)) { + PyObject *__pyx_temp[3] = {__pyx_t_5, ((PyObject *)__pyx_v_buffer), __pyx_t_3}; + __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { + PyObject *__pyx_temp[3] = {__pyx_t_5, ((PyObject *)__pyx_v_buffer), __pyx_t_3}; + __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else + #endif + { + __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (__pyx_t_5) { + __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL; + } + __Pyx_INCREF(((PyObject *)__pyx_v_buffer)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_buffer)); + PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, ((PyObject *)__pyx_v_buffer)); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3); + __pyx_t_3 = 0; + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L0; + } + #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS + __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); + __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self)); + if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) { + __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS + } + #endif + } + + /* "questdb/ingress.pyx":1490 + * specified. + * """ + * if buffer is None and not clear: # <<<<<<<<<<<<<< + * raise ValueError('The internal buffer must always be cleared.') + * + */ + __pyx_t_9 = (((PyObject *)__pyx_v_buffer) == Py_None); + __pyx_t_10 = (__pyx_t_9 != 0); + if (__pyx_t_10) { + } else { + __pyx_t_8 = __pyx_t_10; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_10 = ((!(__pyx_v_clear != 0)) != 0); + __pyx_t_8 = __pyx_t_10; + __pyx_L4_bool_binop_done:; + if (unlikely(__pyx_t_8)) { + + /* "questdb/ingress.pyx":1491 + * """ + * if buffer is None and not clear: + * raise ValueError('The internal buffer must always be cleared.') # <<<<<<<<<<<<<< + * + * cdef line_sender_error* err = NULL + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1491, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 1491, __pyx_L1_error) + + /* "questdb/ingress.pyx":1490 + * specified. + * """ + * if buffer is None and not clear: # <<<<<<<<<<<<<< + * raise ValueError('The internal buffer must always be cleared.') + * + */ + } + + /* "questdb/ingress.pyx":1493 + * raise ValueError('The internal buffer must always be cleared.') + * + * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< + * cdef line_sender_buffer* c_buf = NULL + * if self._impl == NULL: + */ + __pyx_v_err = NULL; + + /* "questdb/ingress.pyx":1494 + * + * cdef line_sender_error* err = NULL + * cdef line_sender_buffer* c_buf = NULL # <<<<<<<<<<<<<< + * if self._impl == NULL: + * raise IngressError( + */ + __pyx_v_c_buf = NULL; + + /* "questdb/ingress.pyx":1495 + * cdef line_sender_error* err = NULL + * cdef line_sender_buffer* c_buf = NULL + * if self._impl == NULL: # <<<<<<<<<<<<<< + * raise IngressError( + * IngressErrorCode.InvalidApiCall, + */ + __pyx_t_8 = ((__pyx_v_self->_impl == NULL) != 0); + if (unlikely(__pyx_t_8)) { + + /* "questdb/ingress.pyx":1496 + * cdef line_sender_buffer* c_buf = NULL + * if self._impl == NULL: + * raise IngressError( # <<<<<<<<<<<<<< + * IngressErrorCode.InvalidApiCall, + * 'flush() can\'t be called: Not connected.') + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "questdb/ingress.pyx":1497 + * if self._impl == NULL: + * raise IngressError( + * IngressErrorCode.InvalidApiCall, # <<<<<<<<<<<<<< + * 'flush() can\'t be called: Not connected.') + * if buffer is not None: + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1497, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_InvalidApiCall); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1497, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + __pyx_t_6 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_6 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_7, __pyx_kp_u_flush_can_t_be_called_Not_connec}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1496, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_7, __pyx_kp_u_flush_can_t_be_called_Not_connec}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1496, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + } else + #endif + { + __pyx_t_3 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (__pyx_t_4) { + __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = NULL; + } + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_6, __pyx_t_7); + __Pyx_INCREF(__pyx_kp_u_flush_can_t_be_called_Not_connec); + __Pyx_GIVEREF(__pyx_kp_u_flush_can_t_be_called_Not_connec); + PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_6, __pyx_kp_u_flush_can_t_be_called_Not_connec); + __pyx_t_7 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 1496, __pyx_L1_error) + + /* "questdb/ingress.pyx":1495 + * cdef line_sender_error* err = NULL + * cdef line_sender_buffer* c_buf = NULL + * if self._impl == NULL: # <<<<<<<<<<<<<< + * raise IngressError( + * IngressErrorCode.InvalidApiCall, + */ + } + + /* "questdb/ingress.pyx":1499 + * IngressErrorCode.InvalidApiCall, + * 'flush() can\'t be called: Not connected.') + * if buffer is not None: # <<<<<<<<<<<<<< + * c_buf = buffer._impl + * else: + */ + __pyx_t_8 = (((PyObject *)__pyx_v_buffer) != Py_None); + __pyx_t_10 = (__pyx_t_8 != 0); + if (__pyx_t_10) { + + /* "questdb/ingress.pyx":1500 + * 'flush() can\'t be called: Not connected.') + * if buffer is not None: + * c_buf = buffer._impl # <<<<<<<<<<<<<< + * else: + * c_buf = self._buffer._impl + */ + __pyx_t_11 = __pyx_v_buffer->_impl; + __pyx_v_c_buf = __pyx_t_11; + + /* "questdb/ingress.pyx":1499 + * IngressErrorCode.InvalidApiCall, + * 'flush() can\'t be called: Not connected.') + * if buffer is not None: # <<<<<<<<<<<<<< + * c_buf = buffer._impl + * else: + */ + goto __pyx_L7; + } + + /* "questdb/ingress.pyx":1502 + * c_buf = buffer._impl + * else: + * c_buf = self._buffer._impl # <<<<<<<<<<<<<< + * if line_sender_buffer_size(c_buf) == 0: + * return + */ + /*else*/ { + __pyx_t_11 = __pyx_v_self->_buffer->_impl; + __pyx_v_c_buf = __pyx_t_11; + } + __pyx_L7:; + + /* "questdb/ingress.pyx":1503 + * else: + * c_buf = self._buffer._impl + * if line_sender_buffer_size(c_buf) == 0: # <<<<<<<<<<<<<< + * return + * + */ + __pyx_t_10 = ((line_sender_buffer_size(__pyx_v_c_buf) == 0) != 0); + if (__pyx_t_10) { + + /* "questdb/ingress.pyx":1504 + * c_buf = self._buffer._impl + * if line_sender_buffer_size(c_buf) == 0: + * return # <<<<<<<<<<<<<< + * + * try: + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "questdb/ingress.pyx":1503 + * else: + * c_buf = self._buffer._impl + * if line_sender_buffer_size(c_buf) == 0: # <<<<<<<<<<<<<< + * return + * + */ + } + + /* "questdb/ingress.pyx":1506 + * return + * + * try: # <<<<<<<<<<<<<< + * if clear: + * if not line_sender_flush(self._impl, c_buf, &err): + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14); + __Pyx_XGOTREF(__pyx_t_12); + __Pyx_XGOTREF(__pyx_t_13); + __Pyx_XGOTREF(__pyx_t_14); + /*try:*/ { + + /* "questdb/ingress.pyx":1507 + * + * try: + * if clear: # <<<<<<<<<<<<<< + * if not line_sender_flush(self._impl, c_buf, &err): + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + */ + __pyx_t_10 = (__pyx_v_clear != 0); + if (__pyx_t_10) { + + /* "questdb/ingress.pyx":1508 + * try: + * if clear: + * if not line_sender_flush(self._impl, c_buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + * else: + */ + __pyx_t_10 = ((!(line_sender_flush(__pyx_v_self->_impl, __pyx_v_c_buf, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_10)) { + + /* "questdb/ingress.pyx":1509 + * if clear: + * if not line_sender_flush(self._impl, c_buf, &err): + * raise c_err_to_py_fmt(err, _FLUSH_FMT) # <<<<<<<<<<<<<< + * else: + * if not line_sender_flush_and_keep(self._impl, c_buf, &err): + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FLUSH_FMT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1509, __pyx_L9_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 1509, __pyx_L9_error) + __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py_fmt(__pyx_v_err, ((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1509, __pyx_L9_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 1509, __pyx_L9_error) + + /* "questdb/ingress.pyx":1508 + * try: + * if clear: + * if not line_sender_flush(self._impl, c_buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + * else: + */ + } + + /* "questdb/ingress.pyx":1507 + * + * try: + * if clear: # <<<<<<<<<<<<<< + * if not line_sender_flush(self._impl, c_buf, &err): + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + */ + goto __pyx_L15; + } + + /* "questdb/ingress.pyx":1511 + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + * else: + * if not line_sender_flush_and_keep(self._impl, c_buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + * except: + */ + /*else*/ { + __pyx_t_10 = ((!(line_sender_flush_and_keep(__pyx_v_self->_impl, __pyx_v_c_buf, (&__pyx_v_err)) != 0)) != 0); + if (unlikely(__pyx_t_10)) { + + /* "questdb/ingress.pyx":1512 + * else: + * if not line_sender_flush_and_keep(self._impl, c_buf, &err): + * raise c_err_to_py_fmt(err, _FLUSH_FMT) # <<<<<<<<<<<<<< + * except: + * # Prevent a follow-up call to `.close(flush=True)` (as is usually + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FLUSH_FMT); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1512, __pyx_L9_error) + __Pyx_GOTREF(__pyx_t_2); + if (!(likely(PyUnicode_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1512, __pyx_L9_error) + __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_to_py_fmt(__pyx_v_err, ((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1512, __pyx_L9_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 1512, __pyx_L9_error) + + /* "questdb/ingress.pyx":1511 + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + * else: + * if not line_sender_flush_and_keep(self._impl, c_buf, &err): # <<<<<<<<<<<<<< + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + * except: + */ + } + } + __pyx_L15:; + + /* "questdb/ingress.pyx":1506 + * return + * + * try: # <<<<<<<<<<<<<< + * if clear: + * if not line_sender_flush(self._impl, c_buf, &err): + */ + } + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; + goto __pyx_L14_try_end; + __pyx_L9_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "questdb/ingress.pyx":1513 + * if not line_sender_flush_and_keep(self._impl, c_buf, &err): + * raise c_err_to_py_fmt(err, _FLUSH_FMT) + * except: # <<<<<<<<<<<<<< + * # Prevent a follow-up call to `.close(flush=True)` (as is usually + * # called from `__exit__`) to raise after the sender entered an error + */ + /*except:*/ { + __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) __PYX_ERR(0, 1513, __pyx_L11_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_t_3); + + /* "questdb/ingress.pyx":1517 + * # called from `__exit__`) to raise after the sender entered an error + * # state following a failed call to `.flush()`. + * if c_buf == self._buffer._impl: # <<<<<<<<<<<<<< + * line_sender_buffer_clear(c_buf) + * raise + */ + __pyx_t_10 = ((__pyx_v_c_buf == __pyx_v_self->_buffer->_impl) != 0); + if (__pyx_t_10) { + + /* "questdb/ingress.pyx":1518 + * # state following a failed call to `.flush()`. + * if c_buf == self._buffer._impl: + * line_sender_buffer_clear(c_buf) # <<<<<<<<<<<<<< + * raise + * + */ + line_sender_buffer_clear(__pyx_v_c_buf); + + /* "questdb/ingress.pyx":1517 + * # called from `__exit__`) to raise after the sender entered an error + * # state following a failed call to `.flush()`. + * if c_buf == self._buffer._impl: # <<<<<<<<<<<<<< + * line_sender_buffer_clear(c_buf) + * raise + */ + } + + /* "questdb/ingress.pyx":1519 + * if c_buf == self._buffer._impl: + * line_sender_buffer_clear(c_buf) + * raise # <<<<<<<<<<<<<< + * + * cdef _close(self): + */ + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ErrRestoreWithState(__pyx_t_1, __pyx_t_2, __pyx_t_3); + __pyx_t_1 = 0; __pyx_t_2 = 0; __pyx_t_3 = 0; + __PYX_ERR(0, 1519, __pyx_L11_except_error) + } + __pyx_L11_except_error:; + + /* "questdb/ingress.pyx":1506 + * return + * + * try: # <<<<<<<<<<<<<< + * if clear: + * if not line_sender_flush(self._impl, c_buf, &err): + */ + __Pyx_XGIVEREF(__pyx_t_12); + __Pyx_XGIVEREF(__pyx_t_13); + __Pyx_XGIVEREF(__pyx_t_14); + __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14); + goto __pyx_L1_error; + __pyx_L14_try_end:; + } + + /* "questdb/ingress.pyx":1470 + * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) + * + * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< + * """ + * If called with no arguments, immediately flushes the internal buffer. + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_15flush(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_14flush[] = "\n If called with no arguments, immediately flushes the internal buffer.\n\n Alternatively you can flush a buffer that was constructed explicitly\n by passing ``buffer``.\n\n The buffer will be cleared by default, unless ``clear`` is set to\n ``False``.\n\n This method does nothing if the provided or internal buffer is empty.\n\n :param buffer: The buffer to flush. If ``None``, the internal buffer\n is flushed.\n\n :param clear: If ``True``, the flushed buffer is cleared (default).\n If ``False``, the flushed buffer is left in the internal buffer.\n Note that ``clear=False`` is only supported if ``buffer`` is also\n specified.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_15flush = {"flush", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_15flush, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_14flush}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_15flush(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer = 0; + int __pyx_v_clear; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("flush (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_buffer,&__pyx_n_s_clear,0}; + PyObject* values[2] = {0,0}; + values[0] = (PyObject *)((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_buffer); + if (value) { values[0] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 1: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_clear); + if (value) { values[1] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "flush") < 0)) __PYX_ERR(0, 1470, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)values[0]); + if (values[1]) { + __pyx_v_clear = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_clear == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1470, __pyx_L3_error) + } else { + __pyx_v_clear = ((int)1); + } + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("flush", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1470, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_buffer), __pyx_ptype_7questdb_7ingress_Buffer, 1, "buffer", 0))) __PYX_ERR(0, 1470, __pyx_L1_error) + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_14flush(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_buffer, __pyx_v_clear); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_14flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer, int __pyx_v_clear) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + struct __pyx_opt_args_7questdb_7ingress_6Sender_flush __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("flush", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_2.__pyx_n = 2; + __pyx_t_2.buffer = __pyx_v_buffer; + __pyx_t_2.clear = __pyx_v_clear; + __pyx_t_1 = __pyx_vtabptr_7questdb_7ingress_Sender->flush(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1521 + * raise + * + * cdef _close(self): # <<<<<<<<<<<<<< + * self._buffer = None + * line_sender_opts_free(self._opts) + */ + +static PyObject *__pyx_f_7questdb_7ingress_6Sender__close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_close", 0); + + /* "questdb/ingress.pyx":1522 + * + * cdef _close(self): + * self._buffer = None # <<<<<<<<<<<<<< + * line_sender_opts_free(self._opts) + * self._opts = NULL + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_buffer); + __Pyx_DECREF(((PyObject *)__pyx_v_self->_buffer)); + __pyx_v_self->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); + + /* "questdb/ingress.pyx":1523 + * cdef _close(self): + * self._buffer = None + * line_sender_opts_free(self._opts) # <<<<<<<<<<<<<< + * self._opts = NULL + * line_sender_close(self._impl) + */ + line_sender_opts_free(__pyx_v_self->_opts); + + /* "questdb/ingress.pyx":1524 + * self._buffer = None + * line_sender_opts_free(self._opts) + * self._opts = NULL # <<<<<<<<<<<<<< + * line_sender_close(self._impl) + * self._impl = NULL + */ + __pyx_v_self->_opts = NULL; + + /* "questdb/ingress.pyx":1525 + * line_sender_opts_free(self._opts) + * self._opts = NULL + * line_sender_close(self._impl) # <<<<<<<<<<<<<< + * self._impl = NULL + * + */ + line_sender_close(__pyx_v_self->_impl); + + /* "questdb/ingress.pyx":1526 + * self._opts = NULL + * line_sender_close(self._impl) + * self._impl = NULL # <<<<<<<<<<<<<< + * + * cpdef close(self, bint flush=True): + */ + __pyx_v_self->_impl = NULL; + + /* "questdb/ingress.pyx":1521 + * raise + * + * cdef _close(self): # <<<<<<<<<<<<<< + * self._buffer = None + * line_sender_opts_free(self._opts) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1528 + * self._impl = NULL + * + * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< + * """ + * Disconnect. + */ + +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_17close(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_7questdb_7ingress_6Sender_close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args) { + int __pyx_v_flush = ((int)1); + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_t_7; + struct __pyx_opt_args_7questdb_7ingress_6Sender_flush __pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + char const *__pyx_t_11; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + PyObject *__pyx_t_16 = NULL; + PyObject *__pyx_t_17 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("close", 0); + if (__pyx_optional_args) { + if (__pyx_optional_args->__pyx_n > 0) { + __pyx_v_flush = __pyx_optional_args->flush; + } + } + /* Check if called by wrapper */ + if (unlikely(__pyx_skip_dispatch)) ; + /* Check if overridden in Python */ + else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) { + #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS + static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; + if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) { + PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); + #endif + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_close); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1528, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7questdb_7ingress_6Sender_17close)) { + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_flush); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1528, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1528, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L0; + } + #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS + __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); + __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self)); + if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) { + __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; + } + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS + } + #endif + } + + /* "questdb/ingress.pyx":1538 + * :param bool flush: If ``True``, flush the internal buffer before closing. + * """ + * try: # <<<<<<<<<<<<<< + * if (flush and (self._impl != NULL) and + * (not line_sender_must_close(self._impl))): + */ + /*try:*/ { + + /* "questdb/ingress.pyx":1539 + * """ + * try: + * if (flush and (self._impl != NULL) and # <<<<<<<<<<<<<< + * (not line_sender_must_close(self._impl))): + * self.flush(None, True) + */ + __pyx_t_7 = (__pyx_v_flush != 0); + if (__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_t_7 = ((__pyx_v_self->_impl != NULL) != 0); + if (__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + + /* "questdb/ingress.pyx":1540 + * try: + * if (flush and (self._impl != NULL) and + * (not line_sender_must_close(self._impl))): # <<<<<<<<<<<<<< + * self.flush(None, True) + * finally: + */ + __pyx_t_7 = ((!(line_sender_must_close(__pyx_v_self->_impl) != 0)) != 0); + __pyx_t_6 = __pyx_t_7; + __pyx_L7_bool_binop_done:; + + /* "questdb/ingress.pyx":1539 + * """ + * try: + * if (flush and (self._impl != NULL) and # <<<<<<<<<<<<<< + * (not line_sender_must_close(self._impl))): + * self.flush(None, True) + */ + if (__pyx_t_6) { + + /* "questdb/ingress.pyx":1541 + * if (flush and (self._impl != NULL) and + * (not line_sender_must_close(self._impl))): + * self.flush(None, True) # <<<<<<<<<<<<<< + * finally: + * self._close() + */ + __pyx_t_8.__pyx_n = 2; + __pyx_t_8.buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); + __pyx_t_8.clear = 1; + __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->flush(__pyx_v_self, 0, &__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1541, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1539 + * """ + * try: + * if (flush and (self._impl != NULL) and # <<<<<<<<<<<<<< + * (not line_sender_must_close(self._impl))): + * self.flush(None, True) + */ + } + } + + /* "questdb/ingress.pyx":1543 + * self.flush(None, True) + * finally: + * self._close() # <<<<<<<<<<<<<< + * + * def __exit__(self, exc_type, _exc_val, _exc_tb): + */ + /*finally:*/ { + /*normal exit:*/{ + __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->_close(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1543, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L5; + } + __pyx_L4_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_15, &__pyx_t_16, &__pyx_t_17); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14) < 0)) __Pyx_ErrFetch(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14); + __Pyx_XGOTREF(__pyx_t_12); + __Pyx_XGOTREF(__pyx_t_13); + __Pyx_XGOTREF(__pyx_t_14); + __Pyx_XGOTREF(__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_16); + __Pyx_XGOTREF(__pyx_t_17); + __pyx_t_9 = __pyx_lineno; __pyx_t_10 = __pyx_clineno; __pyx_t_11 = __pyx_filename; + { + __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->_close(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1543, __pyx_L11_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_15); + __Pyx_XGIVEREF(__pyx_t_16); + __Pyx_XGIVEREF(__pyx_t_17); + __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_16, __pyx_t_17); + } + __Pyx_XGIVEREF(__pyx_t_12); + __Pyx_XGIVEREF(__pyx_t_13); + __Pyx_XGIVEREF(__pyx_t_14); + __Pyx_ErrRestore(__pyx_t_12, __pyx_t_13, __pyx_t_14); + __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; + __pyx_lineno = __pyx_t_9; __pyx_clineno = __pyx_t_10; __pyx_filename = __pyx_t_11; + goto __pyx_L1_error; + __pyx_L11_error:; + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_15); + __Pyx_XGIVEREF(__pyx_t_16); + __Pyx_XGIVEREF(__pyx_t_17); + __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_16, __pyx_t_17); + } + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; + goto __pyx_L1_error; + } + __pyx_L5:; + } + + /* "questdb/ingress.pyx":1528 + * self._impl = NULL + * + * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< + * """ + * Disconnect. + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("questdb.ingress.Sender.close", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_17close(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_16close[] = "\n Disconnect.\n\n This method is idempotent and can be called repeatedly.\n\n Once a sender is closed, it can't be re-used.\n\n :param bool flush: If ``True``, flush the internal buffer before closing.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_17close = {"close", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_17close, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_16close}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_17close(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + int __pyx_v_flush; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("close (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_flush,0}; + PyObject* values[1] = {0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_flush); + if (value) { values[0] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "close") < 0)) __PYX_ERR(0, 1528, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + } + if (values[0]) { + __pyx_v_flush = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_flush == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1528, __pyx_L3_error) + } else { + __pyx_v_flush = ((int)1); + } + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("close", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1528, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Sender.close", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_16close(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_flush); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_16close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_v_flush) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + struct __pyx_opt_args_7questdb_7ingress_6Sender_close __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("close", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_2.__pyx_n = 1; + __pyx_t_2.flush = __pyx_v_flush; + __pyx_t_1 = __pyx_vtabptr_7questdb_7ingress_Sender->close(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1528, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.close", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1545 + * self._close() + * + * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< + * """ + * Flush pending and disconnect at the end of a ``with`` block. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_19__exit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7questdb_7ingress_6Sender_18__exit__[] = "\n Flush pending and disconnect at the end of a ``with`` block.\n\n If the ``with`` block raises an exception, any pending data will\n *NOT* be flushed.\n\n This is implemented by calling :func:`Sender.close`.\n "; +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_19__exit__ = {"__exit__", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_19__exit__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_18__exit__}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_19__exit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_exc_type = 0; + CYTHON_UNUSED PyObject *__pyx_v__exc_val = 0; + CYTHON_UNUSED PyObject *__pyx_v__exc_tb = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__exit__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_exc_type,&__pyx_n_s_exc_val,&__pyx_n_s_exc_tb,0}; + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_type)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_val)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 1); __PYX_ERR(0, 1545, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_tb)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 2); __PYX_ERR(0, 1545, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__exit__") < 0)) __PYX_ERR(0, 1545, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v_exc_type = values[0]; + __pyx_v__exc_val = values[1]; + __pyx_v__exc_tb = values[2]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1545, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("questdb.ingress.Sender.__exit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_18__exit__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_exc_type, __pyx_v__exc_val, __pyx_v__exc_tb); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_18__exit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_exc_type, CYTHON_UNUSED PyObject *__pyx_v__exc_val, CYTHON_UNUSED PyObject *__pyx_v__exc_tb) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + struct __pyx_opt_args_7questdb_7ingress_6Sender_close __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__exit__", 0); + + /* "questdb/ingress.pyx":1554 + * This is implemented by calling :func:`Sender.close`. + * """ + * self.close(not exc_type) # <<<<<<<<<<<<<< + * + * def __dealloc__(self): + */ + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_exc_type); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 1554, __pyx_L1_error) + __pyx_t_3.__pyx_n = 1; + __pyx_t_3.flush = (!__pyx_t_1); + __pyx_t_2 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->close(__pyx_v_self, 0, &__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1554, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1545 + * self._close() + * + * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< + * """ + * Flush pending and disconnect at the end of a ``with`` block. + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("questdb.ingress.Sender.__exit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "questdb/ingress.pyx":1556 + * self.close(not exc_type) + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * self._close() + */ + +/* Python wrapper */ +static void __pyx_pw_7questdb_7ingress_6Sender_21__dealloc__(PyObject *__pyx_v_self); /*proto*/ +static void __pyx_pw_7questdb_7ingress_6Sender_21__dealloc__(PyObject *__pyx_v_self) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); + __pyx_pf_7questdb_7ingress_6Sender_20__dealloc__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_7questdb_7ingress_6Sender_20__dealloc__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__dealloc__", 0); + + /* "questdb/ingress.pyx":1557 + * + * def __dealloc__(self): + * self._close() # <<<<<<<<<<<<<< + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->_close(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1557, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":1556 + * self.close(not exc_type) + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * self._close() + */ + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_WriteUnraisable("questdb.ingress.Sender.__dealloc__", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_L0:; + __Pyx_RefNannyFinishContext(); +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_23__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__, METH_NOARGS, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_22__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_22__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_25__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__, METH_O, 0}; +static PyObject *__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_24__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7questdb_7ingress_6Sender_24__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(3, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("questdb.ingress.Sender.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":104 + * # Datetime C API initialization function. + * # You have to call it before any usage of DateTime CAPI functions. + * cdef inline void import_datetime(): # <<<<<<<<<<<<<< + * PyDateTime_IMPORT + * + */ + +static CYTHON_INLINE void __pyx_f_7cpython_8datetime_import_datetime(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("import_datetime", 0); + + /* "cpython/datetime.pxd":105 + * # You have to call it before any usage of DateTime CAPI functions. + * cdef inline void import_datetime(): + * PyDateTime_IMPORT # <<<<<<<<<<<<<< + * + * # Create date object using DateTime CAPI factory function. + */ + (void)(PyDateTime_IMPORT); + + /* "cpython/datetime.pxd":104 + * # Datetime C API initialization function. + * # You have to call it before any usage of DateTime CAPI functions. + * cdef inline void import_datetime(): # <<<<<<<<<<<<<< + * PyDateTime_IMPORT + * + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "cpython/datetime.pxd":109 + * # Create date object using DateTime CAPI factory function. + * # Note, there are no range checks for any of the arguments. + * cdef inline object date_new(int year, int month, int day): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_date_new(int __pyx_v_year, int __pyx_v_month, int __pyx_v_day) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("date_new", 0); + + /* "cpython/datetime.pxd":110 + * # Note, there are no range checks for any of the arguments. + * cdef inline object date_new(int year, int month, int day): + * return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) # <<<<<<<<<<<<<< + * + * # Create time object using DateTime CAPI factory function + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyDateTimeAPI->Date_FromDate(__pyx_v_year, __pyx_v_month, __pyx_v_day, PyDateTimeAPI->DateType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "cpython/datetime.pxd":109 + * # Create date object using DateTime CAPI factory function. + * # Note, there are no range checks for any of the arguments. + * cdef inline object date_new(int year, int month, int day): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("cpython.datetime.date_new", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":114 + * # Create time object using DateTime CAPI factory function + * # Note, there are no range checks for any of the arguments. + * cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_time_new(int __pyx_v_hour, int __pyx_v_minute, int __pyx_v_second, int __pyx_v_microsecond, PyObject *__pyx_v_tz) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("time_new", 0); + + /* "cpython/datetime.pxd":115 + * # Note, there are no range checks for any of the arguments. + * cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): + * return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) # <<<<<<<<<<<<<< + * + * # Create datetime object using DateTime CAPI factory function. + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyDateTimeAPI->Time_FromTime(__pyx_v_hour, __pyx_v_minute, __pyx_v_second, __pyx_v_microsecond, __pyx_v_tz, PyDateTimeAPI->TimeType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 115, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "cpython/datetime.pxd":114 + * # Create time object using DateTime CAPI factory function + * # Note, there are no range checks for any of the arguments. + * cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("cpython.datetime.time_new", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":119 + * # Create datetime object using DateTime CAPI factory function. + * # Note, there are no range checks for any of the arguments. + * cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_datetime_new(int __pyx_v_year, int __pyx_v_month, int __pyx_v_day, int __pyx_v_hour, int __pyx_v_minute, int __pyx_v_second, int __pyx_v_microsecond, PyObject *__pyx_v_tz) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("datetime_new", 0); + + /* "cpython/datetime.pxd":120 + * # Note, there are no range checks for any of the arguments. + * cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): + * return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) # <<<<<<<<<<<<<< + * + * # Create timedelta object using DateTime CAPI factory function. + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyDateTimeAPI->DateTime_FromDateAndTime(__pyx_v_year, __pyx_v_month, __pyx_v_day, __pyx_v_hour, __pyx_v_minute, __pyx_v_second, __pyx_v_microsecond, __pyx_v_tz, PyDateTimeAPI->DateTimeType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 120, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "cpython/datetime.pxd":119 + * # Create datetime object using DateTime CAPI factory function. + * # Note, there are no range checks for any of the arguments. + * cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("cpython.datetime.datetime_new", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":124 + * # Create timedelta object using DateTime CAPI factory function. + * # Note, there are no range checks for any of the arguments. + * cdef inline object timedelta_new(int days, int seconds, int useconds): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_timedelta_new(int __pyx_v_days, int __pyx_v_seconds, int __pyx_v_useconds) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("timedelta_new", 0); + + /* "cpython/datetime.pxd":125 + * # Note, there are no range checks for any of the arguments. + * cdef inline object timedelta_new(int days, int seconds, int useconds): + * return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) # <<<<<<<<<<<<<< + * + * # More recognizable getters for date/time/datetime/timedelta. + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyDateTimeAPI->Delta_FromDelta(__pyx_v_days, __pyx_v_seconds, __pyx_v_useconds, 1, PyDateTimeAPI->DeltaType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 125, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "cpython/datetime.pxd":124 + * # Create timedelta object using DateTime CAPI factory function. + * # Note, there are no range checks for any of the arguments. + * cdef inline object timedelta_new(int days, int seconds, int useconds): # <<<<<<<<<<<<<< + * return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("cpython.datetime.timedelta_new", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":133 + * + * # Get tzinfo of time + * cdef inline object time_tzinfo(object o): # <<<<<<<<<<<<<< + * if (o).hastzinfo: + * return (o).tzinfo + */ + +static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_time_tzinfo(PyObject *__pyx_v_o) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("time_tzinfo", 0); + + /* "cpython/datetime.pxd":134 + * # Get tzinfo of time + * cdef inline object time_tzinfo(object o): + * if (o).hastzinfo: # <<<<<<<<<<<<<< + * return (o).tzinfo + * else: + */ + __pyx_t_1 = (((PyDateTime_Time *)__pyx_v_o)->hastzinfo != 0); + if (__pyx_t_1) { + + /* "cpython/datetime.pxd":135 + * cdef inline object time_tzinfo(object o): + * if (o).hastzinfo: + * return (o).tzinfo # <<<<<<<<<<<<<< + * else: + * return None + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)((PyDateTime_Time *)__pyx_v_o)->tzinfo)); + __pyx_r = ((PyObject *)((PyDateTime_Time *)__pyx_v_o)->tzinfo); + goto __pyx_L0; + + /* "cpython/datetime.pxd":134 + * # Get tzinfo of time + * cdef inline object time_tzinfo(object o): + * if (o).hastzinfo: # <<<<<<<<<<<<<< + * return (o).tzinfo + * else: + */ + } + + /* "cpython/datetime.pxd":137 + * return (o).tzinfo + * else: + * return None # <<<<<<<<<<<<<< + * + * # Get tzinfo of datetime + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + } + + /* "cpython/datetime.pxd":133 + * + * # Get tzinfo of time + * cdef inline object time_tzinfo(object o): # <<<<<<<<<<<<<< + * if (o).hastzinfo: + * return (o).tzinfo + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":140 + * + * # Get tzinfo of datetime + * cdef inline object datetime_tzinfo(object o): # <<<<<<<<<<<<<< + * if (o).hastzinfo: + * return (o).tzinfo + */ + +static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_datetime_tzinfo(PyObject *__pyx_v_o) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("datetime_tzinfo", 0); + + /* "cpython/datetime.pxd":141 + * # Get tzinfo of datetime + * cdef inline object datetime_tzinfo(object o): + * if (o).hastzinfo: # <<<<<<<<<<<<<< + * return (o).tzinfo + * else: + */ + __pyx_t_1 = (((PyDateTime_DateTime *)__pyx_v_o)->hastzinfo != 0); + if (__pyx_t_1) { + + /* "cpython/datetime.pxd":142 + * cdef inline object datetime_tzinfo(object o): + * if (o).hastzinfo: + * return (o).tzinfo # <<<<<<<<<<<<<< + * else: + * return None + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)((PyDateTime_DateTime *)__pyx_v_o)->tzinfo)); + __pyx_r = ((PyObject *)((PyDateTime_DateTime *)__pyx_v_o)->tzinfo); + goto __pyx_L0; + + /* "cpython/datetime.pxd":141 + * # Get tzinfo of datetime + * cdef inline object datetime_tzinfo(object o): + * if (o).hastzinfo: # <<<<<<<<<<<<<< + * return (o).tzinfo + * else: + */ + } + + /* "cpython/datetime.pxd":144 + * return (o).tzinfo + * else: + * return None # <<<<<<<<<<<<<< + * + * # Get year of date + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + } + + /* "cpython/datetime.pxd":140 + * + * # Get tzinfo of datetime + * cdef inline object datetime_tzinfo(object o): # <<<<<<<<<<<<<< + * if (o).hastzinfo: + * return (o).tzinfo + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":147 + * + * # Get year of date + * cdef inline int date_year(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_YEAR(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_date_year(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("date_year", 0); + + /* "cpython/datetime.pxd":148 + * # Get year of date + * cdef inline int date_year(object o): + * return PyDateTime_GET_YEAR(o) # <<<<<<<<<<<<<< + * + * # Get month of date + */ + __pyx_r = PyDateTime_GET_YEAR(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":147 + * + * # Get year of date + * cdef inline int date_year(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_YEAR(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":151 + * + * # Get month of date + * cdef inline int date_month(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_MONTH(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_date_month(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("date_month", 0); + + /* "cpython/datetime.pxd":152 + * # Get month of date + * cdef inline int date_month(object o): + * return PyDateTime_GET_MONTH(o) # <<<<<<<<<<<<<< + * + * # Get day of date + */ + __pyx_r = PyDateTime_GET_MONTH(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":151 + * + * # Get month of date + * cdef inline int date_month(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_MONTH(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":155 + * + * # Get day of date + * cdef inline int date_day(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_DAY(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_date_day(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("date_day", 0); + + /* "cpython/datetime.pxd":156 + * # Get day of date + * cdef inline int date_day(object o): + * return PyDateTime_GET_DAY(o) # <<<<<<<<<<<<<< + * + * # Get year of datetime + */ + __pyx_r = PyDateTime_GET_DAY(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":155 + * + * # Get day of date + * cdef inline int date_day(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_DAY(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":159 + * + * # Get year of datetime + * cdef inline int datetime_year(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_YEAR(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_year(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("datetime_year", 0); + + /* "cpython/datetime.pxd":160 + * # Get year of datetime + * cdef inline int datetime_year(object o): + * return PyDateTime_GET_YEAR(o) # <<<<<<<<<<<<<< + * + * # Get month of datetime + */ + __pyx_r = PyDateTime_GET_YEAR(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":159 + * + * # Get year of datetime + * cdef inline int datetime_year(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_YEAR(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":163 + * + * # Get month of datetime + * cdef inline int datetime_month(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_MONTH(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_month(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("datetime_month", 0); + + /* "cpython/datetime.pxd":164 + * # Get month of datetime + * cdef inline int datetime_month(object o): + * return PyDateTime_GET_MONTH(o) # <<<<<<<<<<<<<< + * + * # Get day of datetime + */ + __pyx_r = PyDateTime_GET_MONTH(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":163 + * + * # Get month of datetime + * cdef inline int datetime_month(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_MONTH(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":167 + * + * # Get day of datetime + * cdef inline int datetime_day(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_DAY(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_day(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("datetime_day", 0); + + /* "cpython/datetime.pxd":168 + * # Get day of datetime + * cdef inline int datetime_day(object o): + * return PyDateTime_GET_DAY(o) # <<<<<<<<<<<<<< + * + * # Get hour of time + */ + __pyx_r = PyDateTime_GET_DAY(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":167 + * + * # Get day of datetime + * cdef inline int datetime_day(object o): # <<<<<<<<<<<<<< + * return PyDateTime_GET_DAY(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":171 + * + * # Get hour of time + * cdef inline int time_hour(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_HOUR(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_hour(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("time_hour", 0); + + /* "cpython/datetime.pxd":172 + * # Get hour of time + * cdef inline int time_hour(object o): + * return PyDateTime_TIME_GET_HOUR(o) # <<<<<<<<<<<<<< + * + * # Get minute of time + */ + __pyx_r = PyDateTime_TIME_GET_HOUR(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":171 + * + * # Get hour of time + * cdef inline int time_hour(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_HOUR(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":175 + * + * # Get minute of time + * cdef inline int time_minute(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_MINUTE(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_minute(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("time_minute", 0); + + /* "cpython/datetime.pxd":176 + * # Get minute of time + * cdef inline int time_minute(object o): + * return PyDateTime_TIME_GET_MINUTE(o) # <<<<<<<<<<<<<< + * + * # Get second of time + */ + __pyx_r = PyDateTime_TIME_GET_MINUTE(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":175 + * + * # Get minute of time + * cdef inline int time_minute(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_MINUTE(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":179 + * + * # Get second of time + * cdef inline int time_second(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_SECOND(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_second(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("time_second", 0); + + /* "cpython/datetime.pxd":180 + * # Get second of time + * cdef inline int time_second(object o): + * return PyDateTime_TIME_GET_SECOND(o) # <<<<<<<<<<<<<< + * + * # Get microsecond of time + */ + __pyx_r = PyDateTime_TIME_GET_SECOND(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":179 + * + * # Get second of time + * cdef inline int time_second(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_SECOND(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":183 + * + * # Get microsecond of time + * cdef inline int time_microsecond(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_MICROSECOND(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_microsecond(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("time_microsecond", 0); + + /* "cpython/datetime.pxd":184 + * # Get microsecond of time + * cdef inline int time_microsecond(object o): + * return PyDateTime_TIME_GET_MICROSECOND(o) # <<<<<<<<<<<<<< + * + * # Get hour of datetime + */ + __pyx_r = PyDateTime_TIME_GET_MICROSECOND(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":183 + * + * # Get microsecond of time + * cdef inline int time_microsecond(object o): # <<<<<<<<<<<<<< + * return PyDateTime_TIME_GET_MICROSECOND(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":187 + * + * # Get hour of datetime + * cdef inline int datetime_hour(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_HOUR(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_hour(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("datetime_hour", 0); + + /* "cpython/datetime.pxd":188 + * # Get hour of datetime + * cdef inline int datetime_hour(object o): + * return PyDateTime_DATE_GET_HOUR(o) # <<<<<<<<<<<<<< + * + * # Get minute of datetime + */ + __pyx_r = PyDateTime_DATE_GET_HOUR(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":187 + * + * # Get hour of datetime + * cdef inline int datetime_hour(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_HOUR(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":191 + * + * # Get minute of datetime + * cdef inline int datetime_minute(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_MINUTE(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_minute(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("datetime_minute", 0); + + /* "cpython/datetime.pxd":192 + * # Get minute of datetime + * cdef inline int datetime_minute(object o): + * return PyDateTime_DATE_GET_MINUTE(o) # <<<<<<<<<<<<<< + * + * # Get second of datetime + */ + __pyx_r = PyDateTime_DATE_GET_MINUTE(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":191 + * + * # Get minute of datetime + * cdef inline int datetime_minute(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_MINUTE(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":195 + * + * # Get second of datetime + * cdef inline int datetime_second(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_SECOND(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_second(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("datetime_second", 0); + + /* "cpython/datetime.pxd":196 + * # Get second of datetime + * cdef inline int datetime_second(object o): + * return PyDateTime_DATE_GET_SECOND(o) # <<<<<<<<<<<<<< + * + * # Get microsecond of datetime + */ + __pyx_r = PyDateTime_DATE_GET_SECOND(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":195 + * + * # Get second of datetime + * cdef inline int datetime_second(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_SECOND(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":199 + * + * # Get microsecond of datetime + * cdef inline int datetime_microsecond(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_MICROSECOND(o) + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_microsecond(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("datetime_microsecond", 0); + + /* "cpython/datetime.pxd":200 + * # Get microsecond of datetime + * cdef inline int datetime_microsecond(object o): + * return PyDateTime_DATE_GET_MICROSECOND(o) # <<<<<<<<<<<<<< + * + * # Get days of timedelta + */ + __pyx_r = PyDateTime_DATE_GET_MICROSECOND(__pyx_v_o); + goto __pyx_L0; + + /* "cpython/datetime.pxd":199 + * + * # Get microsecond of datetime + * cdef inline int datetime_microsecond(object o): # <<<<<<<<<<<<<< + * return PyDateTime_DATE_GET_MICROSECOND(o) + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":203 + * + * # Get days of timedelta + * cdef inline int timedelta_days(object o): # <<<<<<<<<<<<<< + * return (o).days + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_timedelta_days(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("timedelta_days", 0); + + /* "cpython/datetime.pxd":204 + * # Get days of timedelta + * cdef inline int timedelta_days(object o): + * return (o).days # <<<<<<<<<<<<<< + * + * # Get seconds of timedelta + */ + __pyx_r = ((PyDateTime_Delta *)__pyx_v_o)->days; + goto __pyx_L0; + + /* "cpython/datetime.pxd":203 + * + * # Get days of timedelta + * cdef inline int timedelta_days(object o): # <<<<<<<<<<<<<< + * return (o).days + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":207 + * + * # Get seconds of timedelta + * cdef inline int timedelta_seconds(object o): # <<<<<<<<<<<<<< + * return (o).seconds + * + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_timedelta_seconds(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("timedelta_seconds", 0); + + /* "cpython/datetime.pxd":208 + * # Get seconds of timedelta + * cdef inline int timedelta_seconds(object o): + * return (o).seconds # <<<<<<<<<<<<<< + * + * # Get microseconds of timedelta + */ + __pyx_r = ((PyDateTime_Delta *)__pyx_v_o)->seconds; + goto __pyx_L0; + + /* "cpython/datetime.pxd":207 + * + * # Get seconds of timedelta + * cdef inline int timedelta_seconds(object o): # <<<<<<<<<<<<<< + * return (o).seconds + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "cpython/datetime.pxd":211 + * + * # Get microseconds of timedelta + * cdef inline int timedelta_microseconds(object o): # <<<<<<<<<<<<<< + * return (o).microseconds + */ + +static CYTHON_INLINE int __pyx_f_7cpython_8datetime_timedelta_microseconds(PyObject *__pyx_v_o) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("timedelta_microseconds", 0); + + /* "cpython/datetime.pxd":212 + * # Get microseconds of timedelta + * cdef inline int timedelta_microseconds(object o): + * return (o).microseconds # <<<<<<<<<<<<<< + */ + __pyx_r = ((PyDateTime_Delta *)__pyx_v_o)->microseconds; + goto __pyx_L0; + + /* "cpython/datetime.pxd":211 + * + * # Get microseconds of timedelta + * cdef inline int timedelta_microseconds(object o): # <<<<<<<<<<<<<< + * return (o).microseconds + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampMicros(PyTypeObject *t, PyObject *a, PyObject *k) { + PyObject *o; + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + if (unlikely(__pyx_pw_7questdb_7ingress_15TimestampMicros_1__cinit__(o, a, k) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; +} + +static void __pyx_tp_dealloc_7questdb_7ingress_TimestampMicros(PyObject *o) { + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + (*Py_TYPE(o)->tp_free)(o); +} + +static PyObject *__pyx_getprop_7questdb_7ingress_15TimestampMicros_value(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7questdb_7ingress_15TimestampMicros_5value_1__get__(o); +} + +static PyMethodDef __pyx_methods_7questdb_7ingress_TimestampMicros[] = { + {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_15TimestampMicros_2from_datetime}, + {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_TimestampMicros[] = { + {(char *)"value", __pyx_getprop_7questdb_7ingress_15TimestampMicros_value, 0, (char *)"Number of microseconds.", 0}, + {0, 0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7questdb_7ingress_TimestampMicros = { + PyVarObject_HEAD_INIT(0, 0) + "questdb.ingress.TimestampMicros", /*tp_name*/ + sizeof(struct __pyx_obj_7questdb_7ingress_TimestampMicros), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7questdb_7ingress_TimestampMicros, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "\n A timestamp in microseconds since the UNIX epoch.\n\n You may construct a ``TimestampMicros`` from an integer or a ``datetime``.\n\n .. code-block:: python\n\n # Can't be negative.\n TimestampMicros(1657888365426838016)\n\n # Careful with the timezeone!\n TimestampMicros.from_datetime(datetime.datetime.utcnow())\n\n When constructing from a ``datetime``, you should take extra care\n to ensure that the timezone is correct.\n\n For example, ``datetime.now()`` implies the `local` timezone which\n is probably not what you want.\n\n When constructing the ``datetime`` object explicity, you pass in the\n timezone to use.\n\n .. code-block:: python\n\n TimestampMicros.from_datetime(\n datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc))\n\n ", /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7questdb_7ingress_TimestampMicros, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7questdb_7ingress_TimestampMicros, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7questdb_7ingress_TimestampMicros, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 + 0, /*tp_pypy_flags*/ + #endif +}; + +static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampNanos(PyTypeObject *t, PyObject *a, PyObject *k) { + PyObject *o; + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + if (unlikely(__pyx_pw_7questdb_7ingress_14TimestampNanos_1__cinit__(o, a, k) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; +} + +static void __pyx_tp_dealloc_7questdb_7ingress_TimestampNanos(PyObject *o) { + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + (*Py_TYPE(o)->tp_free)(o); +} + +static PyObject *__pyx_getprop_7questdb_7ingress_14TimestampNanos_value(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7questdb_7ingress_14TimestampNanos_5value_1__get__(o); +} + +static PyMethodDef __pyx_methods_7questdb_7ingress_TimestampNanos[] = { + {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_14TimestampNanos_2from_datetime}, + {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_TimestampNanos[] = { + {(char *)"value", __pyx_getprop_7questdb_7ingress_14TimestampNanos_value, 0, (char *)"Number of nanoseconds.", 0}, + {0, 0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7questdb_7ingress_TimestampNanos = { + PyVarObject_HEAD_INIT(0, 0) + "questdb.ingress.TimestampNanos", /*tp_name*/ + sizeof(struct __pyx_obj_7questdb_7ingress_TimestampNanos), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7questdb_7ingress_TimestampNanos, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "\n A timestamp in nanoseconds since the UNIX epoch.\n\n You may construct a ``TimestampNanos`` from an integer or a ``datetime``.\n\n .. code-block:: python\n\n # Can't be negative.\n TimestampNanos(1657888365426838016)\n\n # Careful with the timezeone!\n TimestampNanos.from_datetime(datetime.datetime.utcnow())\n\n When constructing from a ``datetime``, you should take extra care\n to ensure that the timezone is correct.\n\n For example, ``datetime.now()`` implies the `local` timezone which\n is probably not what you want.\n\n When constructing the ``datetime`` object explicity, you pass in the\n timezone to use.\n\n .. code-block:: python\n\n TimestampMicros.from_datetime(\n datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc))\n\n ", /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7questdb_7ingress_TimestampNanos, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7questdb_7ingress_TimestampNanos, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7questdb_7ingress_TimestampNanos, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 + 0, /*tp_pypy_flags*/ + #endif +}; +static struct __pyx_vtabstruct_7questdb_7ingress_Sender __pyx_vtable_7questdb_7ingress_Sender; + +static PyObject *__pyx_tp_new_7questdb_7ingress_Sender(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_obj_7questdb_7ingress_Sender *p; + PyObject *o; + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + p = ((struct __pyx_obj_7questdb_7ingress_Sender *)o); + p->__pyx_vtab = __pyx_vtabptr_7questdb_7ingress_Sender; + p->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); Py_INCREF(Py_None); + if (unlikely(__pyx_pw_7questdb_7ingress_6Sender_1__cinit__(o, a, k) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; +} + +static void __pyx_tp_dealloc_7questdb_7ingress_Sender(PyObject *o) { + struct __pyx_obj_7questdb_7ingress_Sender *p = (struct __pyx_obj_7questdb_7ingress_Sender *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + PyObject_GC_UnTrack(o); + { + PyObject *etype, *eval, *etb; + PyErr_Fetch(&etype, &eval, &etb); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); + __pyx_pw_7questdb_7ingress_6Sender_21__dealloc__(o); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); + PyErr_Restore(etype, eval, etb); + } + if (p->__weakref__) PyObject_ClearWeakRefs(o); + Py_CLEAR(p->_buffer); + (*Py_TYPE(o)->tp_free)(o); +} + +static int __pyx_tp_traverse_7questdb_7ingress_Sender(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7questdb_7ingress_Sender *p = (struct __pyx_obj_7questdb_7ingress_Sender *)o; + if (p->_buffer) { + e = (*v)(((PyObject *)p->_buffer), a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7questdb_7ingress_Sender(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7questdb_7ingress_Sender *p = (struct __pyx_obj_7questdb_7ingress_Sender *)o; + tmp = ((PyObject*)p->_buffer); + p->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} + +static PyObject *__pyx_getprop_7questdb_7ingress_6Sender_init_capacity(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7questdb_7ingress_6Sender_13init_capacity_1__get__(o); +} + +static PyObject *__pyx_getprop_7questdb_7ingress_6Sender_max_name_len(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7questdb_7ingress_6Sender_12max_name_len_1__get__(o); +} + +static PyMethodDef __pyx_methods_7questdb_7ingress_Sender[] = { + {"new_buffer", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_3new_buffer, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_2new_buffer}, + {"connect", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_5connect, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_4connect}, + {"__enter__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_7__enter__, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_6__enter__}, + {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_13row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_12row}, + {"__exit__", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_19__exit__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_18__exit__}, + {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_Sender[] = { + {(char *)"init_capacity", __pyx_getprop_7questdb_7ingress_6Sender_init_capacity, 0, (char *)"The initial capacity of the sender's internal buffer.", 0}, + {(char *)"max_name_len", __pyx_getprop_7questdb_7ingress_6Sender_max_name_len, 0, (char *)"Maximum length of a table or column name.", 0}, + {0, 0, 0, 0, 0} +}; + +static PySequenceMethods __pyx_tp_as_sequence_Sender = { + __pyx_pw_7questdb_7ingress_6Sender_11__len__, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + 0, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + 0, /*sq_contains*/ + 0, /*sq_inplace_concat*/ + 0, /*sq_inplace_repeat*/ +}; + +static PyMappingMethods __pyx_tp_as_mapping_Sender = { + __pyx_pw_7questdb_7ingress_6Sender_11__len__, /*mp_length*/ + 0, /*mp_subscript*/ + 0, /*mp_ass_subscript*/ +}; + +static PyTypeObject __pyx_type_7questdb_7ingress_Sender = { + PyVarObject_HEAD_INIT(0, 0) + "questdb.ingress.Sender", /*tp_name*/ + sizeof(struct __pyx_obj_7questdb_7ingress_Sender), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7questdb_7ingress_Sender, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + &__pyx_tp_as_sequence_Sender, /*tp_as_sequence*/ + &__pyx_tp_as_mapping_Sender, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + __pyx_pw_7questdb_7ingress_6Sender_9__str__, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + "\n A sender is a client that inserts rows into QuestDB via the ILP protocol.\n\n **Inserting two rows**\n\n In this example, data will be flushed and sent at the end of the ``with``\n block.\n\n .. code-block:: python\n\n with Sender('localhost', 9009) as sender:\n sender.row(\n 'weather_sensor',\n symbols={'id': 'toronto1'},\n columns={'temperature': 23.5, 'humidity': 0.49})\n sensor.row(\n 'weather_sensor',\n symbols={'id': 'dubai2'},\n columns={'temperature': 41.2, 'humidity': 0.34})\n\n The ``Sender`` object holds an internal buffer. The call to ``.row()``\n simply forwards all arguments to the :func:`Buffer.row` method.\n\n\n **Explicit flushing**\n\n An explicit call to :func:`Sender.flush` will send any pending data\n immediately.\n\n .. code-block:: python\n\n with Sender('localhost', 9009) as sender:\n sender.row(\n 'weather_sensor',\n symbols={'id': 'toronto1'},\n columns={'temperature': 23.5, 'humidity': 0.49})\n sender.flush()\n sender.row(\n 'weather_sensor',\n symbols={'id': 'dubai2'},\n columns={'temperature': 41.2, 'humidity': 0.34})\n sender.flush()\n\n\n **Auto-flushing (on by default, watermark at 63KiB)**\n\n To avoid accumulating very large buffers, the sender will flush the buffer\n automatically once its buffer reaches a certain byte-size watermark.\n\n You can control this behavior by setting the ``auto_flush`` argument.\n\n .. code-block:: python\n\n # Never flushes automatically.\n sender = Sender('localhost', 9009, auto_flush=False)\n sender = Sender('localhost', 9009, auto_flush=None) # Ditto.\n sender = Sender('localhost', 9009, auto_flush=0) # Ditto.\n\n # Flushes automatically when the buffer reach""es 1KiB.\n sender = Sender('localhost', 9009, auto_flush=1024)\n\n # Flushes automatically after every row.\n sender = Sender('localhost', 9009, auto_flush=True)\n sender = Sender('localhost', 9009, auto_flush=1) # Ditto.\n\n\n **Authentication and TLS Encryption**\n\n This implementation supports authentication and TLS full-connection\n encryption.\n\n The ``Sender(.., auth=..)`` argument is a tuple of ``(kid, d, x, y)`` as\n documented on the `QuestDB ILP authentication\n `_ documentation.\n Authentication is optional and disabled by default.\n\n The ``Sender(.., tls=..)`` argument is one of:\n\n * ``False``: No TLS encryption (default).\n\n * ``True``: TLS encryption, accepting all common certificates as recognized\n by the `webpki-roots `_ Rust crate\n which in turn relies on https://mkcert.org/.\n\n * A ``str`` or ``pathlib.Path``: Path to a PEM-encoded certificate authority\n file. This is useful for testing with self-signed certificates.\n\n * A special ``'insecure_skip_verify'`` string: Dangerously disable all\n TLS certificate verification (do *NOT* use in production environments).\n\n **Positional constructor arguments for the Sender(..)**\n\n * ``host``: Hostname or IP address of the QuestDB server.\n\n * ``port``: Port number of the QuestDB server.\n\n\n **Keyword-only constructor arguments for the Sender(..)**\n\n * ``interface`` (``str``): Network interface to bind to.\n Set this if you have an accelerated network interface (e.g. Solarflare)\n and want to use it.\n\n * ``auth`` (``tuple``): Authentication tuple or ``None`` (default).\n *See above for details*.\n\n * ``tls`` (``bool``, ``pathlib.Path`` or ``str``): TLS configuration or\n ``False`` (default). *See above for details*.\n\n * ``read_timeout`` (``int``): How long to wait ""for messages from the QuestDB server\n during the TLS handshake or authentication process.\n This field is expressed in milliseconds. The default is 15 seconds.\n\n * ``init_capacity`` (``int``): Initial buffer capacity of the internal buffer.\n *Default: 65536 (64KiB).*\n *See Buffer's constructor for more details.*\n\n * ``max_name_length`` (``int``): Maximum length of a table or column name.\n *See Buffer's constructor for more details.*\n\n * ``auto_flush`` (``bool`` or ``int``): Whether to automatically flush the\n buffer when it reaches a certain byte-size watermark.\n *Default: 64512 (63KiB).*\n *See above for details.*\n ", /*tp_doc*/ + __pyx_tp_traverse_7questdb_7ingress_Sender, /*tp_traverse*/ + __pyx_tp_clear_7questdb_7ingress_Sender, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7questdb_7ingress_Sender, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7questdb_7ingress_Sender, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7questdb_7ingress_Sender, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 + 0, /*tp_pypy_flags*/ + #endif +}; +static struct __pyx_vtabstruct_7questdb_7ingress_Buffer __pyx_vtable_7questdb_7ingress_Buffer; + +static PyObject *__pyx_tp_new_7questdb_7ingress_Buffer(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_obj_7questdb_7ingress_Buffer *p; + PyObject *o; + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + p = ((struct __pyx_obj_7questdb_7ingress_Buffer *)o); + p->__pyx_vtab = __pyx_vtabptr_7questdb_7ingress_Buffer; + p->_row_complete_sender = Py_None; Py_INCREF(Py_None); + if (unlikely(__pyx_pw_7questdb_7ingress_6Buffer_1__cinit__(o, a, k) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; +} + +static void __pyx_tp_dealloc_7questdb_7ingress_Buffer(PyObject *o) { + struct __pyx_obj_7questdb_7ingress_Buffer *p = (struct __pyx_obj_7questdb_7ingress_Buffer *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + PyObject_GC_UnTrack(o); + { + PyObject *etype, *eval, *etb; + PyErr_Fetch(&etype, &eval, &etb); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); + __pyx_pw_7questdb_7ingress_6Buffer_3__dealloc__(o); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); + PyErr_Restore(etype, eval, etb); + } + Py_CLEAR(p->_row_complete_sender); + (*Py_TYPE(o)->tp_free)(o); +} + +static int __pyx_tp_traverse_7questdb_7ingress_Buffer(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7questdb_7ingress_Buffer *p = (struct __pyx_obj_7questdb_7ingress_Buffer *)o; + if (p->_row_complete_sender) { + e = (*v)(p->_row_complete_sender, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7questdb_7ingress_Buffer(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7questdb_7ingress_Buffer *p = (struct __pyx_obj_7questdb_7ingress_Buffer *)o; + tmp = ((PyObject*)p->_row_complete_sender); + p->_row_complete_sender = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} + +static PyObject *__pyx_getprop_7questdb_7ingress_6Buffer_init_capacity(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7questdb_7ingress_6Buffer_13init_capacity_1__get__(o); +} + +static PyObject *__pyx_getprop_7questdb_7ingress_6Buffer_max_name_len(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7questdb_7ingress_6Buffer_12max_name_len_1__get__(o); +} + +static PyMethodDef __pyx_methods_7questdb_7ingress_Buffer[] = { + {"reserve", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_5reserve, METH_O, __pyx_doc_7questdb_7ingress_6Buffer_4reserve}, + {"capacity", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_7capacity, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_6capacity}, + {"clear", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_9clear, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_8clear}, + {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_15row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_14row}, + {"pandas", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_17pandas, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_16pandas}, + {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_Buffer[] = { + {(char *)"init_capacity", __pyx_getprop_7questdb_7ingress_6Buffer_init_capacity, 0, (char *)"\n The initial capacity of the buffer when first created.\n\n This may grow over time, see ``capacity()``.\n ", 0}, + {(char *)"max_name_len", __pyx_getprop_7questdb_7ingress_6Buffer_max_name_len, 0, (char *)"Maximum length of a table or column name.", 0}, + {0, 0, 0, 0, 0} +}; + +static PySequenceMethods __pyx_tp_as_sequence_Buffer = { + __pyx_pw_7questdb_7ingress_6Buffer_11__len__, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + 0, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + 0, /*sq_contains*/ + 0, /*sq_inplace_concat*/ + 0, /*sq_inplace_repeat*/ +}; + +static PyMappingMethods __pyx_tp_as_mapping_Buffer = { + __pyx_pw_7questdb_7ingress_6Buffer_11__len__, /*mp_length*/ + 0, /*mp_subscript*/ + 0, /*mp_ass_subscript*/ +}; + +static PyTypeObject __pyx_type_7questdb_7ingress_Buffer = { + PyVarObject_HEAD_INIT(0, 0) + "questdb.ingress.Buffer", /*tp_name*/ + sizeof(struct __pyx_obj_7questdb_7ingress_Buffer), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7questdb_7ingress_Buffer, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + &__pyx_tp_as_sequence_Buffer, /*tp_as_sequence*/ + &__pyx_tp_as_mapping_Buffer, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + __pyx_pw_7questdb_7ingress_6Buffer_13__str__, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + "\n Construct QuestDB-flavored InfluxDB Line Protocol (ILP) messages.\n\n The :func:`Buffer.row` method is used to add a row to the buffer.\n\n You can call this many times.\n\n .. code-block:: python\n\n from questdb.ingress import Buffer\n\n buf = Buffer()\n buf.row(\n 'table_name1',\n symbols={'s1', 'v1', 's2', 'v2'},\n columns={'c1': True, 'c2': 0.5})\n\n buf.row(\n 'table_name2',\n symbols={'questdb': '\342\235\244\357\270\217'},\n columns={'like': 100000})\n\n # Append any additional rows then, once ready, call\n sender.flush(buffer) # a `Sender` instance.\n\n # The sender auto-cleared the buffer, ready for reuse.\n\n buf.row(\n 'table_name1',\n symbols={'s1', 'v1', 's2', 'v2'},\n columns={'c1': True, 'c2': 0.5})\n\n # etc.\n\n\n Buffer Constructor Arguments:\n * ``init_capacity`` (``int``): Initial capacity of the buffer in bytes.\n Defaults to ``65536`` (64KiB).\n * ``max_name_len`` (``int``): Maximum length of a column name.\n Defaults to ``127`` which is the same default value as QuestDB.\n This should match the ``cairo.max.file.name.length`` setting of the\n QuestDB instance you're connecting to.\n\n .. code-block:: python\n\n # These two buffer constructions are equivalent.\n buf1 = Buffer()\n buf2 = Buffer(init_capacity=65536, max_name_len=127)\n\n To avoid having to manually set these arguments every time, you can call\n the sender's ``new_buffer()`` method instead.\n\n .. code-block:: python\n\n from questdb.ingress import Sender, Buffer\n\n sender = Sender(host='localhost', port=9009,\n init_capacity=16384, max_name_len=64)\n buf = sender.new_buffer()\n assert buf.init_capacity == 16384\n assert buf.max_name_len == 64\n\n ", /*tp_doc*/ + __pyx_tp_traverse_7questdb_7ingress_Buffer, /*tp_traverse*/ + __pyx_tp_clear_7questdb_7ingress_Buffer, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7questdb_7ingress_Buffer, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7questdb_7ingress_Buffer, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7questdb_7ingress_Buffer, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif + #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 + 0, /*tp_pypy_flags*/ + #endif +}; + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_ingress(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_ingress}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "ingress", + __pyx_k_API_for_fast_data_ingestion_int, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_s_An_error_whilst_using_the_Sender, __pyx_k_An_error_whilst_using_the_Sender, sizeof(__pyx_k_An_error_whilst_using_the_Sender), 0, 0, 1, 0}, + {&__pyx_n_s_Any, __pyx_k_Any, sizeof(__pyx_k_Any), 0, 0, 1, 1}, + {&__pyx_n_s_AuthError, __pyx_k_AuthError, sizeof(__pyx_k_AuthError), 0, 0, 1, 1}, + {&__pyx_kp_u_Bad_argument, __pyx_k_Bad_argument, sizeof(__pyx_k_Bad_argument), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_at_Bad_dtype, __pyx_k_Bad_argument_at_Bad_dtype, sizeof(__pyx_k_Bad_argument_at_Bad_dtype), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_at_Unsupported_type, __pyx_k_Bad_argument_at_Unsupported_type, sizeof(__pyx_k_Bad_argument_at_Unsupported_type), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_data_Expected, __pyx_k_Bad_argument_data_Expected, sizeof(__pyx_k_Bad_argument_data_Expected), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_symbols_Cannot_use, __pyx_k_Bad_argument_symbols_Cannot_use, sizeof(__pyx_k_Bad_argument_symbols_Cannot_use), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_symbols_Cannot_use_2, __pyx_k_Bad_argument_symbols_Cannot_use_2, sizeof(__pyx_k_Bad_argument_symbols_Cannot_use_2), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_symbols_Elements_mu, __pyx_k_Bad_argument_symbols_Elements_mu, sizeof(__pyx_k_Bad_argument_symbols_Elements_mu), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_symbols_Must_be_a_b, __pyx_k_Bad_argument_symbols_Must_be_a_b, sizeof(__pyx_k_Bad_argument_symbols_Must_be_a_b), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_table_name, __pyx_k_Bad_argument_table_name, sizeof(__pyx_k_Bad_argument_table_name), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_table_name_Must_be, __pyx_k_Bad_argument_table_name_Must_be, sizeof(__pyx_k_Bad_argument_table_name_Must_be), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_table_name_col, __pyx_k_Bad_argument_table_name_col, sizeof(__pyx_k_Bad_argument_table_name_col), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_argument_table_name_col_must, __pyx_k_Bad_argument_table_name_col_must, sizeof(__pyx_k_Bad_argument_table_name_col_must), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_column_Expected_a_numpy_arra, __pyx_k_Bad_column_Expected_a_numpy_arra, sizeof(__pyx_k_Bad_column_Expected_a_numpy_arra), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_column_Expected_a_string, __pyx_k_Bad_column_Expected_a_string, sizeof(__pyx_k_Bad_column_Expected_a_string), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_dtype, __pyx_k_Bad_dtype, sizeof(__pyx_k_Bad_dtype), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_element_in_argument_symbols, __pyx_k_Bad_element_in_argument_symbols, sizeof(__pyx_k_Bad_element_in_argument_symbols), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_value_Negative_timestamp_got, __pyx_k_Bad_value_Negative_timestamp_got, sizeof(__pyx_k_Bad_value_Negative_timestamp_got), 0, 1, 0, 0}, + {&__pyx_kp_u_Bad_value_None_table_name_value, __pyx_k_Bad_value_None_table_name_value, sizeof(__pyx_k_Bad_value_None_table_name_value), 0, 1, 0, 0}, + {&__pyx_n_s_Buffer, __pyx_k_Buffer, sizeof(__pyx_k_Buffer), 0, 0, 1, 1}, + {&__pyx_n_s_Buffer___reduce_cython, __pyx_k_Buffer___reduce_cython, sizeof(__pyx_k_Buffer___reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_Buffer___setstate_cython, __pyx_k_Buffer___setstate_cython, sizeof(__pyx_k_Buffer___setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_s_Buffer_capacity, __pyx_k_Buffer_capacity, sizeof(__pyx_k_Buffer_capacity), 0, 0, 1, 1}, + {&__pyx_n_s_Buffer_clear, __pyx_k_Buffer_clear, sizeof(__pyx_k_Buffer_clear), 0, 0, 1, 1}, + {&__pyx_n_s_Buffer_pandas, __pyx_k_Buffer_pandas, sizeof(__pyx_k_Buffer_pandas), 0, 0, 1, 1}, + {&__pyx_n_s_Buffer_reserve, __pyx_k_Buffer_reserve, sizeof(__pyx_k_Buffer_reserve), 0, 0, 1, 1}, + {&__pyx_n_s_Buffer_row, __pyx_k_Buffer_row, sizeof(__pyx_k_Buffer_row), 0, 0, 1, 1}, + {&__pyx_n_s_Callable, __pyx_k_Callable, sizeof(__pyx_k_Callable), 0, 0, 1, 1}, + {&__pyx_kp_u_Can_specify_only_one_of_table_na, __pyx_k_Can_specify_only_one_of_table_na, sizeof(__pyx_k_Can_specify_only_one_of_table_na), 0, 1, 0, 0}, + {&__pyx_kp_u_Cannot_be_encoded_as_UTF_8, __pyx_k_Cannot_be_encoded_as_UTF_8, sizeof(__pyx_k_Cannot_be_encoded_as_UTF_8), 0, 1, 0, 0}, + {&__pyx_kp_s_Category_of_Error, __pyx_k_Category_of_Error, sizeof(__pyx_k_Category_of_Error), 0, 0, 1, 0}, + {&__pyx_kp_u_Character_out_of_ASCII_range_go, __pyx_k_Character_out_of_ASCII_range_go, sizeof(__pyx_k_Character_out_of_ASCII_range_go), 0, 1, 0, 0}, + {&__pyx_kp_u_Column, __pyx_k_Column, sizeof(__pyx_k_Column), 0, 1, 0, 0}, + {&__pyx_n_s_CouldNotResolveAddr, __pyx_k_CouldNotResolveAddr, sizeof(__pyx_k_CouldNotResolveAddr), 0, 0, 1, 1}, + {&__pyx_n_u_DataFrame, __pyx_k_DataFrame, sizeof(__pyx_k_DataFrame), 0, 1, 0, 1}, + {&__pyx_n_s_Dict, __pyx_k_Dict, sizeof(__pyx_k_Dict), 0, 0, 1, 1}, + {&__pyx_n_s_Enum, __pyx_k_Enum, sizeof(__pyx_k_Enum), 0, 0, 1, 1}, + {&__pyx_kp_u_Expected_a_single_character_got, __pyx_k_Expected_a_single_character_got, sizeof(__pyx_k_Expected_a_single_character_got), 0, 1, 0, 0}, + {&__pyx_n_s_FLUSH_FMT, __pyx_k_FLUSH_FMT, sizeof(__pyx_k_FLUSH_FMT), 0, 0, 1, 1}, + {&__pyx_kp_u_Found_non_string_value, __pyx_k_Found_non_string_value, sizeof(__pyx_k_Found_non_string_value), 0, 1, 0, 0}, + {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, + {&__pyx_n_s_IngressError, __pyx_k_IngressError, sizeof(__pyx_k_IngressError), 0, 0, 1, 1}, + {&__pyx_n_s_IngressErrorCode, __pyx_k_IngressErrorCode, sizeof(__pyx_k_IngressErrorCode), 0, 0, 1, 1}, + {&__pyx_n_s_IngressErrorCode___str, __pyx_k_IngressErrorCode___str, sizeof(__pyx_k_IngressErrorCode___str), 0, 0, 1, 1}, + {&__pyx_n_s_IngressError___init, __pyx_k_IngressError___init, sizeof(__pyx_k_IngressError___init), 0, 0, 1, 1}, + {&__pyx_n_s_IngressError_code, __pyx_k_IngressError_code, sizeof(__pyx_k_IngressError_code), 0, 0, 1, 1}, + {&__pyx_kp_u_Internal_error_converting_error, __pyx_k_Internal_error_converting_error, sizeof(__pyx_k_Internal_error_converting_error), 0, 1, 0, 0}, + {&__pyx_n_s_InvalidApiCall, __pyx_k_InvalidApiCall, sizeof(__pyx_k_InvalidApiCall), 0, 0, 1, 1}, + {&__pyx_n_s_InvalidName, __pyx_k_InvalidName, sizeof(__pyx_k_InvalidName), 0, 0, 1, 1}, + {&__pyx_n_s_InvalidTimestamp, __pyx_k_InvalidTimestamp, sizeof(__pyx_k_InvalidTimestamp), 0, 0, 1, 1}, + {&__pyx_n_s_InvalidUtf8, __pyx_k_InvalidUtf8, sizeof(__pyx_k_InvalidUtf8), 0, 0, 1, 1}, + {&__pyx_kp_u_Invalid_codepoint_0x, __pyx_k_Invalid_codepoint_0x, sizeof(__pyx_k_Invalid_codepoint_0x), 0, 1, 0, 0}, + {&__pyx_n_s_Iterable, __pyx_k_Iterable, sizeof(__pyx_k_Iterable), 0, 0, 1, 1}, + {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, + {&__pyx_n_s_List, __pyx_k_List, sizeof(__pyx_k_List), 0, 0, 1, 1}, + {&__pyx_n_u_M, __pyx_k_M, sizeof(__pyx_k_M), 0, 1, 0, 1}, + {&__pyx_kp_u_Must_be_one_of, __pyx_k_Must_be_one_of, sizeof(__pyx_k_Must_be_one_of), 0, 1, 0, 0}, + {&__pyx_kp_u_Must_be_one_of_None_TimestampNan, __pyx_k_Must_be_one_of_None_TimestampNan, sizeof(__pyx_k_Must_be_one_of_None_TimestampNan), 0, 1, 0, 0}, + {&__pyx_kp_u_Must_specify_at_least_one_of_tab, __pyx_k_Must_specify_at_least_one_of_tab, sizeof(__pyx_k_Must_specify_at_least_one_of_tab), 0, 1, 0, 0}, + {&__pyx_n_s_NA, __pyx_k_NA, sizeof(__pyx_k_NA), 0, 0, 1, 1}, + {&__pyx_kp_u_NOT_YET_IMPLEMENTED_Kind, __pyx_k_NOT_YET_IMPLEMENTED_Kind, sizeof(__pyx_k_NOT_YET_IMPLEMENTED_Kind), 0, 1, 0, 0}, + {&__pyx_kp_u_None, __pyx_k_None, sizeof(__pyx_k_None), 0, 1, 0, 0}, + {&__pyx_n_u_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 1, 0, 1}, + {&__pyx_n_s_Optional, __pyx_k_Optional, sizeof(__pyx_k_Optional), 0, 0, 1, 1}, + {&__pyx_n_s_Path, __pyx_k_Path, sizeof(__pyx_k_Path), 0, 0, 1, 1}, + {&__pyx_n_u_S, __pyx_k_S, sizeof(__pyx_k_S), 0, 1, 0, 1}, + {&__pyx_n_u_SO, __pyx_k_SO, sizeof(__pyx_k_SO), 0, 1, 0, 1}, + {&__pyx_kp_u_See_https_py_questdb_client_rea, __pyx_k_See_https_py_questdb_client_rea, sizeof(__pyx_k_See_https_py_questdb_client_rea), 0, 1, 0, 0}, + {&__pyx_n_s_Sender, __pyx_k_Sender, sizeof(__pyx_k_Sender), 0, 0, 1, 1}, + {&__pyx_n_u_Sender, __pyx_k_Sender, sizeof(__pyx_k_Sender), 0, 1, 0, 1}, + {&__pyx_n_s_Sender___enter, __pyx_k_Sender___enter, sizeof(__pyx_k_Sender___enter), 0, 0, 1, 1}, + {&__pyx_n_s_Sender___exit, __pyx_k_Sender___exit, sizeof(__pyx_k_Sender___exit), 0, 0, 1, 1}, + {&__pyx_n_s_Sender___reduce_cython, __pyx_k_Sender___reduce_cython, sizeof(__pyx_k_Sender___reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_Sender___setstate_cython, __pyx_k_Sender___setstate_cython, sizeof(__pyx_k_Sender___setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_s_Sender_close, __pyx_k_Sender_close, sizeof(__pyx_k_Sender_close), 0, 0, 1, 1}, + {&__pyx_n_s_Sender_connect, __pyx_k_Sender_connect, sizeof(__pyx_k_Sender_connect), 0, 0, 1, 1}, + {&__pyx_n_s_Sender_flush, __pyx_k_Sender_flush, sizeof(__pyx_k_Sender_flush), 0, 0, 1, 1}, + {&__pyx_n_s_Sender_new_buffer, __pyx_k_Sender_new_buffer, sizeof(__pyx_k_Sender_new_buffer), 0, 0, 1, 1}, + {&__pyx_n_s_Sender_row, __pyx_k_Sender_row, sizeof(__pyx_k_Sender_row), 0, 0, 1, 1}, + {&__pyx_n_s_SocketError, __pyx_k_SocketError, sizeof(__pyx_k_SocketError), 0, 0, 1, 1}, + {&__pyx_kp_u_The_internal_buffer_must_always, __pyx_k_The_internal_buffer_must_always, sizeof(__pyx_k_The_internal_buffer_must_always), 0, 1, 0, 0}, + {&__pyx_n_s_TimestampMicros, __pyx_k_TimestampMicros, sizeof(__pyx_k_TimestampMicros), 0, 0, 1, 1}, + {&__pyx_n_u_TimestampMicros, __pyx_k_TimestampMicros, sizeof(__pyx_k_TimestampMicros), 0, 1, 0, 1}, + {&__pyx_n_s_TimestampMicros___reduce_cython, __pyx_k_TimestampMicros___reduce_cython, sizeof(__pyx_k_TimestampMicros___reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_TimestampMicros___setstate_cytho, __pyx_k_TimestampMicros___setstate_cytho, sizeof(__pyx_k_TimestampMicros___setstate_cytho), 0, 0, 1, 1}, + {&__pyx_n_s_TimestampMicros_from_datetime, __pyx_k_TimestampMicros_from_datetime, sizeof(__pyx_k_TimestampMicros_from_datetime), 0, 0, 1, 1}, + {&__pyx_n_s_TimestampNanos, __pyx_k_TimestampNanos, sizeof(__pyx_k_TimestampNanos), 0, 0, 1, 1}, + {&__pyx_n_s_TimestampNanos___reduce_cython, __pyx_k_TimestampNanos___reduce_cython, sizeof(__pyx_k_TimestampNanos___reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_TimestampNanos___setstate_cython, __pyx_k_TimestampNanos___setstate_cython, sizeof(__pyx_k_TimestampNanos___setstate_cython), 0, 0, 1, 1}, + {&__pyx_kp_u_TimestampNanos_datetime_None, __pyx_k_TimestampNanos_datetime_None, sizeof(__pyx_k_TimestampNanos_datetime_None), 0, 1, 0, 0}, + {&__pyx_n_s_TimestampNanos_from_datetime, __pyx_k_TimestampNanos_from_datetime, sizeof(__pyx_k_TimestampNanos_from_datetime), 0, 0, 1, 1}, + {&__pyx_n_s_TlsError, __pyx_k_TlsError, sizeof(__pyx_k_TlsError), 0, 0, 1, 1}, + {&__pyx_n_s_Tuple, __pyx_k_Tuple, sizeof(__pyx_k_Tuple), 0, 0, 1, 1}, + {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, + {&__pyx_n_s_Union, __pyx_k_Union, sizeof(__pyx_k_Union), 0, 0, 1, 1}, + {&__pyx_kp_u_Unknown_UCS_kind, __pyx_k_Unknown_UCS_kind, sizeof(__pyx_k_Unknown_UCS_kind), 0, 1, 0, 0}, + {&__pyx_kp_u_Unsupported_type, __pyx_k_Unsupported_type, sizeof(__pyx_k_Unsupported_type), 0, 1, 0, 0}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_kp_u__10, __pyx_k__10, sizeof(__pyx_k__10), 0, 1, 0, 0}, + {&__pyx_kp_u__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 1, 0, 0}, + {&__pyx_kp_u__12, __pyx_k__12, sizeof(__pyx_k__12), 0, 1, 0, 0}, + {&__pyx_kp_u__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 1, 0, 0}, + {&__pyx_kp_u__15, __pyx_k__15, sizeof(__pyx_k__15), 0, 1, 0, 0}, + {&__pyx_kp_u__17, __pyx_k__17, sizeof(__pyx_k__17), 0, 1, 0, 0}, + {&__pyx_kp_u__24, __pyx_k__24, sizeof(__pyx_k__24), 0, 1, 0, 0}, + {&__pyx_kp_u__27, __pyx_k__27, sizeof(__pyx_k__27), 0, 1, 0, 0}, + {&__pyx_kp_u__5, __pyx_k__5, sizeof(__pyx_k__5), 0, 1, 0, 0}, + {&__pyx_kp_u__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 1, 0, 0}, + {&__pyx_kp_u__9, __pyx_k__9, sizeof(__pyx_k__9), 0, 1, 0, 0}, + {&__pyx_n_s_additional, __pyx_k_additional, sizeof(__pyx_k_additional), 0, 0, 1, 1}, + {&__pyx_kp_u_additional_must_be_non_negative, __pyx_k_additional_must_be_non_negative, sizeof(__pyx_k_additional_must_be_non_negative), 0, 1, 0, 0}, + {&__pyx_n_s_alignment, __pyx_k_alignment, sizeof(__pyx_k_alignment), 0, 0, 1, 1}, + {&__pyx_n_u_alignment, __pyx_k_alignment, sizeof(__pyx_k_alignment), 0, 1, 0, 1}, + {&__pyx_kp_u_as_a_symbol_column, __pyx_k_as_a_symbol_column, sizeof(__pyx_k_as_a_symbol_column), 0, 1, 0, 0}, + {&__pyx_kp_u_as_both_the_table_name_and_as_a, __pyx_k_as_both_the_table_name_and_as_a, sizeof(__pyx_k_as_both_the_table_name_and_as_a), 0, 1, 0, 0}, + {&__pyx_n_s_at, __pyx_k_at, sizeof(__pyx_k_at), 0, 0, 1, 1}, + {&__pyx_n_u_at, __pyx_k_at, sizeof(__pyx_k_at), 0, 1, 0, 1}, + {&__pyx_kp_u_at_2, __pyx_k_at_2, sizeof(__pyx_k_at_2), 0, 1, 0, 0}, + {&__pyx_kp_u_at_col, __pyx_k_at_col, sizeof(__pyx_k_at_col), 0, 1, 0, 0}, + {&__pyx_kp_u_at_value, __pyx_k_at_value, sizeof(__pyx_k_at_value), 0, 1, 0, 0}, + {&__pyx_n_s_auth, __pyx_k_auth, sizeof(__pyx_k_auth), 0, 0, 1, 1}, + {&__pyx_n_s_auto_flush, __pyx_k_auto_flush, sizeof(__pyx_k_auto_flush), 0, 0, 1, 1}, + {&__pyx_kp_u_auto_flush_watermark_must_be_0_n, __pyx_k_auto_flush_watermark_must_be_0_n, sizeof(__pyx_k_auto_flush_watermark_must_be_0_n), 0, 1, 0, 0}, + {&__pyx_n_u_bool, __pyx_k_bool, sizeof(__pyx_k_bool), 0, 1, 0, 1}, + {&__pyx_n_s_buffer, __pyx_k_buffer, sizeof(__pyx_k_buffer), 0, 0, 1, 1}, + {&__pyx_n_s_byteorder, __pyx_k_byteorder, sizeof(__pyx_k_byteorder), 0, 0, 1, 1}, + {&__pyx_n_u_byteorder, __pyx_k_byteorder, sizeof(__pyx_k_byteorder), 0, 1, 0, 1}, + {&__pyx_n_s_capacity, __pyx_k_capacity, sizeof(__pyx_k_capacity), 0, 0, 1, 1}, + {&__pyx_n_s_clear, __pyx_k_clear, sizeof(__pyx_k_clear), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1}, + {&__pyx_n_s_cls, __pyx_k_cls, sizeof(__pyx_k_cls), 0, 0, 1, 1}, + {&__pyx_n_s_code, __pyx_k_code, sizeof(__pyx_k_code), 0, 0, 1, 1}, + {&__pyx_n_s_code_2, __pyx_k_code_2, sizeof(__pyx_k_code_2), 0, 0, 1, 1}, + {&__pyx_kp_u_column_Must_be_a_datetime64_ns, __pyx_k_column_Must_be_a_datetime64_ns, sizeof(__pyx_k_column_Must_be_a_datetime64_ns), 0, 1, 0, 0}, + {&__pyx_kp_u_column_Must_be_a_strings_column, __pyx_k_column_Must_be_a_strings_column, sizeof(__pyx_k_column_Must_be_a_strings_column), 0, 1, 0, 0}, + {&__pyx_n_s_columns, __pyx_k_columns, sizeof(__pyx_k_columns), 0, 0, 1, 1}, + {&__pyx_n_s_connect, __pyx_k_connect, sizeof(__pyx_k_connect), 0, 0, 1, 1}, + {&__pyx_kp_u_connect_can_t_be_called_after_cl, __pyx_k_connect_can_t_be_called_after_cl, sizeof(__pyx_k_connect_can_t_be_called_after_cl), 0, 1, 0, 0}, + {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1}, + {&__pyx_n_u_datetime, __pyx_k_datetime, sizeof(__pyx_k_datetime), 0, 1, 0, 1}, + {&__pyx_kp_u_datetime_datetime, __pyx_k_datetime_datetime, sizeof(__pyx_k_datetime_datetime), 0, 1, 0, 0}, + {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1}, + {&__pyx_n_s_dt, __pyx_k_dt, sizeof(__pyx_k_dt), 0, 0, 1, 1}, + {&__pyx_kp_u_dt_must_be_a_datetime_object, __pyx_k_dt_must_be_a_datetime_object, sizeof(__pyx_k_dt_must_be_a_datetime_object), 0, 1, 0, 0}, + {&__pyx_kp_u_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 1, 0, 0}, + {&__pyx_n_s_dtypes, __pyx_k_dtypes, sizeof(__pyx_k_dtypes), 0, 0, 1, 1}, + {&__pyx_n_s_enter, __pyx_k_enter, sizeof(__pyx_k_enter), 0, 0, 1, 1}, + {&__pyx_n_s_enum, __pyx_k_enum, sizeof(__pyx_k_enum), 0, 0, 1, 1}, + {&__pyx_n_s_err, __pyx_k_err, sizeof(__pyx_k_err), 0, 0, 1, 1}, + {&__pyx_n_s_exc_tb, __pyx_k_exc_tb, sizeof(__pyx_k_exc_tb), 0, 0, 1, 1}, + {&__pyx_n_s_exc_type, __pyx_k_exc_type, sizeof(__pyx_k_exc_type), 0, 0, 1, 1}, + {&__pyx_n_s_exc_val, __pyx_k_exc_val, sizeof(__pyx_k_exc_val), 0, 0, 1, 1}, + {&__pyx_n_s_exit, __pyx_k_exit, sizeof(__pyx_k_exit), 0, 0, 1, 1}, + {&__pyx_kp_u_field_indices, __pyx_k_field_indices, sizeof(__pyx_k_field_indices), 0, 1, 0, 0}, + {&__pyx_n_u_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 1, 0, 1}, + {&__pyx_n_s_flush, __pyx_k_flush, sizeof(__pyx_k_flush), 0, 0, 1, 1}, + {&__pyx_kp_u_flush_can_t_be_called_Not_connec, __pyx_k_flush_can_t_be_called_Not_connec, sizeof(__pyx_k_flush_can_t_be_called_Not_connec), 0, 1, 0, 0}, + {&__pyx_kp_u_for_the, __pyx_k_for_the, sizeof(__pyx_k_for_the), 0, 1, 0, 0}, + {&__pyx_kp_u_for_the_2, __pyx_k_for_the_2, sizeof(__pyx_k_for_the_2), 0, 1, 0, 0}, + {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, + {&__pyx_n_s_from_datetime, __pyx_k_from_datetime, sizeof(__pyx_k_from_datetime), 0, 0, 1, 1}, + {&__pyx_n_s_get_loc, __pyx_k_get_loc, sizeof(__pyx_k_get_loc), 0, 0, 1, 1}, + {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, + {&__pyx_kp_u_got, __pyx_k_got, sizeof(__pyx_k_got), 0, 1, 0, 0}, + {&__pyx_n_s_hasobject, __pyx_k_hasobject, sizeof(__pyx_k_hasobject), 0, 0, 1, 1}, + {&__pyx_n_u_hasobject, __pyx_k_hasobject, sizeof(__pyx_k_hasobject), 0, 1, 0, 1}, + {&__pyx_n_s_host, __pyx_k_host, sizeof(__pyx_k_host), 0, 0, 1, 1}, + {&__pyx_n_s_iloc, __pyx_k_iloc, sizeof(__pyx_k_iloc), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_kp_u_in_column, __pyx_k_in_column, sizeof(__pyx_k_in_column), 0, 1, 0, 0}, + {&__pyx_kp_u_in_string, __pyx_k_in_string, sizeof(__pyx_k_in_string), 0, 1, 0, 0}, + {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1}, + {&__pyx_kp_u_index_out_of_range, __pyx_k_index_out_of_range, sizeof(__pyx_k_index_out_of_range), 0, 1, 0, 0}, + {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1}, + {&__pyx_n_s_init_capacity, __pyx_k_init_capacity, sizeof(__pyx_k_init_capacity), 0, 0, 1, 1}, + {&__pyx_n_u_insecure_skip_verify, __pyx_k_insecure_skip_verify, sizeof(__pyx_k_insecure_skip_verify), 0, 1, 0, 1}, + {&__pyx_n_u_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 1, 0, 1}, + {&__pyx_kp_u_int_column_index_str_colum_name, __pyx_k_int_column_index_str_colum_name, sizeof(__pyx_k_int_column_index_str_colum_name), 0, 1, 0, 0}, + {&__pyx_n_s_interface, __pyx_k_interface, sizeof(__pyx_k_interface), 0, 0, 1, 1}, + {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, + {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, + {&__pyx_n_u_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 1, 0, 1}, + {&__pyx_n_s_kind, __pyx_k_kind, sizeof(__pyx_k_kind), 0, 0, 1, 1}, + {&__pyx_n_u_kind, __pyx_k_kind, sizeof(__pyx_k_kind), 0, 1, 0, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_max_name_len, __pyx_k_max_name_len, sizeof(__pyx_k_max_name_len), 0, 0, 1, 1}, + {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1}, + {&__pyx_n_s_microsecond, __pyx_k_microsecond, sizeof(__pyx_k_microsecond), 0, 0, 1, 1}, + {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1}, + {&__pyx_n_s_msg, __pyx_k_msg, sizeof(__pyx_k_msg), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, + {&__pyx_kp_u_name_col, __pyx_k_name_col, sizeof(__pyx_k_name_col), 0, 1, 0, 0}, + {&__pyx_n_s_new_buffer, __pyx_k_new_buffer, sizeof(__pyx_k_new_buffer), 0, 0, 1, 1}, + {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, + {&__pyx_kp_u_not, __pyx_k_not, sizeof(__pyx_k_not), 0, 1, 0, 0}, + {&__pyx_kp_u_not_found_in_the_dataframe, __pyx_k_not_found_in_the_dataframe, sizeof(__pyx_k_not_found_in_the_dataframe), 0, 1, 0, 0}, + {&__pyx_n_s_pandas, __pyx_k_pandas, sizeof(__pyx_k_pandas), 0, 0, 1, 1}, + {&__pyx_kp_u_pandas_A, __pyx_k_pandas_A, sizeof(__pyx_k_pandas_A), 0, 1, 0, 0}, + {&__pyx_kp_u_pandas_A_2, __pyx_k_pandas_A_2, sizeof(__pyx_k_pandas_A_2), 0, 1, 0, 0}, + {&__pyx_kp_u_pandas_B, __pyx_k_pandas_B, sizeof(__pyx_k_pandas_B), 0, 1, 0, 0}, + {&__pyx_kp_u_pandas_core_frame, __pyx_k_pandas_core_frame, sizeof(__pyx_k_pandas_core_frame), 0, 1, 0, 0}, + {&__pyx_n_s_pathlib, __pyx_k_pathlib, sizeof(__pyx_k_pathlib), 0, 0, 1, 1}, + {&__pyx_n_s_port, __pyx_k_port, sizeof(__pyx_k_port), 0, 0, 1, 1}, + {&__pyx_kp_u_port_must_be_an_integer_or_a_str, __pyx_k_port_must_be_an_integer_or_a_str, sizeof(__pyx_k_port_must_be_an_integer_or_a_str), 0, 1, 0, 0}, + {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1}, + {&__pyx_n_s_property, __pyx_k_property, sizeof(__pyx_k_property), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, + {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1}, + {&__pyx_n_s_questdb_ingress, __pyx_k_questdb_ingress, sizeof(__pyx_k_questdb_ingress), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_read_timeout, __pyx_k_read_timeout, sizeof(__pyx_k_read_timeout), 0, 0, 1, 1}, + {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, + {&__pyx_n_s_reserve, __pyx_k_reserve, sizeof(__pyx_k_reserve), 0, 0, 1, 1}, + {&__pyx_n_s_return, __pyx_k_return, sizeof(__pyx_k_return), 0, 0, 1, 1}, + {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1}, + {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1}, + {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, + {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_u_size_t_vec, __pyx_k_size_t_vec, sizeof(__pyx_k_size_t_vec), 0, 1, 0, 1}, + {&__pyx_n_s_sort, __pyx_k_sort, sizeof(__pyx_k_sort), 0, 0, 1, 1}, + {&__pyx_kp_u_sort_2, __pyx_k_sort_2, sizeof(__pyx_k_sort_2), 0, 1, 0, 0}, + {&__pyx_kp_s_src_questdb_ingress_pyx, __pyx_k_src_questdb_ingress_pyx, sizeof(__pyx_k_src_questdb_ingress_pyx), 0, 0, 1, 0}, + {&__pyx_n_s_stderr, __pyx_k_stderr, sizeof(__pyx_k_stderr), 0, 0, 1, 1}, + {&__pyx_n_u_str, __pyx_k_str, sizeof(__pyx_k_str), 0, 1, 0, 1}, + {&__pyx_n_s_str_2, __pyx_k_str_2, sizeof(__pyx_k_str_2), 0, 0, 1, 1}, + {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, + {&__pyx_n_s_super, __pyx_k_super, sizeof(__pyx_k_super), 0, 0, 1, 1}, + {&__pyx_n_u_symbol, __pyx_k_symbol, sizeof(__pyx_k_symbol), 0, 1, 0, 1}, + {&__pyx_kp_u_symbol_indices, __pyx_k_symbol_indices, sizeof(__pyx_k_symbol_indices), 0, 1, 0, 0}, + {&__pyx_n_s_symbols, __pyx_k_symbols, sizeof(__pyx_k_symbols), 0, 0, 1, 1}, + {&__pyx_n_u_symbols, __pyx_k_symbols, sizeof(__pyx_k_symbols), 0, 1, 0, 1}, + {&__pyx_kp_u_symbols_2, __pyx_k_symbols_2, sizeof(__pyx_k_symbols_2), 0, 1, 0, 0}, + {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1}, + {&__pyx_n_s_table_name, __pyx_k_table_name, sizeof(__pyx_k_table_name), 0, 0, 1, 1}, + {&__pyx_kp_u_table_name_2, __pyx_k_table_name_2, sizeof(__pyx_k_table_name_2), 0, 1, 0, 0}, + {&__pyx_n_s_table_name_col, __pyx_k_table_name_col, sizeof(__pyx_k_table_name_col), 0, 0, 1, 1}, + {&__pyx_n_u_table_name_col, __pyx_k_table_name_col, sizeof(__pyx_k_table_name_col), 0, 1, 0, 1}, + {&__pyx_kp_u_table_name_col_2, __pyx_k_table_name_col_2, sizeof(__pyx_k_table_name_col_2), 0, 1, 0, 0}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_timestamp, __pyx_k_timestamp, sizeof(__pyx_k_timestamp), 0, 0, 1, 1}, + {&__pyx_n_s_tls, __pyx_k_tls, sizeof(__pyx_k_tls), 0, 0, 1, 1}, + {&__pyx_kp_u_tls_must_be_a_bool_a_path_or_str, __pyx_k_tls_must_be_a_bool_a_path_or_str, sizeof(__pyx_k_tls_must_be_a_bool_a_path_or_str), 0, 1, 0, 0}, + {&__pyx_n_s_to_numpy, __pyx_k_to_numpy, sizeof(__pyx_k_to_numpy), 0, 0, 1, 1}, + {&__pyx_n_s_typing, __pyx_k_typing, sizeof(__pyx_k_typing), 0, 0, 1, 1}, + {&__pyx_n_u_unicode, __pyx_k_unicode, sizeof(__pyx_k_unicode), 0, 1, 0, 1}, + {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1}, + {&__pyx_n_s_value_2, __pyx_k_value_2, sizeof(__pyx_k_value_2), 0, 0, 1, 1}, + {&__pyx_kp_u_value_must_positive_integer, __pyx_k_value_must_positive_integer, sizeof(__pyx_k_value_must_positive_integer), 0, 1, 0, 0}, + {&__pyx_n_s_write, __pyx_k_write, sizeof(__pyx_k_write), 0, 0, 1, 1}, + {&__pyx_n_u_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 1, 0, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_n_s_property); if (!__pyx_builtin_property) __PYX_ERR(0, 84, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(1, 21, __pyx_L1_error) + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(2, 110, __pyx_L1_error) + __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(2, 119, __pyx_L1_error) + __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(2, 211, __pyx_L1_error) + __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(2, 316, __pyx_L1_error) + __pyx_builtin_super = __Pyx_GetBuiltinName(__pyx_n_s_super); if (!__pyx_builtin_super) __PYX_ERR(0, 81, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "src/questdb/pandas_helpers.pxi":110 + * if table_name is not None: + * if table_name_col is not None: + * raise ValueError( # <<<<<<<<<<<<<< + * 'Can specify only one of `table_name` or `table_name_col`.') + * if isinstance(table_name, str): + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_Can_specify_only_one_of_table_na); if (unlikely(!__pyx_tuple_)) __PYX_ERR(2, 110, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "src/questdb/pandas_helpers.pxi":119 + * raise ValueError(f'Bad argument `table_name`: {ie}') + * else: + * raise TypeError('Bad argument `table_name`: Must be str.') # <<<<<<<<<<<<<< + * elif table_name_col is not None: + * if isinstance(table_name_col, str): + */ + __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_table_name_Must_be); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(2, 119, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "src/questdb/pandas_helpers.pxi":127 + * 'table_name_col', table_name_col, col_count, &col_index) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * 'Bad argument `table_name_col`: ' + + * 'must be a column name (str) or index (int).') + */ + __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_table_name_col_must); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(2, 127, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__3); + __Pyx_GIVEREF(__pyx_tuple__3); + + /* "src/questdb/pandas_helpers.pxi":137 + * return col_index + * else: + * raise ValueError( # <<<<<<<<<<<<<< + * 'Must specify at least one of `table_name` or `table_name_col`.') + * + */ + __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Must_specify_at_least_one_of_tab); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(2, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "src/questdb/pandas_helpers.pxi":278 + * else: + * if not isinstance(symbols, (tuple, list)): + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ + * 'of column names (str) or indices (int).') + */ + __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_symbols_Must_be_a_b); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(2, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + + /* "src/questdb/pandas_helpers.pxi":287 + * _bind_col_index('symbol', symbol, col_count, &col_index) + * else: + * raise TypeError( # <<<<<<<<<<<<<< + * f'Bad argument `symbols`: Elements must ' + + * 'be a column name (str) or index (int).') + */ + __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_symbols_Elements_mu); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(2, 287, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + + /* "src/questdb/pandas_helpers.pxi":418 + * cdef const dtype_t* dtype + * for col_index in range(col_count): + * nparr = data.iloc[:, col_index].to_numpy() # <<<<<<<<<<<<<< + * view = &col_buffers[col_index] + * dtype = &dtypes[col_index] + */ + __pyx_slice__13 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__13)) __PYX_ERR(2, 418, __pyx_L1_error) + __Pyx_GOTREF(__pyx_slice__13); + __Pyx_GIVEREF(__pyx_slice__13); + + /* "questdb/ingress.pyx":108 + * return IngressErrorCode.TlsError + * else: + * raise ValueError('Internal error converting error code.') # <<<<<<<<<<<<<< + * + * + */ + __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_u_Internal_error_converting_error); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__16); + __Pyx_GIVEREF(__pyx_tuple__16); + + /* "questdb/ingress.pyx":294 + * def __cinit__(self, value: int): + * if value < 0: + * raise ValueError('value must positive integer.') # <<<<<<<<<<<<<< + * self._value = value + * + */ + __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_u_value_must_positive_integer); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 294, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__18); + __Pyx_GIVEREF(__pyx_tuple__18); + + /* "questdb/ingress.pyx":303 + * """ + * if not isinstance(dt, datetime): + * raise TypeError('dt must be a datetime object.') # <<<<<<<<<<<<<< + * return cls(datetime_to_micros(dt)) + * + */ + __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_u_dt_must_be_a_datetime_object); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 303, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__19); + __Pyx_GIVEREF(__pyx_tuple__19); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__20); + __Pyx_GIVEREF(__pyx_tuple__20); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__21); + __Pyx_GIVEREF(__pyx_tuple__21); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__22); + __Pyx_GIVEREF(__pyx_tuple__22); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__23); + __Pyx_GIVEREF(__pyx_tuple__23); + + /* "questdb/ingress.pyx":500 + * """ + * if additional < 0: + * raise ValueError('additional must be non-negative.') # <<<<<<<<<<<<<< + * line_sender_buffer_reserve(self._impl, additional) + * + */ + __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_u_additional_must_be_non_negative); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 500, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__25); + __Pyx_GIVEREF(__pyx_tuple__25); + + /* "questdb/ingress.pyx":634 + * else: + * valid = ', '.join(( + * 'bool', # <<<<<<<<<<<<<< + * 'int', + * 'float', + */ + __pyx_tuple__26 = PyTuple_Pack(6, __pyx_n_u_bool, __pyx_n_u_int, __pyx_n_u_float, __pyx_n_u_str, __pyx_n_u_TimestampMicros, __pyx_kp_u_datetime_datetime); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 634, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__26); + __Pyx_GIVEREF(__pyx_tuple__26); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__28); + __Pyx_GIVEREF(__pyx_tuple__28); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__29); + __Pyx_GIVEREF(__pyx_tuple__29); + + /* "questdb/ingress.pyx":1491 + * """ + * if buffer is None and not clear: + * raise ValueError('The internal buffer must always be cleared.') # <<<<<<<<<<<<<< + * + * cdef line_sender_error* err = NULL + */ + __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_u_The_internal_buffer_must_always); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(0, 1491, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__30); + __Pyx_GIVEREF(__pyx_tuple__30); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(3, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__31); + __Pyx_GIVEREF(__pyx_tuple__31); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(3, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__32); + __Pyx_GIVEREF(__pyx_tuple__32); + + /* "questdb/ingress.pyx":73 + * TlsError = line_sender_error_tls_error + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """Return the name of the enum.""" + * return self.name + */ + __pyx_tuple__33 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__33); + __Pyx_GIVEREF(__pyx_tuple__33); + __pyx_codeobj__34 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__33, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_str_2, 73, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__34)) __PYX_ERR(0, 73, __pyx_L1_error) + + /* "questdb/ingress.pyx":80 + * class IngressError(Exception): + * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" + * def __init__(self, code, msg): # <<<<<<<<<<<<<< + * super().__init__(msg) + * self._code = code + */ + __pyx_tuple__35 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_code, __pyx_n_s_msg); if (unlikely(!__pyx_tuple__35)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__35); + __Pyx_GIVEREF(__pyx_tuple__35); + __pyx_codeobj__36 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__35, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_init, 80, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__36)) __PYX_ERR(0, 80, __pyx_L1_error) + + /* "questdb/ingress.pyx":85 + * + * @property + * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< + * """Return the error code.""" + * return self._code + */ + __pyx_tuple__37 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__37); + __Pyx_GIVEREF(__pyx_tuple__37); + __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_code, 85, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) __PYX_ERR(0, 85, __pyx_L1_error) + + /* "questdb/ingress.pyx":298 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. + */ + __pyx_tuple__39 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_dt); if (unlikely(!__pyx_tuple__39)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__39); + __Pyx_GIVEREF(__pyx_tuple__39); + __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_from_datetime, 298, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) __PYX_ERR(0, 298, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_tuple__41 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__41)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__41); + __Pyx_GIVEREF(__pyx_tuple__41); + __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) __PYX_ERR(3, 1, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__43 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__43)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__43); + __Pyx_GIVEREF(__pyx_tuple__43); + __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) __PYX_ERR(3, 3, __pyx_L1_error) + + /* "questdb/ingress.pyx":349 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. + */ + __pyx_tuple__45 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_dt); if (unlikely(!__pyx_tuple__45)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__45); + __Pyx_GIVEREF(__pyx_tuple__45); + __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_from_datetime, 349, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) __PYX_ERR(0, 349, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_tuple__47 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__47)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__47); + __Pyx_GIVEREF(__pyx_tuple__47); + __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) __PYX_ERR(3, 1, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__49 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__49)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__49); + __Pyx_GIVEREF(__pyx_tuple__49); + __pyx_codeobj__50 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__49, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__50)) __PYX_ERR(3, 3, __pyx_L1_error) + + /* "questdb/ingress.pyx":493 + * return self._max_name_len + * + * def reserve(self, additional: int): # <<<<<<<<<<<<<< + * """ + * Ensure the buffer has at least `additional` bytes of future capacity. + */ + __pyx_tuple__51 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_additional); if (unlikely(!__pyx_tuple__51)) __PYX_ERR(0, 493, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__51); + __Pyx_GIVEREF(__pyx_tuple__51); + __pyx_codeobj__52 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__51, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_reserve, 493, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__52)) __PYX_ERR(0, 493, __pyx_L1_error) + + /* "questdb/ingress.pyx":503 + * line_sender_buffer_reserve(self._impl, additional) + * + * def capacity(self) -> int: # <<<<<<<<<<<<<< + * """The current buffer capacity.""" + * return line_sender_buffer_capacity(self._impl) + */ + __pyx_tuple__53 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__53)) __PYX_ERR(0, 503, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__53); + __Pyx_GIVEREF(__pyx_tuple__53); + __pyx_codeobj__54 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__53, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_capacity, 503, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__54)) __PYX_ERR(0, 503, __pyx_L1_error) + + /* "questdb/ingress.pyx":507 + * return line_sender_buffer_capacity(self._impl) + * + * def clear(self): # <<<<<<<<<<<<<< + * """ + * Reset the buffer. + */ + __pyx_tuple__55 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__55)) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__55); + __Pyx_GIVEREF(__pyx_tuple__55); + __pyx_codeobj__56 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__55, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_clear, 507, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__56)) __PYX_ERR(0, 507, __pyx_L1_error) + + /* "questdb/ingress.pyx":716 + * self._may_trigger_row_complete() + * + * def row( # <<<<<<<<<<<<<< + * self, + * table_name: str, + */ + __pyx_tuple__57 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_table_name, __pyx_n_s_symbols, __pyx_n_s_columns, __pyx_n_s_at); if (unlikely(!__pyx_tuple__57)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__57); + __Pyx_GIVEREF(__pyx_tuple__57); + __pyx_codeobj__58 = (PyObject*)__Pyx_PyCode_New(2, 3, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__57, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_row, 716, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__58)) __PYX_ERR(0, 716, __pyx_L1_error) + + /* "questdb/ingress.pyx":1090 + * qdb_pystr_buf_clear(self._b) + * + * def pandas( # <<<<<<<<<<<<<< + * self, + * data, # : pd.DataFrame + */ + __pyx_tuple__59 = PyTuple_Pack(8, __pyx_n_s_self, __pyx_n_s_data, __pyx_n_s_table_name, __pyx_n_s_table_name_col, __pyx_n_s_symbols, __pyx_n_s_at, __pyx_n_s_sort, __pyx_n_s_sys); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__59); + __Pyx_GIVEREF(__pyx_tuple__59); + __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(2, 5, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_pandas, 1090, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) __PYX_ERR(0, 1090, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_tuple__61 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__61)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__61); + __Pyx_GIVEREF(__pyx_tuple__61); + __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) __PYX_ERR(3, 1, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__63 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__63); + __Pyx_GIVEREF(__pyx_tuple__63); + __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) __PYX_ERR(3, 3, __pyx_L1_error) + + /* "questdb/ingress.pyx":1383 + * qdb_pystr_buf_clear(b) + * + * def new_buffer(self): # <<<<<<<<<<<<<< + * """ + * Make a new configured buffer. + */ + __pyx_tuple__65 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 1383, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__65); + __Pyx_GIVEREF(__pyx_tuple__65); + __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_new_buffer, 1383, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 1383, __pyx_L1_error) + + /* "questdb/ingress.pyx":1404 + * return self._max_name_len + * + * def connect(self): # <<<<<<<<<<<<<< + * """ + * Connect to the QuestDB server. + */ + __pyx_tuple__67 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_err); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 1404, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__67); + __Pyx_GIVEREF(__pyx_tuple__67); + __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_connect, 1404, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 1404, __pyx_L1_error) + + /* "questdb/ingress.pyx":1429 + * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) + * + * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< + * """Call :func:`Sender.connect` at the start of a ``with`` block.""" + * self.connect() + */ + __pyx_tuple__69 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 1429, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__69); + __Pyx_GIVEREF(__pyx_tuple__69); + __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_enter, 1429, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 1429, __pyx_L1_error) + + /* "questdb/ingress.pyx":1452 + * return len(self._buffer) + * + * def row(self, # <<<<<<<<<<<<<< + * table_name: str, + * *, + */ + __pyx_tuple__71 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_table_name, __pyx_n_s_symbols, __pyx_n_s_columns, __pyx_n_s_at); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 1452, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__71); + __Pyx_GIVEREF(__pyx_tuple__71); + __pyx_codeobj__72 = (PyObject*)__Pyx_PyCode_New(2, 3, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_row, 1452, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__72)) __PYX_ERR(0, 1452, __pyx_L1_error) + + /* "questdb/ingress.pyx":1470 + * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) + * + * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< + * """ + * If called with no arguments, immediately flushes the internal buffer. + */ + __pyx_tuple__73 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_buffer, __pyx_n_s_clear); if (unlikely(!__pyx_tuple__73)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__73); + __Pyx_GIVEREF(__pyx_tuple__73); + __pyx_codeobj__74 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__73, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_flush, 1470, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__74)) __PYX_ERR(0, 1470, __pyx_L1_error) + + /* "questdb/ingress.pyx":1528 + * self._impl = NULL + * + * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< + * """ + * Disconnect. + */ + __pyx_tuple__75 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_flush); if (unlikely(!__pyx_tuple__75)) __PYX_ERR(0, 1528, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__75); + __Pyx_GIVEREF(__pyx_tuple__75); + __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_close, 1528, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) __PYX_ERR(0, 1528, __pyx_L1_error) + + /* "questdb/ingress.pyx":1545 + * self._close() + * + * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< + * """ + * Flush pending and disconnect at the end of a ``with`` block. + */ + __pyx_tuple__77 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_exc_type, __pyx_n_s_exc_val, __pyx_n_s_exc_tb); if (unlikely(!__pyx_tuple__77)) __PYX_ERR(0, 1545, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__77); + __Pyx_GIVEREF(__pyx_tuple__77); + __pyx_codeobj__78 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__77, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_exit, 1545, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__78)) __PYX_ERR(0, 1545, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_tuple__79 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__79)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__79); + __Pyx_GIVEREF(__pyx_tuple__79); + __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) __PYX_ERR(3, 1, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__81 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__81)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__81); + __Pyx_GIVEREF(__pyx_tuple__81); + __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + __pyx_umethod_PyUnicode_Type_format.type = (PyObject*)&PyUnicode_Type; + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_127 = PyInt_FromLong(127); if (unlikely(!__pyx_int_127)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_1000 = PyInt_FromLong(1000); if (unlikely(!__pyx_int_1000)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_64512 = PyInt_FromLong(64512L); if (unlikely(!__pyx_int_64512)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_65536 = PyInt_FromLong(65536L); if (unlikely(!__pyx_int_65536)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __pyx_v_7questdb_7ingress__PANDAS_NA = Py_None; Py_INCREF(Py_None); + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + if (PyType_Ready(&__pyx_type_7questdb_7ingress_TimestampMicros) < 0) __PYX_ERR(0, 261, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7questdb_7ingress_TimestampMicros.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_TimestampMicros.tp_dictoffset && __pyx_type_7questdb_7ingress_TimestampMicros.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7questdb_7ingress_TimestampMicros.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_TimestampMicros, (PyObject *)&__pyx_type_7questdb_7ingress_TimestampMicros) < 0) __PYX_ERR(0, 261, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_TimestampMicros) < 0) __PYX_ERR(0, 261, __pyx_L1_error) + __pyx_ptype_7questdb_7ingress_TimestampMicros = &__pyx_type_7questdb_7ingress_TimestampMicros; + if (PyType_Ready(&__pyx_type_7questdb_7ingress_TimestampNanos) < 0) __PYX_ERR(0, 312, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7questdb_7ingress_TimestampNanos.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_TimestampNanos.tp_dictoffset && __pyx_type_7questdb_7ingress_TimestampNanos.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7questdb_7ingress_TimestampNanos.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_TimestampNanos, (PyObject *)&__pyx_type_7questdb_7ingress_TimestampNanos) < 0) __PYX_ERR(0, 312, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_TimestampNanos) < 0) __PYX_ERR(0, 312, __pyx_L1_error) + __pyx_ptype_7questdb_7ingress_TimestampNanos = &__pyx_type_7questdb_7ingress_TimestampNanos; + __pyx_vtabptr_7questdb_7ingress_Sender = &__pyx_vtable_7questdb_7ingress_Sender; + __pyx_vtable_7questdb_7ingress_Sender.flush = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args))__pyx_f_7questdb_7ingress_6Sender_flush; + __pyx_vtable_7questdb_7ingress_Sender._close = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Sender *))__pyx_f_7questdb_7ingress_6Sender__close; + __pyx_vtable_7questdb_7ingress_Sender.close = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args))__pyx_f_7questdb_7ingress_6Sender_close; + if (PyType_Ready(&__pyx_type_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7questdb_7ingress_Sender.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_Sender.tp_dictoffset && __pyx_type_7questdb_7ingress_Sender.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7questdb_7ingress_Sender.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + #if CYTHON_UPDATE_DESCRIPTOR_DOC + { + PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Sender, "__str__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1127, __pyx_L1_error) + if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { + __pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__ = *((PyWrapperDescrObject *)wrapper)->d_base; + __pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__.doc = __pyx_doc_7questdb_7ingress_6Sender_8__str__; + ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__; + } + } + #endif + #if CYTHON_UPDATE_DESCRIPTOR_DOC + { + PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Sender, "__len__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1127, __pyx_L1_error) + if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { + __pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__ = *((PyWrapperDescrObject *)wrapper)->d_base; + __pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__.doc = __pyx_doc_7questdb_7ingress_6Sender_10__len__; + ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__; + } + } + #endif + if (__Pyx_SetVtable(__pyx_type_7questdb_7ingress_Sender.tp_dict, __pyx_vtabptr_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Sender, (PyObject *)&__pyx_type_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) + if (__pyx_type_7questdb_7ingress_Sender.tp_weaklistoffset == 0) __pyx_type_7questdb_7ingress_Sender.tp_weaklistoffset = offsetof(struct __pyx_obj_7questdb_7ingress_Sender, __weakref__); + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) + __pyx_ptype_7questdb_7ingress_Sender = &__pyx_type_7questdb_7ingress_Sender; + __pyx_vtabptr_7questdb_7ingress_Buffer = &__pyx_vtable_7questdb_7ingress_Buffer; + __pyx_vtable_7questdb_7ingress_Buffer._cinit_impl = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *, size_t, size_t))__pyx_f_7questdb_7ingress_6Buffer__cinit_impl; + __pyx_vtable_7questdb_7ingress_Buffer._to_str = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__to_str; + __pyx_vtable_7questdb_7ingress_Buffer._set_marker = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__set_marker; + __pyx_vtable_7questdb_7ingress_Buffer._rewind_to_marker = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker; + __pyx_vtable_7questdb_7ingress_Buffer._clear_marker = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__clear_marker; + __pyx_vtable_7questdb_7ingress_Buffer._table = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__table; + __pyx_vtable_7questdb_7ingress_Buffer._cleared_b = (struct qdb_pystr_buf *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__cleared_b; + __pyx_vtable_7questdb_7ingress_Buffer._symbol = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__symbol; + __pyx_vtable_7questdb_7ingress_Buffer._column_bool = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int))__pyx_f_7questdb_7ingress_6Buffer__column_bool; + __pyx_vtable_7questdb_7ingress_Buffer._column_i64 = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int64_t))__pyx_f_7questdb_7ingress_6Buffer__column_i64; + __pyx_vtable_7questdb_7ingress_Buffer._column_f64 = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, double))__pyx_f_7questdb_7ingress_6Buffer__column_f64; + __pyx_vtable_7questdb_7ingress_Buffer._column_str = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__column_str; + __pyx_vtable_7questdb_7ingress_Buffer._column_ts = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *))__pyx_f_7questdb_7ingress_6Buffer__column_ts; + __pyx_vtable_7questdb_7ingress_Buffer._column_dt = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyDateTime_DateTime *))__pyx_f_7questdb_7ingress_6Buffer__column_dt; + __pyx_vtable_7questdb_7ingress_Buffer._column = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__column; + __pyx_vtable_7questdb_7ingress_Buffer._may_trigger_row_complete = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete; + __pyx_vtable_7questdb_7ingress_Buffer._at_ts = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_TimestampNanos *))__pyx_f_7questdb_7ingress_6Buffer__at_ts; + __pyx_vtable_7questdb_7ingress_Buffer._at_dt = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyDateTime_DateTime *))__pyx_f_7questdb_7ingress_6Buffer__at_dt; + __pyx_vtable_7questdb_7ingress_Buffer._at_now = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__at_now; + __pyx_vtable_7questdb_7ingress_Buffer._at = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__at; + __pyx_vtable_7questdb_7ingress_Buffer._row = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args))__pyx_f_7questdb_7ingress_6Buffer__row; + __pyx_vtable_7questdb_7ingress_Buffer._pandas = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int))__pyx_f_7questdb_7ingress_6Buffer__pandas; + if (PyType_Ready(&__pyx_type_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7questdb_7ingress_Buffer.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_Buffer.tp_dictoffset && __pyx_type_7questdb_7ingress_Buffer.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7questdb_7ingress_Buffer.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + #if CYTHON_UPDATE_DESCRIPTOR_DOC + { + PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Buffer, "__len__"); if (unlikely(!wrapper)) __PYX_ERR(0, 383, __pyx_L1_error) + if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { + __pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__ = *((PyWrapperDescrObject *)wrapper)->d_base; + __pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__.doc = __pyx_doc_7questdb_7ingress_6Buffer_10__len__; + ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__; + } + } + #endif + #if CYTHON_UPDATE_DESCRIPTOR_DOC + { + PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Buffer, "__str__"); if (unlikely(!wrapper)) __PYX_ERR(0, 383, __pyx_L1_error) + if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { + __pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__ = *((PyWrapperDescrObject *)wrapper)->d_base; + __pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__.doc = __pyx_doc_7questdb_7ingress_6Buffer_12__str__; + ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__; + } + } + #endif + if (__Pyx_SetVtable(__pyx_type_7questdb_7ingress_Buffer.tp_dict, __pyx_vtabptr_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Buffer, (PyObject *)&__pyx_type_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) + __pyx_ptype_7questdb_7ingress_Buffer = &__pyx_type_7questdb_7ingress_Buffer; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", + #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(5, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule("datetime"); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_8datetime_date = __Pyx_ImportType(__pyx_t_1, "datetime", "date", sizeof(PyDateTime_Date), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_8datetime_date) __PYX_ERR(4, 9, __pyx_L1_error) + __pyx_ptype_7cpython_8datetime_time = __Pyx_ImportType(__pyx_t_1, "datetime", "time", sizeof(PyDateTime_Time), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_8datetime_time) __PYX_ERR(4, 12, __pyx_L1_error) + __pyx_ptype_7cpython_8datetime_datetime = __Pyx_ImportType(__pyx_t_1, "datetime", "datetime", sizeof(PyDateTime_DateTime), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_8datetime_datetime) __PYX_ERR(4, 15, __pyx_L1_error) + __pyx_ptype_7cpython_8datetime_timedelta = __Pyx_ImportType(__pyx_t_1, "datetime", "timedelta", sizeof(PyDateTime_Delta), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_8datetime_timedelta) __PYX_ERR(4, 18, __pyx_L1_error) + __pyx_ptype_7cpython_8datetime_tzinfo = __Pyx_ImportType(__pyx_t_1, "datetime", "tzinfo", sizeof(PyDateTime_TZInfo), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_8datetime_tzinfo) __PYX_ERR(4, 21, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(6, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(6, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC initingress(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC initingress(void) +#else +__Pyx_PyMODINIT_FUNC PyInit_ingress(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_ingress(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_ingress(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'ingress' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_ingress(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + PyEval_InitThreads(); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("ingress", __pyx_methods, __pyx_k_API_for_fast_data_ingestion_int, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_b); + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_cython_runtime); + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_questdb__ingress) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "questdb.ingress")) { + if (unlikely(PyDict_SetItemString(modules, "questdb.ingress", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "src/questdb/pandas_helpers.pxi":76 + * + * + * cdef object _PANDAS_NA = None # <<<<<<<<<<<<<< + * + * + */ + __Pyx_INCREF(Py_None); + __Pyx_XGOTREF(__pyx_v_7questdb_7ingress__PANDAS_NA); + __Pyx_DECREF_SET(__pyx_v_7questdb_7ingress__PANDAS_NA, Py_None); + __Pyx_GIVEREF(Py_None); + + /* "src/questdb/pandas_helpers.pxi":435 + * + * + * cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' # <<<<<<<<<<<<<< + * cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' + * + */ + __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_OBJECT = ((char)79); + + /* "src/questdb/pandas_helpers.pxi":436 + * + * cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' + * cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' # <<<<<<<<<<<<<< + * + * + */ + __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_DATETIME = ((char)77); + + /* "questdb/ingress.pyx":56 + * + * import cython + * from enum import Enum # <<<<<<<<<<<<<< + * from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable + * import pathlib + */ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_Enum); + __Pyx_GIVEREF(__pyx_n_s_Enum); + PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_Enum); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_enum, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Enum, __pyx_t_1) < 0) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":57 + * import cython + * from enum import Enum + * from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable # <<<<<<<<<<<<<< + * import pathlib + * + */ + __pyx_t_2 = PyList_New(8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_List); + __Pyx_GIVEREF(__pyx_n_s_List); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_List); + __Pyx_INCREF(__pyx_n_s_Tuple); + __Pyx_GIVEREF(__pyx_n_s_Tuple); + PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_Tuple); + __Pyx_INCREF(__pyx_n_s_Dict); + __Pyx_GIVEREF(__pyx_n_s_Dict); + PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_Dict); + __Pyx_INCREF(__pyx_n_s_Union); + __Pyx_GIVEREF(__pyx_n_s_Union); + PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_s_Union); + __Pyx_INCREF(__pyx_n_s_Any); + __Pyx_GIVEREF(__pyx_n_s_Any); + PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_s_Any); + __Pyx_INCREF(__pyx_n_s_Optional); + __Pyx_GIVEREF(__pyx_n_s_Optional); + PyList_SET_ITEM(__pyx_t_2, 5, __pyx_n_s_Optional); + __Pyx_INCREF(__pyx_n_s_Callable); + __Pyx_GIVEREF(__pyx_n_s_Callable); + PyList_SET_ITEM(__pyx_t_2, 6, __pyx_n_s_Callable); + __Pyx_INCREF(__pyx_n_s_Iterable); + __Pyx_GIVEREF(__pyx_n_s_Iterable); + PyList_SET_ITEM(__pyx_t_2, 7, __pyx_n_s_Iterable); + __pyx_t_1 = __Pyx_Import(__pyx_n_s_typing, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_List, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Tuple, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Dict, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Union); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Union, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Any); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Any, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Optional); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Optional, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Callable); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Callable, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Iterable); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_Iterable, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":58 + * from enum import Enum + * from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable + * import pathlib # <<<<<<<<<<<<<< + * + * import sys + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_pathlib, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pathlib, __pyx_t_1) < 0) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":60 + * import pathlib + * + * import sys # <<<<<<<<<<<<<< + * + * class IngressErrorCode(Enum): + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "questdb/ingress.pyx":62 + * import sys + * + * class IngressErrorCode(Enum): # <<<<<<<<<<<<<< + * """Category of Error.""" + * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); + __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_IngressErrorCode, __pyx_n_s_IngressErrorCode, (PyObject *) NULL, __pyx_n_s_questdb_ingress, __pyx_kp_s_Category_of_Error); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "questdb/ingress.pyx":64 + * class IngressErrorCode(Enum): + * """Category of Error.""" + * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr # <<<<<<<<<<<<<< + * InvalidApiCall = line_sender_error_invalid_api_call + * SocketError = line_sender_error_socket_error + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_could_not_resolve_addr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_CouldNotResolveAddr, __pyx_t_4) < 0) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":65 + * """Category of Error.""" + * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr + * InvalidApiCall = line_sender_error_invalid_api_call # <<<<<<<<<<<<<< + * SocketError = line_sender_error_socket_error + * InvalidUtf8 = line_sender_error_invalid_utf8 + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_api_call); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidApiCall, __pyx_t_4) < 0) __PYX_ERR(0, 65, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":66 + * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr + * InvalidApiCall = line_sender_error_invalid_api_call + * SocketError = line_sender_error_socket_error # <<<<<<<<<<<<<< + * InvalidUtf8 = line_sender_error_invalid_utf8 + * InvalidName = line_sender_error_invalid_name + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_socket_error); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SocketError, __pyx_t_4) < 0) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":67 + * InvalidApiCall = line_sender_error_invalid_api_call + * SocketError = line_sender_error_socket_error + * InvalidUtf8 = line_sender_error_invalid_utf8 # <<<<<<<<<<<<<< + * InvalidName = line_sender_error_invalid_name + * InvalidTimestamp = line_sender_error_invalid_timestamp + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_utf8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 67, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidUtf8, __pyx_t_4) < 0) __PYX_ERR(0, 67, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":68 + * SocketError = line_sender_error_socket_error + * InvalidUtf8 = line_sender_error_invalid_utf8 + * InvalidName = line_sender_error_invalid_name # <<<<<<<<<<<<<< + * InvalidTimestamp = line_sender_error_invalid_timestamp + * AuthError = line_sender_error_auth_error + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidName, __pyx_t_4) < 0) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":69 + * InvalidUtf8 = line_sender_error_invalid_utf8 + * InvalidName = line_sender_error_invalid_name + * InvalidTimestamp = line_sender_error_invalid_timestamp # <<<<<<<<<<<<<< + * AuthError = line_sender_error_auth_error + * TlsError = line_sender_error_tls_error + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_timestamp); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidTimestamp, __pyx_t_4) < 0) __PYX_ERR(0, 69, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":70 + * InvalidName = line_sender_error_invalid_name + * InvalidTimestamp = line_sender_error_invalid_timestamp + * AuthError = line_sender_error_auth_error # <<<<<<<<<<<<<< + * TlsError = line_sender_error_tls_error + * + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_auth_error); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_AuthError, __pyx_t_4) < 0) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":71 + * InvalidTimestamp = line_sender_error_invalid_timestamp + * AuthError = line_sender_error_auth_error + * TlsError = line_sender_error_tls_error # <<<<<<<<<<<<<< + * + * def __str__(self) -> str: + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_tls_error); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_TlsError, __pyx_t_4) < 0) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":73 + * TlsError = line_sender_error_tls_error + * + * def __str__(self) -> str: # <<<<<<<<<<<<<< + * """Return the name of the enum.""" + * return self.name + */ + __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 73, __pyx_L1_error) + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_16IngressErrorCode_1__str__, 0, __pyx_n_s_IngressErrorCode___str, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__34)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_4); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_str_2, __pyx_t_5) < 0) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "questdb/ingress.pyx":62 + * import sys + * + * class IngressErrorCode(Enum): # <<<<<<<<<<<<<< + * """Category of Error.""" + * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr + */ + __pyx_t_5 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_IngressErrorCode, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_IngressErrorCode, __pyx_t_5) < 0) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":78 + * + * + * class IngressError(Exception): # <<<<<<<<<<<<<< + * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" + * def __init__(self, code, msg): + */ + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + __Pyx_GIVEREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_IngressError, __pyx_n_s_IngressError, (PyObject *) NULL, __pyx_n_s_questdb_ingress, __pyx_kp_s_An_error_whilst_using_the_Sender); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + + /* "questdb/ingress.pyx":80 + * class IngressError(Exception): + * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" + * def __init__(self, code, msg): # <<<<<<<<<<<<<< + * super().__init__(msg) + * self._code = code + */ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_12IngressError_1__init__, 0, __pyx_n_s_IngressError___init, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__36)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_4); + PyList_Append(__pyx_t_5, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_init, __pyx_t_4) < 0) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":85 + * + * @property + * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< + * """Return the error code.""" + * return self._code + */ + __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_12IngressError_3code, 0, __pyx_n_s_IngressError_code, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__38)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_4); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":84 + * self._code = code + * + * @property # <<<<<<<<<<<<<< + * def code(self) -> IngressErrorCode: + * """Return the error code.""" + */ + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_property, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 84, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_code, __pyx_t_4) < 0) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":78 + * + * + * class IngressError(Exception): # <<<<<<<<<<<<<< + * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" + * def __init__(self, code, msg): + */ + __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_IngressError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_CyFunction_InitClassCell(__pyx_t_5, __pyx_t_4) < 0) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_IngressError, __pyx_t_4) < 0) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":298 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dt, __pyx_n_u_datetime) < 0) __PYX_ERR(0, 298, __pyx_L1_error) + __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_15TimestampMicros_3from_datetime, __Pyx_CYFUNCTION_CLASSMETHOD | __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampMicros_from_datetime, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__40)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros->tp_dict, __pyx_n_s_from_datetime, __pyx_t_1) < 0) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampMicros); + + /* "questdb/ingress.pyx":297 + * self._value = value + * + * @classmethod # <<<<<<<<<<<<<< + * def from_datetime(cls, dt: datetime): + * """ + */ + __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros, __pyx_n_s_from_datetime); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 297, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros->tp_dict, __pyx_n_s_from_datetime, __pyx_t_2) < 0) __PYX_ERR(0, 298, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampMicros); + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_15TimestampMicros_5__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampMicros___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__42)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_2) < 0) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_15TimestampMicros_7__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampMicros___setstate_cytho, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__44)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_2) < 0) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":349 + * + * @classmethod + * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< + * """ + * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dt, __pyx_n_u_datetime) < 0) __PYX_ERR(0, 349, __pyx_L1_error) + __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_14TimestampNanos_3from_datetime, __Pyx_CYFUNCTION_CLASSMETHOD | __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampNanos_from_datetime, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos->tp_dict, __pyx_n_s_from_datetime, __pyx_t_1) < 0) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampNanos); + + /* "questdb/ingress.pyx":348 + * self._value = value + * + * @classmethod # <<<<<<<<<<<<<< + * def from_datetime(cls, dt: datetime): + * """ + */ + __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos, __pyx_n_s_from_datetime); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 348, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos->tp_dict, __pyx_n_s_from_datetime, __pyx_t_2) < 0) __PYX_ERR(0, 349, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampNanos); + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_14TimestampNanos_5__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampNanos___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_2) < 0) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_14TimestampNanos_7__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampNanos___setstate_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__50)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_2) < 0) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":493 + * return self._max_name_len + * + * def reserve(self, additional: int): # <<<<<<<<<<<<<< + * """ + * Ensure the buffer has at least `additional` bytes of future capacity. + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 493, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_additional, __pyx_n_u_int) < 0) __PYX_ERR(0, 493, __pyx_L1_error) + __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_5reserve, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_reserve, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__52)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_reserve, __pyx_t_1) < 0) __PYX_ERR(0, 493, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); + + /* "questdb/ingress.pyx":503 + * line_sender_buffer_reserve(self._impl, additional) + * + * def capacity(self) -> int: # <<<<<<<<<<<<<< + * """The current buffer capacity.""" + * return line_sender_buffer_capacity(self._impl) + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 503, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_n_u_int) < 0) __PYX_ERR(0, 503, __pyx_L1_error) + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_7capacity, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_capacity, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__54)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 503, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_capacity, __pyx_t_2) < 0) __PYX_ERR(0, 503, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); + + /* "questdb/ingress.pyx":507 + * return line_sender_buffer_capacity(self._impl) + * + * def clear(self): # <<<<<<<<<<<<<< + * """ + * Reset the buffer. + */ + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_9clear, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_clear, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__56)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_clear, __pyx_t_2) < 0) __PYX_ERR(0, 507, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); + + /* "questdb/ingress.pyx":716 + * self._may_trigger_row_complete() + * + * def row( # <<<<<<<<<<<<<< + * self, + * table_name: str, + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_table_name, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 716, __pyx_L1_error) + + /* "questdb/ingress.pyx":720 + * table_name: str, + * *, + * symbols: Optional[Dict[str, Optional[str]]]=None, # <<<<<<<<<<<<<< + * columns: Optional[Dict[ + * str, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Optional); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Dict); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Optional); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_4, ((PyObject *)(&PyUnicode_Type))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_symbols, __pyx_t_4) < 0) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":721 + * *, + * symbols: Optional[Dict[str, Optional[str]]]=None, + * columns: Optional[Dict[ # <<<<<<<<<<<<<< + * str, + * Union[None, bool, int, float, str, TimestampMicros, datetime]] + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Optional); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Dict); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + + /* "questdb/ingress.pyx":723 + * columns: Optional[Dict[ + * str, + * Union[None, bool, int, float, str, TimestampMicros, datetime]] # <<<<<<<<<<<<<< + * ]=None, + * at: Union[None, TimestampNanos, datetime]=None): + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Union); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyTuple_New(7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + PyTuple_SET_ITEM(__pyx_t_3, 1, ((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + __Pyx_INCREF(((PyObject *)(&PyInt_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); + PyTuple_SET_ITEM(__pyx_t_3, 2, ((PyObject *)(&PyInt_Type))); + __Pyx_INCREF(((PyObject *)(&PyFloat_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type))); + PyTuple_SET_ITEM(__pyx_t_3, 3, ((PyObject *)(&PyFloat_Type))); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_3, 4, ((PyObject *)(&PyUnicode_Type))); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); + PyTuple_SET_ITEM(__pyx_t_3, 5, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + PyTuple_SET_ITEM(__pyx_t_3, 6, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 723, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":721 + * *, + * symbols: Optional[Dict[str, Optional[str]]]=None, + * columns: Optional[Dict[ # <<<<<<<<<<<<<< + * str, + * Union[None, bool, int, float, str, TimestampMicros, datetime]] + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 721, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_columns, __pyx_t_3) < 0) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":725 + * Union[None, bool, int, float, str, TimestampMicros, datetime]] + * ]=None, + * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< + * """ + * Add a single row (line) to the buffer. + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 725, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 725, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_6, 0, Py_None); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + PyTuple_SET_ITEM(__pyx_t_6, 1, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + PyTuple_SET_ITEM(__pyx_t_6, 2, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 725, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_at, __pyx_t_4) < 0) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "questdb/ingress.pyx":716 + * self._may_trigger_row_complete() + * + * def row( # <<<<<<<<<<<<<< + * self, + * table_name: str, + */ + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_15row, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_row, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__58)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_row, __pyx_t_4) < 0) __PYX_ERR(0, 716, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); + + /* "questdb/ingress.pyx":1090 + * qdb_pystr_buf_clear(self._b) + * + * def pandas( # <<<<<<<<<<<<<< + * self, + * data, # : pd.DataFrame + */ + __pyx_t_4 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + + /* "questdb/ingress.pyx":1094 + * data, # : pd.DataFrame + * *, + * table_name: Optional[str] = None, # <<<<<<<<<<<<<< + * table_name_col: Union[None, int, str] = None, + * symbols: Union[bool, List[int], List[str]] = False, + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Optional); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1094, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, ((PyObject *)(&PyUnicode_Type))); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1094, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_table_name, __pyx_t_6) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "questdb/ingress.pyx":1095 + * *, + * table_name: Optional[str] = None, + * table_name_col: Union[None, int, str] = None, # <<<<<<<<<<<<<< + * symbols: Union[bool, List[int], List[str]] = False, + * at: Union[None, int, str, TimestampNanos, datetime] = None, + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Union); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1095, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1095, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_2, 0, Py_None); + __Pyx_INCREF(((PyObject *)(&PyInt_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 1, ((PyObject *)(&PyInt_Type))); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 2, ((PyObject *)(&PyUnicode_Type))); + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1095, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_table_name_col, __pyx_t_3) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":1096 + * table_name: Optional[str] = None, + * table_name_col: Union[None, int, str] = None, + * symbols: Union[bool, List[int], List[str]] = False, # <<<<<<<<<<<<<< + * at: Union[None, int, str, TimestampNanos, datetime] = None, + * sort: bool = True): + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1096, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1096, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, ((PyObject *)(&PyInt_Type))); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1096, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1096, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_2, ((PyObject *)(&PyUnicode_Type))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1096, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1096, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5); + __pyx_t_6 = 0; + __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1096, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_symbols, __pyx_t_5) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "questdb/ingress.pyx":1097 + * table_name_col: Union[None, int, str] = None, + * symbols: Union[bool, List[int], List[str]] = False, + * at: Union[None, int, str, TimestampNanos, datetime] = None, # <<<<<<<<<<<<<< + * sort: bool = True): + * """ + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Union); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1097, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = PyTuple_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1097, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_2, 0, Py_None); + __Pyx_INCREF(((PyObject *)(&PyInt_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 1, ((PyObject *)(&PyInt_Type))); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 2, ((PyObject *)(&PyUnicode_Type))); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + PyTuple_SET_ITEM(__pyx_t_2, 3, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + PyTuple_SET_ITEM(__pyx_t_2, 4, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1097, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_at, __pyx_t_3) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_sort, __pyx_n_u_bool) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) + + /* "questdb/ingress.pyx":1090 + * qdb_pystr_buf_clear(self._b) + * + * def pandas( # <<<<<<<<<<<<<< + * self, + * data, # : pd.DataFrame + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_17pandas, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_pandas, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__60)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_4); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_pandas, __pyx_t_3) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_19__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__62)); if (unlikely(!__pyx_t_3)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_3) < 0) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_21__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer___setstate_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__64)); if (unlikely(!__pyx_t_3)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_3) < 0) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "questdb/ingress.pyx":1122 + * + * + * _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' # <<<<<<<<<<<<<< + * 'v1.0.2' + * '/troubleshooting.html#inspecting-and-debugging-errors#flush-failed') + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_FLUSH_FMT, __pyx_kp_u_See_https_py_questdb_client_rea) < 0) __PYX_ERR(0, 1122, __pyx_L1_error) + + /* "questdb/ingress.pyx":1383 + * qdb_pystr_buf_clear(b) + * + * def new_buffer(self): # <<<<<<<<<<<<<< + * """ + * Make a new configured buffer. + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_3new_buffer, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_new_buffer, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__66)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1383, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_new_buffer, __pyx_t_3) < 0) __PYX_ERR(0, 1383, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); + + /* "questdb/ingress.pyx":1404 + * return self._max_name_len + * + * def connect(self): # <<<<<<<<<<<<<< + * """ + * Connect to the QuestDB server. + */ + __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_5connect, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_connect, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1404, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_connect, __pyx_t_3) < 0) __PYX_ERR(0, 1404, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); + + /* "questdb/ingress.pyx":1429 + * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) + * + * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< + * """Call :func:`Sender.connect` at the start of a ``with`` block.""" + * self.connect() + */ + __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1429, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_return, __pyx_n_u_Sender) < 0) __PYX_ERR(0, 1429, __pyx_L1_error) + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_7__enter__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___enter, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1429, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_enter, __pyx_t_4) < 0) __PYX_ERR(0, 1429, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); + + /* "questdb/ingress.pyx":1452 + * return len(self._buffer) + * + * def row(self, # <<<<<<<<<<<<<< + * table_name: str, + * *, + */ + __pyx_t_4 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1452, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_table_name, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) + + /* "questdb/ingress.pyx":1455 + * table_name: str, + * *, + * symbols: Optional[Dict[str, str]]=None, # <<<<<<<<<<<<<< + * columns: Optional[Dict[ + * str, + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Optional); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1455, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1455, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1455, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyUnicode_Type))); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)(&PyUnicode_Type))); + __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1455, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1455, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_symbols, __pyx_t_5) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "questdb/ingress.pyx":1456 + * *, + * symbols: Optional[Dict[str, str]]=None, + * columns: Optional[Dict[ # <<<<<<<<<<<<<< + * str, + * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Optional); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1456, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1456, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "questdb/ingress.pyx":1458 + * columns: Optional[Dict[ + * str, + * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, # <<<<<<<<<<<<<< + * at: Union[None, TimestampNanos, datetime]=None): + * """ + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1458, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = PyTuple_New(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1458, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_ptype_7cpython_4bool_bool)); + __Pyx_INCREF(((PyObject *)(&PyInt_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 1, ((PyObject *)(&PyInt_Type))); + __Pyx_INCREF(((PyObject *)(&PyFloat_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 2, ((PyObject *)(&PyFloat_Type))); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 3, ((PyObject *)(&PyUnicode_Type))); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); + PyTuple_SET_ITEM(__pyx_t_2, 4, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + PyTuple_SET_ITEM(__pyx_t_2, 5, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1458, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1456 + * *, + * symbols: Optional[Dict[str, str]]=None, + * columns: Optional[Dict[ # <<<<<<<<<<<<<< + * str, + * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, + */ + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1456, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)(&PyUnicode_Type))); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1); + __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1456, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1456, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_columns, __pyx_t_2) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "questdb/ingress.pyx":1459 + * str, + * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, + * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< + * """ + * Write a row to the internal buffer. + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Union); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_1, 0, Py_None); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + PyTuple_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); + __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + PyTuple_SET_ITEM(__pyx_t_1, 2, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); + __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_at, __pyx_t_5) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "questdb/ingress.pyx":1452 + * return len(self._buffer) + * + * def row(self, # <<<<<<<<<<<<<< + * table_name: str, + * *, + */ + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_13row, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_row, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__72)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1452, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_4); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_row, __pyx_t_5) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); + + /* "questdb/ingress.pyx":1470 + * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) + * + * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< + * """ + * If called with no arguments, immediately flushes the internal buffer. + */ + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_15flush, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_flush, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__74)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_flush, __pyx_t_5) < 0) __PYX_ERR(0, 1470, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); + + /* "questdb/ingress.pyx":1528 + * self._impl = NULL + * + * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< + * """ + * Disconnect. + */ + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_17close, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_close, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__76)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1528, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_close, __pyx_t_5) < 0) __PYX_ERR(0, 1528, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); + + /* "questdb/ingress.pyx":1545 + * self._close() + * + * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< + * """ + * Flush pending and disconnect at the end of a ``with`` block. + */ + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_19__exit__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___exit, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__78)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1545, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_exit, __pyx_t_5) < 0) __PYX_ERR(0, 1545, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_23__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__80)); if (unlikely(!__pyx_t_5)) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_5) < 0) __PYX_ERR(3, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_25__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___setstate_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__82)); if (unlikely(!__pyx_t_5)) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_5) < 0) __PYX_ERR(3, 3, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "questdb/ingress.pyx":1 + * ################################################################################ # <<<<<<<<<<<<<< + * ## ___ _ ____ ____ + * ## / _ \ _ _ ___ ___| |_| _ \| __ ) + */ + __pyx_t_5 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_5) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "cpython/datetime.pxd":211 + * + * # Get microseconds of timedelta + * cdef inline int timedelta_microseconds(object o): # <<<<<<<<<<<<<< + * return (o).microseconds + */ + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init questdb.ingress", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_CLEAR(__pyx_m); + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init questdb.ingress"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* PyCFunctionFastCall */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); + } +} +#endif + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { + return NULL; + } + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = Py_TYPE(func)->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallOneArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, &arg, 1); + } +#endif + if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); +#if CYTHON_FAST_PYCCALL + } else if (__Pyx_PyFastCFunction_Check(func)) { + return __Pyx_PyCFunction_FastCall(func, &arg, 1); +#endif + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + #endif + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +#endif + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; itp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type, *local_value, *local_tb; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return m->sq_item(o, i); + } + } +#else + if (is_list || PySequence_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* PyUnicode_Unicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj) { + if (unlikely(obj == Py_None)) + obj = __pyx_kp_u_None; + return __Pyx_NewRef(obj); +} + +/* CIntToDigits */ +static const char DIGIT_PAIRS_10[2*10*10+1] = { + "00010203040506070809" + "10111213141516171819" + "20212223242526272829" + "30313233343536373839" + "40414243444546474849" + "50515253545556575859" + "60616263646566676869" + "70717273747576777879" + "80818283848586878889" + "90919293949596979899" +}; +static const char DIGIT_PAIRS_8[2*8*8+1] = { + "0001020304050607" + "1011121314151617" + "2021222324252627" + "3031323334353637" + "4041424344454647" + "5051525354555657" + "6061626364656667" + "7071727374757677" +}; +static const char DIGITS_HEX[2*16+1] = { + "0123456789abcdef" + "0123456789ABCDEF" +}; + +/* BuildPyUnicode */ +static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, + int prepend_sign, char padding_char) { + PyObject *uval; + Py_ssize_t uoffset = ulength - clength; +#if CYTHON_USE_UNICODE_INTERNALS + Py_ssize_t i; +#if CYTHON_PEP393_ENABLED + void *udata; + uval = PyUnicode_New(ulength, 127); + if (unlikely(!uval)) return NULL; + udata = PyUnicode_DATA(uval); +#else + Py_UNICODE *udata; + uval = PyUnicode_FromUnicode(NULL, ulength); + if (unlikely(!uval)) return NULL; + udata = PyUnicode_AS_UNICODE(uval); +#endif + if (uoffset > 0) { + i = 0; + if (prepend_sign) { + __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, 0, '-'); + i++; + } + for (; i < uoffset; i++) { + __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, i, padding_char); + } + } + for (i=0; i < clength; i++) { + __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, uoffset+i, chars[i]); + } +#else + { + PyObject *sign = NULL, *padding = NULL; + uval = NULL; + if (uoffset > 0) { + prepend_sign = !!prepend_sign; + if (uoffset > prepend_sign) { + padding = PyUnicode_FromOrdinal(padding_char); + if (likely(padding) && uoffset > prepend_sign + 1) { + PyObject *tmp; + PyObject *repeat = PyInt_FromSize_t(uoffset - prepend_sign); + if (unlikely(!repeat)) goto done_or_error; + tmp = PyNumber_Multiply(padding, repeat); + Py_DECREF(repeat); + Py_DECREF(padding); + padding = tmp; + } + if (unlikely(!padding)) goto done_or_error; + } + if (prepend_sign) { + sign = PyUnicode_FromOrdinal('-'); + if (unlikely(!sign)) goto done_or_error; + } + } + uval = PyUnicode_DecodeASCII(chars, clength, NULL); + if (likely(uval) && padding) { + PyObject *tmp = PyNumber_Add(padding, uval); + Py_DECREF(uval); + uval = tmp; + } + if (likely(uval) && sign) { + PyObject *tmp = PyNumber_Add(sign, uval); + Py_DECREF(uval); + uval = tmp; + } +done_or_error: + Py_XDECREF(padding); + Py_XDECREF(sign); + } +#endif + return uval; +} + +/* CIntToPyUnicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char) { + char digits[sizeof(int)*3+2]; + char *dpos, *end = digits + sizeof(int)*3+2; + const char *hex_digits = DIGITS_HEX; + Py_ssize_t length, ulength; + int prepend_sign, last_one_off; + int remaining; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (format_char == 'X') { + hex_digits += 16; + format_char = 'x'; + } + remaining = value; + last_one_off = 0; + dpos = end; + do { + int digit_pos; + switch (format_char) { + case 'o': + digit_pos = abs((int)(remaining % (8*8))); + remaining = (int) (remaining / (8*8)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); + last_one_off = (digit_pos < 8); + break; + case 'd': + digit_pos = abs((int)(remaining % (10*10))); + remaining = (int) (remaining / (10*10)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); + last_one_off = (digit_pos < 10); + break; + case 'x': + *(--dpos) = hex_digits[abs((int)(remaining % 16))]; + remaining = (int) (remaining / 16); + break; + default: + assert(0); + break; + } + } while (unlikely(remaining != 0)); + if (last_one_off) { + assert(*dpos == '0'); + dpos++; + } + length = end - dpos; + ulength = length; + prepend_sign = 0; + if (!is_unsigned && value <= neg_one) { + if (padding_char == ' ' || width <= length + 1) { + *(--dpos) = '-'; + ++length; + } else { + prepend_sign = 1; + } + ++ulength; + } + if (width > ulength) { + ulength = width; + } + if (ulength == 1) { + return PyUnicode_FromOrdinal(*dpos); + } + return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); +} + +/* JoinPyUnicode */ +static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, + CYTHON_UNUSED Py_UCS4 max_char) { +#if CYTHON_USE_UNICODE_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + PyObject *result_uval; + int result_ukind; + Py_ssize_t i, char_pos; + void *result_udata; +#if CYTHON_PEP393_ENABLED + result_uval = PyUnicode_New(result_ulength, max_char); + if (unlikely(!result_uval)) return NULL; + result_ukind = (max_char <= 255) ? PyUnicode_1BYTE_KIND : (max_char <= 65535) ? PyUnicode_2BYTE_KIND : PyUnicode_4BYTE_KIND; + result_udata = PyUnicode_DATA(result_uval); +#else + result_uval = PyUnicode_FromUnicode(NULL, result_ulength); + if (unlikely(!result_uval)) return NULL; + result_ukind = sizeof(Py_UNICODE); + result_udata = PyUnicode_AS_UNICODE(result_uval); +#endif + char_pos = 0; + for (i=0; i < value_count; i++) { + int ukind; + Py_ssize_t ulength; + void *udata; + PyObject *uval = PyTuple_GET_ITEM(value_tuple, i); + if (unlikely(__Pyx_PyUnicode_READY(uval))) + goto bad; + ulength = __Pyx_PyUnicode_GET_LENGTH(uval); + if (unlikely(!ulength)) + continue; + if (unlikely(char_pos + ulength < 0)) + goto overflow; + ukind = __Pyx_PyUnicode_KIND(uval); + udata = __Pyx_PyUnicode_DATA(uval); + if (!CYTHON_PEP393_ENABLED || ukind == result_ukind) { + memcpy((char *)result_udata + char_pos * result_ukind, udata, (size_t) (ulength * result_ukind)); + } else { + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030300F0 || defined(_PyUnicode_FastCopyCharacters) + _PyUnicode_FastCopyCharacters(result_uval, char_pos, uval, 0, ulength); + #else + Py_ssize_t j; + for (j=0; j < ulength; j++) { + Py_UCS4 uchar = __Pyx_PyUnicode_READ(ukind, udata, j); + __Pyx_PyUnicode_WRITE(result_ukind, result_udata, char_pos+j, uchar); + } + #endif + } + char_pos += ulength; + } + return result_uval; +overflow: + PyErr_SetString(PyExc_OverflowError, "join() result is too long for a Python string"); +bad: + Py_DECREF(result_uval); + return NULL; +#else + result_ulength++; + value_count++; + return PyUnicode_Join(__pyx_empty_unicode, value_tuple); +#endif +} + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { + PyObject *runerr; + Py_ssize_t key_value; + PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; + if (unlikely(!(m && m->sq_item))) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); + return NULL; + } + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); + } + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); + } + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { + PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; + if (likely(m && m->mp_subscript)) { + return m->mp_subscript(obj, key); + } + return __Pyx_PyObject_GetIndex(obj, key); +} +#endif + +/* PyObjectFormatAndDecref */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatSimpleAndDecref(PyObject* s, PyObject* f) { + if (unlikely(!s)) return NULL; + if (likely(PyUnicode_CheckExact(s))) return s; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_CheckExact(s))) { + PyObject *result = PyUnicode_FromEncodedObject(s, NULL, "strict"); + Py_DECREF(s); + return result; + } + #endif + return __Pyx_PyObject_FormatAndDecref(s, f); +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatAndDecref(PyObject* s, PyObject* f) { + PyObject *result = PyObject_Format(s, f); + Py_DECREF(s); + return result; +} + +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; icurexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; + if (unlikely(PyTuple_Check(err))) + return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); +} +#endif + +/* ExtTypeTest */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (likely(__Pyx_TypeCheck(obj, type))) + return 1; + PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", + Py_TYPE(obj)->tp_name, type->tp_name); + return 0; +} + +/* PyIntCompare */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED long inplace) { + if (op1 == op2) { + Py_RETURN_TRUE; + } + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long a = PyInt_AS_LONG(op1); + if (a == b) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + int unequal; + unsigned long uintval; + Py_ssize_t size = Py_SIZE(op1); + const digit* digits = ((PyLongObject*)op1)->ob_digit; + if (intval == 0) { + if (size == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } else if (intval < 0) { + if (size >= 0) + Py_RETURN_FALSE; + intval = -intval; + size = -size; + } else { + if (size <= 0) + Py_RETURN_FALSE; + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + if (unequal == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; + double a = PyFloat_AS_DOUBLE(op1); + if ((double)a == (double)b) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } + return ( + PyObject_RichCompare(op1, op2, Py_EQ)); +} + +/* UnicodeAsUCS4 */ +static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject* x) { + Py_ssize_t length; + #if CYTHON_PEP393_ENABLED + length = PyUnicode_GET_LENGTH(x); + if (likely(length == 1)) { + return PyUnicode_READ_CHAR(x, 0); + } + #else + length = PyUnicode_GET_SIZE(x); + if (likely(length == 1)) { + return PyUnicode_AS_UNICODE(x)[0]; + } + #if Py_UNICODE_SIZE == 2 + else if (PyUnicode_GET_SIZE(x) == 2) { + Py_UCS4 high_val = PyUnicode_AS_UNICODE(x)[0]; + if (high_val >= 0xD800 && high_val <= 0xDBFF) { + Py_UCS4 low_val = PyUnicode_AS_UNICODE(x)[1]; + if (low_val >= 0xDC00 && low_val <= 0xDFFF) { + return 0x10000 + (((high_val & ((1<<10)-1)) << 10) | (low_val & ((1<<10)-1))); + } + } + } + #endif + #endif + PyErr_Format(PyExc_ValueError, + "only single character unicode strings can be converted to Py_UCS4, " + "got length %" CYTHON_FORMAT_SSIZE_T "d", length); + return (Py_UCS4)-1; +} + +/* object_ord */ +static long __Pyx__PyObject_Ord(PyObject* c) { + Py_ssize_t size; + if (PyBytes_Check(c)) { + size = PyBytes_GET_SIZE(c); + if (likely(size == 1)) { + return (unsigned char) PyBytes_AS_STRING(c)[0]; + } +#if PY_MAJOR_VERSION < 3 + } else if (PyUnicode_Check(c)) { + return (long)__Pyx_PyUnicode_AsPy_UCS4(c); +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + } else if (PyByteArray_Check(c)) { + size = PyByteArray_GET_SIZE(c); + if (likely(size == 1)) { + return (unsigned char) PyByteArray_AS_STRING(c)[0]; + } +#endif + } else { + PyErr_Format(PyExc_TypeError, + "ord() expected string of length 1, but %.200s found", Py_TYPE(c)->tp_name); + return (long)(Py_UCS4)-1; + } + PyErr_Format(PyExc_TypeError, + "ord() expected a character, but string of length %zd found", size); + return (long)(Py_UCS4)-1; +} + +/* GetAttr */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { +#if CYTHON_USE_TYPE_SLOTS +#if PY_MAJOR_VERSION >= 3 + if (likely(PyUnicode_Check(n))) +#else + if (likely(PyString_Check(n))) +#endif + return __Pyx_PyObject_GetAttrStr(o, n); +#endif + return PyObject_GetAttr(o, n); +} + +/* GetAttr3 */ +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(d); + return d; +} +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { + PyObject *r = __Pyx_GetAttr(o, n); + return (likely(r)) ? r : __Pyx_GetAttr3Default(d); +} + +/* PyObjectCallNoArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, NULL, 0); + } +#endif +#ifdef __Pyx_CyFunction_USED + if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) +#else + if (likely(PyCFunction_Check(func))) +#endif + { + if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { + return __Pyx_PyObject_CallMethO(func, NULL); + } + } + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); +} +#endif + +/* CIntToPyUnicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_char(char value, Py_ssize_t width, char padding_char, char format_char) { + char digits[sizeof(char)*3+2]; + char *dpos, *end = digits + sizeof(char)*3+2; + const char *hex_digits = DIGITS_HEX; + Py_ssize_t length, ulength; + int prepend_sign, last_one_off; + char remaining; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const char neg_one = (char) -1, const_zero = (char) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (format_char == 'X') { + hex_digits += 16; + format_char = 'x'; + } + remaining = value; + last_one_off = 0; + dpos = end; + do { + int digit_pos; + switch (format_char) { + case 'o': + digit_pos = abs((int)(remaining % (8*8))); + remaining = (char) (remaining / (8*8)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); + last_one_off = (digit_pos < 8); + break; + case 'd': + digit_pos = abs((int)(remaining % (10*10))); + remaining = (char) (remaining / (10*10)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); + last_one_off = (digit_pos < 10); + break; + case 'x': + *(--dpos) = hex_digits[abs((int)(remaining % 16))]; + remaining = (char) (remaining / 16); + break; + default: + assert(0); + break; + } + } while (unlikely(remaining != 0)); + if (last_one_off) { + assert(*dpos == '0'); + dpos++; + } + length = end - dpos; + ulength = length; + prepend_sign = 0; + if (!is_unsigned && value <= neg_one) { + if (padding_char == ' ' || width <= length + 1) { + *(--dpos) = '-'; + ++length; + } else { + prepend_sign = 1; + } + ++ulength; + } + if (width > ulength) { + ulength = width; + } + if (ulength == 1) { + return PyUnicode_FromOrdinal(*dpos); + } + return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); +} + +/* CIntToPyUnicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_size_t(size_t value, Py_ssize_t width, char padding_char, char format_char) { + char digits[sizeof(size_t)*3+2]; + char *dpos, *end = digits + sizeof(size_t)*3+2; + const char *hex_digits = DIGITS_HEX; + Py_ssize_t length, ulength; + int prepend_sign, last_one_off; + size_t remaining; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const size_t neg_one = (size_t) -1, const_zero = (size_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (format_char == 'X') { + hex_digits += 16; + format_char = 'x'; + } + remaining = value; + last_one_off = 0; + dpos = end; + do { + int digit_pos; + switch (format_char) { + case 'o': + digit_pos = abs((int)(remaining % (8*8))); + remaining = (size_t) (remaining / (8*8)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); + last_one_off = (digit_pos < 8); + break; + case 'd': + digit_pos = abs((int)(remaining % (10*10))); + remaining = (size_t) (remaining / (10*10)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); + last_one_off = (digit_pos < 10); + break; + case 'x': + *(--dpos) = hex_digits[abs((int)(remaining % 16))]; + remaining = (size_t) (remaining / 16); + break; + default: + assert(0); + break; + } + } while (unlikely(remaining != 0)); + if (last_one_off) { + assert(*dpos == '0'); + dpos++; + } + length = end - dpos; + ulength = length; + prepend_sign = 0; + if (!is_unsigned && value <= neg_one) { + if (padding_char == ' ' || width <= length + 1) { + *(--dpos) = '-'; + ++length; + } else { + prepend_sign = 1; + } + ++ulength; + } + if (width > ulength) { + ulength = width; + } + if (ulength == 1) { + return PyUnicode_FromOrdinal(*dpos); + } + return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* PyObjectSetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_setattro)) + return tp->tp_setattro(obj, attr_name, value); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_setattr)) + return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value); +#endif + return PyObject_SetAttr(obj, attr_name, value); +} +#endif + +/* UnpackUnboundCMethod */ +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + target->method = method; +#if CYTHON_COMPILING_IN_CPYTHON + #if PY_MAJOR_VERSION >= 3 + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + #endif + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } +#endif + return 0; +} + +/* CallUnboundCMethod1 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg) { + if (likely(cfunc->func)) { + int flag = cfunc->flag; + if (flag == METH_O) { + return (*(cfunc->func))(self, arg); + } else if (PY_VERSION_HEX >= 0x030600B1 && flag == METH_FASTCALL) { + if (PY_VERSION_HEX >= 0x030700A0) { + return (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)cfunc->func)(self, &arg, 1); + } else { + return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); + } + } else if (PY_VERSION_HEX >= 0x030700A0 && flag == (METH_FASTCALL | METH_KEYWORDS)) { + return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); + } + } + return __Pyx__CallUnboundCMethod1(cfunc, self, arg); +} +#endif +static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg){ + PyObject *args, *result = NULL; + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + args = PyTuple_New(1); + if (unlikely(!args)) goto bad; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + if (cfunc->flag & METH_KEYWORDS) + result = (*(PyCFunctionWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, NULL); + else + result = (*cfunc->func)(self, args); + } else { + args = PyTuple_New(2); + if (unlikely(!args)) goto bad; + Py_INCREF(self); + PyTuple_SET_ITEM(args, 0, self); + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 1, arg); + result = __Pyx_PyObject_Call(cfunc->method, args, NULL); + } +#else + args = PyTuple_Pack(2, self, arg); + if (unlikely(!args)) goto bad; + result = __Pyx_PyObject_Call(cfunc->method, args, NULL); +#endif +bad: + Py_XDECREF(args); + return result; +} + +/* PyObjectFormat */ +#if CYTHON_USE_UNICODE_WRITER +static PyObject* __Pyx_PyObject_Format(PyObject* obj, PyObject* format_spec) { + int ret; + _PyUnicodeWriter writer; + if (likely(PyFloat_CheckExact(obj))) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x03040000 + _PyUnicodeWriter_Init(&writer, 0); +#else + _PyUnicodeWriter_Init(&writer); +#endif + ret = _PyFloat_FormatAdvancedWriter( + &writer, + obj, + format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); + } else if (likely(PyLong_CheckExact(obj))) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x03040000 + _PyUnicodeWriter_Init(&writer, 0); +#else + _PyUnicodeWriter_Init(&writer); +#endif + ret = _PyLong_FormatAdvancedWriter( + &writer, + obj, + format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); + } else { + return PyObject_Format(obj, format_spec); + } + if (unlikely(ret == -1)) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + return _PyUnicodeWriter_Finish(&writer); +} +#endif + +/* WriteUnraisableException */ +static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, + CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, + int full_traceback, CYTHON_UNUSED int nogil) { + PyObject *old_exc, *old_val, *old_tb; + PyObject *ctx; + __Pyx_PyThreadState_declare +#ifdef WITH_THREAD + PyGILState_STATE state; + if (nogil) + state = PyGILState_Ensure(); +#ifdef _MSC_VER + else state = (PyGILState_STATE)-1; +#endif +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); + if (full_traceback) { + Py_XINCREF(old_exc); + Py_XINCREF(old_val); + Py_XINCREF(old_tb); + __Pyx_ErrRestore(old_exc, old_val, old_tb); + PyErr_PrintEx(1); + } + #if PY_MAJOR_VERSION < 3 + ctx = PyString_FromString(name); + #else + ctx = PyUnicode_FromString(name); + #endif + __Pyx_ErrRestore(old_exc, old_val, old_tb); + if (!ctx) { + PyErr_WriteUnraisable(Py_None); + } else { + PyErr_WriteUnraisable(ctx); + Py_DECREF(ctx); + } +#ifdef WITH_THREAD + if (nogil) + PyGILState_Release(state); +#endif +} + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); + return 0; +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { +#if CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* exc_type = tstate->curexc_type; + if (unlikely(exc_type)) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) { + PyObject *exc_value, *exc_tb; + exc_value = tstate->curexc_value; + exc_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + Py_DECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + return 0; + } else { + return -1; + } + } + return 0; +#else + if (unlikely(PyErr_Occurred())) { + if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { + PyErr_Clear(); + return 0; + } else { + return -1; + } + } + return 0; +#endif +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (descr != NULL) { + *method = descr; + return 0; + } + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(name)); +#endif + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod0 */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } else { + return __Pyx_IterFinish(); + } + return 0; +} + +/* RaiseNoneIterError */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* UnpackTupleError */ +static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { + if (t == Py_None) { + __Pyx_RaiseNoneNotIterableError(); + } else if (PyTuple_GET_SIZE(t) < index) { + __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t)); + } else { + __Pyx_RaiseTooManyValuesError(index); + } +} + +/* UnpackTuple2 */ +static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( + PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int decref_tuple) { + PyObject *value1 = NULL, *value2 = NULL; +#if CYTHON_COMPILING_IN_PYPY + value1 = PySequence_ITEM(tuple, 0); if (unlikely(!value1)) goto bad; + value2 = PySequence_ITEM(tuple, 1); if (unlikely(!value2)) goto bad; +#else + value1 = PyTuple_GET_ITEM(tuple, 0); Py_INCREF(value1); + value2 = PyTuple_GET_ITEM(tuple, 1); Py_INCREF(value2); +#endif + if (decref_tuple) { + Py_DECREF(tuple); + } + *pvalue1 = value1; + *pvalue2 = value2; + return 0; +#if CYTHON_COMPILING_IN_PYPY +bad: + Py_XDECREF(value1); + Py_XDECREF(value2); + if (decref_tuple) { Py_XDECREF(tuple); } + return -1; +#endif +} +static int __Pyx_unpack_tuple2_generic(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, + int has_known_size, int decref_tuple) { + Py_ssize_t index; + PyObject *value1 = NULL, *value2 = NULL, *iter = NULL; + iternextfunc iternext; + iter = PyObject_GetIter(tuple); + if (unlikely(!iter)) goto bad; + if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; } + iternext = Py_TYPE(iter)->tp_iternext; + value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; } + value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; } + if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad; + Py_DECREF(iter); + *pvalue1 = value1; + *pvalue2 = value2; + return 0; +unpacking_failed: + if (!has_known_size && __Pyx_IterFinish() == 0) + __Pyx_RaiseNeedMoreValuesError(index); +bad: + Py_XDECREF(iter); + Py_XDECREF(value1); + Py_XDECREF(value2); + if (decref_tuple) { Py_XDECREF(tuple); } + return -1; +} + +/* dict_iter */ +static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name, + Py_ssize_t* p_orig_length, int* p_source_is_dict) { + is_dict = is_dict || likely(PyDict_CheckExact(iterable)); + *p_source_is_dict = is_dict; + if (is_dict) { +#if !CYTHON_COMPILING_IN_PYPY + *p_orig_length = PyDict_Size(iterable); + Py_INCREF(iterable); + return iterable; +#elif PY_MAJOR_VERSION >= 3 + static PyObject *py_items = NULL, *py_keys = NULL, *py_values = NULL; + PyObject **pp = NULL; + if (method_name) { + const char *name = PyUnicode_AsUTF8(method_name); + if (strcmp(name, "iteritems") == 0) pp = &py_items; + else if (strcmp(name, "iterkeys") == 0) pp = &py_keys; + else if (strcmp(name, "itervalues") == 0) pp = &py_values; + if (pp) { + if (!*pp) { + *pp = PyUnicode_FromString(name + 4); + if (!*pp) + return NULL; + } + method_name = *pp; + } + } +#endif + } + *p_orig_length = 0; + if (method_name) { + PyObject* iter; + iterable = __Pyx_PyObject_CallMethod0(iterable, method_name); + if (!iterable) + return NULL; +#if !CYTHON_COMPILING_IN_PYPY + if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable)) + return iterable; +#endif + iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + return iter; + } + return PyObject_GetIter(iterable); +} +static CYTHON_INLINE int __Pyx_dict_iter_next( + PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos, + PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) { + PyObject* next_item; +#if !CYTHON_COMPILING_IN_PYPY + if (source_is_dict) { + PyObject *key, *value; + if (unlikely(orig_length != PyDict_Size(iter_obj))) { + PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); + return -1; + } + if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) { + return 0; + } + if (pitem) { + PyObject* tuple = PyTuple_New(2); + if (unlikely(!tuple)) { + return -1; + } + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(tuple, 0, key); + PyTuple_SET_ITEM(tuple, 1, value); + *pitem = tuple; + } else { + if (pkey) { + Py_INCREF(key); + *pkey = key; + } + if (pvalue) { + Py_INCREF(value); + *pvalue = value; + } + } + return 1; + } else if (PyTuple_CheckExact(iter_obj)) { + Py_ssize_t pos = *ppos; + if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0; + *ppos = pos + 1; + next_item = PyTuple_GET_ITEM(iter_obj, pos); + Py_INCREF(next_item); + } else if (PyList_CheckExact(iter_obj)) { + Py_ssize_t pos = *ppos; + if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0; + *ppos = pos + 1; + next_item = PyList_GET_ITEM(iter_obj, pos); + Py_INCREF(next_item); + } else +#endif + { + next_item = PyIter_Next(iter_obj); + if (unlikely(!next_item)) { + return __Pyx_IterFinish(); + } + } + if (pitem) { + *pitem = next_item; + } else if (pkey && pvalue) { + if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1)) + return -1; + } else if (pkey) { + *pkey = next_item; + } else { + *pvalue = next_item; + } + return 1; +} + +/* CIntToPyUnicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char) { + char digits[sizeof(Py_ssize_t)*3+2]; + char *dpos, *end = digits + sizeof(Py_ssize_t)*3+2; + const char *hex_digits = DIGITS_HEX; + Py_ssize_t length, ulength; + int prepend_sign, last_one_off; + Py_ssize_t remaining; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const Py_ssize_t neg_one = (Py_ssize_t) -1, const_zero = (Py_ssize_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (format_char == 'X') { + hex_digits += 16; + format_char = 'x'; + } + remaining = value; + last_one_off = 0; + dpos = end; + do { + int digit_pos; + switch (format_char) { + case 'o': + digit_pos = abs((int)(remaining % (8*8))); + remaining = (Py_ssize_t) (remaining / (8*8)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); + last_one_off = (digit_pos < 8); + break; + case 'd': + digit_pos = abs((int)(remaining % (10*10))); + remaining = (Py_ssize_t) (remaining / (10*10)); + dpos -= 2; + memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); + last_one_off = (digit_pos < 10); + break; + case 'x': + *(--dpos) = hex_digits[abs((int)(remaining % 16))]; + remaining = (Py_ssize_t) (remaining / 16); + break; + default: + assert(0); + break; + } + } while (unlikely(remaining != 0)); + if (last_one_off) { + assert(*dpos == '0'); + dpos++; + } + length = end - dpos; + ulength = length; + prepend_sign = 0; + if (!is_unsigned && value <= neg_one) { + if (padding_char == ' ' || width <= length + 1) { + *(--dpos) = '-'; + ++length; + } else { + prepend_sign = 1; + } + ++ulength; + } + if (width > ulength) { + ulength = width; + } + if (ulength == 1) { + return PyUnicode_FromOrdinal(*dpos); + } + return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, attr_name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(attr_name)); +#endif + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* PyObject_GenericGetAttr */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { + if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { + return PyObject_GenericGetAttr(obj, attr_name); + } + return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +} + +/* SetupReduce */ +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { + int ret; + PyObject *name_attr; + name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name_2); + if (likely(name_attr)) { + ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); + } else { + ret = -1; + } + if (unlikely(ret < 0)) { + PyErr_Clear(); + ret = 0; + } + Py_XDECREF(name_attr); + return ret; +} +static int __Pyx_setup_reduce(PyObject* type_obj) { + int ret = 0; + PyObject *object_reduce = NULL; + PyObject *object_getstate = NULL; + PyObject *object_reduce_ex = NULL; + PyObject *reduce = NULL; + PyObject *reduce_ex = NULL; + PyObject *reduce_cython = NULL; + PyObject *setstate = NULL; + PyObject *setstate_cython = NULL; + PyObject *getstate = NULL; +#if CYTHON_USE_PYTYPE_LOOKUP + getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); +#else + getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); + if (!getstate && PyErr_Occurred()) { + goto __PYX_BAD; + } +#endif + if (getstate) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); +#else + object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); + if (!object_getstate && PyErr_Occurred()) { + goto __PYX_BAD; + } +#endif + if (object_getstate != getstate) { + goto __PYX_GOOD; + } + } +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#else + object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#endif + reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; + if (reduce_ex == object_reduce_ex) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#else + object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#endif + reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; + if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { + reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); + if (likely(reduce_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (reduce == object_reduce || PyErr_Occurred()) { + goto __PYX_BAD; + } + setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); + if (!setstate) PyErr_Clear(); + if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { + setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); + if (likely(setstate_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (!setstate || PyErr_Occurred()) { + goto __PYX_BAD; + } + } + PyType_Modified((PyTypeObject*)type_obj); + } + } + goto __PYX_GOOD; +__PYX_BAD: + if (!PyErr_Occurred()) + PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); + ret = -1; +__PYX_GOOD: +#if !CYTHON_USE_PYTYPE_LOOKUP + Py_XDECREF(object_reduce); + Py_XDECREF(object_reduce_ex); + Py_XDECREF(object_getstate); + Py_XDECREF(getstate); +#endif + Py_XDECREF(reduce); + Py_XDECREF(reduce_ex); + Py_XDECREF(reduce_cython); + Py_XDECREF(setstate); + Py_XDECREF(setstate_cython); + return ret; +} + +/* SetVTable */ +static int __Pyx_SetVtable(PyObject *dict, void *vtable) { +#if PY_VERSION_HEX >= 0x02070000 + PyObject *ob = PyCapsule_New(vtable, 0, 0); +#else + PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); +#endif + if (!ob) + goto bad; + if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) + goto bad; + Py_DECREF(ob); + return 0; +bad: + Py_XDECREF(ob); + return -1; +} + +/* TypeImport */ +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, + size_t size, enum __Pyx_ImportType_CheckSize check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if ((size_t)basicsize < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* CalculateMetaclass */ +static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) { + Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases); + for (i=0; i < nbases; i++) { + PyTypeObject *tmptype; + PyObject *tmp = PyTuple_GET_ITEM(bases, i); + tmptype = Py_TYPE(tmp); +#if PY_MAJOR_VERSION < 3 + if (tmptype == &PyClass_Type) + continue; +#endif + if (!metaclass) { + metaclass = tmptype; + continue; + } + if (PyType_IsSubtype(metaclass, tmptype)) + continue; + if (PyType_IsSubtype(tmptype, metaclass)) { + metaclass = tmptype; + continue; + } + PyErr_SetString(PyExc_TypeError, + "metaclass conflict: " + "the metaclass of a derived class " + "must be a (non-strict) subclass " + "of the metaclasses of all its bases"); + return NULL; + } + if (!metaclass) { +#if PY_MAJOR_VERSION < 3 + metaclass = &PyClass_Type; +#else + metaclass = &PyType_Type; +#endif + } + Py_INCREF((PyObject*) metaclass); + return (PyObject*) metaclass; +} + +/* FetchCommonType */ +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { + PyObject* fake_module; + PyTypeObject* cached_type = NULL; + fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI); + if (!fake_module) return NULL; + Py_INCREF(fake_module); + cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name); + if (cached_type) { + if (!PyType_Check((PyObject*)cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", + type->tp_name); + goto bad; + } + if (cached_type->tp_basicsize != type->tp_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + type->tp_name); + goto bad; + } + } else { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; + } +done: + Py_DECREF(fake_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} + +/* CythonFunctionShared */ +#include +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure) +{ + if (unlikely(op->func_doc == NULL)) { + if (op->func.m_ml->ml_doc) { +#if PY_MAJOR_VERSION >= 3 + op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc); +#else + op->func_doc = PyString_FromString(op->func.m_ml->ml_doc); +#endif + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) +{ + PyObject *tmp = op->func_doc; + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + op->func_doc = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) +{ + if (unlikely(op->func_name == NULL)) { +#if PY_MAJOR_VERSION >= 3 + op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name); +#else + op->func_name = PyString_InternFromString(op->func.m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) +{ + PyObject *tmp; +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + tmp = op->func_name; + Py_INCREF(value); + op->func_name = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) +{ + Py_INCREF(op->func_qualname); + return op->func_qualname; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) +{ + PyObject *tmp; +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + tmp = op->func_qualname; + Py_INCREF(value); + op->func_qualname = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure) +{ + PyObject *self; + self = m->func_closure; + if (self == NULL) + self = Py_None; + Py_INCREF(self); + return self; +} +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) +{ + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +static int +__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) +{ + PyObject *tmp; + if (unlikely(value == NULL)) { + PyErr_SetString(PyExc_TypeError, + "function's dictionary may not be deleted"); + return -1; + } + if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "setting function's dictionary to a non-dict"); + return -1; + } + tmp = op->func_dict; + Py_INCREF(value); + op->func_dict = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) +{ + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) +{ + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) { + PyObject* tmp; + if (!value) { + value = Py_None; + } else if (value != Py_None && !PyTuple_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + Py_INCREF(value); + tmp = op->defaults_tuple; + op->defaults_tuple = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) { + PyObject* result = op->defaults_tuple; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) { + PyObject* tmp; + if (!value) { + value = Py_None; + } else if (value != Py_None && !PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + Py_INCREF(value); + tmp = op->defaults_kwdict; + op->defaults_kwdict = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) { + PyObject* result = op->defaults_kwdict; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) { + PyObject* tmp; + if (!value || value == Py_None) { + value = NULL; + } else if (!PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + tmp = op->func_annotations; + op->func_annotations = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) { + PyObject* result = op->func_annotations; + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, + {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0}, + {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, + {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { + {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), PY_WRITE_RESTRICTED, 0}, + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args) +{ +#if PY_MAJOR_VERSION >= 3 + Py_INCREF(m->func_qualname); + return m->func_qualname; +#else + return PyString_FromString(m->func.m_ml->ml_name); +#endif +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if PY_VERSION_HEX < 0x030500A0 +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + if (unlikely(op == NULL)) + return NULL; + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; + op->func.m_ml = ml; + op->func.m_self = (PyObject *) op; + Py_XINCREF(closure); + op->func_closure = closure; + Py_XINCREF(module); + op->func.m_module = module; + op->func_dict = NULL; + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; + op->func_classobj = NULL; + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults_pyobjects = 0; + op->defaults_size = 0; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); + Py_CLEAR(m->func.m_module); + Py_CLEAR(m->func_dict); + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); + Py_CLEAR(m->func_classobj); + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_XDECREF(pydefaults[i]); + PyObject_Free(m->defaults); + m->defaults = NULL; + } + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + PyObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + Py_VISIT(m->func_closure); + Py_VISIT(m->func.m_module); + Py_VISIT(m->func_dict); + Py_VISIT(m->func_name); + Py_VISIT(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + Py_VISIT(m->func_code); + Py_VISIT(m->func_classobj); + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + if (m->defaults) { + PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); + int i; + for (i = 0; i < m->defaults_pyobjects; i++) + Py_VISIT(pydefaults[i]); + } + return 0; +} +static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ +#if PY_MAJOR_VERSION < 3 + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) { + Py_INCREF(func); + return func; + } + if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) { + if (type == NULL) + type = (PyObject *)(Py_TYPE(obj)); + return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type))); + } + if (obj == Py_None) + obj = NULL; +#endif + return __Pyx_PyMethod_New(func, obj, type); +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("", + op->func_qualname, (void *)op); +#else + return PyString_FromFormat("", + PyString_AsString(op->func_qualname), (void *)op); +#endif +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + Py_ssize_t size; + switch (f->m_ml->ml_flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { + size = PyTuple_GET_SIZE(arg); + if (likely(size == 0)) + return (*meth)(self, NULL); + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { + size = PyTuple_GET_SIZE(arg); + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", + f->m_ml->ml_name, size); + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags in " + "__Pyx_CyFunction_Call. METH_OLDARGS is no " + "longer supported!"); + return NULL; + } + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + return __Pyx_CyFunction_CallMethod(func, ((PyCFunctionObject*)func)->m_self, arg, kw); +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; + argc = PyTuple_GET_SIZE(args); + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +static PyTypeObject __pyx_CyFunctionType_type = { + PyVarObject_HEAD_INIT(0, 0) + "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, + (destructor) __Pyx_CyFunction_dealloc, + 0, + 0, + 0, +#if PY_MAJOR_VERSION < 3 + 0, +#else + 0, +#endif + (reprfunc) __Pyx_CyFunction_repr, + 0, + 0, + 0, + 0, + __Pyx_CyFunction_CallAsMethod, + 0, + 0, + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + 0, + (traverseproc) __Pyx_CyFunction_traverse, + (inquiry) __Pyx_CyFunction_clear, + 0, +#if PY_VERSION_HEX < 0x030500A0 + offsetof(__pyx_CyFunctionObject, func_weakreflist), +#else + offsetof(PyCFunctionObject, m_weakreflist), +#endif + 0, + 0, + __pyx_CyFunction_methods, + __pyx_CyFunction_members, + __pyx_CyFunction_getsets, + 0, + 0, + __Pyx_CyFunction_descr_get, + 0, + offsetof(__pyx_CyFunctionObject, func_dict), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 + 0, +#endif +}; +static int __pyx_CyFunction_init(void) { + __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); + if (unlikely(__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_Malloc(size); + if (unlikely(!m->defaults)) + return PyErr_NoMemory(); + memset(m->defaults, 0, size); + m->defaults_pyobjects = pyobjects; + m->defaults_size = size; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* Py3ClassCreate */ +static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, + PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) { + PyObject *ns; + if (metaclass) { + PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, __pyx_n_s_prepare); + if (prep) { + PyObject *pargs = PyTuple_Pack(2, name, bases); + if (unlikely(!pargs)) { + Py_DECREF(prep); + return NULL; + } + ns = PyObject_Call(prep, pargs, mkw); + Py_DECREF(prep); + Py_DECREF(pargs); + } else { + if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + PyErr_Clear(); + ns = PyDict_New(); + } + } else { + ns = PyDict_New(); + } + if (unlikely(!ns)) + return NULL; + if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad; + if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad; + if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad; + return ns; +bad: + Py_DECREF(ns); + return NULL; +} +static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, + PyObject *dict, PyObject *mkw, + int calculate_metaclass, int allow_py2_metaclass) { + PyObject *result, *margs; + PyObject *owned_metaclass = NULL; + if (allow_py2_metaclass) { + owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass); + if (owned_metaclass) { + metaclass = owned_metaclass; + } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { + PyErr_Clear(); + } else { + return NULL; + } + } + if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) { + metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); + Py_XDECREF(owned_metaclass); + if (unlikely(!metaclass)) + return NULL; + owned_metaclass = metaclass; + } + margs = PyTuple_Pack(3, name, bases, dict); + if (unlikely(!margs)) { + result = NULL; + } else { + result = PyObject_Call(metaclass, margs, mkw); + Py_DECREF(margs); + } + Py_XDECREF(owned_metaclass); + return result; +} + +/* CyFunctionClassCell */ +static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj) { + Py_ssize_t i, count = PyList_GET_SIZE(cyfunctions); + for (i = 0; i < count; i++) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + PyList_GET_ITEM(cyfunctions, i); +#else + PySequence_ITEM(cyfunctions, i); + if (unlikely(!m)) + return -1; +#endif + Py_INCREF(classobj); + m->func_classobj = classobj; +#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF((PyObject*)m); +#endif + } + return 0; +} + +/* ClassMethod */ +static PyObject* __Pyx_Method_ClassMethod(PyObject *method) { +#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM <= 0x05080000 + if (PyObject_TypeCheck(method, &PyWrapperDescr_Type)) { + return PyClassMethod_New(method); + } +#else +#if CYTHON_COMPILING_IN_PYSTON || CYTHON_COMPILING_IN_PYPY + if (PyMethodDescr_Check(method)) +#else + #if PY_MAJOR_VERSION == 2 + static PyTypeObject *methoddescr_type = NULL; + if (methoddescr_type == NULL) { + PyObject *meth = PyObject_GetAttrString((PyObject*)&PyList_Type, "append"); + if (!meth) return NULL; + methoddescr_type = Py_TYPE(meth); + Py_DECREF(meth); + } + #else + PyTypeObject *methoddescr_type = &PyMethodDescr_Type; + #endif + if (__Pyx_TypeCheck(method, methoddescr_type)) +#endif + { + PyMethodDescrObject *descr = (PyMethodDescrObject *)method; + #if PY_VERSION_HEX < 0x03020000 + PyTypeObject *d_type = descr->d_type; + #else + PyTypeObject *d_type = descr->d_common.d_type; + #endif + return PyDescr_NewClassMethod(d_type, descr->d_method); + } +#endif + else if (PyMethod_Check(method)) { + return PyClassMethod_New(PyMethod_GET_FUNCTION(method)); + } + else { + return PyClassMethod_New(method); + } +} + +/* GetNameInClass */ +static PyObject *__Pyx_GetGlobalNameAfterAttributeLookup(PyObject *name) { + PyObject *result; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + __Pyx_PyErr_Clear(); + __Pyx_GetModuleGlobalNameUncached(result, name); + return result; +} +static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) { + PyObject *result; + result = __Pyx_PyObject_GetAttrStr(nmspace, name); + if (!result) { + result = __Pyx_GetGlobalNameAfterAttributeLookup(name); + } + return result; +} + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + #if PY_MAJOR_VERSION < 3 + PyObject *py_srcfile = NULL; + py_srcfile = PyString_FromString(filename); + if (!py_srcfile) goto bad; + #endif + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + if (!py_funcname) goto bad; + #endif + } + #if PY_MAJOR_VERSION < 3 + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + #else + py_code = PyCode_NewEmpty(filename, funcname, py_line); + #endif + Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline + return py_code; +bad: + Py_XDECREF(py_funcname); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_srcfile); + #endif + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__line_sender_error_code(enum line_sender_error_code value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const enum line_sender_error_code neg_one = (enum line_sender_error_code) -1, const_zero = (enum line_sender_error_code) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(enum line_sender_error_code) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(enum line_sender_error_code) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum line_sender_error_code) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(enum line_sender_error_code) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum line_sender_error_code) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(enum line_sender_error_code), + little, !is_unsigned); + } +} + +/* CIntFromPy */ +static CYTHON_INLINE uint64_t __Pyx_PyInt_As_uint64_t(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const uint64_t neg_one = (uint64_t) -1, const_zero = (uint64_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(uint64_t) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(uint64_t, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (uint64_t) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (uint64_t) 0; + case 1: __PYX_VERIFY_RETURN_INT(uint64_t, digit, digits[0]) + case 2: + if (8 * sizeof(uint64_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) >= 2 * PyLong_SHIFT) { + return (uint64_t) (((((uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(uint64_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) >= 3 * PyLong_SHIFT) { + return (uint64_t) (((((((uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(uint64_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) >= 4 * PyLong_SHIFT) { + return (uint64_t) (((((((((uint64_t)digits[3]) << PyLong_SHIFT) | (uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (uint64_t) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(uint64_t) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(uint64_t, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint64_t) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(uint64_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (uint64_t) 0; + case -1: __PYX_VERIFY_RETURN_INT(uint64_t, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(uint64_t, digit, +digits[0]) + case -2: + if (8 * sizeof(uint64_t) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) - 1 > 2 * PyLong_SHIFT) { + return (uint64_t) (((uint64_t)-1)*(((((uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(uint64_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) - 1 > 2 * PyLong_SHIFT) { + return (uint64_t) ((((((uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(uint64_t) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) - 1 > 3 * PyLong_SHIFT) { + return (uint64_t) (((uint64_t)-1)*(((((((uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(uint64_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) - 1 > 3 * PyLong_SHIFT) { + return (uint64_t) ((((((((uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(uint64_t) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) - 1 > 4 * PyLong_SHIFT) { + return (uint64_t) (((uint64_t)-1)*(((((((((uint64_t)digits[3]) << PyLong_SHIFT) | (uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(uint64_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(uint64_t) - 1 > 4 * PyLong_SHIFT) { + return (uint64_t) ((((((((((uint64_t)digits[3]) << PyLong_SHIFT) | (uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); + } + } + break; + } +#endif + if (sizeof(uint64_t) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(uint64_t, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint64_t) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(uint64_t, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + uint64_t val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (uint64_t) -1; + } + } else { + uint64_t val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (uint64_t) -1; + val = __Pyx_PyInt_As_uint64_t(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to uint64_t"); + return (uint64_t) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to uint64_t"); + return (uint64_t) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const size_t neg_one = (size_t) -1, const_zero = (size_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(size_t) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (size_t) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (size_t) 0; + case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, digits[0]) + case 2: + if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) >= 2 * PyLong_SHIFT) { + return (size_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) >= 3 * PyLong_SHIFT) { + return (size_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) >= 4 * PyLong_SHIFT) { + return (size_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (size_t) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(size_t) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(size_t) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (size_t) 0; + case -1: __PYX_VERIFY_RETURN_INT(size_t, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, +digits[0]) + case -2: + if (8 * sizeof(size_t) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { + return (size_t) (((size_t)-1)*(((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { + return (size_t) ((((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { + return (size_t) (((size_t)-1)*(((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { + return (size_t) ((((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { + return (size_t) (((size_t)-1)*(((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { + return (size_t) ((((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + } +#endif + if (sizeof(size_t) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(size_t) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + size_t val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (size_t) -1; + } + } else { + size_t val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (size_t) -1; + val = __Pyx_PyInt_As_size_t(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to size_t"); + return (size_t) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to size_t"); + return (size_t) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +/* CIntFromPy */ +static CYTHON_INLINE int64_t __Pyx_PyInt_As_int64_t(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int64_t) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int64_t, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int64_t) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int64_t) 0; + case 1: __PYX_VERIFY_RETURN_INT(int64_t, digit, digits[0]) + case 2: + if (8 * sizeof(int64_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) >= 2 * PyLong_SHIFT) { + return (int64_t) (((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int64_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) >= 3 * PyLong_SHIFT) { + return (int64_t) (((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int64_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) >= 4 * PyLong_SHIFT) { + return (int64_t) (((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int64_t) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int64_t) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int64_t, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int64_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int64_t) 0; + case -1: __PYX_VERIFY_RETURN_INT(int64_t, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int64_t, digit, +digits[0]) + case -2: + if (8 * sizeof(int64_t) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) { + return (int64_t) (((int64_t)-1)*(((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int64_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) { + return (int64_t) ((((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) { + return (int64_t) (((int64_t)-1)*(((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int64_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) { + return (int64_t) ((((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) - 1 > 4 * PyLong_SHIFT) { + return (int64_t) (((int64_t)-1)*(((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int64_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int64_t) - 1 > 4 * PyLong_SHIFT) { + return (int64_t) ((((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int64_t) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int64_t, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int64_t, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int64_t val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int64_t) -1; + } + } else { + int64_t val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int64_t) -1; + val = __Pyx_PyInt_As_int64_t(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int64_t"); + return (int64_t) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int64_t"); + return (int64_t) -1; +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int64_t) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int64_t) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int64_t) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int64_t), + little, !is_unsigned); + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const uint32_t neg_one = (uint32_t) -1, const_zero = (uint32_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(uint32_t) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(uint32_t) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint32_t) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(uint32_t) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(uint32_t), + little, !is_unsigned); + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint64_t(uint64_t value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const uint64_t neg_one = (uint64_t) -1, const_zero = (uint64_t) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(uint64_t) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(uint64_t) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint64_t) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(uint64_t) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint64_t) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(uint64_t), + little, !is_unsigned); + } +} + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CheckBinaryVersion */ +static int __Pyx_check_binary_version(void) { + char ctversion[5]; + int same=1, i, found_dot; + const char* rt_from_call = Py_GetVersion(); + PyOS_snprintf(ctversion, 5, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + found_dot = 0; + for (i = 0; i < 4; i++) { + if (!ctversion[i]) { + same = (rt_from_call[i] < '0' || rt_from_call[i] > '9'); + break; + } + if (rt_from_call[i] != ctversion[i]) { + same = 0; + break; + } + } + if (!same) { + char rtversion[5] = {'\0'}; + char message[200]; + for (i=0; i<4; ++i) { + if (rt_from_call[i] == '.') { + if (found_dot) break; + found_dot = 1; + } else if (rt_from_call[i] < '0' || rt_from_call[i] > '9') { + break; + } + rtversion[i] = rt_from_call[i]; + } + PyOS_snprintf(message, sizeof(message), + "compiletime version %s of module '%.100s' " + "does not match runtime version %s", + ctversion, __Pyx_MODULE_NAME, rtversion); + return PyErr_WarnEx(NULL, message, 1); + } + return 0; +} + +/* InitStrings */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); +#if PY_MAJOR_VERSION < 3 + } else if (likely(PyInt_CheckExact(o))) { + return PyInt_AS_LONG(o); +#endif + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyInt_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/src/questdb/pandas_helpers.md b/src/questdb/pandas_helpers.md new file mode 100644 index 00000000..73efa5d3 --- /dev/null +++ b/src/questdb/pandas_helpers.md @@ -0,0 +1,104 @@ +# Pandas Integration High-level Overview + +## Goal + +We want to access data in a pandas dataframe from Cython efficiently. +To do this, we need to access its raw memory to traverse it efficiently. +The data held by a dataframe is organized in a columnar fashion. +Each column is a Series object in Python. +Each series object can be backed up by either a Numpy data-structure or +by an Arrow data-structure. + +## Accessing raw Numpy data +To access Numpy data we take the series, call its `.to_numpy()` method +and then access the numpy data as a `Py_buffer`. +* https://docs.python.org/3/c-api/buffer.html +* http://jakevdp.github.io/blog/2014/05/05/introduction-to-the-python-buffer-protocol/ + +## Accessing raw Arrow data +To access Arrow data we first need to unpack each chunk of data at the +Python level giving us `pyarrow` wrapper Array objects. +Each Arrow object in `pyarrow` has a `._export_to_c(..)` python method where we +can pass a Python ints with the addresses to a pre-allocated `ArrowArray` and +`ArrowSchema` C structures. +* https://arrow.apache.org/docs/python/integration/python_java.html + (Ignore the Java part, we just use the same approach for Python to C.) +* https://arrow.apache.org/docs/format/CDataInterface.html +* https://arrow.apache.org/docs/format/Columnar.html#format-columnar + +## Consolidating data access +Now that we've obtained all the pointers we can traverse through the data +without the aid of the Python interpreter (until we hit a Python string in a +Numpy array that is). + +The trouble is, though, that we're dealing with so many potential column types +numpy strides, arrow dictionaries and nullables that we risk having an +unmaintainable spaghetti mess of conditionals, special cases and downright +untestability. + +To tame this and maintain one's sanity we need to remember that we +don't need to support every type, data-structure et cetera that pandas, numpy +and arrow can throw at us: Instead we approach this by only accepting +one-dimensional arrays that support our basic ILP supported types _only_. + +We can also further simplify iteration via the introduction of a cursor: +a struct that is a mishmash of the simplified subsets of arrow and py buffers +that we we actually care about. + +## Cherry-picking `Py_buffer` and `ArrowArray` features + +First, off the bat, we can exclude supporting some of these structs' fields: + +### `Py_buffer` +_Always one single `Py_buffer` per column. Not chunked._ + +* `void *buf`: Points to the start of our data. **`[NEEDED]`** +* `PyObject *obj`: No need to access Py object again. **`[IGNORED]`** +* `int readonly`: We never write. **`[IGNORED]`** +* `Py_ssize_t len`: We already have the row-count. **`[IGNORED]`** +* `Py_ssize_t itemsize`: It's enough to know our stride. **`[IGNORED]`** +* `int ndim`: We only support 1-D data. **`[VALIDATED]`** +* `Py_ssize_t *shape`: We only support 1-D data. **`[IGNORED]`** +* `Py_ssize_t *strides`: We only need the first value **`[SIMPLIFIED]`** +* `Py_ssize_t *suboffsets`: Numpy shouldn't be using this. **`[VALIDATED]`** +* `void *internal`: Says on the tin. **`[IGNORED]`** + +### `ArrowArray` +_Multiple of these `ArrowArray` structs per column. Chunked._ + +* `int64_t length`: We need it for the length of the chunk. **`[NEEDED]`** +* `int64_t null_count`: Needed as if == 0, null col may be NULL. **`[NEEDED]`** +* `int64_t offset`: Needed to determine number of skipped rows. **`[NEEDED]`** +* `int64_t n_buffers`: A function of the type, not needed. **`[NEEDED]`** +* `int64_t n_children`: +* `const void** buffers`: Data, e.g. buffers[0] is validity bitvec. **`[NEEDED]`** +* `ArrowArray** children`: Needed only for strings where: **`[NEEDED]`** + * `buffers[0]` is nulls bitvec + * `buffers[1]` is int32 offsets buffer + * `children[0]` is ArrowArray of int8 + * See: https://arrow.apache.org/docs/format/Columnar.html#variable-size-list-layout +* `ArrowArray* dictionary`: Needed to support Pandas categories. **`[INITIALLY OUT OF SCOPE]`** + * Given the complexity of supporting this feature + (and it being less common in use) we instead validate that it's not set. + See: https://pandas.pydata.org/docs/reference/api/pandas.CategoricalDtype.html + +## Mapping Datatypes + +We can now start to remind ourselves of the destination data-types that we +actually need to support, and see how these map from source column data-types +in both of Numpy and Arrow. + +We need to extract: +* booleans +* 64-bit signed integers +* 64-bit floats +* UTF-8 string buffers +* Nanosecond-precision UTC unix epoch 64-bit signed int timestamps + +### Booleans + +**Numpy** + + + +TO BE CONTINUED .... \ No newline at end of file diff --git a/src/questdb/pandas_helpers.pxi b/src/questdb/pandas_helpers.pxi index ab06ae14..65b84f3a 100644 --- a/src/questdb/pandas_helpers.pxi +++ b/src/questdb/pandas_helpers.pxi @@ -1,106 +1,76 @@ +include "size_t_vec.pxi" +include "column_name_vec.pxi" +# See: pandas_helpers.md for technical overview. -cdef struct c_size_t_vec: - size_t capacity - size_t size - size_t* d - -ctypedef c_size_t_vec size_t_vec - -cdef size_t_vec size_t_vec_new(): - cdef size_t_vec vec - vec.capacity = 0 - vec.size = 0 - vec.d = NULL - return vec - -cdef void size_t_vec_free(size_t_vec* vec): - if vec.d: - free(vec.d) - vec.d = NULL - -cdef str size_t_vec_str(size_t_vec* vec): - return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) - -cdef void size_t_vec_push(size_t_vec* vec, size_t value): - if vec.capacity == 0: - vec.capacity = 8 - vec.d = malloc(vec.capacity * sizeof(size_t)) - if vec.d == NULL: - abort() - elif vec.size == vec.capacity: - vec.capacity = vec.capacity * 2 - vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - if not vec.d: - abort() - vec.d[vec.size] = value - vec.size += 1 - - -cdef struct c_column_name_vec: - size_t capacity - size_t size - line_sender_column_name* d - -ctypedef c_column_name_vec column_name_vec - -cdef column_name_vec column_name_vec_new(): - cdef column_name_vec vec - vec.capacity = 0 - vec.size = 0 - vec.d = NULL - return vec - -cdef void column_name_vec_free(column_name_vec* vec): - if vec.d: - free(vec.d) - vec.d = NULL - -cdef void column_name_vec_push( - column_name_vec* vec, line_sender_column_name value): - if vec.capacity == 0: - vec.capacity = 8 - vec.d = malloc( - vec.capacity * sizeof(line_sender_column_name)) - if vec.d == NULL: - abort() - elif vec.size == vec.capacity: - vec.capacity = vec.capacity * 2 - vec.d = realloc( - vec.d, - vec.capacity * sizeof(line_sender_column_name)) - if not vec.d: - abort() - vec.d[vec.size] = value - vec.size += 1 - - -cdef enum col_type_t: - COL_TYPE_INT = 0 - COL_TYPE_FLOAT = 1 - COL_TYPE_STRING = 2 - COL_TYPE_BOOL = 3 - COL_TYPE_DATE = 4 - COL_TYPE_TIME = 5 - COL_TYPE_DATETIME = 6 - COL_TYPE_BLOB = 7 - COL_TYPE_NULL = 8 - -# Inspired by a Py_buffer. -# See: https://docs.python.org/3/c-api/buffer.html -# This is simpler as we discard Python-specifics and it's one-dimensional only, -# i.e. `ndim` is always 1. -# If this stuff makes no sense to you: -# http://jakevdp.github.io/blog/2014/05/05/introduction-to-the-python-buffer-protocol/ -# and https://www.youtube.com/watch?v=10smLBD0kXg -cdef struct column_buf_t: - col_type_t dtype # internal enum value of supported pandas type. - void* d # start of the buffer (pointer to element 0) - ssize_t nbytes # size of the buffer in bytes - ssize_t count # number of elements in the buffer (aka shape[0]) - ssize_t itemsize # element size in bytes (!=nbytes/count due to strides) - ssize_t stride # stride in bytes between elements - # NB: We don't support suboffsets. +cdef struct dtype_t: + # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html + # ?highlight=dtype#numpy.dtype + # See: https://numpy.org/doc/stable/reference/c-api + # /types-and-structures.html#c.PyArray_Descr + int alignment + char kind + int itemsize + char byteorder + bint hasobject + + +cdef struct col_numpy_data_t: + dtype_t dtype + Py_buffer pybuf + + +cdef struct col_arrow_data_t: + ArrowSchema schema + size_t n_chunks + ArrowArray chunks + + +cdef enum col_access_tag_t: + numpy + arrow + + +cdef union col_access_t: + col_numpy_data_t numpy + col_arrow_data_t arrow + + +cdef struct col_cursor_t: + size_t chunk_index + size_t n_chunks + size_t offset # i.e. the element index (not byte offset) + size_t length # number of elements in current chunk + + # Expanded pointers to Numpy or Arrow buffers + + # https://arrow.apache.org/docs/format/Columnar.html#validity-bitmaps + # Always NULL for Numpy, optionally null for Arrow. + uint8_t* validity + + # Must cast to correct datatype + void* data + + # NULL for Numpy, may be set for Arrow strings. + uint8_t* utf8_buf + + +cdef enum col_line_sender_target_t: + table + symbol + column_bool + column_i64 + column_f64 + column_str + column_ts + at + + +cdef struct col_handle_t: + col_access_tag_t access_tag + col_access_t access + col_cursor_t cursor + col_line_sender_target_t target cdef object _PANDAS_NA = None @@ -394,15 +364,7 @@ cdef object _pandas_is_supported_datetime(object dtype): (not dtype.hasobject)) -cdef struct dtype_t: - # A ripoff of a subset of PyArray_Descr as we were able to extract from numpy.dtype. - # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html?highlight=dtype#numpy.dtype - # See: https://numpy.org/doc/stable/reference/c-api/types-and-structures.html#c.PyArray_Descr - int alignment - char kind - int itemsize - char byteorder - bint hasobject + cdef char _str_to_char(str field, str s) except 0: diff --git a/src/questdb/size_t_vec.pxi b/src/questdb/size_t_vec.pxi new file mode 100644 index 00000000..6a53a646 --- /dev/null +++ b/src/questdb/size_t_vec.pxi @@ -0,0 +1,35 @@ +cdef struct c_size_t_vec: + size_t capacity + size_t size + size_t* d + +ctypedef c_size_t_vec size_t_vec + +cdef size_t_vec size_t_vec_new(): + cdef size_t_vec vec + vec.capacity = 0 + vec.size = 0 + vec.d = NULL + return vec + +cdef void size_t_vec_free(size_t_vec* vec): + if vec.d: + free(vec.d) + vec.d = NULL + +cdef str size_t_vec_str(size_t_vec* vec): + return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) + +cdef void size_t_vec_push(size_t_vec* vec, size_t value): + if vec.capacity == 0: + vec.capacity = 8 + vec.d = malloc(vec.capacity * sizeof(size_t)) + if vec.d == NULL: + abort() + elif vec.size == vec.capacity: + vec.capacity = vec.capacity * 2 + vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) + if not vec.d: + abort() + vec.d[vec.size] = value + vec.size += 1 From 94378a0dc7645fdb2c9002fac0258fb67bf698d5 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 14 Nov 2022 13:08:00 +0000 Subject: [PATCH 040/147] Undid removal of ingress.c from gitignore. --- .gitignore | 1 + src/questdb/ingress.c | 29176 ---------------------------------------- 2 files changed, 1 insertion(+), 29176 deletions(-) delete mode 100644 src/questdb/ingress.c diff --git a/.gitignore b/.gitignore index ef5fd695..5043a003 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +src/questdb/ingress.c src/questdb/*.html rustup-init.exe diff --git a/src/questdb/ingress.c b/src/questdb/ingress.c deleted file mode 100644 index 2e8cf694..00000000 --- a/src/questdb/ingress.c +++ /dev/null @@ -1,29176 +0,0 @@ -/* Generated by Cython 0.29.30 */ - -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [], - "extra_link_args": [ - "-framework", - "Security" - ], - "extra_objects": [ - "/Users/adam/questdb/repos/py-questdb-client/c-questdb-client/questdb-rs-ffi/target/release/libquestdb_client.a", - "/Users/adam/questdb/repos/py-questdb-client/pystr-to-utf8/target/release/libpystr_to_utf8.a" - ], - "include_dirs": [ - "c-questdb-client/include", - "pystr-to-utf8/include" - ], - "language": "c", - "name": "questdb.ingress", - "sources": [ - "src/questdb/ingress.pyx" - ] - }, - "module_name": "questdb.ingress" -} -END: Cython Metadata */ - -#ifndef PY_SSIZE_T_CLEAN -#define PY_SSIZE_T_CLEAN -#endif /* PY_SSIZE_T_CLEAN */ -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_29_30" -#define CYTHON_HEX_VERSION 0x001D1EF0 -#define CYTHON_FUTURE_DIVISION 1 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_HEX >= 0x07030900) - #endif -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 - #undef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS 0 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 - #endif -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #if PY_VERSION_HEX >= 0x030B00A4 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #elif !defined(CYTHON_FAST_THREAD_STATE) - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL (PY_VERSION_HEX < 0x030A0000) - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif - #ifndef CYTHON_USE_DICT_VERSIONS - #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) - #endif - #if PY_VERSION_HEX >= 0x030B00A4 - #undef CYTHON_USE_EXC_INFO_STACK - #define CYTHON_USE_EXC_INFO_STACK 0 - #elif !defined(CYTHON_USE_EXC_INFO_STACK) - #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) - #endif - #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC - #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #if PY_MAJOR_VERSION < 3 - #include "longintrepr.h" - #endif - #undef SHIFT - #undef BASE - #undef MASK - #ifdef SIZEOF_VOID_P - enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; - #endif -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" - #define __Pyx_DefaultClassType PyType_Type -#if PY_VERSION_HEX >= 0x030B00A1 - static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int k, int l, int s, int f, - PyObject *code, PyObject *c, PyObject* n, PyObject *v, - PyObject *fv, PyObject *cell, PyObject* fn, - PyObject *name, int fline, PyObject *lnos) { - PyObject *kwds=NULL, *argcount=NULL, *posonlyargcount=NULL, *kwonlyargcount=NULL; - PyObject *nlocals=NULL, *stacksize=NULL, *flags=NULL, *replace=NULL, *call_result=NULL, *empty=NULL; - const char *fn_cstr=NULL; - const char *name_cstr=NULL; - PyCodeObject* co=NULL; - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - if (!(kwds=PyDict_New())) goto end; - if (!(argcount=PyLong_FromLong(a))) goto end; - if (PyDict_SetItemString(kwds, "co_argcount", argcount) != 0) goto end; - if (!(posonlyargcount=PyLong_FromLong(0))) goto end; - if (PyDict_SetItemString(kwds, "co_posonlyargcount", posonlyargcount) != 0) goto end; - if (!(kwonlyargcount=PyLong_FromLong(k))) goto end; - if (PyDict_SetItemString(kwds, "co_kwonlyargcount", kwonlyargcount) != 0) goto end; - if (!(nlocals=PyLong_FromLong(l))) goto end; - if (PyDict_SetItemString(kwds, "co_nlocals", nlocals) != 0) goto end; - if (!(stacksize=PyLong_FromLong(s))) goto end; - if (PyDict_SetItemString(kwds, "co_stacksize", stacksize) != 0) goto end; - if (!(flags=PyLong_FromLong(f))) goto end; - if (PyDict_SetItemString(kwds, "co_flags", flags) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_code", code) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_consts", c) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_names", n) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_varnames", v) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_freevars", fv) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_cellvars", cell) != 0) goto end; - if (PyDict_SetItemString(kwds, "co_linetable", lnos) != 0) goto end; - if (!(fn_cstr=PyUnicode_AsUTF8AndSize(fn, NULL))) goto end; - if (!(name_cstr=PyUnicode_AsUTF8AndSize(name, NULL))) goto end; - if (!(co = PyCode_NewEmpty(fn_cstr, name_cstr, fline))) goto end; - if (!(replace = PyObject_GetAttrString((PyObject*)co, "replace"))) goto cleanup_code_too; - if (!(empty = PyTuple_New(0))) goto cleanup_code_too; // unfortunately __pyx_empty_tuple isn't available here - if (!(call_result = PyObject_Call(replace, empty, kwds))) goto cleanup_code_too; - Py_XDECREF((PyObject*)co); - co = (PyCodeObject*)call_result; - call_result = NULL; - if (0) { - cleanup_code_too: - Py_XDECREF((PyObject*)co); - co = NULL; - } - end: - Py_XDECREF(kwds); - Py_XDECREF(argcount); - Py_XDECREF(posonlyargcount); - Py_XDECREF(kwonlyargcount); - Py_XDECREF(nlocals); - Py_XDECREF(stacksize); - Py_XDECREF(replace); - Py_XDECREF(call_result); - Py_XDECREF(empty); - if (type) { - PyErr_Restore(type, value, traceback); - } - return co; - } -#else - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) -#endif - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#ifndef METH_STACKLESS - #define METH_STACKLESS 0 -#endif -#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 - #define PyMem_RawMalloc(n) PyMem_Malloc(n) - #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) - #define PyMem_RawFree(p) PyMem_Free(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) -#include "pythread.h" -#define Py_tss_NEEDS_INIT 0 -typedef int Py_tss_t; -static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { - *key = PyThread_create_key(); - return 0; -} -static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { - Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); - *key = Py_tss_NEEDS_INIT; - return key; -} -static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { - PyObject_Free(key); -} -static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { - return *key != Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { - PyThread_delete_key(*key); - *key = Py_tss_NEEDS_INIT; -} -static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { - return PyThread_set_key_value(*key, value); -} -static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { - return PyThread_get_key_value(*key); -} -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS -#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) -#else -#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #if defined(PyUnicode_IS_READY) - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #else - #define __Pyx_PyUnicode_READY(op) (0) - #endif - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) - #endif - #else - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) - #endif -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#ifndef PyObject_Unicode - #define PyObject_Unicode PyObject_Str -#endif -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#if PY_VERSION_HEX >= 0x030900A4 - #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) -#else - #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) - #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) -#endif -#if CYTHON_ASSUME_SAFE_MACROS - #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) -#else - #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif - -#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) - #if !defined(_USE_MATH_DEFINES) - #define _USE_MATH_DEFINES - #endif -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - -#define __PYX_MARK_ERR_POS(f_index, lineno) \ - { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } -#define __PYX_ERR(f_index, lineno, Ln_error) \ - { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__questdb__ingress -#define __PYX_HAVE_API__questdb__ingress -/* Early includes */ -#include -#include -#include -#include -#include "datetime.h" -#include "questdb/ilp/line_sender.h" -#include "pystr_to_utf8.h" -#include "arrow_c_data_interface.h" -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { - return (size_t) i < (size_t) limit; -} -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime = NULL; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - - -static const char *__pyx_f[] = { - "src/questdb/ingress.pyx", - "src/questdb/size_t_vec.pxi", - "src/questdb/pandas_helpers.pxi", - "stringsource", - "datetime.pxd", - "type.pxd", - "bool.pxd", -}; - -/*--- Type declarations ---*/ -struct __pyx_obj_7questdb_7ingress_TimestampMicros; -struct __pyx_obj_7questdb_7ingress_TimestampNanos; -struct __pyx_obj_7questdb_7ingress_Buffer; -struct __pyx_obj_7questdb_7ingress_Sender; -struct __pyx_t_7questdb_7ingress_c_size_t_vec; -struct __pyx_t_7questdb_7ingress_c_column_name_vec; -struct __pyx_t_7questdb_7ingress_dtype_t; -struct __pyx_t_7questdb_7ingress_col_numpy_data_t; -struct __pyx_t_7questdb_7ingress_col_arrow_data_t; -union __pyx_t_7questdb_7ingress_col_access_t; -struct __pyx_t_7questdb_7ingress_col_cursor_t; -struct __pyx_t_7questdb_7ingress_col_handle_t; -struct __pyx_opt_args_7questdb_7ingress_6Buffer__row; -struct __pyx_opt_args_7questdb_7ingress_6Sender_flush; -struct __pyx_opt_args_7questdb_7ingress_6Sender_close; - -/* "src/questdb/pandas_helpers.pxi":29 - * - * - * cdef enum col_access_tag_t: # <<<<<<<<<<<<<< - * numpy - * arrow - */ -enum __pyx_t_7questdb_7ingress_col_access_tag_t { - __pyx_e_7questdb_7ingress_numpy, - __pyx_e_7questdb_7ingress_arrow -}; - -/* "src/questdb/pandas_helpers.pxi":58 - * - * - * cdef enum col_line_sender_target_t: # <<<<<<<<<<<<<< - * table - * symbol - */ -enum __pyx_t_7questdb_7ingress_col_line_sender_target_t { - __pyx_e_7questdb_7ingress_table, - __pyx_e_7questdb_7ingress_symbol, - __pyx_e_7questdb_7ingress_column_bool, - __pyx_e_7questdb_7ingress_column_i64, - __pyx_e_7questdb_7ingress_column_f64, - __pyx_e_7questdb_7ingress_column_str, - __pyx_e_7questdb_7ingress_column_ts, - __pyx_e_7questdb_7ingress_at -}; - -/* "src/questdb/size_t_vec.pxi":1 - * cdef struct c_size_t_vec: # <<<<<<<<<<<<<< - * size_t capacity - * size_t size - */ -struct __pyx_t_7questdb_7ingress_c_size_t_vec { - size_t capacity; - size_t size; - size_t *d; -}; - -/* "src/questdb/size_t_vec.pxi":6 - * size_t* d - * - * ctypedef c_size_t_vec size_t_vec # <<<<<<<<<<<<<< - * - * cdef size_t_vec size_t_vec_new(): - */ -typedef struct __pyx_t_7questdb_7ingress_c_size_t_vec __pyx_t_7questdb_7ingress_size_t_vec; - -/* "src/questdb/column_name_vec.pxi":1 - * cdef struct c_column_name_vec: # <<<<<<<<<<<<<< - * size_t capacity - * size_t size - */ -struct __pyx_t_7questdb_7ingress_c_column_name_vec { - size_t capacity; - size_t size; - struct line_sender_column_name *d; -}; - -/* "src/questdb/column_name_vec.pxi":6 - * line_sender_column_name* d - * - * ctypedef c_column_name_vec column_name_vec # <<<<<<<<<<<<<< - * - * cdef column_name_vec column_name_vec_new(): - */ -typedef struct __pyx_t_7questdb_7ingress_c_column_name_vec __pyx_t_7questdb_7ingress_column_name_vec; - -/* "src/questdb/pandas_helpers.pxi":6 - * # See: pandas_helpers.md for technical overview. - * - * cdef struct dtype_t: # <<<<<<<<<<<<<< - * # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html - * # ?highlight=dtype#numpy.dtype - */ -struct __pyx_t_7questdb_7ingress_dtype_t { - int alignment; - char kind; - int itemsize; - char byteorder; - int hasobject; -}; - -/* "src/questdb/pandas_helpers.pxi":18 - * - * - * cdef struct col_numpy_data_t: # <<<<<<<<<<<<<< - * dtype_t dtype - * Py_buffer pybuf - */ -struct __pyx_t_7questdb_7ingress_col_numpy_data_t { - struct __pyx_t_7questdb_7ingress_dtype_t dtype; - Py_buffer pybuf; -}; - -/* "src/questdb/pandas_helpers.pxi":23 - * - * - * cdef struct col_arrow_data_t: # <<<<<<<<<<<<<< - * ArrowSchema schema - * size_t n_chunks - */ -struct __pyx_t_7questdb_7ingress_col_arrow_data_t { - struct ArrowSchema schema; - size_t n_chunks; - struct ArrowArray chunks; -}; - -/* "src/questdb/pandas_helpers.pxi":34 - * - * - * cdef union col_access_t: # <<<<<<<<<<<<<< - * col_numpy_data_t numpy - * col_arrow_data_t arrow - */ -union __pyx_t_7questdb_7ingress_col_access_t { - struct __pyx_t_7questdb_7ingress_col_numpy_data_t numpy; - struct __pyx_t_7questdb_7ingress_col_arrow_data_t arrow; -}; - -/* "src/questdb/pandas_helpers.pxi":39 - * - * - * cdef struct col_cursor_t: # <<<<<<<<<<<<<< - * size_t chunk_index - * size_t n_chunks - */ -struct __pyx_t_7questdb_7ingress_col_cursor_t { - size_t chunk_index; - size_t n_chunks; - size_t offset; - size_t length; - uint8_t *validity; - void *data; - uint8_t *utf8_buf; -}; - -/* "src/questdb/pandas_helpers.pxi":69 - * - * - * cdef struct col_handle_t: # <<<<<<<<<<<<<< - * col_access_tag_t access_tag - * col_access_t access - */ -struct __pyx_t_7questdb_7ingress_col_handle_t { - enum __pyx_t_7questdb_7ingress_col_access_tag_t access_tag; - union __pyx_t_7questdb_7ingress_col_access_t access; - struct __pyx_t_7questdb_7ingress_col_cursor_t cursor; - enum __pyx_t_7questdb_7ingress_col_line_sender_target_t target; -}; - -/* "questdb/ingress.pyx":682 - * 'TimestampNanos, datetime, None') - * - * cdef int _row( # <<<<<<<<<<<<<< - * self, - * str table_name, - */ -struct __pyx_opt_args_7questdb_7ingress_6Buffer__row { - int __pyx_n; - PyObject *symbols; - PyObject *columns; - PyObject *at; -}; - -/* "questdb/ingress.pyx":1470 - * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) - * - * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< - * """ - * If called with no arguments, immediately flushes the internal buffer. - */ -struct __pyx_opt_args_7questdb_7ingress_6Sender_flush { - int __pyx_n; - struct __pyx_obj_7questdb_7ingress_Buffer *buffer; - int clear; -}; - -/* "questdb/ingress.pyx":1528 - * self._impl = NULL - * - * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< - * """ - * Disconnect. - */ -struct __pyx_opt_args_7questdb_7ingress_6Sender_close { - int __pyx_n; - int flush; -}; - -/* "questdb/ingress.pyx":261 - * - * - * cdef class TimestampMicros: # <<<<<<<<<<<<<< - * """ - * A timestamp in microseconds since the UNIX epoch. - */ -struct __pyx_obj_7questdb_7ingress_TimestampMicros { - PyObject_HEAD - int64_t _value; -}; - - -/* "questdb/ingress.pyx":312 - * - * - * cdef class TimestampNanos: # <<<<<<<<<<<<<< - * """ - * A timestamp in nanoseconds since the UNIX epoch. - */ -struct __pyx_obj_7questdb_7ingress_TimestampNanos { - PyObject_HEAD - int64_t _value; -}; - - -/* "questdb/ingress.pyx":374 - * - * cdef class Sender - * cdef class Buffer # <<<<<<<<<<<<<< - * - * - */ -struct __pyx_obj_7questdb_7ingress_Buffer { - PyObject_HEAD - struct __pyx_vtabstruct_7questdb_7ingress_Buffer *__pyx_vtab; - struct line_sender_buffer *_impl; - struct qdb_pystr_buf *_b; - size_t _init_capacity; - size_t _max_name_len; - PyObject *_row_complete_sender; -}; - - -/* "questdb/ingress.pyx":373 - * - * - * cdef class Sender # <<<<<<<<<<<<<< - * cdef class Buffer - * - */ -struct __pyx_obj_7questdb_7ingress_Sender { - PyObject_HEAD - struct __pyx_vtabstruct_7questdb_7ingress_Sender *__pyx_vtab; - PyObject *__weakref__; - struct line_sender_opts *_opts; - struct line_sender *_impl; - struct __pyx_obj_7questdb_7ingress_Buffer *_buffer; - int _auto_flush_enabled; - Py_ssize_t _auto_flush_watermark; - size_t _init_capacity; - size_t _max_name_len; -}; - - - -/* "questdb/ingress.pyx":1127 - * - * - * cdef class Sender: # <<<<<<<<<<<<<< - * """ - * A sender is a client that inserts rows into QuestDB via the ILP protocol. - */ - -struct __pyx_vtabstruct_7questdb_7ingress_Sender { - PyObject *(*flush)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args); - PyObject *(*_close)(struct __pyx_obj_7questdb_7ingress_Sender *); - PyObject *(*close)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args); -}; -static struct __pyx_vtabstruct_7questdb_7ingress_Sender *__pyx_vtabptr_7questdb_7ingress_Sender; - - -/* "questdb/ingress.pyx":383 - * - * - * cdef class Buffer: # <<<<<<<<<<<<<< - * """ - * Construct QuestDB-flavored InfluxDB Line Protocol (ILP) messages. - */ - -struct __pyx_vtabstruct_7questdb_7ingress_Buffer { - PyObject *(*_cinit_impl)(struct __pyx_obj_7questdb_7ingress_Buffer *, size_t, size_t); - PyObject *(*_to_str)(struct __pyx_obj_7questdb_7ingress_Buffer *); - int (*_set_marker)(struct __pyx_obj_7questdb_7ingress_Buffer *); - int (*_rewind_to_marker)(struct __pyx_obj_7questdb_7ingress_Buffer *); - PyObject *(*_clear_marker)(struct __pyx_obj_7questdb_7ingress_Buffer *); - int (*_table)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); - struct qdb_pystr_buf *(*_cleared_b)(struct __pyx_obj_7questdb_7ingress_Buffer *); - int (*_symbol)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); - int (*_column_bool)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int); - int (*_column_i64)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int64_t); - int (*_column_f64)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, double); - int (*_column_str)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyObject *); - int (*_column_ts)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *); - int (*_column_dt)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyDateTime_DateTime *); - int (*_column)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); - int (*_may_trigger_row_complete)(struct __pyx_obj_7questdb_7ingress_Buffer *); - int (*_at_ts)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_TimestampNanos *); - int (*_at_dt)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyDateTime_DateTime *); - int (*_at_now)(struct __pyx_obj_7questdb_7ingress_Buffer *); - int (*_at)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); - int (*_row)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args); - int (*_pandas)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int); -}; -static struct __pyx_vtabstruct_7questdb_7ingress_Buffer *__pyx_vtabptr_7questdb_7ingress_Buffer; -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__cinit_impl(struct __pyx_obj_7questdb_7ingress_Buffer *, size_t, size_t); -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__to_str(struct __pyx_obj_7questdb_7ingress_Buffer *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__set_marker(struct __pyx_obj_7questdb_7ingress_Buffer *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(struct __pyx_obj_7questdb_7ingress_Buffer *); -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__clear_marker(struct __pyx_obj_7questdb_7ingress_Buffer *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__table(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); -static CYTHON_INLINE struct qdb_pystr_buf *__pyx_f_7questdb_7ingress_6Buffer__cleared_b(struct __pyx_obj_7questdb_7ingress_Buffer *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__symbol(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_bool(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_i64(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int64_t); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_f64(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, double); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_str(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyObject *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_ts(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_dt(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyDateTime_DateTime *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_ts(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_TimestampNanos *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_dt(struct __pyx_obj_7questdb_7ingress_Buffer *, PyDateTime_DateTime *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_now(struct __pyx_obj_7questdb_7ingress_Buffer *); -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *); - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* ListCompAppend.proto */ -#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS -static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { - PyListObject* L = (PyListObject*) list; - Py_ssize_t len = Py_SIZE(list); - if (likely(L->allocated > len)) { - Py_INCREF(x); - PyList_SET_ITEM(list, len, x); - __Pyx_SET_SIZE(list, len + 1); - return 0; - } - return PyList_Append(list, x); -} -#else -#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) -#endif - -/* PyCFunctionFastCall.proto */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); -#else -#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) -#endif - -/* PyFunctionFastCall.proto */ -#if CYTHON_FAST_PYCALL -#define __Pyx_PyFunction_FastCall(func, args, nargs)\ - __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); -#else -#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) -#endif -#define __Pyx_BUILD_ASSERT_EXPR(cond)\ - (sizeof(char [1 - 2*!(cond)]) - 1) -#ifndef Py_MEMBER_SIZE -#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#endif -#if CYTHON_FAST_PYCALL - static size_t __pyx_pyframe_localsplus_offset = 0; - #include "frameobject.h" -#if PY_VERSION_HEX >= 0x030b00a6 - #ifndef Py_BUILD_CORE - #define Py_BUILD_CORE 1 - #endif - #include "internal/pycore_frame.h" -#endif - #define __Pxy_PyFrame_Initialize_Offsets()\ - ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ - (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) - #define __Pyx_PyFrame_GetLocalsplus(frame)\ - (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) -#endif // CYTHON_FAST_PYCALL -#endif - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* PyObjectCallMethO.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); -#endif - -/* PyObjectCallOneArg.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* GetTopmostException.proto */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); -#endif - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) - -/* PyDictVersioning.proto */ -#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS -#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) -#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ - (version_var) = __PYX_GET_DICT_VERSION(dict);\ - (cache_var) = (value); -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ - (VAR) = __pyx_dict_cached_value;\ - } else {\ - (VAR) = __pyx_dict_cached_value = (LOOKUP);\ - __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ - }\ -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); -#else -#define __PYX_GET_DICT_VERSION(dict) (0) -#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) -#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); -#endif - -/* GetModuleGlobalName.proto */ -#if CYTHON_USE_DICT_VERSIONS -#define __Pyx_GetModuleGlobalName(var, name) {\ - static PY_UINT64_T __pyx_dict_version = 0;\ - static PyObject *__pyx_dict_cached_value = NULL;\ - (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ - (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ - __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ - PY_UINT64_T __pyx_dict_version;\ - PyObject *__pyx_dict_cached_value;\ - (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ -} -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); -#else -#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) -#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); -#endif - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* PyObjectFormatSimple.proto */ -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - PyObject_Format(s, f)) -#elif PY_MAJOR_VERSION < 3 - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - likely(PyString_CheckExact(s)) ? PyUnicode_FromEncodedObject(s, NULL, "strict") :\ - PyObject_Format(s, f)) -#elif CYTHON_USE_TYPE_SLOTS - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_str(s) :\ - likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_str(s) :\ - PyObject_Format(s, f)) -#else - #define __Pyx_PyObject_FormatSimple(s, f) (\ - likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ - PyObject_Format(s, f)) -#endif - -/* SwapException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* PyUnicode_Unicode.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj); - -/* GCCDiagnostics.proto */ -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -#define __Pyx_HAS_GCC_DIAGNOSTIC -#endif - -/* BuildPyUnicode.proto */ -static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, - int prepend_sign, char padding_char); - -/* IncludeStringH.proto */ -#include - -/* CIntToPyUnicode.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char); - -/* JoinPyUnicode.proto */ -static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, - Py_UCS4 max_char); - -/* BytesEquals.proto */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); - -/* UnicodeEquals.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); - -/* ObjectGetItem.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); -#else -#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) -#endif - -/* PyUnicodeContains.proto */ -static CYTHON_INLINE int __Pyx_PyUnicode_ContainsTF(PyObject* substring, PyObject* text, int eq) { - int result = PyUnicode_Contains(text, substring); - return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); -} - -/* PyObjectFormatAndDecref.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatSimpleAndDecref(PyObject* s, PyObject* f); -static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatAndDecref(PyObject* s, PyObject* f); - -/* PyObjectCall2Args.proto */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* ExtTypeTest.proto */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); - -/* PyIntCompare.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); - -/* UnicodeAsUCS4.proto */ -static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject*); - -/* object_ord.proto */ -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyObject_Ord(c)\ - (likely(PyUnicode_Check(c)) ? (long)__Pyx_PyUnicode_AsPy_UCS4(c) : __Pyx__PyObject_Ord(c)) -#else -#define __Pyx_PyObject_Ord(c) __Pyx__PyObject_Ord(c) -#endif -static long __Pyx__PyObject_Ord(PyObject* c); - -/* GetAttr.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); - -/* GetAttr3.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); - -/* PyObjectCallNoArg.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); -#else -#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) -#endif - -/* CIntToPyUnicode.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_char(char value, Py_ssize_t width, char padding_char, char format_char); - -/* CIntToPyUnicode.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_size_t(size_t value, Py_ssize_t width, char padding_char, char format_char); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* PyObjectSetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o, n, NULL) -static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value); -#else -#define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n) -#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v) -#endif - -/* UnpackUnboundCMethod.proto */ -typedef struct { - PyObject *type; - PyObject **method_name; - PyCFunction func; - PyObject *method; - int flag; -} __Pyx_CachedCFunction; - -/* CallUnboundCMethod1.proto */ -static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); -#else -#define __Pyx_CallUnboundCMethod1(cfunc, self, arg) __Pyx__CallUnboundCMethod1(cfunc, self, arg) -#endif - -/* PyObjectFormat.proto */ -#if CYTHON_USE_UNICODE_WRITER -static PyObject* __Pyx_PyObject_Format(PyObject* s, PyObject* f); -#else -#define __Pyx_PyObject_Format(s, f) PyObject_Format(s, f) -#endif - -/* WriteUnraisableException.proto */ -static void __Pyx_WriteUnraisable(const char *name, int clineno, - int lineno, const char *filename, - int full_traceback, int nogil); - -/* ArgTypeTest.proto */ -#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ - __Pyx__ArgTypeTest(obj, type, name, exact)) -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); - -/* IterFinish.proto */ -static CYTHON_INLINE int __Pyx_IterFinish(void); - -/* PyObjectGetMethod.proto */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); - -/* PyObjectCallMethod0.proto */ -static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* UnpackItemEndCheck.proto */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); - -/* RaiseNoneIterError.proto */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); - -/* UnpackTupleError.proto */ -static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); - -/* UnpackTuple2.proto */ -#define __Pyx_unpack_tuple2(tuple, value1, value2, is_tuple, has_known_size, decref_tuple)\ - (likely(is_tuple || PyTuple_Check(tuple)) ?\ - (likely(has_known_size || PyTuple_GET_SIZE(tuple) == 2) ?\ - __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple) :\ - (__Pyx_UnpackTupleError(tuple, 2), -1)) :\ - __Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple)) -static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( - PyObject* tuple, PyObject** value1, PyObject** value2, int decref_tuple); -static int __Pyx_unpack_tuple2_generic( - PyObject* tuple, PyObject** value1, PyObject** value2, int has_known_size, int decref_tuple); - -/* dict_iter.proto */ -static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name, - Py_ssize_t* p_orig_length, int* p_is_dict); -static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos, - PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict); - -/* CIntToPyUnicode.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char); - -/* PyObject_GenericGetAttrNoDict.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr -#endif - -/* PyObject_GenericGetAttr.proto */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); -#else -#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr -#endif - -/* PyObjectGetAttrStrNoError.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); - -/* SetupReduce.proto */ -static int __Pyx_setup_reduce(PyObject* type_obj); - -/* SetVTable.proto */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable); - -/* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto -#define __PYX_HAVE_RT_ImportType_proto -enum __Pyx_ImportType_CheckSize { - __Pyx_ImportType_CheckSize_Error = 0, - __Pyx_ImportType_CheckSize_Warn = 1, - __Pyx_ImportType_CheckSize_Ignore = 2 -}; -static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); -#endif - -/* ImportFrom.proto */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); - -/* CalculateMetaclass.proto */ -static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases); - -/* SetNameInClass.proto */ -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 -#define __Pyx_SetNameInClass(ns, name, value)\ - (likely(PyDict_CheckExact(ns)) ? _PyDict_SetItem_KnownHash(ns, name, value, ((PyASCIIObject *) name)->hash) : PyObject_SetItem(ns, name, value)) -#elif CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_SetNameInClass(ns, name, value)\ - (likely(PyDict_CheckExact(ns)) ? PyDict_SetItem(ns, name, value) : PyObject_SetItem(ns, name, value)) -#else -#define __Pyx_SetNameInClass(ns, name, value) PyObject_SetItem(ns, name, value) -#endif - -/* FetchCommonType.proto */ -static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); - -/* CythonFunctionShared.proto */ -#define __Pyx_CyFunction_USED 1 -#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 -#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 -#define __Pyx_CYFUNCTION_CCLASS 0x04 -#define __Pyx_CyFunction_GetClosure(f)\ - (((__pyx_CyFunctionObject *) (f))->func_closure) -#define __Pyx_CyFunction_GetClassObj(f)\ - (((__pyx_CyFunctionObject *) (f))->func_classobj) -#define __Pyx_CyFunction_Defaults(type, f)\ - ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) -#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ - ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) -typedef struct { - PyCFunctionObject func; -#if PY_VERSION_HEX < 0x030500A0 - PyObject *func_weakreflist; -#endif - PyObject *func_dict; - PyObject *func_name; - PyObject *func_qualname; - PyObject *func_doc; - PyObject *func_globals; - PyObject *func_code; - PyObject *func_closure; - PyObject *func_classobj; - void *defaults; - int defaults_pyobjects; - size_t defaults_size; // used by FusedFunction for copying defaults - int flags; - PyObject *defaults_tuple; - PyObject *defaults_kwdict; - PyObject *(*defaults_getter)(PyObject *); - PyObject *func_annotations; -} __pyx_CyFunctionObject; -static PyTypeObject *__pyx_CyFunctionType = 0; -#define __Pyx_CyFunction_Check(obj) (__Pyx_TypeCheck(obj, __pyx_CyFunctionType)) -static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, - int flags, PyObject* qualname, - PyObject *self, - PyObject *module, PyObject *globals, - PyObject* code); -static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, - size_t size, - int pyobjects); -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, - PyObject *tuple); -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, - PyObject *dict); -static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, - PyObject *dict); -static int __pyx_CyFunction_init(void); - -/* CythonFunction.proto */ -static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, - int flags, PyObject* qualname, - PyObject *closure, - PyObject *module, PyObject *globals, - PyObject* code); - -/* Py3ClassCreate.proto */ -static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, - PyObject *mkw, PyObject *modname, PyObject *doc); -static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, - PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); - -/* CyFunctionClassCell.proto */ -static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj); - -/* ClassMethod.proto */ -#include "descrobject.h" -static CYTHON_UNUSED PyObject* __Pyx_Method_ClassMethod(PyObject *method); - -/* GetNameInClass.proto */ -#define __Pyx_GetNameInClass(var, nmspace, name) (var) = __Pyx__GetNameInClass(nmspace, name) -static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name); - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__line_sender_error_code(enum line_sender_error_code value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE uint64_t __Pyx_PyInt_As_uint64_t(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int64_t __Pyx_PyInt_As_int64_t(PyObject *); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint64_t(uint64_t value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__cinit_impl(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, size_t __pyx_v_init_capacity, size_t __pyx_v_max_name_len); /* proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__to_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__set_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__clear_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__table(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name); /* proto*/ -static CYTHON_INLINE struct qdb_pystr_buf *__pyx_f_7questdb_7ingress_6Buffer__cleared_b(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__symbol(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_bool(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int __pyx_v_value); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_i64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int64_t __pyx_v_value); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_f64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, double __pyx_v_value); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyObject *__pyx_v_value); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_ts); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyDateTime_DateTime *__pyx_v_dt); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_ts); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyDateTime_DateTime *__pyx_v_dt); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_now(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto*/ -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_ts); /* proto*/ -static int __pyx_f_7questdb_7ingress_6Buffer__row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args); /* proto*/ -static int __pyx_f_7questdb_7ingress_6Buffer__pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, CYTHON_UNUSED int __pyx_v_sort); /* proto*/ -static PyObject *__pyx_f_7questdb_7ingress_6Sender_flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args); /* proto*/ -static PyObject *__pyx_f_7questdb_7ingress_6Sender__close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto*/ -static PyObject *__pyx_f_7questdb_7ingress_6Sender_close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args); /* proto*/ - -/* Module declarations from 'libc.stdint' */ - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdlib' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; - -/* Module declarations from 'cpython' */ - -/* Module declarations from 'cpython.object' */ - -/* Module declarations from 'datetime' */ - -/* Module declarations from 'cpython.datetime' */ -static PyTypeObject *__pyx_ptype_7cpython_8datetime_date = 0; -static PyTypeObject *__pyx_ptype_7cpython_8datetime_time = 0; -static PyTypeObject *__pyx_ptype_7cpython_8datetime_datetime = 0; -static PyTypeObject *__pyx_ptype_7cpython_8datetime_timedelta = 0; -static PyTypeObject *__pyx_ptype_7cpython_8datetime_tzinfo = 0; - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.bool' */ -static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; - -/* Module declarations from 'cpython.weakref' */ - -/* Module declarations from 'cpython.float' */ - -/* Module declarations from 'cpython.int' */ - -/* Module declarations from 'cpython.unicode' */ - -/* Module declarations from 'cpython.buffer' */ - -/* Module declarations from 'cpython.memoryview' */ - -/* Module declarations from 'questdb.line_sender' */ - -/* Module declarations from 'questdb.pystr_to_utf8' */ - -/* Module declarations from 'questdb.arrow_c_data_interface' */ - -/* Module declarations from 'questdb.extra_cpython' */ - -/* Module declarations from 'cython' */ - -/* Module declarations from 'questdb.ingress' */ -static PyTypeObject *__pyx_ptype_7questdb_7ingress_TimestampMicros = 0; -static PyTypeObject *__pyx_ptype_7questdb_7ingress_TimestampNanos = 0; -static PyTypeObject *__pyx_ptype_7questdb_7ingress_Sender = 0; -static PyTypeObject *__pyx_ptype_7questdb_7ingress_Buffer = 0; -static PyObject *__pyx_v_7questdb_7ingress__PANDAS_NA = 0; -static char __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_OBJECT; -static char __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_DATETIME; -static __pyx_t_7questdb_7ingress_size_t_vec __pyx_f_7questdb_7ingress_size_t_vec_new(void); /*proto*/ -static void __pyx_f_7questdb_7ingress_size_t_vec_free(__pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress_size_t_vec_str(__pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ -static void __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_t_7questdb_7ingress_size_t_vec *, size_t); /*proto*/ -static __pyx_t_7questdb_7ingress_column_name_vec __pyx_f_7questdb_7ingress_column_name_vec_new(void); /*proto*/ -static void __pyx_f_7questdb_7ingress_column_name_vec_free(__pyx_t_7questdb_7ingress_column_name_vec *); /*proto*/ -static void __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_t_7questdb_7ingress_column_name_vec *, struct line_sender_column_name); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress__pandas_may_set_na_type(void); /*proto*/ -static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_table_name(struct qdb_pystr_buf *, PyObject *, PyObject *, PyObject *, size_t, struct line_sender_table_name *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_resolve_fields(int, __pyx_t_7questdb_7ingress_size_t_vec const *, int, size_t, __pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_resolve_col_names(struct qdb_pystr_buf *, PyObject *, __pyx_t_7questdb_7ingress_size_t_vec const *, __pyx_t_7questdb_7ingress_size_t_vec const *, __pyx_t_7questdb_7ingress_column_name_vec *, __pyx_t_7questdb_7ingress_column_name_vec *); /*proto*/ -static int __pyx_f_7questdb_7ingress__bind_col_index(PyObject *, int, size_t, size_t *); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress__pandas_column_is_str(PyObject *, int); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress__pandas_check_column_is_str(PyObject *, size_t, PyObject *, PyObject *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_resolve_symbols(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *, size_t, __pyx_t_7questdb_7ingress_size_t_vec *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_get_loc(PyObject *, PyObject *, PyObject *, size_t *); /*proto*/ -static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_at(PyObject *, PyObject *, size_t, int64_t *); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress__pandas_is_supported_datetime(PyObject *); /*proto*/ -static char __pyx_f_7questdb_7ingress__str_to_char(PyObject *, PyObject *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_parse_dtype(PyObject *, struct __pyx_t_7questdb_7ingress_dtype_t *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_resolve_dtypes(PyObject *, size_t, struct __pyx_t_7questdb_7ingress_dtype_t *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_resolve_col_buffers(PyObject *, size_t, struct __pyx_t_7questdb_7ingress_dtype_t const *, Py_buffer *, size_t *); /*proto*/ -static CYTHON_INLINE void const *__pyx_f_7questdb_7ingress__pandas_get_cell(Py_buffer *, size_t); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_get_str_cell(struct qdb_pystr_buf *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t, int *, struct line_sender_utf8 *); /*proto*/ -static int64_t __pyx_f_7questdb_7ingress__pandas_get_timestamp_cell(struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_row_table_name(struct line_sender_buffer *, struct qdb_pystr_buf *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, Py_ssize_t, size_t, struct line_sender_table_name); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_row_symbols(struct line_sender_buffer *, struct qdb_pystr_buf *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t, __pyx_t_7questdb_7ingress_column_name_vec const *, __pyx_t_7questdb_7ingress_size_t_vec const *); /*proto*/ -static int __pyx_f_7questdb_7ingress__pandas_row_at(struct line_sender_buffer *, struct __pyx_t_7questdb_7ingress_dtype_t *, Py_buffer *, size_t, Py_ssize_t, int64_t); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_code_to_py(enum line_sender_error_code); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_code_and_msg(struct line_sender_error *); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py(struct line_sender_error *); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py_fmt(struct line_sender_error *, PyObject *); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress__utf8_decode_error(PyObject *, uint32_t); /*proto*/ -static int __pyx_f_7questdb_7ingress_str_to_utf8(struct qdb_pystr_buf *, PyObject *, struct line_sender_utf8 *); /*proto*/ -static int __pyx_f_7questdb_7ingress_str_to_table_name(struct qdb_pystr_buf *, PyObject *, struct line_sender_table_name *); /*proto*/ -static int __pyx_f_7questdb_7ingress_str_to_column_name(struct qdb_pystr_buf *, PyObject *, struct line_sender_column_name *); /*proto*/ -static int64_t __pyx_f_7questdb_7ingress_datetime_to_micros(PyDateTime_DateTime *); /*proto*/ -static int64_t __pyx_f_7questdb_7ingress_datetime_to_nanos(PyDateTime_DateTime *); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress__check_is_pandas_dataframe(PyObject *); /*proto*/ -static int __pyx_f_7questdb_7ingress_may_flush_on_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_Sender *); /*proto*/ -#define __Pyx_MODULE_NAME "questdb.ingress" -extern int __pyx_module_is_main_questdb__ingress; -int __pyx_module_is_main_questdb__ingress = 0; - -/* Implementation of 'questdb.ingress' */ -static PyObject *__pyx_builtin_property; -static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_ValueError; -static PyObject *__pyx_builtin_TypeError; -static PyObject *__pyx_builtin_IndexError; -static PyObject *__pyx_builtin_KeyError; -static PyObject *__pyx_builtin_super; -static const char __pyx_k_M[] = "M"; -static const char __pyx_k_O[] = "O"; -static const char __pyx_k_S[] = "S"; -static const char __pyx_k_x[] = "x"; -static const char __pyx_k_NA[] = "NA"; -static const char __pyx_k_SO[] = "SO"; -static const char __pyx_k__5[] = "`: "; -static const char __pyx_k__6[] = "."; -static const char __pyx_k__9[] = "("; -static const char __pyx_k_at[] = "at"; -static const char __pyx_k_dt[] = "dt"; -static const char __pyx_k_Any[] = "Any"; -static const char __pyx_k__10[] = ". "; -static const char __pyx_k__11[] = "` "; -static const char __pyx_k__12[] = "="; -static const char __pyx_k__14[] = " ("; -static const char __pyx_k__15[] = ")"; -static const char __pyx_k__17[] = ": "; -static const char __pyx_k__24[] = ", "; -static const char __pyx_k__27[] = "\n"; -static const char __pyx_k_cls[] = "cls"; -static const char __pyx_k_doc[] = "__doc__"; -static const char __pyx_k_err[] = "err"; -static const char __pyx_k_got[] = "got "; -static const char __pyx_k_int[] = "int"; -static const char __pyx_k_msg[] = "msg"; -static const char __pyx_k_not[] = "not "; -static const char __pyx_k_row[] = "row"; -static const char __pyx_k_str[] = "str"; -static const char __pyx_k_sys[] = "sys"; -static const char __pyx_k_tls[] = "tls"; -static const char __pyx_k_Dict[] = "Dict"; -static const char __pyx_k_Enum[] = "Enum"; -static const char __pyx_k_List[] = "List"; -static const char __pyx_k_None[] = "None"; -static const char __pyx_k_Path[] = "Path"; -static const char __pyx_k_at_2[] = "at: "; -static const char __pyx_k_auth[] = "auth"; -static const char __pyx_k_bool[] = "bool"; -static const char __pyx_k_code[] = "code"; -static const char __pyx_k_data[] = "data"; -static const char __pyx_k_enum[] = "enum"; -static const char __pyx_k_exit[] = "__exit__"; -static const char __pyx_k_host[] = "host"; -static const char __pyx_k_iloc[] = "iloc"; -static const char __pyx_k_init[] = "__init__"; -static const char __pyx_k_kind[] = "kind"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_name[] = "name"; -static const char __pyx_k_port[] = "port"; -static const char __pyx_k_self[] = "self"; -static const char __pyx_k_sort[] = "sort"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_Tuple[] = "Tuple"; -static const char __pyx_k_Union[] = "Union"; -static const char __pyx_k_clear[] = "clear"; -static const char __pyx_k_close[] = "close"; -static const char __pyx_k_dtype[] = "dtype."; -static const char __pyx_k_enter[] = "__enter__"; -static const char __pyx_k_float[] = "float"; -static const char __pyx_k_flush[] = "flush"; -static const char __pyx_k_index[] = "index"; -static const char __pyx_k_items[] = "items"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_str_2[] = "__str__"; -static const char __pyx_k_super[] = "super"; -static const char __pyx_k_value[] = "_value"; -static const char __pyx_k_write[] = "write"; -static const char __pyx_k_Buffer[] = "Buffer"; -static const char __pyx_k_Column[] = "Column "; -static const char __pyx_k_Sender[] = "Sender"; -static const char __pyx_k_at_col[] = "at_col: "; -static const char __pyx_k_buffer[] = "buffer"; -static const char __pyx_k_code_2[] = "_code"; -static const char __pyx_k_dtypes[] = "dtypes"; -static const char __pyx_k_exc_tb[] = "_exc_tb"; -static const char __pyx_k_format[] = "format"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_module[] = "__module__"; -static const char __pyx_k_name_2[] = "__name__"; -static const char __pyx_k_pandas[] = "pandas"; -static const char __pyx_k_reduce[] = "__reduce__"; -static const char __pyx_k_return[] = "return"; -static const char __pyx_k_sort_2[] = "sort: "; -static const char __pyx_k_stderr[] = "stderr"; -static const char __pyx_k_symbol[] = "symbol"; -static const char __pyx_k_typing[] = "typing"; -static const char __pyx_k_columns[] = "columns"; -static const char __pyx_k_connect[] = "connect"; -static const char __pyx_k_exc_val[] = "_exc_val"; -static const char __pyx_k_for_the[] = "` for the "; -static const char __pyx_k_get_loc[] = "get_loc"; -static const char __pyx_k_pathlib[] = "pathlib"; -static const char __pyx_k_prepare[] = "__prepare__"; -static const char __pyx_k_reserve[] = "reserve"; -static const char __pyx_k_symbols[] = "symbols"; -static const char __pyx_k_unicode[] = "unicode"; -static const char __pyx_k_value_2[] = "value"; -static const char __pyx_k_Callable[] = "Callable"; -static const char __pyx_k_Iterable[] = "Iterable"; -static const char __pyx_k_KeyError[] = "KeyError"; -static const char __pyx_k_Optional[] = "Optional"; -static const char __pyx_k_TlsError[] = "TlsError"; -static const char __pyx_k_at_value[] = "at_value: "; -static const char __pyx_k_capacity[] = "capacity"; -static const char __pyx_k_datetime[] = "datetime"; -static const char __pyx_k_exc_type[] = "exc_type"; -static const char __pyx_k_getstate[] = "__getstate__"; -static const char __pyx_k_itemsize[] = "itemsize"; -static const char __pyx_k_name_col[] = "name_col: "; -static const char __pyx_k_pandas_A[] = "_pandas :: (A) "; -static const char __pyx_k_pandas_B[] = "pandas :: (B) "; -static const char __pyx_k_property[] = "property"; -static const char __pyx_k_qualname[] = "__qualname__"; -static const char __pyx_k_setstate[] = "__setstate__"; -static const char __pyx_k_to_numpy[] = "to_numpy"; -static const char __pyx_k_AuthError[] = "AuthError"; -static const char __pyx_k_Bad_dtype[] = "Bad dtype `"; -static const char __pyx_k_DataFrame[] = "DataFrame"; -static const char __pyx_k_FLUSH_FMT[] = "_FLUSH_FMT"; -static const char __pyx_k_TypeError[] = "TypeError"; -static const char __pyx_k_alignment[] = "alignment"; -static const char __pyx_k_byteorder[] = "byteorder"; -static const char __pyx_k_for_the_2[] = "for the "; -static const char __pyx_k_hasobject[] = "hasobject"; -static const char __pyx_k_in_column[] = "in column "; -static const char __pyx_k_in_string[] = " in string "; -static const char __pyx_k_interface[] = "interface"; -static const char __pyx_k_metaclass[] = "__metaclass__"; -static const char __pyx_k_pyx_state[] = "__pyx_state"; -static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; -static const char __pyx_k_symbols_2[] = "symbols: "; -static const char __pyx_k_timestamp[] = "timestamp"; -static const char __pyx_k_Buffer_row[] = "Buffer.row"; -static const char __pyx_k_IndexError[] = "IndexError"; -static const char __pyx_k_Sender_row[] = "Sender.row"; -static const char __pyx_k_ValueError[] = "ValueError"; -static const char __pyx_k_additional[] = "additional"; -static const char __pyx_k_auto_flush[] = "auto_flush"; -static const char __pyx_k_new_buffer[] = "new_buffer"; -static const char __pyx_k_pandas_A_2[] = "pandas :: (A) "; -static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; -static const char __pyx_k_size_t_vec[] = "size_t_vec"; -static const char __pyx_k_table_name[] = "table_name"; -static const char __pyx_k_InvalidName[] = "InvalidName"; -static const char __pyx_k_InvalidUtf8[] = "InvalidUtf8"; -static const char __pyx_k_SocketError[] = "SocketError"; -static const char __pyx_k_microsecond[] = "microsecond"; -static const char __pyx_k_Bad_argument[] = "Bad argument `"; -static const char __pyx_k_Buffer_clear[] = "Buffer.clear"; -static const char __pyx_k_IngressError[] = "IngressError"; -static const char __pyx_k_Sender_close[] = "Sender.close"; -static const char __pyx_k_Sender_flush[] = "Sender.flush"; -static const char __pyx_k_max_name_len[] = "max_name_len"; -static const char __pyx_k_read_timeout[] = "read_timeout"; -static const char __pyx_k_stringsource[] = "stringsource"; -static const char __pyx_k_table_name_2[] = "table_name: "; -static const char __pyx_k_Buffer_pandas[] = "Buffer.pandas"; -static const char __pyx_k_Sender___exit[] = "Sender.__exit__"; -static const char __pyx_k_field_indices[] = "field_indices: "; -static const char __pyx_k_from_datetime[] = "from_datetime"; -static const char __pyx_k_init_capacity[] = "init_capacity"; -static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; -static const char __pyx_k_Buffer_reserve[] = "Buffer.reserve"; -static const char __pyx_k_InvalidApiCall[] = "InvalidApiCall"; -static const char __pyx_k_Must_be_one_of[] = ". Must be one of: "; -static const char __pyx_k_Sender___enter[] = "Sender.__enter__"; -static const char __pyx_k_Sender_connect[] = "Sender.connect"; -static const char __pyx_k_TimestampNanos[] = "TimestampNanos"; -static const char __pyx_k_symbol_indices[] = "symbol_indices: "; -static const char __pyx_k_table_name_col[] = "table_name_col"; -static const char __pyx_k_Buffer_capacity[] = "Buffer.capacity"; -static const char __pyx_k_TimestampMicros[] = "TimestampMicros"; -static const char __pyx_k_questdb_ingress[] = "questdb.ingress"; -static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; -static const char __pyx_k_IngressErrorCode[] = "IngressErrorCode"; -static const char __pyx_k_InvalidTimestamp[] = "InvalidTimestamp"; -static const char __pyx_k_Unknown_UCS_kind[] = "Unknown UCS kind: "; -static const char __pyx_k_Unsupported_type[] = "Unsupported type: "; -static const char __pyx_k_table_name_col_2[] = "table_name_col: "; -static const char __pyx_k_Category_of_Error[] = "Category of Error."; -static const char __pyx_k_IngressError_code[] = "IngressError.code"; -static const char __pyx_k_Sender_new_buffer[] = "Sender.new_buffer"; -static const char __pyx_k_datetime_datetime[] = "datetime.datetime"; -static const char __pyx_k_pandas_core_frame[] = "pandas.core.frame"; -static const char __pyx_k_as_a_symbol_column[] = ") as a symbol column."; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_index_out_of_range[] = " index out of range"; -static const char __pyx_k_CouldNotResolveAddr[] = "CouldNotResolveAddr"; -static const char __pyx_k_IngressError___init[] = "IngressError.__init__"; -static const char __pyx_k_Invalid_codepoint_0x[] = "Invalid codepoint 0x"; -static const char __pyx_k_insecure_skip_verify[] = "insecure_skip_verify"; -static const char __pyx_k_Buffer___reduce_cython[] = "Buffer.__reduce_cython__"; -static const char __pyx_k_Found_non_string_value[] = "Found non-string value "; -static const char __pyx_k_IngressErrorCode___str[] = "IngressErrorCode.__str__"; -static const char __pyx_k_Sender___reduce_cython[] = "Sender.__reduce_cython__"; -static const char __pyx_k_Bad_argument_table_name[] = "Bad argument `table_name`: "; -static const char __pyx_k_src_questdb_ingress_pyx[] = "src/questdb/ingress.pyx"; -static const char __pyx_k_Buffer___setstate_cython[] = "Buffer.__setstate_cython__"; -static const char __pyx_k_NOT_YET_IMPLEMENTED_Kind[] = "NOT YET IMPLEMENTED. Kind: "; -static const char __pyx_k_Sender___setstate_cython[] = "Sender.__setstate_cython__"; -static const char __pyx_k_Bad_argument_at_Bad_dtype[] = "Bad argument `at`: Bad dtype `"; -static const char __pyx_k_Bad_argument_data_Expected[] = "Bad argument `data`: Expected "; -static const char __pyx_k_Cannot_be_encoded_as_UTF_8[] = "Cannot be encoded as UTF-8."; -static const char __pyx_k_not_found_in_the_dataframe[] = " not found in the dataframe."; -static const char __pyx_k_Bad_argument_table_name_col[] = "Bad argument `table_name_col`: "; -static const char __pyx_k_value_must_positive_integer[] = "value must positive integer."; -static const char __pyx_k_Bad_column_Expected_a_string[] = "Bad column: Expected a string, "; -static const char __pyx_k_TimestampNanos_datetime_None[] = "TimestampNanos, datetime, None"; -static const char __pyx_k_TimestampNanos_from_datetime[] = "TimestampNanos.from_datetime"; -static const char __pyx_k_dt_must_be_a_datetime_object[] = "dt must be a datetime object."; -static const char __pyx_k_TimestampMicros_from_datetime[] = "TimestampMicros.from_datetime"; -static const char __pyx_k_TimestampNanos___reduce_cython[] = "TimestampNanos.__reduce_cython__"; -static const char __pyx_k_column_Must_be_a_datetime64_ns[] = " column: Must be a datetime64[ns] column."; -static const char __pyx_k_API_for_fast_data_ingestion_int[] = "\nAPI for fast data ingestion into QuestDB.\n"; -static const char __pyx_k_Bad_argument_symbols_Cannot_use[] = "Bad argument `symbols`: Cannot use the same column "; -static const char __pyx_k_Bad_argument_table_name_Must_be[] = "Bad argument `table_name`: Must be str."; -static const char __pyx_k_Bad_element_in_argument_symbols[] = "Bad element in argument `symbols`: "; -static const char __pyx_k_Bad_value_None_table_name_value[] = "Bad value: `None` table name value at row "; -static const char __pyx_k_Character_out_of_ASCII_range_go[] = ": Character out of ASCII range, got "; -static const char __pyx_k_Expected_a_single_character_got[] = ": Expected a single character, got "; -static const char __pyx_k_Internal_error_converting_error[] = "Internal error converting error code."; -static const char __pyx_k_See_https_py_questdb_client_rea[] = "{} - See https://py-questdb-client.readthedocs.io/en/v1.0.2/troubleshooting.html#inspecting-and-debugging-errors#flush-failed"; -static const char __pyx_k_The_internal_buffer_must_always[] = "The internal buffer must always be cleared."; -static const char __pyx_k_TimestampMicros___reduce_cython[] = "TimestampMicros.__reduce_cython__"; -static const char __pyx_k_additional_must_be_non_negative[] = "additional must be non-negative."; -static const char __pyx_k_as_both_the_table_name_and_as_a[] = " as both the table_name and as a symbol."; -static const char __pyx_k_column_Must_be_a_strings_column[] = " column: Must be a strings column."; -static const char __pyx_k_int_column_index_str_colum_name[] = "int (column index), str (colum name)"; -static const char __pyx_k_An_error_whilst_using_the_Sender[] = "An error whilst using the ``Sender`` or constructing its ``Buffer``."; -static const char __pyx_k_Bad_argument_at_Unsupported_type[] = "Bad argument `at`: Unsupported type "; -static const char __pyx_k_Bad_argument_symbols_Elements_mu[] = "Bad argument `symbols`: Elements must be a column name (str) or index (int)."; -static const char __pyx_k_Bad_argument_symbols_Must_be_a_b[] = "Bad argument `symbols`: Must be a bool or a tuple or list of column names (str) or indices (int)."; -static const char __pyx_k_Bad_argument_table_name_col_must[] = "Bad argument `table_name_col`: must be a column name (str) or index (int)."; -static const char __pyx_k_Bad_column_Expected_a_numpy_arra[] = "Bad column: Expected a numpy array, got "; -static const char __pyx_k_Bad_value_Negative_timestamp_got[] = "Bad value: Negative timestamp, got "; -static const char __pyx_k_Can_specify_only_one_of_table_na[] = "Can specify only one of `table_name` or `table_name_col`."; -static const char __pyx_k_Must_be_one_of_None_TimestampNan[] = "Must be one of: None, TimestampNanos, datetime, "; -static const char __pyx_k_Must_specify_at_least_one_of_tab[] = "Must specify at least one of `table_name` or `table_name_col`."; -static const char __pyx_k_TimestampMicros___setstate_cytho[] = "TimestampMicros.__setstate_cython__"; -static const char __pyx_k_TimestampNanos___setstate_cython[] = "TimestampNanos.__setstate_cython__"; -static const char __pyx_k_auto_flush_watermark_must_be_0_n[] = "auto_flush_watermark must be >= 0, not "; -static const char __pyx_k_connect_can_t_be_called_after_cl[] = "connect() can't be called after close()."; -static const char __pyx_k_flush_can_t_be_called_Not_connec[] = "flush() can't be called: Not connected."; -static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; -static const char __pyx_k_port_must_be_an_integer_or_a_str[] = "port must be an integer or a string, not "; -static const char __pyx_k_tls_must_be_a_bool_a_path_or_str[] = "tls must be a bool, a path or string pointing to CA file or \"insecure_skip_verify\", not "; -static const char __pyx_k_Bad_argument_symbols_Cannot_use_2[] = "Bad argument `symbols`: Cannot use the `at` column "; -static PyObject *__pyx_kp_s_An_error_whilst_using_the_Sender; -static PyObject *__pyx_n_s_Any; -static PyObject *__pyx_n_s_AuthError; -static PyObject *__pyx_kp_u_Bad_argument; -static PyObject *__pyx_kp_u_Bad_argument_at_Bad_dtype; -static PyObject *__pyx_kp_u_Bad_argument_at_Unsupported_type; -static PyObject *__pyx_kp_u_Bad_argument_data_Expected; -static PyObject *__pyx_kp_u_Bad_argument_symbols_Cannot_use; -static PyObject *__pyx_kp_u_Bad_argument_symbols_Cannot_use_2; -static PyObject *__pyx_kp_u_Bad_argument_symbols_Elements_mu; -static PyObject *__pyx_kp_u_Bad_argument_symbols_Must_be_a_b; -static PyObject *__pyx_kp_u_Bad_argument_table_name; -static PyObject *__pyx_kp_u_Bad_argument_table_name_Must_be; -static PyObject *__pyx_kp_u_Bad_argument_table_name_col; -static PyObject *__pyx_kp_u_Bad_argument_table_name_col_must; -static PyObject *__pyx_kp_u_Bad_column_Expected_a_numpy_arra; -static PyObject *__pyx_kp_u_Bad_column_Expected_a_string; -static PyObject *__pyx_kp_u_Bad_dtype; -static PyObject *__pyx_kp_u_Bad_element_in_argument_symbols; -static PyObject *__pyx_kp_u_Bad_value_Negative_timestamp_got; -static PyObject *__pyx_kp_u_Bad_value_None_table_name_value; -static PyObject *__pyx_n_s_Buffer; -static PyObject *__pyx_n_s_Buffer___reduce_cython; -static PyObject *__pyx_n_s_Buffer___setstate_cython; -static PyObject *__pyx_n_s_Buffer_capacity; -static PyObject *__pyx_n_s_Buffer_clear; -static PyObject *__pyx_n_s_Buffer_pandas; -static PyObject *__pyx_n_s_Buffer_reserve; -static PyObject *__pyx_n_s_Buffer_row; -static PyObject *__pyx_n_s_Callable; -static PyObject *__pyx_kp_u_Can_specify_only_one_of_table_na; -static PyObject *__pyx_kp_u_Cannot_be_encoded_as_UTF_8; -static PyObject *__pyx_kp_s_Category_of_Error; -static PyObject *__pyx_kp_u_Character_out_of_ASCII_range_go; -static PyObject *__pyx_kp_u_Column; -static PyObject *__pyx_n_s_CouldNotResolveAddr; -static PyObject *__pyx_n_u_DataFrame; -static PyObject *__pyx_n_s_Dict; -static PyObject *__pyx_n_s_Enum; -static PyObject *__pyx_kp_u_Expected_a_single_character_got; -static PyObject *__pyx_n_s_FLUSH_FMT; -static PyObject *__pyx_kp_u_Found_non_string_value; -static PyObject *__pyx_n_s_IndexError; -static PyObject *__pyx_n_s_IngressError; -static PyObject *__pyx_n_s_IngressErrorCode; -static PyObject *__pyx_n_s_IngressErrorCode___str; -static PyObject *__pyx_n_s_IngressError___init; -static PyObject *__pyx_n_s_IngressError_code; -static PyObject *__pyx_kp_u_Internal_error_converting_error; -static PyObject *__pyx_n_s_InvalidApiCall; -static PyObject *__pyx_n_s_InvalidName; -static PyObject *__pyx_n_s_InvalidTimestamp; -static PyObject *__pyx_n_s_InvalidUtf8; -static PyObject *__pyx_kp_u_Invalid_codepoint_0x; -static PyObject *__pyx_n_s_Iterable; -static PyObject *__pyx_n_s_KeyError; -static PyObject *__pyx_n_s_List; -static PyObject *__pyx_n_u_M; -static PyObject *__pyx_kp_u_Must_be_one_of; -static PyObject *__pyx_kp_u_Must_be_one_of_None_TimestampNan; -static PyObject *__pyx_kp_u_Must_specify_at_least_one_of_tab; -static PyObject *__pyx_n_s_NA; -static PyObject *__pyx_kp_u_NOT_YET_IMPLEMENTED_Kind; -static PyObject *__pyx_kp_u_None; -static PyObject *__pyx_n_u_O; -static PyObject *__pyx_n_s_Optional; -static PyObject *__pyx_n_s_Path; -static PyObject *__pyx_n_u_S; -static PyObject *__pyx_n_u_SO; -static PyObject *__pyx_kp_u_See_https_py_questdb_client_rea; -static PyObject *__pyx_n_s_Sender; -static PyObject *__pyx_n_u_Sender; -static PyObject *__pyx_n_s_Sender___enter; -static PyObject *__pyx_n_s_Sender___exit; -static PyObject *__pyx_n_s_Sender___reduce_cython; -static PyObject *__pyx_n_s_Sender___setstate_cython; -static PyObject *__pyx_n_s_Sender_close; -static PyObject *__pyx_n_s_Sender_connect; -static PyObject *__pyx_n_s_Sender_flush; -static PyObject *__pyx_n_s_Sender_new_buffer; -static PyObject *__pyx_n_s_Sender_row; -static PyObject *__pyx_n_s_SocketError; -static PyObject *__pyx_kp_u_The_internal_buffer_must_always; -static PyObject *__pyx_n_s_TimestampMicros; -static PyObject *__pyx_n_u_TimestampMicros; -static PyObject *__pyx_n_s_TimestampMicros___reduce_cython; -static PyObject *__pyx_n_s_TimestampMicros___setstate_cytho; -static PyObject *__pyx_n_s_TimestampMicros_from_datetime; -static PyObject *__pyx_n_s_TimestampNanos; -static PyObject *__pyx_n_s_TimestampNanos___reduce_cython; -static PyObject *__pyx_n_s_TimestampNanos___setstate_cython; -static PyObject *__pyx_kp_u_TimestampNanos_datetime_None; -static PyObject *__pyx_n_s_TimestampNanos_from_datetime; -static PyObject *__pyx_n_s_TlsError; -static PyObject *__pyx_n_s_Tuple; -static PyObject *__pyx_n_s_TypeError; -static PyObject *__pyx_n_s_Union; -static PyObject *__pyx_kp_u_Unknown_UCS_kind; -static PyObject *__pyx_kp_u_Unsupported_type; -static PyObject *__pyx_n_s_ValueError; -static PyObject *__pyx_kp_u__10; -static PyObject *__pyx_kp_u__11; -static PyObject *__pyx_kp_u__12; -static PyObject *__pyx_kp_u__14; -static PyObject *__pyx_kp_u__15; -static PyObject *__pyx_kp_u__17; -static PyObject *__pyx_kp_u__24; -static PyObject *__pyx_kp_u__27; -static PyObject *__pyx_kp_u__5; -static PyObject *__pyx_kp_u__6; -static PyObject *__pyx_kp_u__9; -static PyObject *__pyx_n_s_additional; -static PyObject *__pyx_kp_u_additional_must_be_non_negative; -static PyObject *__pyx_n_s_alignment; -static PyObject *__pyx_n_u_alignment; -static PyObject *__pyx_kp_u_as_a_symbol_column; -static PyObject *__pyx_kp_u_as_both_the_table_name_and_as_a; -static PyObject *__pyx_n_s_at; -static PyObject *__pyx_n_u_at; -static PyObject *__pyx_kp_u_at_2; -static PyObject *__pyx_kp_u_at_col; -static PyObject *__pyx_kp_u_at_value; -static PyObject *__pyx_n_s_auth; -static PyObject *__pyx_n_s_auto_flush; -static PyObject *__pyx_kp_u_auto_flush_watermark_must_be_0_n; -static PyObject *__pyx_n_u_bool; -static PyObject *__pyx_n_s_buffer; -static PyObject *__pyx_n_s_byteorder; -static PyObject *__pyx_n_u_byteorder; -static PyObject *__pyx_n_s_capacity; -static PyObject *__pyx_n_s_clear; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_close; -static PyObject *__pyx_n_s_cls; -static PyObject *__pyx_n_s_code; -static PyObject *__pyx_n_s_code_2; -static PyObject *__pyx_kp_u_column_Must_be_a_datetime64_ns; -static PyObject *__pyx_kp_u_column_Must_be_a_strings_column; -static PyObject *__pyx_n_s_columns; -static PyObject *__pyx_n_s_connect; -static PyObject *__pyx_kp_u_connect_can_t_be_called_after_cl; -static PyObject *__pyx_n_s_data; -static PyObject *__pyx_n_u_datetime; -static PyObject *__pyx_kp_u_datetime_datetime; -static PyObject *__pyx_n_s_doc; -static PyObject *__pyx_n_s_dt; -static PyObject *__pyx_kp_u_dt_must_be_a_datetime_object; -static PyObject *__pyx_kp_u_dtype; -static PyObject *__pyx_n_s_dtypes; -static PyObject *__pyx_n_s_enter; -static PyObject *__pyx_n_s_enum; -static PyObject *__pyx_n_s_err; -static PyObject *__pyx_n_s_exc_tb; -static PyObject *__pyx_n_s_exc_type; -static PyObject *__pyx_n_s_exc_val; -static PyObject *__pyx_n_s_exit; -static PyObject *__pyx_kp_u_field_indices; -static PyObject *__pyx_n_u_float; -static PyObject *__pyx_n_s_flush; -static PyObject *__pyx_kp_u_flush_can_t_be_called_Not_connec; -static PyObject *__pyx_kp_u_for_the; -static PyObject *__pyx_kp_u_for_the_2; -static PyObject *__pyx_n_s_format; -static PyObject *__pyx_n_s_from_datetime; -static PyObject *__pyx_n_s_get_loc; -static PyObject *__pyx_n_s_getstate; -static PyObject *__pyx_kp_u_got; -static PyObject *__pyx_n_s_hasobject; -static PyObject *__pyx_n_u_hasobject; -static PyObject *__pyx_n_s_host; -static PyObject *__pyx_n_s_iloc; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_kp_u_in_column; -static PyObject *__pyx_kp_u_in_string; -static PyObject *__pyx_n_s_index; -static PyObject *__pyx_kp_u_index_out_of_range; -static PyObject *__pyx_n_s_init; -static PyObject *__pyx_n_s_init_capacity; -static PyObject *__pyx_n_u_insecure_skip_verify; -static PyObject *__pyx_n_u_int; -static PyObject *__pyx_kp_u_int_column_index_str_colum_name; -static PyObject *__pyx_n_s_interface; -static PyObject *__pyx_n_s_items; -static PyObject *__pyx_n_s_itemsize; -static PyObject *__pyx_n_u_itemsize; -static PyObject *__pyx_n_s_kind; -static PyObject *__pyx_n_u_kind; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_max_name_len; -static PyObject *__pyx_n_s_metaclass; -static PyObject *__pyx_n_s_microsecond; -static PyObject *__pyx_n_s_module; -static PyObject *__pyx_n_s_msg; -static PyObject *__pyx_n_s_name; -static PyObject *__pyx_n_s_name_2; -static PyObject *__pyx_kp_u_name_col; -static PyObject *__pyx_n_s_new_buffer; -static PyObject *__pyx_kp_s_no_default___reduce___due_to_non; -static PyObject *__pyx_kp_u_not; -static PyObject *__pyx_kp_u_not_found_in_the_dataframe; -static PyObject *__pyx_n_s_pandas; -static PyObject *__pyx_kp_u_pandas_A; -static PyObject *__pyx_kp_u_pandas_A_2; -static PyObject *__pyx_kp_u_pandas_B; -static PyObject *__pyx_kp_u_pandas_core_frame; -static PyObject *__pyx_n_s_pathlib; -static PyObject *__pyx_n_s_port; -static PyObject *__pyx_kp_u_port_must_be_an_integer_or_a_str; -static PyObject *__pyx_n_s_prepare; -static PyObject *__pyx_n_s_property; -static PyObject *__pyx_n_s_pyx_state; -static PyObject *__pyx_n_s_pyx_vtable; -static PyObject *__pyx_n_s_qualname; -static PyObject *__pyx_n_s_questdb_ingress; -static PyObject *__pyx_n_s_range; -static PyObject *__pyx_n_s_read_timeout; -static PyObject *__pyx_n_s_reduce; -static PyObject *__pyx_n_s_reduce_cython; -static PyObject *__pyx_n_s_reduce_ex; -static PyObject *__pyx_n_s_reserve; -static PyObject *__pyx_n_s_return; -static PyObject *__pyx_n_s_row; -static PyObject *__pyx_n_s_self; -static PyObject *__pyx_n_s_setstate; -static PyObject *__pyx_n_s_setstate_cython; -static PyObject *__pyx_n_u_size_t_vec; -static PyObject *__pyx_n_s_sort; -static PyObject *__pyx_kp_u_sort_2; -static PyObject *__pyx_kp_s_src_questdb_ingress_pyx; -static PyObject *__pyx_n_s_stderr; -static PyObject *__pyx_n_u_str; -static PyObject *__pyx_n_s_str_2; -static PyObject *__pyx_kp_s_stringsource; -static PyObject *__pyx_n_s_super; -static PyObject *__pyx_n_u_symbol; -static PyObject *__pyx_kp_u_symbol_indices; -static PyObject *__pyx_n_s_symbols; -static PyObject *__pyx_n_u_symbols; -static PyObject *__pyx_kp_u_symbols_2; -static PyObject *__pyx_n_s_sys; -static PyObject *__pyx_n_s_table_name; -static PyObject *__pyx_kp_u_table_name_2; -static PyObject *__pyx_n_s_table_name_col; -static PyObject *__pyx_n_u_table_name_col; -static PyObject *__pyx_kp_u_table_name_col_2; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_n_s_timestamp; -static PyObject *__pyx_n_s_tls; -static PyObject *__pyx_kp_u_tls_must_be_a_bool_a_path_or_str; -static PyObject *__pyx_n_s_to_numpy; -static PyObject *__pyx_n_s_typing; -static PyObject *__pyx_n_u_unicode; -static PyObject *__pyx_n_s_value; -static PyObject *__pyx_n_s_value_2; -static PyObject *__pyx_kp_u_value_must_positive_integer; -static PyObject *__pyx_n_s_write; -static PyObject *__pyx_n_u_x; -static PyObject *__pyx_pf_7questdb_7ingress_16IngressErrorCode___str__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_12IngressError___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_code, PyObject *__pyx_v_msg); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_12IngressError_2code(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */ -static int __pyx_pf_7questdb_7ingress_15TimestampMicros___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, PyObject *__pyx_v_value); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static int __pyx_pf_7questdb_7ingress_14TimestampNanos___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, PyObject *__pyx_v_value); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static int __pyx_pf_7questdb_7ingress_6Buffer___cinit__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_init_capacity, PyObject *__pyx_v_max_name_len); /* proto */ -static void __pyx_pf_7questdb_7ingress_6Buffer_2__dealloc__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_4reserve(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_additional); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_6capacity(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_8clear(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static Py_ssize_t __pyx_pf_7questdb_7ingress_6Buffer_10__len__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12__str__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_14row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_16pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, PyBoolObject *__pyx_v_sort); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_18__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_20__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static int __pyx_pf_7questdb_7ingress_6Sender___cinit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_host, PyObject *__pyx_v_port, PyObject *__pyx_v_interface, PyObject *__pyx_v_auth, PyObject *__pyx_v_tls, uint64_t __pyx_v_read_timeout, uint64_t __pyx_v_init_capacity, uint64_t __pyx_v_max_name_len, PyObject *__pyx_v_auto_flush); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_2new_buffer(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_4connect(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pf_7questdb_7ingress_6Sender_6__enter__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_8__str__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static Py_ssize_t __pyx_pf_7questdb_7ingress_6Sender_10__len__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12row(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_14flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer, int __pyx_v_clear); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_16close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_v_flush); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_18__exit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_exc_type, CYTHON_UNUSED PyObject *__pyx_v__exc_val, CYTHON_UNUSED PyObject *__pyx_v__exc_tb); /* proto */ -static void __pyx_pf_7questdb_7ingress_6Sender_20__dealloc__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_22__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self); /* proto */ -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_24__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */ -static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampMicros(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampNanos(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new_7questdb_7ingress_Sender(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static PyObject *__pyx_tp_new_7questdb_7ingress_Buffer(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ -static __Pyx_CachedCFunction __pyx_umethod_PyUnicode_Type_format = {0, &__pyx_n_s_format, 0, 0, 0}; -static PyObject *__pyx_int_0; -static PyObject *__pyx_int_8; -static PyObject *__pyx_int_127; -static PyObject *__pyx_int_1000; -static PyObject *__pyx_int_64512; -static PyObject *__pyx_int_65536; -static PyObject *__pyx_tuple_; -static PyObject *__pyx_tuple__2; -static PyObject *__pyx_tuple__3; -static PyObject *__pyx_tuple__4; -static PyObject *__pyx_tuple__7; -static PyObject *__pyx_tuple__8; -static PyObject *__pyx_slice__13; -static PyObject *__pyx_tuple__16; -static PyObject *__pyx_tuple__18; -static PyObject *__pyx_tuple__19; -static PyObject *__pyx_tuple__20; -static PyObject *__pyx_tuple__21; -static PyObject *__pyx_tuple__22; -static PyObject *__pyx_tuple__23; -static PyObject *__pyx_tuple__25; -static PyObject *__pyx_tuple__26; -static PyObject *__pyx_tuple__28; -static PyObject *__pyx_tuple__29; -static PyObject *__pyx_tuple__30; -static PyObject *__pyx_tuple__31; -static PyObject *__pyx_tuple__32; -static PyObject *__pyx_tuple__33; -static PyObject *__pyx_tuple__35; -static PyObject *__pyx_tuple__37; -static PyObject *__pyx_tuple__39; -static PyObject *__pyx_tuple__41; -static PyObject *__pyx_tuple__43; -static PyObject *__pyx_tuple__45; -static PyObject *__pyx_tuple__47; -static PyObject *__pyx_tuple__49; -static PyObject *__pyx_tuple__51; -static PyObject *__pyx_tuple__53; -static PyObject *__pyx_tuple__55; -static PyObject *__pyx_tuple__57; -static PyObject *__pyx_tuple__59; -static PyObject *__pyx_tuple__61; -static PyObject *__pyx_tuple__63; -static PyObject *__pyx_tuple__65; -static PyObject *__pyx_tuple__67; -static PyObject *__pyx_tuple__69; -static PyObject *__pyx_tuple__71; -static PyObject *__pyx_tuple__73; -static PyObject *__pyx_tuple__75; -static PyObject *__pyx_tuple__77; -static PyObject *__pyx_tuple__79; -static PyObject *__pyx_tuple__81; -static PyObject *__pyx_codeobj__34; -static PyObject *__pyx_codeobj__36; -static PyObject *__pyx_codeobj__38; -static PyObject *__pyx_codeobj__40; -static PyObject *__pyx_codeobj__42; -static PyObject *__pyx_codeobj__44; -static PyObject *__pyx_codeobj__46; -static PyObject *__pyx_codeobj__48; -static PyObject *__pyx_codeobj__50; -static PyObject *__pyx_codeobj__52; -static PyObject *__pyx_codeobj__54; -static PyObject *__pyx_codeobj__56; -static PyObject *__pyx_codeobj__58; -static PyObject *__pyx_codeobj__60; -static PyObject *__pyx_codeobj__62; -static PyObject *__pyx_codeobj__64; -static PyObject *__pyx_codeobj__66; -static PyObject *__pyx_codeobj__68; -static PyObject *__pyx_codeobj__70; -static PyObject *__pyx_codeobj__72; -static PyObject *__pyx_codeobj__74; -static PyObject *__pyx_codeobj__76; -static PyObject *__pyx_codeobj__78; -static PyObject *__pyx_codeobj__80; -static PyObject *__pyx_codeobj__82; -/* Late includes */ - -/* "src/questdb/size_t_vec.pxi":8 - * ctypedef c_size_t_vec size_t_vec - * - * cdef size_t_vec size_t_vec_new(): # <<<<<<<<<<<<<< - * cdef size_t_vec vec - * vec.capacity = 0 - */ - -static __pyx_t_7questdb_7ingress_size_t_vec __pyx_f_7questdb_7ingress_size_t_vec_new(void) { - __pyx_t_7questdb_7ingress_size_t_vec __pyx_v_vec; - __pyx_t_7questdb_7ingress_size_t_vec __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("size_t_vec_new", 0); - - /* "src/questdb/size_t_vec.pxi":10 - * cdef size_t_vec size_t_vec_new(): - * cdef size_t_vec vec - * vec.capacity = 0 # <<<<<<<<<<<<<< - * vec.size = 0 - * vec.d = NULL - */ - __pyx_v_vec.capacity = 0; - - /* "src/questdb/size_t_vec.pxi":11 - * cdef size_t_vec vec - * vec.capacity = 0 - * vec.size = 0 # <<<<<<<<<<<<<< - * vec.d = NULL - * return vec - */ - __pyx_v_vec.size = 0; - - /* "src/questdb/size_t_vec.pxi":12 - * vec.capacity = 0 - * vec.size = 0 - * vec.d = NULL # <<<<<<<<<<<<<< - * return vec - * - */ - __pyx_v_vec.d = ((size_t *)NULL); - - /* "src/questdb/size_t_vec.pxi":13 - * vec.size = 0 - * vec.d = NULL - * return vec # <<<<<<<<<<<<<< - * - * cdef void size_t_vec_free(size_t_vec* vec): - */ - __pyx_r = __pyx_v_vec; - goto __pyx_L0; - - /* "src/questdb/size_t_vec.pxi":8 - * ctypedef c_size_t_vec size_t_vec - * - * cdef size_t_vec size_t_vec_new(): # <<<<<<<<<<<<<< - * cdef size_t_vec vec - * vec.capacity = 0 - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/size_t_vec.pxi":15 - * return vec - * - * cdef void size_t_vec_free(size_t_vec* vec): # <<<<<<<<<<<<<< - * if vec.d: - * free(vec.d) - */ - -static void __pyx_f_7questdb_7ingress_size_t_vec_free(__pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_vec) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("size_t_vec_free", 0); - - /* "src/questdb/size_t_vec.pxi":16 - * - * cdef void size_t_vec_free(size_t_vec* vec): - * if vec.d: # <<<<<<<<<<<<<< - * free(vec.d) - * vec.d = NULL - */ - __pyx_t_1 = (__pyx_v_vec->d != 0); - if (__pyx_t_1) { - - /* "src/questdb/size_t_vec.pxi":17 - * cdef void size_t_vec_free(size_t_vec* vec): - * if vec.d: - * free(vec.d) # <<<<<<<<<<<<<< - * vec.d = NULL - * - */ - free(__pyx_v_vec->d); - - /* "src/questdb/size_t_vec.pxi":18 - * if vec.d: - * free(vec.d) - * vec.d = NULL # <<<<<<<<<<<<<< - * - * cdef str size_t_vec_str(size_t_vec* vec): - */ - __pyx_v_vec->d = NULL; - - /* "src/questdb/size_t_vec.pxi":16 - * - * cdef void size_t_vec_free(size_t_vec* vec): - * if vec.d: # <<<<<<<<<<<<<< - * free(vec.d) - * vec.d = NULL - */ - } - - /* "src/questdb/size_t_vec.pxi":15 - * return vec - * - * cdef void size_t_vec_free(size_t_vec* vec): # <<<<<<<<<<<<<< - * if vec.d: - * free(vec.d) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "src/questdb/size_t_vec.pxi":20 - * vec.d = NULL - * - * cdef str size_t_vec_str(size_t_vec* vec): # <<<<<<<<<<<<<< - * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) - * - */ - -static PyObject *__pyx_f_7questdb_7ingress_size_t_vec_str(__pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_vec) { - size_t __pyx_7genexpr__pyx_v_i; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - size_t __pyx_t_2; - size_t __pyx_t_3; - size_t __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("size_t_vec_str", 0); - - /* "src/questdb/size_t_vec.pxi":21 - * - * cdef str size_t_vec_str(size_t_vec* vec): - * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) # <<<<<<<<<<<<<< - * - * cdef void size_t_vec_push(size_t_vec* vec, size_t value): - */ - __Pyx_XDECREF(__pyx_r); - { /* enter inner scope */ - __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 21, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __pyx_v_vec->size; - __pyx_t_3 = __pyx_t_2; - for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { - __pyx_7genexpr__pyx_v_i = __pyx_t_4; - __pyx_t_5 = __Pyx_PyInt_FromSize_t((__pyx_v_vec->d[__pyx_7genexpr__pyx_v_i])); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 21, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(1, 21, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - } /* exit inner scope */ - __pyx_t_5 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 21, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_n_u_size_t_vec, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 21, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_r = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "src/questdb/size_t_vec.pxi":20 - * vec.d = NULL - * - * cdef str size_t_vec_str(size_t_vec* vec): # <<<<<<<<<<<<<< - * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("questdb.ingress.size_t_vec_str", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/size_t_vec.pxi":23 - * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) - * - * cdef void size_t_vec_push(size_t_vec* vec, size_t value): # <<<<<<<<<<<<<< - * if vec.capacity == 0: - * vec.capacity = 8 - */ - -static void __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_vec, size_t __pyx_v_value) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("size_t_vec_push", 0); - - /* "src/questdb/size_t_vec.pxi":24 - * - * cdef void size_t_vec_push(size_t_vec* vec, size_t value): - * if vec.capacity == 0: # <<<<<<<<<<<<<< - * vec.capacity = 8 - * vec.d = malloc(vec.capacity * sizeof(size_t)) - */ - __pyx_t_1 = ((__pyx_v_vec->capacity == 0) != 0); - if (__pyx_t_1) { - - /* "src/questdb/size_t_vec.pxi":25 - * cdef void size_t_vec_push(size_t_vec* vec, size_t value): - * if vec.capacity == 0: - * vec.capacity = 8 # <<<<<<<<<<<<<< - * vec.d = malloc(vec.capacity * sizeof(size_t)) - * if vec.d == NULL: - */ - __pyx_v_vec->capacity = 8; - - /* "src/questdb/size_t_vec.pxi":26 - * if vec.capacity == 0: - * vec.capacity = 8 - * vec.d = malloc(vec.capacity * sizeof(size_t)) # <<<<<<<<<<<<<< - * if vec.d == NULL: - * abort() - */ - __pyx_v_vec->d = ((size_t *)malloc((__pyx_v_vec->capacity * (sizeof(size_t))))); - - /* "src/questdb/size_t_vec.pxi":27 - * vec.capacity = 8 - * vec.d = malloc(vec.capacity * sizeof(size_t)) - * if vec.d == NULL: # <<<<<<<<<<<<<< - * abort() - * elif vec.size == vec.capacity: - */ - __pyx_t_1 = ((__pyx_v_vec->d == NULL) != 0); - if (__pyx_t_1) { - - /* "src/questdb/size_t_vec.pxi":28 - * vec.d = malloc(vec.capacity * sizeof(size_t)) - * if vec.d == NULL: - * abort() # <<<<<<<<<<<<<< - * elif vec.size == vec.capacity: - * vec.capacity = vec.capacity * 2 - */ - abort(); - - /* "src/questdb/size_t_vec.pxi":27 - * vec.capacity = 8 - * vec.d = malloc(vec.capacity * sizeof(size_t)) - * if vec.d == NULL: # <<<<<<<<<<<<<< - * abort() - * elif vec.size == vec.capacity: - */ - } - - /* "src/questdb/size_t_vec.pxi":24 - * - * cdef void size_t_vec_push(size_t_vec* vec, size_t value): - * if vec.capacity == 0: # <<<<<<<<<<<<<< - * vec.capacity = 8 - * vec.d = malloc(vec.capacity * sizeof(size_t)) - */ - goto __pyx_L3; - } - - /* "src/questdb/size_t_vec.pxi":29 - * if vec.d == NULL: - * abort() - * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< - * vec.capacity = vec.capacity * 2 - * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - */ - __pyx_t_1 = ((__pyx_v_vec->size == __pyx_v_vec->capacity) != 0); - if (__pyx_t_1) { - - /* "src/questdb/size_t_vec.pxi":30 - * abort() - * elif vec.size == vec.capacity: - * vec.capacity = vec.capacity * 2 # <<<<<<<<<<<<<< - * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - * if not vec.d: - */ - __pyx_v_vec->capacity = (__pyx_v_vec->capacity * 2); - - /* "src/questdb/size_t_vec.pxi":31 - * elif vec.size == vec.capacity: - * vec.capacity = vec.capacity * 2 - * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) # <<<<<<<<<<<<<< - * if not vec.d: - * abort() - */ - __pyx_v_vec->d = ((size_t *)realloc(__pyx_v_vec->d, (__pyx_v_vec->capacity * (sizeof(size_t))))); - - /* "src/questdb/size_t_vec.pxi":32 - * vec.capacity = vec.capacity * 2 - * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - * if not vec.d: # <<<<<<<<<<<<<< - * abort() - * vec.d[vec.size] = value - */ - __pyx_t_1 = ((!(__pyx_v_vec->d != 0)) != 0); - if (__pyx_t_1) { - - /* "src/questdb/size_t_vec.pxi":33 - * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - * if not vec.d: - * abort() # <<<<<<<<<<<<<< - * vec.d[vec.size] = value - * vec.size += 1 - */ - abort(); - - /* "src/questdb/size_t_vec.pxi":32 - * vec.capacity = vec.capacity * 2 - * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - * if not vec.d: # <<<<<<<<<<<<<< - * abort() - * vec.d[vec.size] = value - */ - } - - /* "src/questdb/size_t_vec.pxi":29 - * if vec.d == NULL: - * abort() - * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< - * vec.capacity = vec.capacity * 2 - * vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - */ - } - __pyx_L3:; - - /* "src/questdb/size_t_vec.pxi":34 - * if not vec.d: - * abort() - * vec.d[vec.size] = value # <<<<<<<<<<<<<< - * vec.size += 1 - */ - (__pyx_v_vec->d[__pyx_v_vec->size]) = __pyx_v_value; - - /* "src/questdb/size_t_vec.pxi":35 - * abort() - * vec.d[vec.size] = value - * vec.size += 1 # <<<<<<<<<<<<<< - */ - __pyx_v_vec->size = (__pyx_v_vec->size + 1); - - /* "src/questdb/size_t_vec.pxi":23 - * return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) - * - * cdef void size_t_vec_push(size_t_vec* vec, size_t value): # <<<<<<<<<<<<<< - * if vec.capacity == 0: - * vec.capacity = 8 - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "src/questdb/column_name_vec.pxi":8 - * ctypedef c_column_name_vec column_name_vec - * - * cdef column_name_vec column_name_vec_new(): # <<<<<<<<<<<<<< - * cdef column_name_vec vec - * vec.capacity = 0 - */ - -static __pyx_t_7questdb_7ingress_column_name_vec __pyx_f_7questdb_7ingress_column_name_vec_new(void) { - __pyx_t_7questdb_7ingress_column_name_vec __pyx_v_vec; - __pyx_t_7questdb_7ingress_column_name_vec __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("column_name_vec_new", 0); - - /* "src/questdb/column_name_vec.pxi":10 - * cdef column_name_vec column_name_vec_new(): - * cdef column_name_vec vec - * vec.capacity = 0 # <<<<<<<<<<<<<< - * vec.size = 0 - * vec.d = NULL - */ - __pyx_v_vec.capacity = 0; - - /* "src/questdb/column_name_vec.pxi":11 - * cdef column_name_vec vec - * vec.capacity = 0 - * vec.size = 0 # <<<<<<<<<<<<<< - * vec.d = NULL - * return vec - */ - __pyx_v_vec.size = 0; - - /* "src/questdb/column_name_vec.pxi":12 - * vec.capacity = 0 - * vec.size = 0 - * vec.d = NULL # <<<<<<<<<<<<<< - * return vec - * - */ - __pyx_v_vec.d = ((struct line_sender_column_name *)NULL); - - /* "src/questdb/column_name_vec.pxi":13 - * vec.size = 0 - * vec.d = NULL - * return vec # <<<<<<<<<<<<<< - * - * cdef void column_name_vec_free(column_name_vec* vec): - */ - __pyx_r = __pyx_v_vec; - goto __pyx_L0; - - /* "src/questdb/column_name_vec.pxi":8 - * ctypedef c_column_name_vec column_name_vec - * - * cdef column_name_vec column_name_vec_new(): # <<<<<<<<<<<<<< - * cdef column_name_vec vec - * vec.capacity = 0 - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/column_name_vec.pxi":15 - * return vec - * - * cdef void column_name_vec_free(column_name_vec* vec): # <<<<<<<<<<<<<< - * if vec.d: - * free(vec.d) - */ - -static void __pyx_f_7questdb_7ingress_column_name_vec_free(__pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_vec) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("column_name_vec_free", 0); - - /* "src/questdb/column_name_vec.pxi":16 - * - * cdef void column_name_vec_free(column_name_vec* vec): - * if vec.d: # <<<<<<<<<<<<<< - * free(vec.d) - * vec.d = NULL - */ - __pyx_t_1 = (__pyx_v_vec->d != 0); - if (__pyx_t_1) { - - /* "src/questdb/column_name_vec.pxi":17 - * cdef void column_name_vec_free(column_name_vec* vec): - * if vec.d: - * free(vec.d) # <<<<<<<<<<<<<< - * vec.d = NULL - * - */ - free(__pyx_v_vec->d); - - /* "src/questdb/column_name_vec.pxi":18 - * if vec.d: - * free(vec.d) - * vec.d = NULL # <<<<<<<<<<<<<< - * - * cdef void column_name_vec_push( - */ - __pyx_v_vec->d = NULL; - - /* "src/questdb/column_name_vec.pxi":16 - * - * cdef void column_name_vec_free(column_name_vec* vec): - * if vec.d: # <<<<<<<<<<<<<< - * free(vec.d) - * vec.d = NULL - */ - } - - /* "src/questdb/column_name_vec.pxi":15 - * return vec - * - * cdef void column_name_vec_free(column_name_vec* vec): # <<<<<<<<<<<<<< - * if vec.d: - * free(vec.d) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "src/questdb/column_name_vec.pxi":20 - * vec.d = NULL - * - * cdef void column_name_vec_push( # <<<<<<<<<<<<<< - * column_name_vec* vec, line_sender_column_name value): - * if vec.capacity == 0: - */ - -static void __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_vec, struct line_sender_column_name __pyx_v_value) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("column_name_vec_push", 0); - - /* "src/questdb/column_name_vec.pxi":22 - * cdef void column_name_vec_push( - * column_name_vec* vec, line_sender_column_name value): - * if vec.capacity == 0: # <<<<<<<<<<<<<< - * vec.capacity = 8 - * vec.d = malloc( - */ - __pyx_t_1 = ((__pyx_v_vec->capacity == 0) != 0); - if (__pyx_t_1) { - - /* "src/questdb/column_name_vec.pxi":23 - * column_name_vec* vec, line_sender_column_name value): - * if vec.capacity == 0: - * vec.capacity = 8 # <<<<<<<<<<<<<< - * vec.d = malloc( - * vec.capacity * sizeof(line_sender_column_name)) - */ - __pyx_v_vec->capacity = 8; - - /* "src/questdb/column_name_vec.pxi":24 - * if vec.capacity == 0: - * vec.capacity = 8 - * vec.d = malloc( # <<<<<<<<<<<<<< - * vec.capacity * sizeof(line_sender_column_name)) - * if vec.d == NULL: - */ - __pyx_v_vec->d = ((struct line_sender_column_name *)malloc((__pyx_v_vec->capacity * (sizeof(struct line_sender_column_name))))); - - /* "src/questdb/column_name_vec.pxi":26 - * vec.d = malloc( - * vec.capacity * sizeof(line_sender_column_name)) - * if vec.d == NULL: # <<<<<<<<<<<<<< - * abort() - * elif vec.size == vec.capacity: - */ - __pyx_t_1 = ((__pyx_v_vec->d == NULL) != 0); - if (__pyx_t_1) { - - /* "src/questdb/column_name_vec.pxi":27 - * vec.capacity * sizeof(line_sender_column_name)) - * if vec.d == NULL: - * abort() # <<<<<<<<<<<<<< - * elif vec.size == vec.capacity: - * vec.capacity = vec.capacity * 2 - */ - abort(); - - /* "src/questdb/column_name_vec.pxi":26 - * vec.d = malloc( - * vec.capacity * sizeof(line_sender_column_name)) - * if vec.d == NULL: # <<<<<<<<<<<<<< - * abort() - * elif vec.size == vec.capacity: - */ - } - - /* "src/questdb/column_name_vec.pxi":22 - * cdef void column_name_vec_push( - * column_name_vec* vec, line_sender_column_name value): - * if vec.capacity == 0: # <<<<<<<<<<<<<< - * vec.capacity = 8 - * vec.d = malloc( - */ - goto __pyx_L3; - } - - /* "src/questdb/column_name_vec.pxi":28 - * if vec.d == NULL: - * abort() - * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< - * vec.capacity = vec.capacity * 2 - * vec.d = realloc( - */ - __pyx_t_1 = ((__pyx_v_vec->size == __pyx_v_vec->capacity) != 0); - if (__pyx_t_1) { - - /* "src/questdb/column_name_vec.pxi":29 - * abort() - * elif vec.size == vec.capacity: - * vec.capacity = vec.capacity * 2 # <<<<<<<<<<<<<< - * vec.d = realloc( - * vec.d, - */ - __pyx_v_vec->capacity = (__pyx_v_vec->capacity * 2); - - /* "src/questdb/column_name_vec.pxi":30 - * elif vec.size == vec.capacity: - * vec.capacity = vec.capacity * 2 - * vec.d = realloc( # <<<<<<<<<<<<<< - * vec.d, - * vec.capacity * sizeof(line_sender_column_name)) - */ - __pyx_v_vec->d = ((struct line_sender_column_name *)realloc(__pyx_v_vec->d, (__pyx_v_vec->capacity * (sizeof(struct line_sender_column_name))))); - - /* "src/questdb/column_name_vec.pxi":33 - * vec.d, - * vec.capacity * sizeof(line_sender_column_name)) - * if not vec.d: # <<<<<<<<<<<<<< - * abort() - * vec.d[vec.size] = value - */ - __pyx_t_1 = ((!(__pyx_v_vec->d != 0)) != 0); - if (__pyx_t_1) { - - /* "src/questdb/column_name_vec.pxi":34 - * vec.capacity * sizeof(line_sender_column_name)) - * if not vec.d: - * abort() # <<<<<<<<<<<<<< - * vec.d[vec.size] = value - * vec.size += 1 - */ - abort(); - - /* "src/questdb/column_name_vec.pxi":33 - * vec.d, - * vec.capacity * sizeof(line_sender_column_name)) - * if not vec.d: # <<<<<<<<<<<<<< - * abort() - * vec.d[vec.size] = value - */ - } - - /* "src/questdb/column_name_vec.pxi":28 - * if vec.d == NULL: - * abort() - * elif vec.size == vec.capacity: # <<<<<<<<<<<<<< - * vec.capacity = vec.capacity * 2 - * vec.d = realloc( - */ - } - __pyx_L3:; - - /* "src/questdb/column_name_vec.pxi":35 - * if not vec.d: - * abort() - * vec.d[vec.size] = value # <<<<<<<<<<<<<< - * vec.size += 1 - */ - (__pyx_v_vec->d[__pyx_v_vec->size]) = __pyx_v_value; - - /* "src/questdb/column_name_vec.pxi":36 - * abort() - * vec.d[vec.size] = value - * vec.size += 1 # <<<<<<<<<<<<<< - */ - __pyx_v_vec->size = (__pyx_v_vec->size + 1); - - /* "src/questdb/column_name_vec.pxi":20 - * vec.d = NULL - * - * cdef void column_name_vec_push( # <<<<<<<<<<<<<< - * column_name_vec* vec, line_sender_column_name value): - * if vec.capacity == 0: - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "src/questdb/pandas_helpers.pxi":79 - * - * - * cdef object _pandas_may_set_na_type(): # <<<<<<<<<<<<<< - * global _PANDAS_NA - * if _PANDAS_NA is None: - */ - -static PyObject *__pyx_f_7questdb_7ingress__pandas_may_set_na_type(void) { - PyObject *__pyx_v_pd = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_may_set_na_type", 0); - - /* "src/questdb/pandas_helpers.pxi":81 - * cdef object _pandas_may_set_na_type(): - * global _PANDAS_NA - * if _PANDAS_NA is None: # <<<<<<<<<<<<<< - * import pandas as pd - * _PANDAS_NA = pd.NA - */ - __pyx_t_1 = (__pyx_v_7questdb_7ingress__PANDAS_NA == Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":82 - * global _PANDAS_NA - * if _PANDAS_NA is None: - * import pandas as pd # <<<<<<<<<<<<<< - * _PANDAS_NA = pd.NA - * - */ - __pyx_t_3 = __Pyx_Import(__pyx_n_s_pandas, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_v_pd = __pyx_t_3; - __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":83 - * if _PANDAS_NA is None: - * import pandas as pd - * _PANDAS_NA = pd.NA # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_pd, __pyx_n_s_NA); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 83, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_v_7questdb_7ingress__PANDAS_NA); - __Pyx_DECREF_SET(__pyx_v_7questdb_7ingress__PANDAS_NA, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":81 - * cdef object _pandas_may_set_na_type(): - * global _PANDAS_NA - * if _PANDAS_NA is None: # <<<<<<<<<<<<<< - * import pandas as pd - * _PANDAS_NA = pd.NA - */ - } - - /* "src/questdb/pandas_helpers.pxi":79 - * - * - * cdef object _pandas_may_set_na_type(): # <<<<<<<<<<<<<< - * global _PANDAS_NA - * if _PANDAS_NA is None: - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress._pandas_may_set_na_type", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_pd); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":86 - * - * - * cdef ssize_t _pandas_resolve_table_name( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * object data, - */ - -static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_table_name(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, size_t __pyx_v_col_count, struct line_sender_table_name *__pyx_v_name_out) { - size_t __pyx_v_col_index; - PyObject *__pyx_v_ie = NULL; - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_t_10; - PyObject *__pyx_t_11 = NULL; - int __pyx_t_12; - char const *__pyx_t_13; - PyObject *__pyx_t_14 = NULL; - PyObject *__pyx_t_15 = NULL; - PyObject *__pyx_t_16 = NULL; - PyObject *__pyx_t_17 = NULL; - PyObject *__pyx_t_18 = NULL; - PyObject *__pyx_t_19 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_resolve_table_name", 0); - - /* "src/questdb/pandas_helpers.pxi":107 - * This method validates input and may raise. - * """ - * cdef size_t col_index = 0 # <<<<<<<<<<<<<< - * if table_name is not None: - * if table_name_col is not None: - */ - __pyx_v_col_index = 0; - - /* "src/questdb/pandas_helpers.pxi":108 - * """ - * cdef size_t col_index = 0 - * if table_name is not None: # <<<<<<<<<<<<<< - * if table_name_col is not None: - * raise ValueError( - */ - __pyx_t_1 = (__pyx_v_table_name != Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":109 - * cdef size_t col_index = 0 - * if table_name is not None: - * if table_name_col is not None: # <<<<<<<<<<<<<< - * raise ValueError( - * 'Can specify only one of `table_name` or `table_name_col`.') - */ - __pyx_t_2 = (__pyx_v_table_name_col != Py_None); - __pyx_t_1 = (__pyx_t_2 != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":110 - * if table_name is not None: - * if table_name_col is not None: - * raise ValueError( # <<<<<<<<<<<<<< - * 'Can specify only one of `table_name` or `table_name_col`.') - * if isinstance(table_name, str): - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 110, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":109 - * cdef size_t col_index = 0 - * if table_name is not None: - * if table_name_col is not None: # <<<<<<<<<<<<<< - * raise ValueError( - * 'Can specify only one of `table_name` or `table_name_col`.') - */ - } - - /* "src/questdb/pandas_helpers.pxi":112 - * raise ValueError( - * 'Can specify only one of `table_name` or `table_name_col`.') - * if isinstance(table_name, str): # <<<<<<<<<<<<<< - * try: - * str_to_table_name(b, table_name, name_out) - */ - __pyx_t_1 = PyUnicode_Check(__pyx_v_table_name); - __pyx_t_2 = (__pyx_t_1 != 0); - if (likely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":113 - * 'Can specify only one of `table_name` or `table_name_col`.') - * if isinstance(table_name, str): - * try: # <<<<<<<<<<<<<< - * str_to_table_name(b, table_name, name_out) - * return -1 # Magic value for "no column index". - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - /*try:*/ { - - /* "src/questdb/pandas_helpers.pxi":114 - * if isinstance(table_name, str): - * try: - * str_to_table_name(b, table_name, name_out) # <<<<<<<<<<<<<< - * return -1 # Magic value for "no column index". - * except IngressError as ie: - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_table_name))||((__pyx_v_table_name) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_table_name)->tp_name), 0))) __PYX_ERR(2, 114, __pyx_L6_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_str_to_table_name(__pyx_v_b, ((PyObject*)__pyx_v_table_name), __pyx_v_name_out); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 114, __pyx_L6_error) - - /* "src/questdb/pandas_helpers.pxi":115 - * try: - * str_to_table_name(b, table_name, name_out) - * return -1 # Magic value for "no column index". # <<<<<<<<<<<<<< - * except IngressError as ie: - * raise ValueError(f'Bad argument `table_name`: {ie}') - */ - __pyx_r = -1L; - goto __pyx_L10_try_return; - - /* "src/questdb/pandas_helpers.pxi":113 - * 'Can specify only one of `table_name` or `table_name_col`.') - * if isinstance(table_name, str): - * try: # <<<<<<<<<<<<<< - * str_to_table_name(b, table_name, name_out) - * return -1 # Magic value for "no column index". - */ - } - __pyx_L6_error:; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":116 - * str_to_table_name(b, table_name, name_out) - * return -1 # Magic value for "no column index". - * except IngressError as ie: # <<<<<<<<<<<<<< - * raise ValueError(f'Bad argument `table_name`: {ie}') - * else: - */ - __Pyx_ErrFetch(&__pyx_t_3, &__pyx_t_7, &__pyx_t_8); - __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 116, __pyx_L8_except_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_10 = __Pyx_PyErr_GivenExceptionMatches(__pyx_t_3, __pyx_t_9); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_ErrRestore(__pyx_t_3, __pyx_t_7, __pyx_t_8); - __pyx_t_3 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; - if (__pyx_t_10) { - __Pyx_AddTraceback("questdb.ingress._pandas_resolve_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_3) < 0) __PYX_ERR(2, 116, __pyx_L8_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_7); - __pyx_v_ie = __pyx_t_7; - /*try:*/ { - - /* "src/questdb/pandas_helpers.pxi":117 - * return -1 # Magic value for "no column index". - * except IngressError as ie: - * raise ValueError(f'Bad argument `table_name`: {ie}') # <<<<<<<<<<<<<< - * else: - * raise TypeError('Bad argument `table_name`: Must be str.') - */ - __pyx_t_9 = __Pyx_PyObject_FormatSimple(__pyx_v_ie, __pyx_empty_unicode); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 117, __pyx_L17_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_argument_table_name, __pyx_t_9); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 117, __pyx_L17_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_11); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 117, __pyx_L17_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(2, 117, __pyx_L17_error) - } - - /* "src/questdb/pandas_helpers.pxi":116 - * str_to_table_name(b, table_name, name_out) - * return -1 # Magic value for "no column index". - * except IngressError as ie: # <<<<<<<<<<<<<< - * raise ValueError(f'Bad argument `table_name`: {ie}') - * else: - */ - /*finally:*/ { - __pyx_L17_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16) < 0)) __Pyx_ErrFetch(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16); - __Pyx_XGOTREF(__pyx_t_14); - __Pyx_XGOTREF(__pyx_t_15); - __Pyx_XGOTREF(__pyx_t_16); - __Pyx_XGOTREF(__pyx_t_17); - __Pyx_XGOTREF(__pyx_t_18); - __Pyx_XGOTREF(__pyx_t_19); - __pyx_t_10 = __pyx_lineno; __pyx_t_12 = __pyx_clineno; __pyx_t_13 = __pyx_filename; - { - __Pyx_DECREF(__pyx_v_ie); - __pyx_v_ie = NULL; - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_17); - __Pyx_XGIVEREF(__pyx_t_18); - __Pyx_XGIVEREF(__pyx_t_19); - __Pyx_ExceptionReset(__pyx_t_17, __pyx_t_18, __pyx_t_19); - } - __Pyx_XGIVEREF(__pyx_t_14); - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_XGIVEREF(__pyx_t_16); - __Pyx_ErrRestore(__pyx_t_14, __pyx_t_15, __pyx_t_16); - __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; - __pyx_lineno = __pyx_t_10; __pyx_clineno = __pyx_t_12; __pyx_filename = __pyx_t_13; - goto __pyx_L8_except_error; - } - } - } - goto __pyx_L8_except_error; - __pyx_L8_except_error:; - - /* "src/questdb/pandas_helpers.pxi":113 - * 'Can specify only one of `table_name` or `table_name_col`.') - * if isinstance(table_name, str): - * try: # <<<<<<<<<<<<<< - * str_to_table_name(b, table_name, name_out) - * return -1 # Magic value for "no column index". - */ - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); - goto __pyx_L1_error; - __pyx_L10_try_return:; - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); - goto __pyx_L0; - } - - /* "src/questdb/pandas_helpers.pxi":112 - * raise ValueError( - * 'Can specify only one of `table_name` or `table_name_col`.') - * if isinstance(table_name, str): # <<<<<<<<<<<<<< - * try: - * str_to_table_name(b, table_name, name_out) - */ - } - - /* "src/questdb/pandas_helpers.pxi":119 - * raise ValueError(f'Bad argument `table_name`: {ie}') - * else: - * raise TypeError('Bad argument `table_name`: Must be str.') # <<<<<<<<<<<<<< - * elif table_name_col is not None: - * if isinstance(table_name_col, str): - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 119, __pyx_L1_error) - } - - /* "src/questdb/pandas_helpers.pxi":108 - * """ - * cdef size_t col_index = 0 - * if table_name is not None: # <<<<<<<<<<<<<< - * if table_name_col is not None: - * raise ValueError( - */ - } - - /* "src/questdb/pandas_helpers.pxi":120 - * else: - * raise TypeError('Bad argument `table_name`: Must be str.') - * elif table_name_col is not None: # <<<<<<<<<<<<<< - * if isinstance(table_name_col, str): - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - */ - __pyx_t_2 = (__pyx_v_table_name_col != Py_None); - __pyx_t_1 = (__pyx_t_2 != 0); - if (likely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":121 - * raise TypeError('Bad argument `table_name`: Must be str.') - * elif table_name_col is not None: - * if isinstance(table_name_col, str): # <<<<<<<<<<<<<< - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - * elif isinstance(table_name_col, int): - */ - __pyx_t_1 = PyUnicode_Check(__pyx_v_table_name_col); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":122 - * elif table_name_col is not None: - * if isinstance(table_name_col, str): - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) # <<<<<<<<<<<<<< - * elif isinstance(table_name_col, int): - * _bind_col_index( - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_table_name_col))||((__pyx_v_table_name_col) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_table_name_col)->tp_name), 0))) __PYX_ERR(2, 122, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress__pandas_get_loc(__pyx_v_data, ((PyObject*)__pyx_v_table_name_col), __pyx_n_u_table_name_col, (&__pyx_v_col_index)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 122, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":121 - * raise TypeError('Bad argument `table_name`: Must be str.') - * elif table_name_col is not None: - * if isinstance(table_name_col, str): # <<<<<<<<<<<<<< - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - * elif isinstance(table_name_col, int): - */ - goto __pyx_L23; - } - - /* "src/questdb/pandas_helpers.pxi":123 - * if isinstance(table_name_col, str): - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - * elif isinstance(table_name_col, int): # <<<<<<<<<<<<<< - * _bind_col_index( - * 'table_name_col', table_name_col, col_count, &col_index) - */ - __pyx_t_2 = PyInt_Check(__pyx_v_table_name_col); - __pyx_t_1 = (__pyx_t_2 != 0); - if (likely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":125 - * elif isinstance(table_name_col, int): - * _bind_col_index( - * 'table_name_col', table_name_col, col_count, &col_index) # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_table_name_col); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 125, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":124 - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - * elif isinstance(table_name_col, int): - * _bind_col_index( # <<<<<<<<<<<<<< - * 'table_name_col', table_name_col, col_count, &col_index) - * else: - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress__bind_col_index(__pyx_n_u_table_name_col, __pyx_t_12, __pyx_v_col_count, (&__pyx_v_col_index)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 124, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":123 - * if isinstance(table_name_col, str): - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - * elif isinstance(table_name_col, int): # <<<<<<<<<<<<<< - * _bind_col_index( - * 'table_name_col', table_name_col, col_count, &col_index) - */ - goto __pyx_L23; - } - - /* "src/questdb/pandas_helpers.pxi":127 - * 'table_name_col', table_name_col, col_count, &col_index) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * 'Bad argument `table_name_col`: ' + - * 'must be a column name (str) or index (int).') - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 127, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 127, __pyx_L1_error) - } - __pyx_L23:; - - /* "src/questdb/pandas_helpers.pxi":130 - * 'Bad argument `table_name_col`: ' + - * 'must be a column name (str) or index (int).') - * _pandas_check_column_is_str( # <<<<<<<<<<<<<< - * data, - * col_index, - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress__pandas_check_column_is_str(__pyx_v_data, __pyx_v_col_index, __pyx_kp_u_Bad_argument_table_name_col, __pyx_v_table_name_col); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 130, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":135 - * 'Bad argument `table_name_col`: ', - * table_name_col) - * return col_index # <<<<<<<<<<<<<< - * else: - * raise ValueError( - */ - __pyx_r = __pyx_v_col_index; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":120 - * else: - * raise TypeError('Bad argument `table_name`: Must be str.') - * elif table_name_col is not None: # <<<<<<<<<<<<<< - * if isinstance(table_name_col, str): - * _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) - */ - } - - /* "src/questdb/pandas_helpers.pxi":137 - * return col_index - * else: - * raise ValueError( # <<<<<<<<<<<<<< - * 'Must specify at least one of `table_name` or `table_name_col`.') - * - */ - /*else*/ { - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 137, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 137, __pyx_L1_error) - } - - /* "src/questdb/pandas_helpers.pxi":86 - * - * - * cdef ssize_t _pandas_resolve_table_name( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * object data, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("questdb.ingress._pandas_resolve_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -2L; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_ie); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":141 - * - * - * cdef int _pandas_resolve_fields( # <<<<<<<<<<<<<< - * int name_col, - * const size_t_vec* symbol_indices, - */ - -static int __pyx_f_7questdb_7ingress__pandas_resolve_fields(int __pyx_v_name_col, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_symbol_indices, int __pyx_v_at_col, size_t __pyx_v_col_count, __pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_field_indices_out) { - size_t __pyx_v_col_index; - size_t __pyx_v_sym_index; - size_t __pyx_v_sym_len; - int __pyx_r; - __Pyx_RefNannyDeclarations - size_t __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - __Pyx_RefNannySetupContext("_pandas_resolve_fields", 0); - - /* "src/questdb/pandas_helpers.pxi":154 - * """ - * # We rely on `symbol_indices` being sorted. - * cdef size_t col_index = 0 # <<<<<<<<<<<<<< - * cdef size_t sym_index = 0 - * cdef size_t sym_len = symbol_indices.size - */ - __pyx_v_col_index = 0; - - /* "src/questdb/pandas_helpers.pxi":155 - * # We rely on `symbol_indices` being sorted. - * cdef size_t col_index = 0 - * cdef size_t sym_index = 0 # <<<<<<<<<<<<<< - * cdef size_t sym_len = symbol_indices.size - * while col_index < col_count: - */ - __pyx_v_sym_index = 0; - - /* "src/questdb/pandas_helpers.pxi":156 - * cdef size_t col_index = 0 - * cdef size_t sym_index = 0 - * cdef size_t sym_len = symbol_indices.size # <<<<<<<<<<<<<< - * while col_index < col_count: - * if (name_col >= 0) and (col_index == name_col): - */ - __pyx_t_1 = __pyx_v_symbol_indices->size; - __pyx_v_sym_len = __pyx_t_1; - - /* "src/questdb/pandas_helpers.pxi":157 - * cdef size_t sym_index = 0 - * cdef size_t sym_len = symbol_indices.size - * while col_index < col_count: # <<<<<<<<<<<<<< - * if (name_col >= 0) and (col_index == name_col): - * col_index += 1 - */ - while (1) { - __pyx_t_2 = ((__pyx_v_col_index < __pyx_v_col_count) != 0); - if (!__pyx_t_2) break; - - /* "src/questdb/pandas_helpers.pxi":158 - * cdef size_t sym_len = symbol_indices.size - * while col_index < col_count: - * if (name_col >= 0) and (col_index == name_col): # <<<<<<<<<<<<<< - * col_index += 1 - * continue - */ - __pyx_t_3 = ((__pyx_v_name_col >= 0) != 0); - if (__pyx_t_3) { - } else { - __pyx_t_2 = __pyx_t_3; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_3 = ((__pyx_v_col_index == ((size_t)__pyx_v_name_col)) != 0); - __pyx_t_2 = __pyx_t_3; - __pyx_L6_bool_binop_done:; - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":159 - * while col_index < col_count: - * if (name_col >= 0) and (col_index == name_col): - * col_index += 1 # <<<<<<<<<<<<<< - * continue - * if (at_col >= 0) and (col_index == at_col): - */ - __pyx_v_col_index = (__pyx_v_col_index + 1); - - /* "src/questdb/pandas_helpers.pxi":160 - * if (name_col >= 0) and (col_index == name_col): - * col_index += 1 - * continue # <<<<<<<<<<<<<< - * if (at_col >= 0) and (col_index == at_col): - * col_index += 1 - */ - goto __pyx_L3_continue; - - /* "src/questdb/pandas_helpers.pxi":158 - * cdef size_t sym_len = symbol_indices.size - * while col_index < col_count: - * if (name_col >= 0) and (col_index == name_col): # <<<<<<<<<<<<<< - * col_index += 1 - * continue - */ - } - - /* "src/questdb/pandas_helpers.pxi":161 - * col_index += 1 - * continue - * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< - * col_index += 1 - * continue - */ - __pyx_t_3 = ((__pyx_v_at_col >= 0) != 0); - if (__pyx_t_3) { - } else { - __pyx_t_2 = __pyx_t_3; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_3 = ((__pyx_v_col_index == ((size_t)__pyx_v_at_col)) != 0); - __pyx_t_2 = __pyx_t_3; - __pyx_L9_bool_binop_done:; - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":162 - * continue - * if (at_col >= 0) and (col_index == at_col): - * col_index += 1 # <<<<<<<<<<<<<< - * continue - * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: - */ - __pyx_v_col_index = (__pyx_v_col_index + 1); - - /* "src/questdb/pandas_helpers.pxi":163 - * if (at_col >= 0) and (col_index == at_col): - * col_index += 1 - * continue # <<<<<<<<<<<<<< - * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: - * sym_index += 1 - */ - goto __pyx_L3_continue; - - /* "src/questdb/pandas_helpers.pxi":161 - * col_index += 1 - * continue - * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< - * col_index += 1 - * continue - */ - } - - /* "src/questdb/pandas_helpers.pxi":164 - * col_index += 1 - * continue - * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: # <<<<<<<<<<<<<< - * sym_index += 1 - * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: - */ - while (1) { - __pyx_t_3 = ((__pyx_v_sym_index < __pyx_v_sym_len) != 0); - if (__pyx_t_3) { - } else { - __pyx_t_2 = __pyx_t_3; - goto __pyx_L13_bool_binop_done; - } - __pyx_t_3 = (((__pyx_v_symbol_indices->d[__pyx_v_sym_index]) < __pyx_v_col_index) != 0); - __pyx_t_2 = __pyx_t_3; - __pyx_L13_bool_binop_done:; - if (!__pyx_t_2) break; - - /* "src/questdb/pandas_helpers.pxi":165 - * continue - * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: - * sym_index += 1 # <<<<<<<<<<<<<< - * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: - * col_index += 1 - */ - __pyx_v_sym_index = (__pyx_v_sym_index + 1); - } - - /* "src/questdb/pandas_helpers.pxi":166 - * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: - * sym_index += 1 - * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: # <<<<<<<<<<<<<< - * col_index += 1 - * continue - */ - __pyx_t_3 = ((__pyx_v_sym_index < __pyx_v_sym_len) != 0); - if (__pyx_t_3) { - } else { - __pyx_t_2 = __pyx_t_3; - goto __pyx_L16_bool_binop_done; - } - __pyx_t_3 = (((__pyx_v_symbol_indices->d[__pyx_v_sym_index]) == __pyx_v_col_index) != 0); - __pyx_t_2 = __pyx_t_3; - __pyx_L16_bool_binop_done:; - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":167 - * sym_index += 1 - * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: - * col_index += 1 # <<<<<<<<<<<<<< - * continue - * size_t_vec_push(field_indices_out, col_index) - */ - __pyx_v_col_index = (__pyx_v_col_index + 1); - - /* "src/questdb/pandas_helpers.pxi":168 - * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: - * col_index += 1 - * continue # <<<<<<<<<<<<<< - * size_t_vec_push(field_indices_out, col_index) - * col_index += 1 - */ - goto __pyx_L3_continue; - - /* "src/questdb/pandas_helpers.pxi":166 - * while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: - * sym_index += 1 - * if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: # <<<<<<<<<<<<<< - * col_index += 1 - * continue - */ - } - - /* "src/questdb/pandas_helpers.pxi":169 - * col_index += 1 - * continue - * size_t_vec_push(field_indices_out, col_index) # <<<<<<<<<<<<<< - * col_index += 1 - * return 0 - */ - __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_v_field_indices_out, __pyx_v_col_index); - - /* "src/questdb/pandas_helpers.pxi":170 - * continue - * size_t_vec_push(field_indices_out, col_index) - * col_index += 1 # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_v_col_index = (__pyx_v_col_index + 1); - __pyx_L3_continue:; - } - - /* "src/questdb/pandas_helpers.pxi":171 - * size_t_vec_push(field_indices_out, col_index) - * col_index += 1 - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":141 - * - * - * cdef int _pandas_resolve_fields( # <<<<<<<<<<<<<< - * int name_col, - * const size_t_vec* symbol_indices, - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":174 - * - * - * cdef bint _pandas_resolve_col_names( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * object data, - */ - -static int __pyx_f_7questdb_7ingress__pandas_resolve_col_names(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_data, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_symbol_indices, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_field_indices, __pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_symbol_names_out, __pyx_t_7questdb_7ingress_column_name_vec *__pyx_v_field_names_out) { - struct line_sender_column_name __pyx_v_c_name; - size_t __pyx_v_col_index; - int __pyx_r; - __Pyx_RefNannyDeclarations - size_t __pyx_t_1; - size_t __pyx_t_2; - size_t __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_resolve_col_names", 0); - - /* "src/questdb/pandas_helpers.pxi":183 - * cdef line_sender_column_name c_name - * cdef size_t col_index - * for col_index in range(symbol_indices.size): # <<<<<<<<<<<<<< - * col_index = symbol_indices.d[col_index] - * str_to_column_name(b, data.columns[col_index], &c_name) - */ - __pyx_t_1 = __pyx_v_symbol_indices->size; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_col_index = __pyx_t_3; - - /* "src/questdb/pandas_helpers.pxi":184 - * cdef size_t col_index - * for col_index in range(symbol_indices.size): - * col_index = symbol_indices.d[col_index] # <<<<<<<<<<<<<< - * str_to_column_name(b, data.columns[col_index], &c_name) - * column_name_vec_push(symbol_names_out, c_name) - */ - __pyx_v_col_index = (__pyx_v_symbol_indices->d[__pyx_v_col_index]); - - /* "src/questdb/pandas_helpers.pxi":185 - * for col_index in range(symbol_indices.size): - * col_index = symbol_indices.d[col_index] - * str_to_column_name(b, data.columns[col_index], &c_name) # <<<<<<<<<<<<<< - * column_name_vec_push(symbol_names_out, c_name) - * for col_index in range(field_indices.size): - */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 185, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 185, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (!(likely(PyUnicode_CheckExact(__pyx_t_5))||((__pyx_t_5) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_5)->tp_name), 0))) __PYX_ERR(2, 185, __pyx_L1_error) - __pyx_t_6 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_v_b, ((PyObject*)__pyx_t_5), (&__pyx_v_c_name)); if (unlikely(__pyx_t_6 == ((int)0))) __PYX_ERR(2, 185, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "src/questdb/pandas_helpers.pxi":186 - * col_index = symbol_indices.d[col_index] - * str_to_column_name(b, data.columns[col_index], &c_name) - * column_name_vec_push(symbol_names_out, c_name) # <<<<<<<<<<<<<< - * for col_index in range(field_indices.size): - * col_index = field_indices.d[col_index] - */ - __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_v_symbol_names_out, __pyx_v_c_name); - } - - /* "src/questdb/pandas_helpers.pxi":187 - * str_to_column_name(b, data.columns[col_index], &c_name) - * column_name_vec_push(symbol_names_out, c_name) - * for col_index in range(field_indices.size): # <<<<<<<<<<<<<< - * col_index = field_indices.d[col_index] - * str_to_column_name(b, data.columns[col_index], &c_name) - */ - __pyx_t_1 = __pyx_v_field_indices->size; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_col_index = __pyx_t_3; - - /* "src/questdb/pandas_helpers.pxi":188 - * column_name_vec_push(symbol_names_out, c_name) - * for col_index in range(field_indices.size): - * col_index = field_indices.d[col_index] # <<<<<<<<<<<<<< - * str_to_column_name(b, data.columns[col_index], &c_name) - * column_name_vec_push(field_names_out, c_name) - */ - __pyx_v_col_index = (__pyx_v_field_indices->d[__pyx_v_col_index]); - - /* "src/questdb/pandas_helpers.pxi":189 - * for col_index in range(field_indices.size): - * col_index = field_indices.d[col_index] - * str_to_column_name(b, data.columns[col_index], &c_name) # <<<<<<<<<<<<<< - * column_name_vec_push(field_names_out, c_name) - * return True - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 189, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_5, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 189, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (!(likely(PyUnicode_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 189, __pyx_L1_error) - __pyx_t_6 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_v_b, ((PyObject*)__pyx_t_4), (&__pyx_v_c_name)); if (unlikely(__pyx_t_6 == ((int)0))) __PYX_ERR(2, 189, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "src/questdb/pandas_helpers.pxi":190 - * col_index = field_indices.d[col_index] - * str_to_column_name(b, data.columns[col_index], &c_name) - * column_name_vec_push(field_names_out, c_name) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_f_7questdb_7ingress_column_name_vec_push(__pyx_v_field_names_out, __pyx_v_c_name); - } - - /* "src/questdb/pandas_helpers.pxi":191 - * str_to_column_name(b, data.columns[col_index], &c_name) - * column_name_vec_push(field_names_out, c_name) - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":174 - * - * - * cdef bint _pandas_resolve_col_names( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * object data, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("questdb.ingress._pandas_resolve_col_names", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":194 - * - * - * cdef bint _bind_col_index( # <<<<<<<<<<<<<< - * str arg_name, int col_num, size_t col_count, - * size_t* col_index) except False: - */ - -static int __pyx_f_7questdb_7ingress__bind_col_index(PyObject *__pyx_v_arg_name, int __pyx_v_col_num, size_t __pyx_v_col_count, size_t *__pyx_v_col_index) { - int __pyx_v_bad; - int __pyx_v_orig_col_num; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t __pyx_t_4; - Py_UCS4 __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_bind_col_index", 0); - - /* "src/questdb/pandas_helpers.pxi":202 - * positive indicies. - * """ - * cdef bint bad = False # <<<<<<<<<<<<<< - * cdef int orig_col_num = col_num - * if col_num < 0: - */ - __pyx_v_bad = 0; - - /* "src/questdb/pandas_helpers.pxi":203 - * """ - * cdef bint bad = False - * cdef int orig_col_num = col_num # <<<<<<<<<<<<<< - * if col_num < 0: - * col_num += col_count # Try convert negative offsets to positive ones. - */ - __pyx_v_orig_col_num = __pyx_v_col_num; - - /* "src/questdb/pandas_helpers.pxi":204 - * cdef bint bad = False - * cdef int orig_col_num = col_num - * if col_num < 0: # <<<<<<<<<<<<<< - * col_num += col_count # Try convert negative offsets to positive ones. - * if col_num < 0: - */ - __pyx_t_1 = ((__pyx_v_col_num < 0) != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":205 - * cdef int orig_col_num = col_num - * if col_num < 0: - * col_num += col_count # Try convert negative offsets to positive ones. # <<<<<<<<<<<<<< - * if col_num < 0: - * bad = True - */ - __pyx_v_col_num = (__pyx_v_col_num + __pyx_v_col_count); - - /* "src/questdb/pandas_helpers.pxi":204 - * cdef bint bad = False - * cdef int orig_col_num = col_num - * if col_num < 0: # <<<<<<<<<<<<<< - * col_num += col_count # Try convert negative offsets to positive ones. - * if col_num < 0: - */ - } - - /* "src/questdb/pandas_helpers.pxi":206 - * if col_num < 0: - * col_num += col_count # Try convert negative offsets to positive ones. - * if col_num < 0: # <<<<<<<<<<<<<< - * bad = True - * if (not bad) and (col_num >= col_count): - */ - __pyx_t_1 = ((__pyx_v_col_num < 0) != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":207 - * col_num += col_count # Try convert negative offsets to positive ones. - * if col_num < 0: - * bad = True # <<<<<<<<<<<<<< - * if (not bad) and (col_num >= col_count): - * bad = True - */ - __pyx_v_bad = 1; - - /* "src/questdb/pandas_helpers.pxi":206 - * if col_num < 0: - * col_num += col_count # Try convert negative offsets to positive ones. - * if col_num < 0: # <<<<<<<<<<<<<< - * bad = True - * if (not bad) and (col_num >= col_count): - */ - } - - /* "src/questdb/pandas_helpers.pxi":208 - * if col_num < 0: - * bad = True - * if (not bad) and (col_num >= col_count): # <<<<<<<<<<<<<< - * bad = True - * if bad: - */ - __pyx_t_2 = ((!(__pyx_v_bad != 0)) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_2 = ((((size_t)__pyx_v_col_num) >= __pyx_v_col_count) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L6_bool_binop_done:; - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":209 - * bad = True - * if (not bad) and (col_num >= col_count): - * bad = True # <<<<<<<<<<<<<< - * if bad: - * raise IndexError( - */ - __pyx_v_bad = 1; - - /* "src/questdb/pandas_helpers.pxi":208 - * if col_num < 0: - * bad = True - * if (not bad) and (col_num >= col_count): # <<<<<<<<<<<<<< - * bad = True - * if bad: - */ - } - - /* "src/questdb/pandas_helpers.pxi":210 - * if (not bad) and (col_num >= col_count): - * bad = True - * if bad: # <<<<<<<<<<<<<< - * raise IndexError( - * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') - */ - __pyx_t_1 = (__pyx_v_bad != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":212 - * if bad: - * raise IndexError( - * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') # <<<<<<<<<<<<<< - * col_index[0] = col_num - * return True - */ - __pyx_t_3 = PyTuple_New(5); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 212, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_Bad_argument); - __pyx_t_4 += 14; - __Pyx_GIVEREF(__pyx_kp_u_Bad_argument); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Bad_argument); - __pyx_t_6 = __Pyx_PyUnicode_Unicode(__pyx_v_arg_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 212, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__5); - __pyx_t_4 += 3; - __Pyx_GIVEREF(__pyx_kp_u__5); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__5); - __pyx_t_6 = __Pyx_PyUnicode_From_int(__pyx_v_orig_col_num, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 212, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u_index_out_of_range); - __pyx_t_4 += 19; - __Pyx_GIVEREF(__pyx_kp_u_index_out_of_range); - PyTuple_SET_ITEM(__pyx_t_3, 4, __pyx_kp_u_index_out_of_range); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 5, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 212, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":211 - * bad = True - * if bad: - * raise IndexError( # <<<<<<<<<<<<<< - * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') - * col_index[0] = col_num - */ - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IndexError, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 211, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 211, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":210 - * if (not bad) and (col_num >= col_count): - * bad = True - * if bad: # <<<<<<<<<<<<<< - * raise IndexError( - * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') - */ - } - - /* "src/questdb/pandas_helpers.pxi":213 - * raise IndexError( - * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') - * col_index[0] = col_num # <<<<<<<<<<<<<< - * return True - * - */ - (__pyx_v_col_index[0]) = ((size_t)__pyx_v_col_num); - - /* "src/questdb/pandas_helpers.pxi":214 - * f'Bad argument `{arg_name}`: {orig_col_num} index out of range') - * col_index[0] = col_num - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":194 - * - * - * cdef bint _bind_col_index( # <<<<<<<<<<<<<< - * str arg_name, int col_num, size_t col_count, - * size_t* col_index) except False: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("questdb.ingress._bind_col_index", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":217 - * - * - * cdef object _pandas_column_is_str(object data, int col_index): # <<<<<<<<<<<<<< - * """ - * Return True if the column at `col_index` is a string column. - */ - -static PyObject *__pyx_f_7questdb_7ingress__pandas_column_is_str(PyObject *__pyx_v_data, int __pyx_v_col_index) { - PyObject *__pyx_v_col_kind = 0; - PyObject *__pyx_v_col = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - int __pyx_t_4; - Py_ssize_t __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_column_is_str", 0); - - /* "src/questdb/pandas_helpers.pxi":224 - * cdef str col_kind - * cdef object col - * col_kind = data.dtypes[col_index].kind # <<<<<<<<<<<<<< - * if col_kind == 'S': # string, string[pyarrow] - * return True - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 224, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_col_index, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 224, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_kind); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 224, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 224, __pyx_L1_error) - __pyx_v_col_kind = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "src/questdb/pandas_helpers.pxi":225 - * cdef object col - * col_kind = data.dtypes[col_index].kind - * if col_kind == 'S': # string, string[pyarrow] # <<<<<<<<<<<<<< - * return True - * elif col_kind == 'O': # object - */ - __pyx_t_3 = (__Pyx_PyUnicode_Equals(__pyx_v_col_kind, __pyx_n_u_S, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(2, 225, __pyx_L1_error) - __pyx_t_4 = (__pyx_t_3 != 0); - if (__pyx_t_4) { - - /* "src/questdb/pandas_helpers.pxi":226 - * col_kind = data.dtypes[col_index].kind - * if col_kind == 'S': # string, string[pyarrow] - * return True # <<<<<<<<<<<<<< - * elif col_kind == 'O': # object - * if len(data.index) == 0: - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(Py_True); - __pyx_r = Py_True; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":225 - * cdef object col - * col_kind = data.dtypes[col_index].kind - * if col_kind == 'S': # string, string[pyarrow] # <<<<<<<<<<<<<< - * return True - * elif col_kind == 'O': # object - */ - } - - /* "src/questdb/pandas_helpers.pxi":227 - * if col_kind == 'S': # string, string[pyarrow] - * return True - * elif col_kind == 'O': # object # <<<<<<<<<<<<<< - * if len(data.index) == 0: - * return True - */ - __pyx_t_4 = (__Pyx_PyUnicode_Equals(__pyx_v_col_kind, __pyx_n_u_O, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 227, __pyx_L1_error) - __pyx_t_3 = (__pyx_t_4 != 0); - if (__pyx_t_3) { - - /* "src/questdb/pandas_helpers.pxi":228 - * return True - * elif col_kind == 'O': # object - * if len(data.index) == 0: # <<<<<<<<<<<<<< - * return True - * else: - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 228, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(2, 228, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_3 = ((__pyx_t_5 == 0) != 0); - if (__pyx_t_3) { - - /* "src/questdb/pandas_helpers.pxi":229 - * elif col_kind == 'O': # object - * if len(data.index) == 0: - * return True # <<<<<<<<<<<<<< - * else: - * # We only check the first element and hope for the rest. - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(Py_True); - __pyx_r = Py_True; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":228 - * return True - * elif col_kind == 'O': # object - * if len(data.index) == 0: # <<<<<<<<<<<<<< - * return True - * else: - */ - } - - /* "src/questdb/pandas_helpers.pxi":233 - * # We only check the first element and hope for the rest. - * # We also accept None as a null value. - * col = data.iloc[0, col_index] # <<<<<<<<<<<<<< - * return (col is None) or isinstance(col, str) - * else: - */ - /*else*/ { - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_iloc); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 233, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_col_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 233, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 233, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_INCREF(__pyx_int_0); - __Pyx_GIVEREF(__pyx_int_0); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_int_0); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2); - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 233, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_v_col = __pyx_t_2; - __pyx_t_2 = 0; - - /* "src/questdb/pandas_helpers.pxi":234 - * # We also accept None as a null value. - * col = data.iloc[0, col_index] - * return (col is None) or isinstance(col, str) # <<<<<<<<<<<<<< - * else: - * return False - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = (__pyx_v_col == Py_None); - if (!__pyx_t_3) { - } else { - __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 234, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = __pyx_t_6; - __pyx_t_6 = 0; - goto __pyx_L5_bool_binop_done; - } - __pyx_t_3 = PyUnicode_Check(__pyx_v_col); - __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 234, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = __pyx_t_6; - __pyx_t_6 = 0; - __pyx_L5_bool_binop_done:; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - } - - /* "src/questdb/pandas_helpers.pxi":227 - * if col_kind == 'S': # string, string[pyarrow] - * return True - * elif col_kind == 'O': # object # <<<<<<<<<<<<<< - * if len(data.index) == 0: - * return True - */ - } - - /* "src/questdb/pandas_helpers.pxi":236 - * return (col is None) or isinstance(col, str) - * else: - * return False # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(Py_False); - __pyx_r = Py_False; - goto __pyx_L0; - } - - /* "src/questdb/pandas_helpers.pxi":217 - * - * - * cdef object _pandas_column_is_str(object data, int col_index): # <<<<<<<<<<<<<< - * """ - * Return True if the column at `col_index` is a string column. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("questdb.ingress._pandas_column_is_str", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_col_kind); - __Pyx_XDECREF(__pyx_v_col); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":239 - * - * - * cdef object _pandas_check_column_is_str( # <<<<<<<<<<<<<< - * object data, size_t col_index, str err_msg_prefix, object col_name): - * cdef str col_kind - */ - -static PyObject *__pyx_f_7questdb_7ingress__pandas_check_column_is_str(PyObject *__pyx_v_data, size_t __pyx_v_col_index, PyObject *__pyx_v_err_msg_prefix, PyObject *__pyx_v_col_name) { - PyObject *__pyx_v_col_kind = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - int __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_UCS4 __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_check_column_is_str", 0); - - /* "src/questdb/pandas_helpers.pxi":242 - * object data, size_t col_index, str err_msg_prefix, object col_name): - * cdef str col_kind - * col_kind = data.dtypes[col_index].kind # <<<<<<<<<<<<<< - * if col_kind in 'SO': - * if not _pandas_column_is_str(data, col_index): - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 242, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 242, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_kind); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 242, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 242, __pyx_L1_error) - __pyx_v_col_kind = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - - /* "src/questdb/pandas_helpers.pxi":243 - * cdef str col_kind - * col_kind = data.dtypes[col_index].kind - * if col_kind in 'SO': # <<<<<<<<<<<<<< - * if not _pandas_column_is_str(data, col_index): - * raise TypeError( - */ - __pyx_t_3 = (__Pyx_PyUnicode_ContainsTF(__pyx_v_col_kind, __pyx_n_u_SO, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(2, 243, __pyx_L1_error) - __pyx_t_4 = (__pyx_t_3 != 0); - if (likely(__pyx_t_4)) { - - /* "src/questdb/pandas_helpers.pxi":244 - * col_kind = data.dtypes[col_index].kind - * if col_kind in 'SO': - * if not _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< - * raise TypeError( - * err_msg_prefix + - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_column_is_str(__pyx_v_data, __pyx_v_col_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 244, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 244, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_3 = ((!__pyx_t_4) != 0); - if (unlikely(__pyx_t_3)) { - - /* "src/questdb/pandas_helpers.pxi":246 - * if not _pandas_column_is_str(data, col_index): - * raise TypeError( - * err_msg_prefix + # <<<<<<<<<<<<<< - * 'Found non-string value ' + - * f'in column {col_name!r}.') - */ - __pyx_t_1 = __Pyx_PyUnicode_ConcatSafe(__pyx_v_err_msg_prefix, __pyx_kp_u_Found_non_string_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 246, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - - /* "src/questdb/pandas_helpers.pxi":248 - * err_msg_prefix + - * 'Found non-string value ' + - * f'in column {col_name!r}.') # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 248, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = 0; - __pyx_t_6 = 127; - __Pyx_INCREF(__pyx_kp_u_in_column); - __pyx_t_5 += 10; - __Pyx_GIVEREF(__pyx_kp_u_in_column); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_in_column); - __pyx_t_7 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_col_name), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 248, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6; - __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_7); - __pyx_t_7 = 0; - __Pyx_INCREF(__pyx_kp_u__6); - __pyx_t_5 += 1; - __Pyx_GIVEREF(__pyx_kp_u__6); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); - __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 248, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "src/questdb/pandas_helpers.pxi":247 - * raise TypeError( - * err_msg_prefix + - * 'Found non-string value ' + # <<<<<<<<<<<<<< - * f'in column {col_name!r}.') - * else: - */ - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 247, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "src/questdb/pandas_helpers.pxi":245 - * if col_kind in 'SO': - * if not _pandas_column_is_str(data, col_index): - * raise TypeError( # <<<<<<<<<<<<<< - * err_msg_prefix + - * 'Found non-string value ' + - */ - __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 245, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_7, 0, 0, 0); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __PYX_ERR(2, 245, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":244 - * col_kind = data.dtypes[col_index].kind - * if col_kind in 'SO': - * if not _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< - * raise TypeError( - * err_msg_prefix + - */ - } - - /* "src/questdb/pandas_helpers.pxi":243 - * cdef str col_kind - * col_kind = data.dtypes[col_index].kind - * if col_kind in 'SO': # <<<<<<<<<<<<<< - * if not _pandas_column_is_str(data, col_index): - * raise TypeError( - */ - goto __pyx_L3; - } - - /* "src/questdb/pandas_helpers.pxi":250 - * f'in column {col_name!r}.') - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * err_msg_prefix + - * f'Bad dtype `{data.dtypes[col_index]}` for the ' + - */ - /*else*/ { - - /* "src/questdb/pandas_helpers.pxi":252 - * raise TypeError( - * err_msg_prefix + - * f'Bad dtype `{data.dtypes[col_index]}` for the ' + # <<<<<<<<<<<<<< - * f'{col_name!r} column: Must be a strings column.') - * - */ - __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_5 = 0; - __pyx_t_6 = 127; - __Pyx_INCREF(__pyx_kp_u_Bad_dtype); - __pyx_t_5 += 11; - __Pyx_GIVEREF(__pyx_kp_u_Bad_dtype); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_kp_u_Bad_dtype); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_6; - __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_2); - __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_kp_u_for_the); - __pyx_t_5 += 10; - __Pyx_GIVEREF(__pyx_kp_u_for_the); - PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_kp_u_for_the); - __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_7, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "src/questdb/pandas_helpers.pxi":251 - * else: - * raise TypeError( - * err_msg_prefix + # <<<<<<<<<<<<<< - * f'Bad dtype `{data.dtypes[col_index]}` for the ' + - * f'{col_name!r} column: Must be a strings column.') - */ - __pyx_t_7 = __Pyx_PyUnicode_ConcatSafe(__pyx_v_err_msg_prefix, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 251, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "src/questdb/pandas_helpers.pxi":253 - * err_msg_prefix + - * f'Bad dtype `{data.dtypes[col_index]}` for the ' + - * f'{col_name!r} column: Must be a strings column.') # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_col_name), __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 253, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_kp_u_column_Must_be_a_strings_column); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 253, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "src/questdb/pandas_helpers.pxi":252 - * raise TypeError( - * err_msg_prefix + - * f'Bad dtype `{data.dtypes[col_index]}` for the ' + # <<<<<<<<<<<<<< - * f'{col_name!r} column: Must be a strings column.') - * - */ - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 252, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "src/questdb/pandas_helpers.pxi":250 - * f'in column {col_name!r}.') - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * err_msg_prefix + - * f'Bad dtype `{data.dtypes[col_index]}` for the ' + - */ - __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 250, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(2, 250, __pyx_L1_error) - } - __pyx_L3:; - - /* "src/questdb/pandas_helpers.pxi":239 - * - * - * cdef object _pandas_check_column_is_str( # <<<<<<<<<<<<<< - * object data, size_t col_index, str err_msg_prefix, object col_name): - * cdef str col_kind - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress._pandas_check_column_is_str", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_col_kind); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":256 - * - * - * cdef int _pandas_resolve_symbols( # <<<<<<<<<<<<<< - * object data, - * ssize_t table_name_col, - */ - -static int __pyx_f_7questdb_7ingress__pandas_resolve_symbols(PyObject *__pyx_v_data, Py_ssize_t __pyx_v_table_name_col, Py_ssize_t __pyx_v_at_col, PyObject *__pyx_v_symbols, size_t __pyx_v_col_count, __pyx_t_7questdb_7ingress_size_t_vec *__pyx_v_symbol_indices_out) { - size_t __pyx_v_col_index; - PyObject *__pyx_v_symbol = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - size_t __pyx_t_3; - size_t __pyx_t_4; - size_t __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_t_7; - Py_ssize_t __pyx_t_8; - PyObject *(*__pyx_t_9)(PyObject *); - PyObject *__pyx_t_10 = NULL; - int __pyx_t_11; - PyObject *__pyx_t_12 = NULL; - Py_ssize_t __pyx_t_13; - Py_UCS4 __pyx_t_14; - PyObject *__pyx_t_15 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_resolve_symbols", 0); - - /* "src/questdb/pandas_helpers.pxi":267 - * Returns the length of the vec. - * """ - * cdef size_t col_index = 0 # <<<<<<<<<<<<<< - * cdef object symbol - * if symbols is False: - */ - __pyx_v_col_index = 0; - - /* "src/questdb/pandas_helpers.pxi":269 - * cdef size_t col_index = 0 - * cdef object symbol - * if symbols is False: # <<<<<<<<<<<<<< - * return 0 - * elif symbols is True: - */ - __pyx_t_1 = (__pyx_v_symbols == Py_False); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":270 - * cdef object symbol - * if symbols is False: - * return 0 # <<<<<<<<<<<<<< - * elif symbols is True: - * for col_index in range(col_count): - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":269 - * cdef size_t col_index = 0 - * cdef object symbol - * if symbols is False: # <<<<<<<<<<<<<< - * return 0 - * elif symbols is True: - */ - } - - /* "src/questdb/pandas_helpers.pxi":271 - * if symbols is False: - * return 0 - * elif symbols is True: # <<<<<<<<<<<<<< - * for col_index in range(col_count): - * if _pandas_column_is_str(data, col_index): - */ - __pyx_t_2 = (__pyx_v_symbols == Py_True); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":272 - * return 0 - * elif symbols is True: - * for col_index in range(col_count): # <<<<<<<<<<<<<< - * if _pandas_column_is_str(data, col_index): - * size_t_vec_push(symbol_indices_out, col_index) - */ - __pyx_t_3 = __pyx_v_col_count; - __pyx_t_4 = __pyx_t_3; - for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { - __pyx_v_col_index = __pyx_t_5; - - /* "src/questdb/pandas_helpers.pxi":273 - * elif symbols is True: - * for col_index in range(col_count): - * if _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< - * size_t_vec_push(symbol_indices_out, col_index) - * return 0 - */ - __pyx_t_6 = __pyx_f_7questdb_7ingress__pandas_column_is_str(__pyx_v_data, __pyx_v_col_index); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 273, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 273, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":274 - * for col_index in range(col_count): - * if _pandas_column_is_str(data, col_index): - * size_t_vec_push(symbol_indices_out, col_index) # <<<<<<<<<<<<<< - * return 0 - * else: - */ - __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_v_symbol_indices_out, __pyx_v_col_index); - - /* "src/questdb/pandas_helpers.pxi":273 - * elif symbols is True: - * for col_index in range(col_count): - * if _pandas_column_is_str(data, col_index): # <<<<<<<<<<<<<< - * size_t_vec_push(symbol_indices_out, col_index) - * return 0 - */ - } - } - - /* "src/questdb/pandas_helpers.pxi":275 - * if _pandas_column_is_str(data, col_index): - * size_t_vec_push(symbol_indices_out, col_index) - * return 0 # <<<<<<<<<<<<<< - * else: - * if not isinstance(symbols, (tuple, list)): - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":271 - * if symbols is False: - * return 0 - * elif symbols is True: # <<<<<<<<<<<<<< - * for col_index in range(col_count): - * if _pandas_column_is_str(data, col_index): - */ - } - - /* "src/questdb/pandas_helpers.pxi":277 - * return 0 - * else: - * if not isinstance(symbols, (tuple, list)): # <<<<<<<<<<<<<< - * raise TypeError( - * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - */ - /*else*/ { - __pyx_t_2 = PyTuple_Check(__pyx_v_symbols); - __pyx_t_7 = (__pyx_t_2 != 0); - if (!__pyx_t_7) { - } else { - __pyx_t_1 = __pyx_t_7; - goto __pyx_L8_bool_binop_done; - } - __pyx_t_7 = PyList_Check(__pyx_v_symbols); - __pyx_t_2 = (__pyx_t_7 != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L8_bool_binop_done:; - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (unlikely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":278 - * else: - * if not isinstance(symbols, (tuple, list)): - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - * 'of column names (str) or indices (int).') - */ - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 278, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(2, 278, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":277 - * return 0 - * else: - * if not isinstance(symbols, (tuple, list)): # <<<<<<<<<<<<<< - * raise TypeError( - * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - */ - } - - /* "src/questdb/pandas_helpers.pxi":281 - * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - * 'of column names (str) or indices (int).') - * for symbol in symbols: # <<<<<<<<<<<<<< - * if isinstance(symbol, str): - * _pandas_get_loc(data, symbol, 'symbols', &col_index) - */ - if (likely(PyList_CheckExact(__pyx_v_symbols)) || PyTuple_CheckExact(__pyx_v_symbols)) { - __pyx_t_6 = __pyx_v_symbols; __Pyx_INCREF(__pyx_t_6); __pyx_t_8 = 0; - __pyx_t_9 = NULL; - } else { - __pyx_t_8 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_v_symbols); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 281, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_9 = Py_TYPE(__pyx_t_6)->tp_iternext; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 281, __pyx_L1_error) - } - for (;;) { - if (likely(!__pyx_t_9)) { - if (likely(PyList_CheckExact(__pyx_t_6))) { - if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_6)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_10 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_10); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(2, 281, __pyx_L1_error) - #else - __pyx_t_10 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 281, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - #endif - } else { - if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_6)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_10); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(2, 281, __pyx_L1_error) - #else - __pyx_t_10 = PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 281, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - #endif - } - } else { - __pyx_t_10 = __pyx_t_9(__pyx_t_6); - if (unlikely(!__pyx_t_10)) { - PyObject* exc_type = PyErr_Occurred(); - if (exc_type) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); - else __PYX_ERR(2, 281, __pyx_L1_error) - } - break; - } - __Pyx_GOTREF(__pyx_t_10); - } - __Pyx_XDECREF_SET(__pyx_v_symbol, __pyx_t_10); - __pyx_t_10 = 0; - - /* "src/questdb/pandas_helpers.pxi":282 - * 'of column names (str) or indices (int).') - * for symbol in symbols: - * if isinstance(symbol, str): # <<<<<<<<<<<<<< - * _pandas_get_loc(data, symbol, 'symbols', &col_index) - * elif isinstance(symbol, int): - */ - __pyx_t_2 = PyUnicode_Check(__pyx_v_symbol); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":283 - * for symbol in symbols: - * if isinstance(symbol, str): - * _pandas_get_loc(data, symbol, 'symbols', &col_index) # <<<<<<<<<<<<<< - * elif isinstance(symbol, int): - * _bind_col_index('symbol', symbol, col_count, &col_index) - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_symbol))||((__pyx_v_symbol) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_symbol)->tp_name), 0))) __PYX_ERR(2, 283, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_get_loc(__pyx_v_data, ((PyObject*)__pyx_v_symbol), __pyx_n_u_symbols, (&__pyx_v_col_index)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 283, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":282 - * 'of column names (str) or indices (int).') - * for symbol in symbols: - * if isinstance(symbol, str): # <<<<<<<<<<<<<< - * _pandas_get_loc(data, symbol, 'symbols', &col_index) - * elif isinstance(symbol, int): - */ - goto __pyx_L12; - } - - /* "src/questdb/pandas_helpers.pxi":284 - * if isinstance(symbol, str): - * _pandas_get_loc(data, symbol, 'symbols', &col_index) - * elif isinstance(symbol, int): # <<<<<<<<<<<<<< - * _bind_col_index('symbol', symbol, col_count, &col_index) - * else: - */ - __pyx_t_1 = PyInt_Check(__pyx_v_symbol); - __pyx_t_2 = (__pyx_t_1 != 0); - if (likely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":285 - * _pandas_get_loc(data, symbol, 'symbols', &col_index) - * elif isinstance(symbol, int): - * _bind_col_index('symbol', symbol, col_count, &col_index) # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_symbol); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 285, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress__bind_col_index(__pyx_n_u_symbol, __pyx_t_11, __pyx_v_col_count, (&__pyx_v_col_index)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 285, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":284 - * if isinstance(symbol, str): - * _pandas_get_loc(data, symbol, 'symbols', &col_index) - * elif isinstance(symbol, int): # <<<<<<<<<<<<<< - * _bind_col_index('symbol', symbol, col_count, &col_index) - * else: - */ - goto __pyx_L12; - } - - /* "src/questdb/pandas_helpers.pxi":287 - * _bind_col_index('symbol', symbol, col_count, &col_index) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `symbols`: Elements must ' + - * 'be a column name (str) or index (int).') - */ - /*else*/ { - __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 287, __pyx_L1_error) - } - __pyx_L12:; - - /* "src/questdb/pandas_helpers.pxi":290 - * f'Bad argument `symbols`: Elements must ' + - * 'be a column name (str) or index (int).') - * if (table_name_col >= 0) and (col_index == table_name_col): # <<<<<<<<<<<<<< - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the same column ' + - */ - __pyx_t_1 = ((__pyx_v_table_name_col >= 0) != 0); - if (__pyx_t_1) { - } else { - __pyx_t_2 = __pyx_t_1; - goto __pyx_L14_bool_binop_done; - } - __pyx_t_1 = ((__pyx_v_col_index == ((size_t)__pyx_v_table_name_col)) != 0); - __pyx_t_2 = __pyx_t_1; - __pyx_L14_bool_binop_done:; - if (unlikely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":293 - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the same column ' + - * f'{symbol!r} as both the table_name and as a symbol.') # <<<<<<<<<<<<<< - * if (at_col >= 0) and (col_index == at_col): - * raise ValueError( - */ - __pyx_t_10 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_symbol), __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 293, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __pyx_t_12 = __Pyx_PyUnicode_Concat(__pyx_t_10, __pyx_kp_u_as_both_the_table_name_and_as_a); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 293, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "src/questdb/pandas_helpers.pxi":292 - * if (table_name_col >= 0) and (col_index == table_name_col): - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the same column ' + # <<<<<<<<<<<<<< - * f'{symbol!r} as both the table_name and as a symbol.') - * if (at_col >= 0) and (col_index == at_col): - */ - __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_argument_symbols_Cannot_use, __pyx_t_12); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 292, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - - /* "src/questdb/pandas_helpers.pxi":291 - * 'be a column name (str) or index (int).') - * if (table_name_col >= 0) and (col_index == table_name_col): - * raise ValueError( # <<<<<<<<<<<<<< - * f'Bad argument `symbols`: Cannot use the same column ' + - * f'{symbol!r} as both the table_name and as a symbol.') - */ - __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_10); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 291, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_Raise(__pyx_t_12, 0, 0, 0); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - __PYX_ERR(2, 291, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":290 - * f'Bad argument `symbols`: Elements must ' + - * 'be a column name (str) or index (int).') - * if (table_name_col >= 0) and (col_index == table_name_col): # <<<<<<<<<<<<<< - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the same column ' + - */ - } - - /* "src/questdb/pandas_helpers.pxi":294 - * f'Bad argument `symbols`: Cannot use the same column ' + - * f'{symbol!r} as both the table_name and as a symbol.') - * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the `at` column ' + - */ - __pyx_t_1 = ((__pyx_v_at_col >= 0) != 0); - if (__pyx_t_1) { - } else { - __pyx_t_2 = __pyx_t_1; - goto __pyx_L17_bool_binop_done; - } - __pyx_t_1 = ((__pyx_v_col_index == ((size_t)__pyx_v_at_col)) != 0); - __pyx_t_2 = __pyx_t_1; - __pyx_L17_bool_binop_done:; - if (unlikely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":297 - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the `at` column ' + - * f'({data.columns[at_col]!r}) as a symbol column.') # <<<<<<<<<<<<<< - * _pandas_check_column_is_str( - * data, - */ - __pyx_t_12 = PyTuple_New(3); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 297, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_12); - __pyx_t_13 = 0; - __pyx_t_14 = 127; - __Pyx_INCREF(__pyx_kp_u__9); - __pyx_t_13 += 1; - __Pyx_GIVEREF(__pyx_kp_u__9); - PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_kp_u__9); - __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 297, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __pyx_t_15 = __Pyx_GetItemInt(__pyx_t_10, __pyx_v_at_col, Py_ssize_t, 1, PyInt_FromSsize_t, 0, 1, 1); if (unlikely(!__pyx_t_15)) __PYX_ERR(2, 297, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_15); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __pyx_t_10 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_t_15), __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 297, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; - __pyx_t_14 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) > __pyx_t_14) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) : __pyx_t_14; - __pyx_t_13 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_10); - PyTuple_SET_ITEM(__pyx_t_12, 1, __pyx_t_10); - __pyx_t_10 = 0; - __Pyx_INCREF(__pyx_kp_u_as_a_symbol_column); - __pyx_t_13 += 21; - __Pyx_GIVEREF(__pyx_kp_u_as_a_symbol_column); - PyTuple_SET_ITEM(__pyx_t_12, 2, __pyx_kp_u_as_a_symbol_column); - __pyx_t_10 = __Pyx_PyUnicode_Join(__pyx_t_12, 3, __pyx_t_13, __pyx_t_14); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 297, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - - /* "src/questdb/pandas_helpers.pxi":296 - * if (at_col >= 0) and (col_index == at_col): - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the `at` column ' + # <<<<<<<<<<<<<< - * f'({data.columns[at_col]!r}) as a symbol column.') - * _pandas_check_column_is_str( - */ - __pyx_t_12 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_argument_symbols_Cannot_use_2, __pyx_t_10); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 296, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "src/questdb/pandas_helpers.pxi":295 - * f'{symbol!r} as both the table_name and as a symbol.') - * if (at_col >= 0) and (col_index == at_col): - * raise ValueError( # <<<<<<<<<<<<<< - * f'Bad argument `symbols`: Cannot use the `at` column ' + - * f'({data.columns[at_col]!r}) as a symbol column.') - */ - __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_12); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 295, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 295, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":294 - * f'Bad argument `symbols`: Cannot use the same column ' + - * f'{symbol!r} as both the table_name and as a symbol.') - * if (at_col >= 0) and (col_index == at_col): # <<<<<<<<<<<<<< - * raise ValueError( - * f'Bad argument `symbols`: Cannot use the `at` column ' + - */ - } - - /* "src/questdb/pandas_helpers.pxi":298 - * f'Bad argument `symbols`: Cannot use the `at` column ' + - * f'({data.columns[at_col]!r}) as a symbol column.') - * _pandas_check_column_is_str( # <<<<<<<<<<<<<< - * data, - * col_index, - */ - __pyx_t_10 = __pyx_f_7questdb_7ingress__pandas_check_column_is_str(__pyx_v_data, __pyx_v_col_index, __pyx_kp_u_Bad_element_in_argument_symbols, __pyx_v_symbol); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 298, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "src/questdb/pandas_helpers.pxi":303 - * 'Bad element in argument `symbols`: ', - * symbol) - * size_t_vec_push(symbol_indices_out, col_index) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_f_7questdb_7ingress_size_t_vec_push(__pyx_v_symbol_indices_out, __pyx_v_col_index); - - /* "src/questdb/pandas_helpers.pxi":281 - * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - * 'of column names (str) or indices (int).') - * for symbol in symbols: # <<<<<<<<<<<<<< - * if isinstance(symbol, str): - * _pandas_get_loc(data, symbol, 'symbols', &col_index) - */ - } - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "src/questdb/pandas_helpers.pxi":304 - * symbol) - * size_t_vec_push(symbol_indices_out, col_index) - * return 0 # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 0; - goto __pyx_L0; - } - - /* "src/questdb/pandas_helpers.pxi":256 - * - * - * cdef int _pandas_resolve_symbols( # <<<<<<<<<<<<<< - * object data, - * ssize_t table_name_col, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_12); - __Pyx_XDECREF(__pyx_t_15); - __Pyx_AddTraceback("questdb.ingress._pandas_resolve_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_symbol); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":307 - * - * - * cdef bint _pandas_get_loc( # <<<<<<<<<<<<<< - * object data, str col_name, str arg_name, - * size_t* col_index_out) except False: - */ - -static int __pyx_f_7questdb_7ingress__pandas_get_loc(PyObject *__pyx_v_data, PyObject *__pyx_v_col_name, PyObject *__pyx_v_arg_name, size_t *__pyx_v_col_index_out) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - size_t __pyx_t_7; - int __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - Py_ssize_t __pyx_t_10; - Py_UCS4 __pyx_t_11; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_get_loc", 0); - - /* "src/questdb/pandas_helpers.pxi":313 - * Return the column index for `col_name`. - * """ - * try: # <<<<<<<<<<<<<< - * col_index_out[0] = data.columns.get_loc(col_name) - * return True - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "src/questdb/pandas_helpers.pxi":314 - * """ - * try: - * col_index_out[0] = data.columns.get_loc(col_name) # <<<<<<<<<<<<<< - * return True - * except KeyError: - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 314, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_get_loc); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 314, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_6))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_6, function); - } - } - __pyx_t_4 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_5, __pyx_v_col_name) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_col_name); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 314, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_4); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 314, __pyx_L3_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - (__pyx_v_col_index_out[0]) = __pyx_t_7; - - /* "src/questdb/pandas_helpers.pxi":315 - * try: - * col_index_out[0] = data.columns.get_loc(col_name) - * return True # <<<<<<<<<<<<<< - * except KeyError: - * raise KeyError( - */ - __pyx_r = 1; - goto __pyx_L7_try_return; - - /* "src/questdb/pandas_helpers.pxi":313 - * Return the column index for `col_name`. - * """ - * try: # <<<<<<<<<<<<<< - * col_index_out[0] = data.columns.get_loc(col_name) - * return True - */ - } - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "src/questdb/pandas_helpers.pxi":316 - * col_index_out[0] = data.columns.get_loc(col_name) - * return True - * except KeyError: # <<<<<<<<<<<<<< - * raise KeyError( - * f'Bad argument `{arg_name}`: ' + - */ - __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); - if (__pyx_t_8) { - __Pyx_AddTraceback("questdb.ingress._pandas_get_loc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_5) < 0) __PYX_ERR(2, 316, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_5); - - /* "src/questdb/pandas_helpers.pxi":318 - * except KeyError: - * raise KeyError( - * f'Bad argument `{arg_name}`: ' + # <<<<<<<<<<<<<< - * f'Column {col_name!r} not found in the dataframe.') - * - */ - __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 318, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_10 = 0; - __pyx_t_11 = 127; - __Pyx_INCREF(__pyx_kp_u_Bad_argument); - __pyx_t_10 += 14; - __Pyx_GIVEREF(__pyx_kp_u_Bad_argument); - PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_Bad_argument); - __pyx_t_12 = __Pyx_PyUnicode_Unicode(__pyx_v_arg_name); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 318, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_12); - __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_12) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_12) : __pyx_t_11; - __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_12); - __Pyx_GIVEREF(__pyx_t_12); - PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_12); - __pyx_t_12 = 0; - __Pyx_INCREF(__pyx_kp_u__5); - __pyx_t_10 += 3; - __Pyx_GIVEREF(__pyx_kp_u__5); - PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u__5); - __pyx_t_12 = __Pyx_PyUnicode_Join(__pyx_t_9, 3, __pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(2, 318, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_12); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "src/questdb/pandas_helpers.pxi":319 - * raise KeyError( - * f'Bad argument `{arg_name}`: ' + - * f'Column {col_name!r} not found in the dataframe.') # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 319, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_10 = 0; - __pyx_t_11 = 127; - __Pyx_INCREF(__pyx_kp_u_Column); - __pyx_t_10 += 7; - __Pyx_GIVEREF(__pyx_kp_u_Column); - PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_Column); - __pyx_t_13 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_col_name), __pyx_empty_unicode); if (unlikely(!__pyx_t_13)) __PYX_ERR(2, 319, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_13); - __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_13) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_13) : __pyx_t_11; - __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_13); - __Pyx_GIVEREF(__pyx_t_13); - PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_13); - __pyx_t_13 = 0; - __Pyx_INCREF(__pyx_kp_u_not_found_in_the_dataframe); - __pyx_t_10 += 28; - __Pyx_GIVEREF(__pyx_kp_u_not_found_in_the_dataframe); - PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u_not_found_in_the_dataframe); - __pyx_t_13 = __Pyx_PyUnicode_Join(__pyx_t_9, 3, __pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_13)) __PYX_ERR(2, 319, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_13); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "src/questdb/pandas_helpers.pxi":318 - * except KeyError: - * raise KeyError( - * f'Bad argument `{arg_name}`: ' + # <<<<<<<<<<<<<< - * f'Column {col_name!r} not found in the dataframe.') - * - */ - __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 318, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - - /* "src/questdb/pandas_helpers.pxi":317 - * return True - * except KeyError: - * raise KeyError( # <<<<<<<<<<<<<< - * f'Bad argument `{arg_name}`: ' + - * f'Column {col_name!r} not found in the dataframe.') - */ - __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_9); if (unlikely(!__pyx_t_13)) __PYX_ERR(2, 317, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_13); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_Raise(__pyx_t_13, 0, 0, 0); - __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; - __PYX_ERR(2, 317, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "src/questdb/pandas_helpers.pxi":313 - * Return the column index for `col_name`. - * """ - * try: # <<<<<<<<<<<<<< - * col_index_out[0] = data.columns.get_loc(col_name) - * return True - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L7_try_return:; - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L0; - } - - /* "src/questdb/pandas_helpers.pxi":307 - * - * - * cdef bint _pandas_get_loc( # <<<<<<<<<<<<<< - * object data, str col_name, str arg_name, - * size_t* col_index_out) except False: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_12); - __Pyx_XDECREF(__pyx_t_13); - __Pyx_AddTraceback("questdb.ingress._pandas_get_loc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":322 - * - * - * cdef ssize_t _pandas_resolve_at( # <<<<<<<<<<<<<< - * object data, - * object at, - */ - -static Py_ssize_t __pyx_f_7questdb_7ingress__pandas_resolve_at(PyObject *__pyx_v_data, PyObject *__pyx_v_at, size_t __pyx_v_col_count, int64_t *__pyx_v_at_value_out) { - size_t __pyx_v_col_index; - PyObject *__pyx_v_dtype = 0; - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int64_t __pyx_t_4; - int __pyx_t_5; - Py_ssize_t __pyx_t_6; - Py_UCS4 __pyx_t_7; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_resolve_at", 0); - - /* "src/questdb/pandas_helpers.pxi":329 - * cdef size_t col_index - * cdef object dtype - * if at is None: # <<<<<<<<<<<<<< - * at_value_out[0] = 0 # Special value for `at_now`. - * return -1 - */ - __pyx_t_1 = (__pyx_v_at == Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":330 - * cdef object dtype - * if at is None: - * at_value_out[0] = 0 # Special value for `at_now`. # <<<<<<<<<<<<<< - * return -1 - * elif isinstance(at, TimestampNanos): - */ - (__pyx_v_at_value_out[0]) = 0; - - /* "src/questdb/pandas_helpers.pxi":331 - * if at is None: - * at_value_out[0] = 0 # Special value for `at_now`. - * return -1 # <<<<<<<<<<<<<< - * elif isinstance(at, TimestampNanos): - * at_value_out[0] = at._value - */ - __pyx_r = -1L; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":329 - * cdef size_t col_index - * cdef object dtype - * if at is None: # <<<<<<<<<<<<<< - * at_value_out[0] = 0 # Special value for `at_now`. - * return -1 - */ - } - - /* "src/questdb/pandas_helpers.pxi":332 - * at_value_out[0] = 0 # Special value for `at_now`. - * return -1 - * elif isinstance(at, TimestampNanos): # <<<<<<<<<<<<<< - * at_value_out[0] = at._value - * return -1 - */ - __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_at, __pyx_ptype_7questdb_7ingress_TimestampNanos); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":333 - * return -1 - * elif isinstance(at, TimestampNanos): - * at_value_out[0] = at._value # <<<<<<<<<<<<<< - * return -1 - * elif isinstance(at, datetime): - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_at, __pyx_n_s_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 333, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyInt_As_int64_t(__pyx_t_3); if (unlikely((__pyx_t_4 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(2, 333, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - (__pyx_v_at_value_out[0]) = __pyx_t_4; - - /* "src/questdb/pandas_helpers.pxi":334 - * elif isinstance(at, TimestampNanos): - * at_value_out[0] = at._value - * return -1 # <<<<<<<<<<<<<< - * elif isinstance(at, datetime): - * at_value_out[0] = datetime_to_nanos(at) - */ - __pyx_r = -1L; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":332 - * at_value_out[0] = 0 # Special value for `at_now`. - * return -1 - * elif isinstance(at, TimestampNanos): # <<<<<<<<<<<<<< - * at_value_out[0] = at._value - * return -1 - */ - } - - /* "src/questdb/pandas_helpers.pxi":335 - * at_value_out[0] = at._value - * return -1 - * elif isinstance(at, datetime): # <<<<<<<<<<<<<< - * at_value_out[0] = datetime_to_nanos(at) - * return -1 - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_at, __pyx_ptype_7cpython_8datetime_datetime); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "src/questdb/pandas_helpers.pxi":336 - * return -1 - * elif isinstance(at, datetime): - * at_value_out[0] = datetime_to_nanos(at) # <<<<<<<<<<<<<< - * return -1 - * elif isinstance(at, str): - */ - if (!(likely(((__pyx_v_at) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_at, __pyx_ptype_7cpython_8datetime_datetime))))) __PYX_ERR(2, 336, __pyx_L1_error) - (__pyx_v_at_value_out[0]) = __pyx_f_7questdb_7ingress_datetime_to_nanos(((PyDateTime_DateTime *)__pyx_v_at)); - - /* "src/questdb/pandas_helpers.pxi":337 - * elif isinstance(at, datetime): - * at_value_out[0] = datetime_to_nanos(at) - * return -1 # <<<<<<<<<<<<<< - * elif isinstance(at, str): - * _pandas_get_loc(data, at, 'at', &col_index) - */ - __pyx_r = -1L; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":335 - * at_value_out[0] = at._value - * return -1 - * elif isinstance(at, datetime): # <<<<<<<<<<<<<< - * at_value_out[0] = datetime_to_nanos(at) - * return -1 - */ - } - - /* "src/questdb/pandas_helpers.pxi":338 - * at_value_out[0] = datetime_to_nanos(at) - * return -1 - * elif isinstance(at, str): # <<<<<<<<<<<<<< - * _pandas_get_loc(data, at, 'at', &col_index) - * elif isinstance(at, int): - */ - __pyx_t_2 = PyUnicode_Check(__pyx_v_at); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":339 - * return -1 - * elif isinstance(at, str): - * _pandas_get_loc(data, at, 'at', &col_index) # <<<<<<<<<<<<<< - * elif isinstance(at, int): - * _bind_col_index('at', at, col_count, &col_index) - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_at))||((__pyx_v_at) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_at)->tp_name), 0))) __PYX_ERR(2, 339, __pyx_L1_error) - __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_get_loc(__pyx_v_data, ((PyObject*)__pyx_v_at), __pyx_n_u_at, (&__pyx_v_col_index)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 339, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":338 - * at_value_out[0] = datetime_to_nanos(at) - * return -1 - * elif isinstance(at, str): # <<<<<<<<<<<<<< - * _pandas_get_loc(data, at, 'at', &col_index) - * elif isinstance(at, int): - */ - goto __pyx_L3; - } - - /* "src/questdb/pandas_helpers.pxi":340 - * elif isinstance(at, str): - * _pandas_get_loc(data, at, 'at', &col_index) - * elif isinstance(at, int): # <<<<<<<<<<<<<< - * _bind_col_index('at', at, col_count, &col_index) - * else: - */ - __pyx_t_1 = PyInt_Check(__pyx_v_at); - __pyx_t_2 = (__pyx_t_1 != 0); - if (likely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":341 - * _pandas_get_loc(data, at, 'at', &col_index) - * elif isinstance(at, int): - * _bind_col_index('at', at, col_count, &col_index) # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_v_at); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 341, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress__bind_col_index(__pyx_n_u_at, __pyx_t_5, __pyx_v_col_count, (&__pyx_v_col_index)); if (unlikely(__pyx_t_2 == ((int)0))) __PYX_ERR(2, 341, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":340 - * elif isinstance(at, str): - * _pandas_get_loc(data, at, 'at', &col_index) - * elif isinstance(at, int): # <<<<<<<<<<<<<< - * _bind_col_index('at', at, col_count, &col_index) - * else: - */ - goto __pyx_L3; - } - - /* "src/questdb/pandas_helpers.pxi":343 - * _bind_col_index('at', at, col_count, &col_index) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `at`: Unsupported type {type(at)}. ' + - * 'Must be one of: None, TimestampNanos, datetime, ' + - */ - /*else*/ { - - /* "src/questdb/pandas_helpers.pxi":344 - * else: - * raise TypeError( - * f'Bad argument `at`: Unsupported type {type(at)}. ' + # <<<<<<<<<<<<<< - * 'Must be one of: None, TimestampNanos, datetime, ' + - * 'int (column index), str (colum name)') - */ - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 344, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_6 = 0; - __pyx_t_7 = 127; - __Pyx_INCREF(__pyx_kp_u_Bad_argument_at_Unsupported_type); - __pyx_t_6 += 36; - __Pyx_GIVEREF(__pyx_kp_u_Bad_argument_at_Unsupported_type); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Bad_argument_at_Unsupported_type); - __pyx_t_8 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_at)), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 344, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_7; - __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_8); - __pyx_t_8 = 0; - __Pyx_INCREF(__pyx_kp_u__10); - __pyx_t_6 += 2; - __Pyx_GIVEREF(__pyx_kp_u__10); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__10); - __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 344, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_8, __pyx_kp_u_Must_be_one_of_None_TimestampNan); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 344, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "src/questdb/pandas_helpers.pxi":345 - * raise TypeError( - * f'Bad argument `at`: Unsupported type {type(at)}. ' + - * 'Must be one of: None, TimestampNanos, datetime, ' + # <<<<<<<<<<<<<< - * 'int (column index), str (colum name)') - * dtype = data.dtypes[col_index] - */ - __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_kp_u_int_column_index_str_colum_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 345, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":343 - * _bind_col_index('at', at, col_count, &col_index) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `at`: Unsupported type {type(at)}. ' + - * 'Must be one of: None, TimestampNanos, datetime, ' + - */ - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 343, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 343, __pyx_L1_error) - } - __pyx_L3:; - - /* "src/questdb/pandas_helpers.pxi":347 - * 'Must be one of: None, TimestampNanos, datetime, ' + - * 'int (column index), str (colum name)') - * dtype = data.dtypes[col_index] # <<<<<<<<<<<<<< - * if _pandas_is_supported_datetime(dtype): - * at_value_out[0] = 0 - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 347, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_3, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 347, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_dtype = __pyx_t_8; - __pyx_t_8 = 0; - - /* "src/questdb/pandas_helpers.pxi":348 - * 'int (column index), str (colum name)') - * dtype = data.dtypes[col_index] - * if _pandas_is_supported_datetime(dtype): # <<<<<<<<<<<<<< - * at_value_out[0] = 0 - * return col_index - */ - __pyx_t_8 = __pyx_f_7questdb_7ingress__pandas_is_supported_datetime(__pyx_v_dtype); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 348, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 348, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - if (likely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":349 - * dtype = data.dtypes[col_index] - * if _pandas_is_supported_datetime(dtype): - * at_value_out[0] = 0 # <<<<<<<<<<<<<< - * return col_index - * else: - */ - (__pyx_v_at_value_out[0]) = 0; - - /* "src/questdb/pandas_helpers.pxi":350 - * if _pandas_is_supported_datetime(dtype): - * at_value_out[0] = 0 - * return col_index # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - __pyx_r = __pyx_v_col_index; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":348 - * 'int (column index), str (colum name)') - * dtype = data.dtypes[col_index] - * if _pandas_is_supported_datetime(dtype): # <<<<<<<<<<<<<< - * at_value_out[0] = 0 - * return col_index - */ - } - - /* "src/questdb/pandas_helpers.pxi":352 - * return col_index - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `at`: Bad dtype `{dtype}` ' + - * f'for the {at!r} column: Must be a datetime64[ns] column.') - */ - /*else*/ { - - /* "src/questdb/pandas_helpers.pxi":353 - * else: - * raise TypeError( - * f'Bad argument `at`: Bad dtype `{dtype}` ' + # <<<<<<<<<<<<<< - * f'for the {at!r} column: Must be a datetime64[ns] column.') - * - */ - __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 353, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_6 = 0; - __pyx_t_7 = 127; - __Pyx_INCREF(__pyx_kp_u_Bad_argument_at_Bad_dtype); - __pyx_t_6 += 30; - __Pyx_GIVEREF(__pyx_kp_u_Bad_argument_at_Bad_dtype); - PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_Bad_argument_at_Bad_dtype); - __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_v_dtype, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 353, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) : __pyx_t_7; - __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_3); - __pyx_t_3 = 0; - __Pyx_INCREF(__pyx_kp_u__11); - __pyx_t_6 += 2; - __Pyx_GIVEREF(__pyx_kp_u__11); - PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u__11); - __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 353, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "src/questdb/pandas_helpers.pxi":354 - * raise TypeError( - * f'Bad argument `at`: Bad dtype `{dtype}` ' + - * f'for the {at!r} column: Must be a datetime64[ns] column.') # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 354, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_6 = 0; - __pyx_t_7 = 127; - __Pyx_INCREF(__pyx_kp_u_for_the_2); - __pyx_t_6 += 8; - __Pyx_GIVEREF(__pyx_kp_u_for_the_2); - PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_for_the_2); - __pyx_t_9 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_at), __pyx_empty_unicode); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 354, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) : __pyx_t_7; - __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); - __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_9); - __pyx_t_9 = 0; - __Pyx_INCREF(__pyx_kp_u_column_Must_be_a_datetime64_ns); - __pyx_t_6 += 41; - __Pyx_GIVEREF(__pyx_kp_u_column_Must_be_a_datetime64_ns); - PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u_column_Must_be_a_datetime64_ns); - __pyx_t_9 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 354, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - - /* "src/questdb/pandas_helpers.pxi":353 - * else: - * raise TypeError( - * f'Bad argument `at`: Bad dtype `{dtype}` ' + # <<<<<<<<<<<<<< - * f'for the {at!r} column: Must be a datetime64[ns] column.') - * - */ - __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_t_9); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 353, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "src/questdb/pandas_helpers.pxi":352 - * return col_index - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `at`: Bad dtype `{dtype}` ' + - * f'for the {at!r} column: Must be a datetime64[ns] column.') - */ - __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 352, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_Raise(__pyx_t_9, 0, 0, 0); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __PYX_ERR(2, 352, __pyx_L1_error) - } - - /* "src/questdb/pandas_helpers.pxi":322 - * - * - * cdef ssize_t _pandas_resolve_at( # <<<<<<<<<<<<<< - * object data, - * object at, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("questdb.ingress._pandas_resolve_at", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -2L; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_dtype); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":357 - * - * - * cdef object _pandas_is_supported_datetime(object dtype): # <<<<<<<<<<<<<< - * # We currently only accept datetime64[ns] columns. - * return ( - */ - -static PyObject *__pyx_f_7questdb_7ingress__pandas_is_supported_datetime(PyObject *__pyx_v_dtype) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_is_supported_datetime", 0); - - /* "src/questdb/pandas_helpers.pxi":359 - * cdef object _pandas_is_supported_datetime(object dtype): - * # We currently only accept datetime64[ns] columns. - * return ( # <<<<<<<<<<<<<< - * (dtype.kind == 'M') and - * (dtype.itemsize == 8) and - */ - __Pyx_XDECREF(__pyx_r); - - /* "src/questdb/pandas_helpers.pxi":360 - * # We currently only accept datetime64[ns] columns. - * return ( - * (dtype.kind == 'M') and # <<<<<<<<<<<<<< - * (dtype.itemsize == 8) and - * (dtype.byteorder == '=') and - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 360, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_n_u_M, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 360, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 360, __pyx_L1_error) - if (__pyx_t_4) { - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __Pyx_INCREF(__pyx_t_3); - __pyx_t_1 = __pyx_t_3; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L3_bool_binop_done; - } - - /* "src/questdb/pandas_helpers.pxi":361 - * return ( - * (dtype.kind == 'M') and - * (dtype.itemsize == 8) and # <<<<<<<<<<<<<< - * (dtype.byteorder == '=') and - * (dtype.alignment == 8) and - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 361, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyInt_EqObjC(__pyx_t_3, __pyx_int_8, 8, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 361, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 361, __pyx_L1_error) - if (__pyx_t_4) { - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } else { - __Pyx_INCREF(__pyx_t_2); - __pyx_t_1 = __pyx_t_2; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - goto __pyx_L3_bool_binop_done; - } - - /* "src/questdb/pandas_helpers.pxi":362 - * (dtype.kind == 'M') and - * (dtype.itemsize == 8) and - * (dtype.byteorder == '=') and # <<<<<<<<<<<<<< - * (dtype.alignment == 8) and - * (not dtype.hasobject)) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_byteorder); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 362, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_kp_u__12, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 362, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 362, __pyx_L1_error) - if (__pyx_t_4) { - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else { - __Pyx_INCREF(__pyx_t_3); - __pyx_t_1 = __pyx_t_3; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L3_bool_binop_done; - } - - /* "src/questdb/pandas_helpers.pxi":363 - * (dtype.itemsize == 8) and - * (dtype.byteorder == '=') and - * (dtype.alignment == 8) and # <<<<<<<<<<<<<< - * (not dtype.hasobject)) - * - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_alignment); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 363, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyInt_EqObjC(__pyx_t_3, __pyx_int_8, 8, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 363, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 363, __pyx_L1_error) - if (__pyx_t_4) { - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - } else { - __Pyx_INCREF(__pyx_t_2); - __pyx_t_1 = __pyx_t_2; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - goto __pyx_L3_bool_binop_done; - } - - /* "src/questdb/pandas_helpers.pxi":364 - * (dtype.byteorder == '=') and - * (dtype.alignment == 8) and - * (not dtype.hasobject)) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_hasobject); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 364, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 364, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_5 = (!__pyx_t_4); - __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 364, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __pyx_t_2; - __pyx_t_2 = 0; - __pyx_L3_bool_binop_done:; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":357 - * - * - * cdef object _pandas_is_supported_datetime(object dtype): # <<<<<<<<<<<<<< - * # We currently only accept datetime64[ns] columns. - * return ( - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress._pandas_is_supported_datetime", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":370 - * - * - * cdef char _str_to_char(str field, str s) except 0: # <<<<<<<<<<<<<< - * cdef int res - * if len(s) != 1: - */ - -static char __pyx_f_7questdb_7ingress__str_to_char(PyObject *__pyx_v_field, PyObject *__pyx_v_s) { - int __pyx_v_res; - char __pyx_r; - __Pyx_RefNannyDeclarations - Py_ssize_t __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - Py_UCS4 __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - long __pyx_t_6; - int __pyx_t_7; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_str_to_char", 0); - - /* "src/questdb/pandas_helpers.pxi":372 - * cdef char _str_to_char(str field, str s) except 0: - * cdef int res - * if len(s) != 1: # <<<<<<<<<<<<<< - * raise ValueError( - * f'dtype.{field}: Expected a single character, got {s!r}') - */ - if (unlikely(__pyx_v_s == Py_None)) { - PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); - __PYX_ERR(2, 372, __pyx_L1_error) - } - __pyx_t_1 = __Pyx_PyUnicode_GET_LENGTH(__pyx_v_s); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(2, 372, __pyx_L1_error) - __pyx_t_2 = ((__pyx_t_1 != 1) != 0); - if (unlikely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":374 - * if len(s) != 1: - * raise ValueError( - * f'dtype.{field}: Expected a single character, got {s!r}') # <<<<<<<<<<<<<< - * res = ord(s) - * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. - */ - __pyx_t_3 = PyTuple_New(4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 374, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = 0; - __pyx_t_4 = 127; - __Pyx_INCREF(__pyx_kp_u_dtype); - __pyx_t_1 += 6; - __Pyx_GIVEREF(__pyx_kp_u_dtype); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_dtype); - __pyx_t_5 = __Pyx_PyUnicode_Unicode(__pyx_v_field); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 374, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; - __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5); - __pyx_t_5 = 0; - __Pyx_INCREF(__pyx_kp_u_Expected_a_single_character_got); - __pyx_t_1 += 35; - __Pyx_GIVEREF(__pyx_kp_u_Expected_a_single_character_got); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u_Expected_a_single_character_got); - __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_s), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 374, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; - __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_3, 4, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 374, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":373 - * cdef int res - * if len(s) != 1: - * raise ValueError( # <<<<<<<<<<<<<< - * f'dtype.{field}: Expected a single character, got {s!r}') - * res = ord(s) - */ - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 373, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 373, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":372 - * cdef char _str_to_char(str field, str s) except 0: - * cdef int res - * if len(s) != 1: # <<<<<<<<<<<<<< - * raise ValueError( - * f'dtype.{field}: Expected a single character, got {s!r}') - */ - } - - /* "src/questdb/pandas_helpers.pxi":375 - * raise ValueError( - * f'dtype.{field}: Expected a single character, got {s!r}') - * res = ord(s) # <<<<<<<<<<<<<< - * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. - * raise ValueError( - */ - __pyx_t_6 = __Pyx_PyObject_Ord(__pyx_v_s); if (unlikely(__pyx_t_6 == ((long)(long)(Py_UCS4)-1))) __PYX_ERR(2, 375, __pyx_L1_error) - __pyx_v_res = __pyx_t_6; - - /* "src/questdb/pandas_helpers.pxi":376 - * f'dtype.{field}: Expected a single character, got {s!r}') - * res = ord(s) - * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. # <<<<<<<<<<<<<< - * raise ValueError( - * f'dtype.{field}: Character out of ASCII range, got {s!r}') - */ - __pyx_t_7 = ((__pyx_v_res <= 0) != 0); - if (!__pyx_t_7) { - } else { - __pyx_t_2 = __pyx_t_7; - goto __pyx_L5_bool_binop_done; - } - __pyx_t_7 = ((__pyx_v_res > 0x7F) != 0); - __pyx_t_2 = __pyx_t_7; - __pyx_L5_bool_binop_done:; - if (unlikely(__pyx_t_2)) { - - /* "src/questdb/pandas_helpers.pxi":378 - * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. - * raise ValueError( - * f'dtype.{field}: Character out of ASCII range, got {s!r}') # <<<<<<<<<<<<<< - * return res - * - */ - __pyx_t_3 = PyTuple_New(4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 378, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_1 = 0; - __pyx_t_4 = 127; - __Pyx_INCREF(__pyx_kp_u_dtype); - __pyx_t_1 += 6; - __Pyx_GIVEREF(__pyx_kp_u_dtype); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_dtype); - __pyx_t_5 = __Pyx_PyUnicode_Unicode(__pyx_v_field); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 378, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; - __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5); - __pyx_t_5 = 0; - __Pyx_INCREF(__pyx_kp_u_Character_out_of_ASCII_range_go); - __pyx_t_1 += 36; - __Pyx_GIVEREF(__pyx_kp_u_Character_out_of_ASCII_range_go); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u_Character_out_of_ASCII_range_go); - __pyx_t_5 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_s), __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 378, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_4; - __pyx_t_1 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_3, 4, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 378, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":377 - * res = ord(s) - * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. - * raise ValueError( # <<<<<<<<<<<<<< - * f'dtype.{field}: Character out of ASCII range, got {s!r}') - * return res - */ - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 377, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 377, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":376 - * f'dtype.{field}: Expected a single character, got {s!r}') - * res = ord(s) - * if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. # <<<<<<<<<<<<<< - * raise ValueError( - * f'dtype.{field}: Character out of ASCII range, got {s!r}') - */ - } - - /* "src/questdb/pandas_helpers.pxi":379 - * raise ValueError( - * f'dtype.{field}: Character out of ASCII range, got {s!r}') - * return res # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = ((char)__pyx_v_res); - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":370 - * - * - * cdef char _str_to_char(str field, str s) except 0: # <<<<<<<<<<<<<< - * cdef int res - * if len(s) != 1: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("questdb.ingress._str_to_char", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":382 - * - * - * cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: # <<<<<<<<<<<<<< - * """ - * Parse a numpy dtype and return a dtype_t. - */ - -static int __pyx_f_7questdb_7ingress__pandas_parse_dtype(PyObject *__pyx_v_np_dtype, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype_out) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - char __pyx_t_3; - int __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_parse_dtype", 0); - - /* "src/questdb/pandas_helpers.pxi":386 - * Parse a numpy dtype and return a dtype_t. - * """ - * dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) # <<<<<<<<<<<<<< - * dtype_out.kind = _str_to_char('kind', np_dtype.kind) - * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) - */ - __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_alignment, __pyx_int_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 386, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 386, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_dtype_out->alignment = __pyx_t_2; - - /* "src/questdb/pandas_helpers.pxi":387 - * """ - * dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) - * dtype_out.kind = _str_to_char('kind', np_dtype.kind) # <<<<<<<<<<<<<< - * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) - * dtype_out.byteorder = _str_to_char( - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_np_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 387, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 387, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7questdb_7ingress__str_to_char(__pyx_n_u_kind, ((PyObject*)__pyx_t_1)); if (unlikely(__pyx_t_3 == ((char)0))) __PYX_ERR(2, 387, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_dtype_out->kind = __pyx_t_3; - - /* "src/questdb/pandas_helpers.pxi":388 - * dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) - * dtype_out.kind = _str_to_char('kind', np_dtype.kind) - * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) # <<<<<<<<<<<<<< - * dtype_out.byteorder = _str_to_char( - * 'byteorder', getattr(np_dtype, 'byteorder', '=')) - */ - __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_itemsize, __pyx_int_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 388, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 388, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_dtype_out->itemsize = __pyx_t_2; - - /* "src/questdb/pandas_helpers.pxi":390 - * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) - * dtype_out.byteorder = _str_to_char( - * 'byteorder', getattr(np_dtype, 'byteorder', '=')) # <<<<<<<<<<<<<< - * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) - * return True - */ - __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_byteorder, __pyx_kp_u__12); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 390, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(2, 390, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":389 - * dtype_out.kind = _str_to_char('kind', np_dtype.kind) - * dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) - * dtype_out.byteorder = _str_to_char( # <<<<<<<<<<<<<< - * 'byteorder', getattr(np_dtype, 'byteorder', '=')) - * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress__str_to_char(__pyx_n_u_byteorder, ((PyObject*)__pyx_t_1)); if (unlikely(__pyx_t_3 == ((char)0))) __PYX_ERR(2, 389, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_dtype_out->byteorder = __pyx_t_3; - - /* "src/questdb/pandas_helpers.pxi":391 - * dtype_out.byteorder = _str_to_char( - * 'byteorder', getattr(np_dtype, 'byteorder', '=')) - * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_1 = __Pyx_GetAttr3(__pyx_v_np_dtype, __pyx_n_u_hasobject, Py_False); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 391, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 391, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_dtype_out->hasobject = __pyx_t_4; - - /* "src/questdb/pandas_helpers.pxi":392 - * 'byteorder', getattr(np_dtype, 'byteorder', '=')) - * dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":382 - * - * - * cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: # <<<<<<<<<<<<<< - * """ - * Parse a numpy dtype and return a dtype_t. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress._pandas_parse_dtype", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":395 - * - * - * cdef bint _pandas_resolve_dtypes( # <<<<<<<<<<<<<< - * object data, size_t col_count, dtype_t* dtypes_out) except False: - * cdef size_t col_index - */ - -static int __pyx_f_7questdb_7ingress__pandas_resolve_dtypes(PyObject *__pyx_v_data, size_t __pyx_v_col_count, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes_out) { - size_t __pyx_v_col_index; - int __pyx_r; - __Pyx_RefNannyDeclarations - size_t __pyx_t_1; - size_t __pyx_t_2; - size_t __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_resolve_dtypes", 0); - - /* "src/questdb/pandas_helpers.pxi":398 - * object data, size_t col_count, dtype_t* dtypes_out) except False: - * cdef size_t col_index - * for col_index in range(col_count): # <<<<<<<<<<<<<< - * _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) - * return True - */ - __pyx_t_1 = __pyx_v_col_count; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_col_index = __pyx_t_3; - - /* "src/questdb/pandas_helpers.pxi":399 - * cdef size_t col_index - * for col_index in range(col_count): - * _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtypes); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 399, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_4, __pyx_v_col_index, size_t, 0, __Pyx_PyInt_FromSize_t, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 399, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __pyx_f_7questdb_7ingress__pandas_parse_dtype(__pyx_t_5, (&(__pyx_v_dtypes_out[__pyx_v_col_index]))); if (unlikely(__pyx_t_6 == ((int)0))) __PYX_ERR(2, 399, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } - - /* "src/questdb/pandas_helpers.pxi":400 - * for col_index in range(col_count): - * _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":395 - * - * - * cdef bint _pandas_resolve_dtypes( # <<<<<<<<<<<<<< - * object data, size_t col_count, dtype_t* dtypes_out) except False: - * cdef size_t col_index - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("questdb.ingress._pandas_resolve_dtypes", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":403 - * - * - * cdef bint _pandas_resolve_col_buffers( # <<<<<<<<<<<<<< - * object data, size_t col_count, const dtype_t* dtypes, - * Py_buffer* col_buffers, size_t* set_buf_count) except False: - */ - -static int __pyx_f_7questdb_7ingress__pandas_resolve_col_buffers(PyObject *__pyx_v_data, size_t __pyx_v_col_count, struct __pyx_t_7questdb_7ingress_dtype_t const *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, size_t *__pyx_v_set_buf_count) { - size_t __pyx_v_col_index; - PyObject *__pyx_v_nparr = 0; - Py_buffer *__pyx_v_view; - CYTHON_UNUSED struct __pyx_t_7questdb_7ingress_dtype_t const *__pyx_v_dtype; - int __pyx_r; - __Pyx_RefNannyDeclarations - size_t __pyx_t_1; - size_t __pyx_t_2; - size_t __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_t_9; - long __pyx_t_10; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_resolve_col_buffers", 0); - - /* "src/questdb/pandas_helpers.pxi":417 - * cdef Py_buffer* view - * cdef const dtype_t* dtype - * for col_index in range(col_count): # <<<<<<<<<<<<<< - * nparr = data.iloc[:, col_index].to_numpy() - * view = &col_buffers[col_index] - */ - __pyx_t_1 = __pyx_v_col_count; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_col_index = __pyx_t_3; - - /* "src/questdb/pandas_helpers.pxi":418 - * cdef const dtype_t* dtype - * for col_index in range(col_count): - * nparr = data.iloc[:, col_index].to_numpy() # <<<<<<<<<<<<<< - * view = &col_buffers[col_index] - * dtype = &dtypes[col_index] - */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_iloc); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = __Pyx_PyInt_FromSize_t(__pyx_v_col_index); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_INCREF(__pyx_slice__13); - __Pyx_GIVEREF(__pyx_slice__13); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_slice__13); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_to_numpy); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6) : __Pyx_PyObject_CallNoArg(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF_SET(__pyx_v_nparr, __pyx_t_4); - __pyx_t_4 = 0; - - /* "src/questdb/pandas_helpers.pxi":419 - * for col_index in range(col_count): - * nparr = data.iloc[:, col_index].to_numpy() - * view = &col_buffers[col_index] # <<<<<<<<<<<<<< - * dtype = &dtypes[col_index] - * if not PyObject_CheckBuffer(nparr): - */ - __pyx_v_view = (&(__pyx_v_col_buffers[__pyx_v_col_index])); - - /* "src/questdb/pandas_helpers.pxi":420 - * nparr = data.iloc[:, col_index].to_numpy() - * view = &col_buffers[col_index] - * dtype = &dtypes[col_index] # <<<<<<<<<<<<<< - * if not PyObject_CheckBuffer(nparr): - * raise TypeError( - */ - __pyx_v_dtype = (&(__pyx_v_dtypes[__pyx_v_col_index])); - - /* "src/questdb/pandas_helpers.pxi":421 - * view = &col_buffers[col_index] - * dtype = &dtypes[col_index] - * if not PyObject_CheckBuffer(nparr): # <<<<<<<<<<<<<< - * raise TypeError( - * f'Bad column: Expected a numpy array, got {nparr!r}') - */ - __pyx_t_8 = ((!(PyObject_CheckBuffer(__pyx_v_nparr) != 0)) != 0); - if (unlikely(__pyx_t_8)) { - - /* "src/questdb/pandas_helpers.pxi":423 - * if not PyObject_CheckBuffer(nparr): - * raise TypeError( - * f'Bad column: Expected a numpy array, got {nparr!r}') # <<<<<<<<<<<<<< - * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) - * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. - */ - __pyx_t_4 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_nparr), __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 423, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_column_Expected_a_numpy_arra, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 423, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "src/questdb/pandas_helpers.pxi":422 - * dtype = &dtypes[col_index] - * if not PyObject_CheckBuffer(nparr): - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad column: Expected a numpy array, got {nparr!r}') - * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) - */ - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 422, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(2, 422, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":421 - * view = &col_buffers[col_index] - * dtype = &dtypes[col_index] - * if not PyObject_CheckBuffer(nparr): # <<<<<<<<<<<<<< - * raise TypeError( - * f'Bad column: Expected a numpy array, got {nparr!r}') - */ - } - - /* "src/questdb/pandas_helpers.pxi":424 - * raise TypeError( - * f'Bad column: Expected a numpy array, got {nparr!r}') - * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) # <<<<<<<<<<<<<< - * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. - * set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. - */ - __pyx_t_9 = PyObject_GetBuffer(__pyx_v_nparr, __pyx_v_view, PyBUF_STRIDES); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(2, 424, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":426 - * PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) - * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. - * set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_10 = 0; - (__pyx_v_set_buf_count[__pyx_t_10]) = ((__pyx_v_set_buf_count[__pyx_t_10]) + 1); - } - - /* "src/questdb/pandas_helpers.pxi":427 - * # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. - * set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":403 - * - * - * cdef bint _pandas_resolve_col_buffers( # <<<<<<<<<<<<<< - * object data, size_t col_count, const dtype_t* dtypes, - * Py_buffer* col_buffers, size_t* set_buf_count) except False: - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress._pandas_resolve_col_buffers", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_nparr); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":430 - * - * - * cdef inline const void* _pandas_get_cell( # <<<<<<<<<<<<<< - * Py_buffer* col_buffer, size_t row_index): - * return col_buffer.buf + (row_index * col_buffer.strides[0]) - */ - -static CYTHON_INLINE void const *__pyx_f_7questdb_7ingress__pandas_get_cell(Py_buffer *__pyx_v_col_buffer, size_t __pyx_v_row_index) { - void const *__pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_pandas_get_cell", 0); - - /* "src/questdb/pandas_helpers.pxi":432 - * cdef inline const void* _pandas_get_cell( - * Py_buffer* col_buffer, size_t row_index): - * return col_buffer.buf + (row_index * col_buffer.strides[0]) # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = (__pyx_v_col_buffer->buf + (((Py_ssize_t)__pyx_v_row_index) * (__pyx_v_col_buffer->strides[0]))); - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":430 - * - * - * cdef inline const void* _pandas_get_cell( # <<<<<<<<<<<<<< - * Py_buffer* col_buffer, size_t row_index): - * return col_buffer.buf + (row_index * col_buffer.strides[0]) - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":439 - * - * - * cdef bint _pandas_get_str_cell( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * dtype_t* dtype, - */ - -static int __pyx_f_7questdb_7ingress__pandas_get_str_cell(struct qdb_pystr_buf *__pyx_v_b, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype, Py_buffer *__pyx_v_col_buffer, size_t __pyx_v_row_index, int *__pyx_v_is_null_out, struct line_sender_utf8 *__pyx_v_utf8_out) { - void const *__pyx_v_cell; - PyObject *__pyx_v_obj = 0; - PyObject *__pyx_v_e = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - Py_ssize_t __pyx_t_12; - Py_UCS4 __pyx_t_13; - PyObject *__pyx_t_14 = NULL; - int __pyx_t_15; - char const *__pyx_t_16; - PyObject *__pyx_t_17 = NULL; - PyObject *__pyx_t_18 = NULL; - PyObject *__pyx_t_19 = NULL; - PyObject *__pyx_t_20 = NULL; - PyObject *__pyx_t_21 = NULL; - PyObject *__pyx_t_22 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_get_str_cell", 0); - - /* "src/questdb/pandas_helpers.pxi":446 - * bint* is_null_out, - * line_sender_utf8* utf8_out) except False: - * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) # <<<<<<<<<<<<<< - * cdef object obj - * if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: - */ - __pyx_v_cell = __pyx_f_7questdb_7ingress__pandas_get_cell(__pyx_v_col_buffer, __pyx_v_row_index); - - /* "src/questdb/pandas_helpers.pxi":448 - * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - * cdef object obj - * if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: # <<<<<<<<<<<<<< - * # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. - * # TODO: Improve error messaging. Error message should include the column name. - */ - __pyx_t_1 = ((__pyx_v_dtype->kind == __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_OBJECT) != 0); - if (likely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":451 - * # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. - * # TODO: Improve error messaging. Error message should include the column name. - * obj = ((cell)[0]) # <<<<<<<<<<<<<< - * if (obj is None) or (obj is _PANDAS_NA): - * is_null_out[0] = True - */ - __pyx_t_2 = ((PyObject *)(((PyObject **)__pyx_v_cell)[0])); - __Pyx_INCREF(__pyx_t_2); - __pyx_v_obj = __pyx_t_2; - __pyx_t_2 = 0; - - /* "src/questdb/pandas_helpers.pxi":452 - * # TODO: Improve error messaging. Error message should include the column name. - * obj = ((cell)[0]) - * if (obj is None) or (obj is _PANDAS_NA): # <<<<<<<<<<<<<< - * is_null_out[0] = True - * else: - */ - __pyx_t_3 = (__pyx_v_obj == Py_None); - __pyx_t_4 = (__pyx_t_3 != 0); - if (!__pyx_t_4) { - } else { - __pyx_t_1 = __pyx_t_4; - goto __pyx_L5_bool_binop_done; - } - __pyx_t_4 = (__pyx_v_obj == __pyx_v_7questdb_7ingress__PANDAS_NA); - __pyx_t_3 = (__pyx_t_4 != 0); - __pyx_t_1 = __pyx_t_3; - __pyx_L5_bool_binop_done:; - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":453 - * obj = ((cell)[0]) - * if (obj is None) or (obj is _PANDAS_NA): - * is_null_out[0] = True # <<<<<<<<<<<<<< - * else: - * is_null_out[0] = False - */ - (__pyx_v_is_null_out[0]) = 1; - - /* "src/questdb/pandas_helpers.pxi":452 - * # TODO: Improve error messaging. Error message should include the column name. - * obj = ((cell)[0]) - * if (obj is None) or (obj is _PANDAS_NA): # <<<<<<<<<<<<<< - * is_null_out[0] = True - * else: - */ - goto __pyx_L4; - } - - /* "src/questdb/pandas_helpers.pxi":455 - * is_null_out[0] = True - * else: - * is_null_out[0] = False # <<<<<<<<<<<<<< - * try: - * str_to_utf8(b, obj, utf8_out) - */ - /*else*/ { - (__pyx_v_is_null_out[0]) = 0; - - /* "src/questdb/pandas_helpers.pxi":456 - * else: - * is_null_out[0] = False - * try: # <<<<<<<<<<<<<< - * str_to_utf8(b, obj, utf8_out) - * except TypeError as e: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - /*try:*/ { - - /* "src/questdb/pandas_helpers.pxi":457 - * is_null_out[0] = False - * try: - * str_to_utf8(b, obj, utf8_out) # <<<<<<<<<<<<<< - * except TypeError as e: - * raise TypeError( - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_obj))||((__pyx_v_obj) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_obj)->tp_name), 0))) __PYX_ERR(2, 457, __pyx_L7_error) - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, ((PyObject*)__pyx_v_obj), __pyx_v_utf8_out); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 457, __pyx_L7_error) - - /* "src/questdb/pandas_helpers.pxi":456 - * else: - * is_null_out[0] = False - * try: # <<<<<<<<<<<<<< - * str_to_utf8(b, obj, utf8_out) - * except TypeError as e: - */ - } - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - goto __pyx_L12_try_end; - __pyx_L7_error:; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "src/questdb/pandas_helpers.pxi":458 - * try: - * str_to_utf8(b, obj, utf8_out) - * except TypeError as e: # <<<<<<<<<<<<<< - * raise TypeError( - * 'Bad column: Expected a string, ' + - */ - __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); - if (__pyx_t_8) { - __Pyx_AddTraceback("questdb.ingress._pandas_get_str_cell", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(2, 458, __pyx_L9_except_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_t_9); - __Pyx_GOTREF(__pyx_t_10); - __Pyx_INCREF(__pyx_t_9); - __pyx_v_e = __pyx_t_9; - /*try:*/ { - - /* "src/questdb/pandas_helpers.pxi":461 - * raise TypeError( - * 'Bad column: Expected a string, ' + - * f'got {obj!r} ({type(obj)!r})') from e # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - __pyx_t_11 = PyTuple_New(5); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 461, __pyx_L18_error) - __Pyx_GOTREF(__pyx_t_11); - __pyx_t_12 = 0; - __pyx_t_13 = 127; - __Pyx_INCREF(__pyx_kp_u_got); - __pyx_t_12 += 4; - __Pyx_GIVEREF(__pyx_kp_u_got); - PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_kp_u_got); - __pyx_t_14 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_obj), __pyx_empty_unicode); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 461, __pyx_L18_error) - __Pyx_GOTREF(__pyx_t_14); - __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) : __pyx_t_13; - __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_14); - __Pyx_GIVEREF(__pyx_t_14); - PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_14); - __pyx_t_14 = 0; - __Pyx_INCREF(__pyx_kp_u__14); - __pyx_t_12 += 2; - __Pyx_GIVEREF(__pyx_kp_u__14); - PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_kp_u__14); - __pyx_t_14 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(((PyObject *)Py_TYPE(__pyx_v_obj))), __pyx_empty_unicode); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 461, __pyx_L18_error) - __Pyx_GOTREF(__pyx_t_14); - __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_14) : __pyx_t_13; - __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_14); - __Pyx_GIVEREF(__pyx_t_14); - PyTuple_SET_ITEM(__pyx_t_11, 3, __pyx_t_14); - __pyx_t_14 = 0; - __Pyx_INCREF(__pyx_kp_u__15); - __pyx_t_12 += 1; - __Pyx_GIVEREF(__pyx_kp_u__15); - PyTuple_SET_ITEM(__pyx_t_11, 4, __pyx_kp_u__15); - __pyx_t_14 = __Pyx_PyUnicode_Join(__pyx_t_11, 5, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 461, __pyx_L18_error) - __Pyx_GOTREF(__pyx_t_14); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - - /* "src/questdb/pandas_helpers.pxi":460 - * except TypeError as e: - * raise TypeError( - * 'Bad column: Expected a string, ' + # <<<<<<<<<<<<<< - * f'got {obj!r} ({type(obj)!r})') from e - * else: - */ - __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_column_Expected_a_string, __pyx_t_14); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 460, __pyx_L18_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; - - /* "src/questdb/pandas_helpers.pxi":459 - * str_to_utf8(b, obj, utf8_out) - * except TypeError as e: - * raise TypeError( # <<<<<<<<<<<<<< - * 'Bad column: Expected a string, ' + - * f'got {obj!r} ({type(obj)!r})') from e - */ - __pyx_t_14 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_11); if (unlikely(!__pyx_t_14)) __PYX_ERR(2, 459, __pyx_L18_error) - __Pyx_GOTREF(__pyx_t_14); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - - /* "src/questdb/pandas_helpers.pxi":461 - * raise TypeError( - * 'Bad column: Expected a string, ' + - * f'got {obj!r} ({type(obj)!r})') from e # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - __Pyx_Raise(__pyx_t_14, 0, 0, __pyx_v_e); - __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; - __PYX_ERR(2, 459, __pyx_L18_error) - } - - /* "src/questdb/pandas_helpers.pxi":458 - * try: - * str_to_utf8(b, obj, utf8_out) - * except TypeError as e: # <<<<<<<<<<<<<< - * raise TypeError( - * 'Bad column: Expected a string, ' + - */ - /*finally:*/ { - __pyx_L18_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_20, &__pyx_t_21, &__pyx_t_22); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19) < 0)) __Pyx_ErrFetch(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19); - __Pyx_XGOTREF(__pyx_t_17); - __Pyx_XGOTREF(__pyx_t_18); - __Pyx_XGOTREF(__pyx_t_19); - __Pyx_XGOTREF(__pyx_t_20); - __Pyx_XGOTREF(__pyx_t_21); - __Pyx_XGOTREF(__pyx_t_22); - __pyx_t_8 = __pyx_lineno; __pyx_t_15 = __pyx_clineno; __pyx_t_16 = __pyx_filename; - { - __Pyx_DECREF(__pyx_v_e); - __pyx_v_e = NULL; - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_20); - __Pyx_XGIVEREF(__pyx_t_21); - __Pyx_XGIVEREF(__pyx_t_22); - __Pyx_ExceptionReset(__pyx_t_20, __pyx_t_21, __pyx_t_22); - } - __Pyx_XGIVEREF(__pyx_t_17); - __Pyx_XGIVEREF(__pyx_t_18); - __Pyx_XGIVEREF(__pyx_t_19); - __Pyx_ErrRestore(__pyx_t_17, __pyx_t_18, __pyx_t_19); - __pyx_t_17 = 0; __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; - __pyx_lineno = __pyx_t_8; __pyx_clineno = __pyx_t_15; __pyx_filename = __pyx_t_16; - goto __pyx_L9_except_error; - } - } - } - goto __pyx_L9_except_error; - __pyx_L9_except_error:; - - /* "src/questdb/pandas_helpers.pxi":456 - * else: - * is_null_out[0] = False - * try: # <<<<<<<<<<<<<< - * str_to_utf8(b, obj, utf8_out) - * except TypeError as e: - */ - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_XGIVEREF(__pyx_t_7); - __Pyx_ExceptionReset(__pyx_t_5, __pyx_t_6, __pyx_t_7); - goto __pyx_L1_error; - __pyx_L12_try_end:; - } - } - __pyx_L4:; - - /* "src/questdb/pandas_helpers.pxi":448 - * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - * cdef object obj - * if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: # <<<<<<<<<<<<<< - * # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. - * # TODO: Improve error messaging. Error message should include the column name. - */ - goto __pyx_L3; - } - - /* "src/questdb/pandas_helpers.pxi":463 - * f'got {obj!r} ({type(obj)!r})') from e - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. - * return True - */ - /*else*/ { - - /* "src/questdb/pandas_helpers.pxi":464 - * else: - * raise TypeError( - * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_10 = __Pyx_PyUnicode_From_char(__pyx_v_dtype->kind, 0, ' ', 'd'); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 464, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_kp_u_NOT_YET_IMPLEMENTED_Kind, __pyx_t_10); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 464, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "src/questdb/pandas_helpers.pxi":463 - * f'got {obj!r} ({type(obj)!r})') from e - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. - * return True - */ - __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 463, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_Raise(__pyx_t_10, 0, 0, 0); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __PYX_ERR(2, 463, __pyx_L1_error) - } - __pyx_L3:; - - /* "src/questdb/pandas_helpers.pxi":465 - * raise TypeError( - * f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":439 - * - * - * cdef bint _pandas_get_str_cell( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * dtype_t* dtype, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_XDECREF(__pyx_t_14); - __Pyx_AddTraceback("questdb.ingress._pandas_get_str_cell", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_obj); - __Pyx_XDECREF(__pyx_v_e); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":468 - * - * - * cdef int64_t _pandas_get_timestamp_cell( # <<<<<<<<<<<<<< - * dtype_t* dtype, - * Py_buffer* col_buffer, - */ - -static int64_t __pyx_f_7questdb_7ingress__pandas_get_timestamp_cell(CYTHON_UNUSED struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype, Py_buffer *__pyx_v_col_buffer, size_t __pyx_v_row_index) { - void const *__pyx_v_cell; - int64_t __pyx_v_res; - int64_t __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_get_timestamp_cell", 0); - - /* "src/questdb/pandas_helpers.pxi":473 - * size_t row_index) except -1: - * # Note: Type is pre-validated by `_pandas_is_supported_datetime`. - * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) # <<<<<<<<<<<<<< - * cdef int64_t res = (cell)[0] - * if res < 0: - */ - __pyx_v_cell = __pyx_f_7questdb_7ingress__pandas_get_cell(__pyx_v_col_buffer, __pyx_v_row_index); - - /* "src/questdb/pandas_helpers.pxi":474 - * # Note: Type is pre-validated by `_pandas_is_supported_datetime`. - * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - * cdef int64_t res = (cell)[0] # <<<<<<<<<<<<<< - * if res < 0: - * # TODO [amunra]: Improve error messaging. Add column name. - */ - __pyx_v_res = (((int64_t *)__pyx_v_cell)[0]); - - /* "src/questdb/pandas_helpers.pxi":475 - * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - * cdef int64_t res = (cell)[0] - * if res < 0: # <<<<<<<<<<<<<< - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( - */ - __pyx_t_1 = ((__pyx_v_res < 0) != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":478 - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( - * f'Bad value: Negative timestamp, got {res}') # <<<<<<<<<<<<<< - * return res - * - */ - __pyx_t_2 = __Pyx_PyInt_From_int64_t(__pyx_v_res); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 478, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 478, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Bad_value_Negative_timestamp_got, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 478, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "src/questdb/pandas_helpers.pxi":477 - * if res < 0: - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( # <<<<<<<<<<<<<< - * f'Bad value: Negative timestamp, got {res}') - * return res - */ - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 477, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 477, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":475 - * cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - * cdef int64_t res = (cell)[0] - * if res < 0: # <<<<<<<<<<<<<< - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( - */ - } - - /* "src/questdb/pandas_helpers.pxi":479 - * raise ValueError( - * f'Bad value: Negative timestamp, got {res}') - * return res # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_res; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":468 - * - * - * cdef int64_t _pandas_get_timestamp_cell( # <<<<<<<<<<<<<< - * dtype_t* dtype, - * Py_buffer* col_buffer, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress._pandas_get_timestamp_cell", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1L; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":482 - * - * - * cdef bint _pandas_row_table_name( # <<<<<<<<<<<<<< - * line_sender_buffer* impl, - * qdb_pystr_buf* b, - */ - -static int __pyx_f_7questdb_7ingress__pandas_row_table_name(struct line_sender_buffer *__pyx_v_impl, struct qdb_pystr_buf *__pyx_v_b, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, Py_ssize_t __pyx_v_name_col, size_t __pyx_v_row_index, struct line_sender_table_name __pyx_v_c_table_name) { - struct line_sender_error *__pyx_v_err; - int __pyx_v_is_null; - struct line_sender_utf8 __pyx_v_utf8; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - Py_ssize_t __pyx_t_3; - Py_UCS4 __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_row_table_name", 0); - - /* "src/questdb/pandas_helpers.pxi":490 - * size_t row_index, - * line_sender_table_name c_table_name) except False: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef bint is_null = False - * cdef line_sender_utf8 utf8 - */ - __pyx_v_err = NULL; - - /* "src/questdb/pandas_helpers.pxi":491 - * line_sender_table_name c_table_name) except False: - * cdef line_sender_error* err = NULL - * cdef bint is_null = False # <<<<<<<<<<<<<< - * cdef line_sender_utf8 utf8 - * if name_col >= 0: - */ - __pyx_v_is_null = 0; - - /* "src/questdb/pandas_helpers.pxi":493 - * cdef bint is_null = False - * cdef line_sender_utf8 utf8 - * if name_col >= 0: # <<<<<<<<<<<<<< - * _pandas_get_str_cell( - * b, - */ - __pyx_t_1 = ((__pyx_v_name_col >= 0) != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":494 - * cdef line_sender_utf8 utf8 - * if name_col >= 0: - * _pandas_get_str_cell( # <<<<<<<<<<<<<< - * b, - * &dtypes[name_col], - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_get_str_cell(__pyx_v_b, (&(__pyx_v_dtypes[((size_t)__pyx_v_name_col)])), (&(__pyx_v_col_buffers[((size_t)__pyx_v_name_col)])), __pyx_v_row_index, (&__pyx_v_is_null), (&__pyx_v_utf8)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(2, 494, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":501 - * &is_null, - * &utf8) - * if is_null: # <<<<<<<<<<<<<< - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( - */ - __pyx_t_1 = (__pyx_v_is_null != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":504 - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( - * f'Bad value: `None` table name value at row {row_index}.') # <<<<<<<<<<<<<< - * if not line_sender_table_name_init( - * &c_table_name, utf8.len, utf8.buf, &err): - */ - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 504, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = 0; - __pyx_t_4 = 127; - __Pyx_INCREF(__pyx_kp_u_Bad_value_None_table_name_value); - __pyx_t_3 += 42; - __Pyx_GIVEREF(__pyx_kp_u_Bad_value_None_table_name_value); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_Bad_value_None_table_name_value); - __pyx_t_5 = __Pyx_PyUnicode_From_size_t(__pyx_v_row_index, 0, ' ', 'd'); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 504, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_3 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_5); - __pyx_t_5 = 0; - __Pyx_INCREF(__pyx_kp_u__6); - __pyx_t_3 += 1; - __Pyx_GIVEREF(__pyx_kp_u__6); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); - __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 504, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "src/questdb/pandas_helpers.pxi":503 - * if is_null: - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( # <<<<<<<<<<<<<< - * f'Bad value: `None` table name value at row {row_index}.') - * if not line_sender_table_name_init( - */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 503, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 503, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":501 - * &is_null, - * &utf8) - * if is_null: # <<<<<<<<<<<<<< - * # TODO [amunra]: Improve error messaging. Add column name. - * raise ValueError( - */ - } - - /* "src/questdb/pandas_helpers.pxi":505 - * raise ValueError( - * f'Bad value: `None` table name value at row {row_index}.') - * if not line_sender_table_name_init( # <<<<<<<<<<<<<< - * &c_table_name, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = ((!(line_sender_table_name_init((&__pyx_v_c_table_name), __pyx_v_utf8.len, __pyx_v_utf8.buf, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":507 - * if not line_sender_table_name_init( - * &c_table_name, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * if not line_sender_buffer_table(impl, c_table_name, &err): - * raise c_err_to_py(err) - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 507, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 507, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":505 - * raise ValueError( - * f'Bad value: `None` table name value at row {row_index}.') - * if not line_sender_table_name_init( # <<<<<<<<<<<<<< - * &c_table_name, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - */ - } - - /* "src/questdb/pandas_helpers.pxi":493 - * cdef bint is_null = False - * cdef line_sender_utf8 utf8 - * if name_col >= 0: # <<<<<<<<<<<<<< - * _pandas_get_str_cell( - * b, - */ - } - - /* "src/questdb/pandas_helpers.pxi":508 - * &c_table_name, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - * if not line_sender_buffer_table(impl, c_table_name, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - __pyx_t_1 = ((!(line_sender_buffer_table(__pyx_v_impl, __pyx_v_c_table_name, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":509 - * raise c_err_to_py(err) - * if not line_sender_buffer_table(impl, c_table_name, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 509, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(2, 509, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":508 - * &c_table_name, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - * if not line_sender_buffer_table(impl, c_table_name, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - } - - /* "src/questdb/pandas_helpers.pxi":510 - * if not line_sender_buffer_table(impl, c_table_name, &err): - * raise c_err_to_py(err) - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":482 - * - * - * cdef bint _pandas_row_table_name( # <<<<<<<<<<<<<< - * line_sender_buffer* impl, - * qdb_pystr_buf* b, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("questdb.ingress._pandas_row_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":513 - * - * - * cdef bint _pandas_row_symbols( # <<<<<<<<<<<<<< - * line_sender_buffer* impl, - * qdb_pystr_buf* b, - */ - -static int __pyx_f_7questdb_7ingress__pandas_row_symbols(struct line_sender_buffer *__pyx_v_impl, struct qdb_pystr_buf *__pyx_v_b, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, size_t __pyx_v_row_index, __pyx_t_7questdb_7ingress_column_name_vec const *__pyx_v_symbol_names, __pyx_t_7questdb_7ingress_size_t_vec const *__pyx_v_symbol_indices) { - struct line_sender_error *__pyx_v_err; - size_t __pyx_v_sym_index; - size_t __pyx_v_col_index; - struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype; - Py_buffer *__pyx_v_col_buffer; - struct line_sender_column_name __pyx_v_col_name; - struct line_sender_utf8 __pyx_v_symbol; - int __pyx_v_is_null; - int __pyx_r; - __Pyx_RefNannyDeclarations - size_t __pyx_t_1; - size_t __pyx_t_2; - size_t __pyx_t_3; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_row_symbols", 0); - - /* "src/questdb/pandas_helpers.pxi":521 - * const column_name_vec* symbol_names, - * const size_t_vec* symbol_indices) except False: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef size_t sym_index - * cdef size_t col_index - */ - __pyx_v_err = NULL; - - /* "src/questdb/pandas_helpers.pxi":528 - * cdef line_sender_column_name col_name - * cdef line_sender_utf8 symbol - * cdef bint is_null = False # <<<<<<<<<<<<<< - * for sym_index in range(symbol_indices.size): - * col_name = symbol_names.d[sym_index] - */ - __pyx_v_is_null = 0; - - /* "src/questdb/pandas_helpers.pxi":529 - * cdef line_sender_utf8 symbol - * cdef bint is_null = False - * for sym_index in range(symbol_indices.size): # <<<<<<<<<<<<<< - * col_name = symbol_names.d[sym_index] - * col_index = symbol_indices.d[sym_index] - */ - __pyx_t_1 = __pyx_v_symbol_indices->size; - __pyx_t_2 = __pyx_t_1; - for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { - __pyx_v_sym_index = __pyx_t_3; - - /* "src/questdb/pandas_helpers.pxi":530 - * cdef bint is_null = False - * for sym_index in range(symbol_indices.size): - * col_name = symbol_names.d[sym_index] # <<<<<<<<<<<<<< - * col_index = symbol_indices.d[sym_index] - * col_buffer = &col_buffers[col_index] - */ - __pyx_v_col_name = (__pyx_v_symbol_names->d[__pyx_v_sym_index]); - - /* "src/questdb/pandas_helpers.pxi":531 - * for sym_index in range(symbol_indices.size): - * col_name = symbol_names.d[sym_index] - * col_index = symbol_indices.d[sym_index] # <<<<<<<<<<<<<< - * col_buffer = &col_buffers[col_index] - * dtype = &dtypes[col_index] - */ - __pyx_v_col_index = (__pyx_v_symbol_indices->d[__pyx_v_sym_index]); - - /* "src/questdb/pandas_helpers.pxi":532 - * col_name = symbol_names.d[sym_index] - * col_index = symbol_indices.d[sym_index] - * col_buffer = &col_buffers[col_index] # <<<<<<<<<<<<<< - * dtype = &dtypes[col_index] - * _pandas_get_str_cell( - */ - __pyx_v_col_buffer = (&(__pyx_v_col_buffers[__pyx_v_col_index])); - - /* "src/questdb/pandas_helpers.pxi":533 - * col_index = symbol_indices.d[sym_index] - * col_buffer = &col_buffers[col_index] - * dtype = &dtypes[col_index] # <<<<<<<<<<<<<< - * _pandas_get_str_cell( - * b, - */ - __pyx_v_dtype = (&(__pyx_v_dtypes[__pyx_v_col_index])); - - /* "src/questdb/pandas_helpers.pxi":534 - * col_buffer = &col_buffers[col_index] - * dtype = &dtypes[col_index] - * _pandas_get_str_cell( # <<<<<<<<<<<<<< - * b, - * dtype, - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress__pandas_get_str_cell(__pyx_v_b, __pyx_v_dtype, __pyx_v_col_buffer, __pyx_v_row_index, (&__pyx_v_is_null), (&__pyx_v_symbol)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(2, 534, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":541 - * &is_null, - * &symbol) - * if not is_null: # <<<<<<<<<<<<<< - * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): - * raise c_err_to_py(err) - */ - __pyx_t_4 = ((!(__pyx_v_is_null != 0)) != 0); - if (__pyx_t_4) { - - /* "src/questdb/pandas_helpers.pxi":542 - * &symbol) - * if not is_null: - * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - __pyx_t_4 = ((!(line_sender_buffer_symbol(__pyx_v_impl, __pyx_v_col_name, __pyx_v_symbol, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_4)) { - - /* "src/questdb/pandas_helpers.pxi":543 - * if not is_null: - * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 543, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_Raise(__pyx_t_5, 0, 0, 0); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __PYX_ERR(2, 543, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":542 - * &symbol) - * if not is_null: - * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - } - - /* "src/questdb/pandas_helpers.pxi":541 - * &is_null, - * &symbol) - * if not is_null: # <<<<<<<<<<<<<< - * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): - * raise c_err_to_py(err) - */ - } - } - - /* "src/questdb/pandas_helpers.pxi":544 - * if not line_sender_buffer_symbol(impl, col_name, symbol, &err): - * raise c_err_to_py(err) - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":513 - * - * - * cdef bint _pandas_row_symbols( # <<<<<<<<<<<<<< - * line_sender_buffer* impl, - * qdb_pystr_buf* b, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("questdb.ingress._pandas_row_symbols", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "src/questdb/pandas_helpers.pxi":547 - * - * - * cdef bint _pandas_row_at( # <<<<<<<<<<<<<< - * line_sender_buffer* impl, - * dtype_t* dtypes, - */ - -static int __pyx_f_7questdb_7ingress__pandas_row_at(struct line_sender_buffer *__pyx_v_impl, struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes, Py_buffer *__pyx_v_col_buffers, size_t __pyx_v_row_index, Py_ssize_t __pyx_v_at_col, int64_t __pyx_v_at_value) { - struct line_sender_error *__pyx_v_err; - Py_buffer *__pyx_v_col_buffer; - struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtype; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int64_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas_row_at", 0); - - /* "src/questdb/pandas_helpers.pxi":554 - * ssize_t at_col, - * int64_t at_value) except False: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef Py_buffer* col_buffer - * cdef dtype_t* dtype - */ - __pyx_v_err = NULL; - - /* "src/questdb/pandas_helpers.pxi":557 - * cdef Py_buffer* col_buffer - * cdef dtype_t* dtype - * if at_col >= 0: # <<<<<<<<<<<<<< - * col_buffer = &col_buffers[at_col] - * dtype = &dtypes[at_col] - */ - __pyx_t_1 = ((__pyx_v_at_col >= 0) != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":558 - * cdef dtype_t* dtype - * if at_col >= 0: - * col_buffer = &col_buffers[at_col] # <<<<<<<<<<<<<< - * dtype = &dtypes[at_col] - * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - */ - __pyx_v_col_buffer = (&(__pyx_v_col_buffers[((size_t)__pyx_v_at_col)])); - - /* "src/questdb/pandas_helpers.pxi":559 - * if at_col >= 0: - * col_buffer = &col_buffers[at_col] - * dtype = &dtypes[at_col] # <<<<<<<<<<<<<< - * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - * if at_value > 0: - */ - __pyx_v_dtype = (&(__pyx_v_dtypes[((size_t)__pyx_v_at_col)])); - - /* "src/questdb/pandas_helpers.pxi":560 - * col_buffer = &col_buffers[at_col] - * dtype = &dtypes[at_col] - * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) # <<<<<<<<<<<<<< - * if at_value > 0: - * if not line_sender_buffer_at(impl, at_value, &err): - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress__pandas_get_timestamp_cell(__pyx_v_dtype, __pyx_v_col_buffer, __pyx_v_row_index); if (unlikely(__pyx_t_2 == ((int64_t)-1L))) __PYX_ERR(2, 560, __pyx_L1_error) - __pyx_v_at_value = __pyx_t_2; - - /* "src/questdb/pandas_helpers.pxi":557 - * cdef Py_buffer* col_buffer - * cdef dtype_t* dtype - * if at_col >= 0: # <<<<<<<<<<<<<< - * col_buffer = &col_buffers[at_col] - * dtype = &dtypes[at_col] - */ - } - - /* "src/questdb/pandas_helpers.pxi":561 - * dtype = &dtypes[at_col] - * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - * if at_value > 0: # <<<<<<<<<<<<<< - * if not line_sender_buffer_at(impl, at_value, &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = ((__pyx_v_at_value > 0) != 0); - if (__pyx_t_1) { - - /* "src/questdb/pandas_helpers.pxi":562 - * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - * if at_value > 0: - * if not line_sender_buffer_at(impl, at_value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * else: - */ - __pyx_t_1 = ((!(line_sender_buffer_at(__pyx_v_impl, __pyx_v_at_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":563 - * if at_value > 0: - * if not line_sender_buffer_at(impl, at_value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * else: - * if not line_sender_buffer_at_now(impl, &err): - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 563, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 563, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":562 - * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - * if at_value > 0: - * if not line_sender_buffer_at(impl, at_value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * else: - */ - } - - /* "src/questdb/pandas_helpers.pxi":561 - * dtype = &dtypes[at_col] - * at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - * if at_value > 0: # <<<<<<<<<<<<<< - * if not line_sender_buffer_at(impl, at_value, &err): - * raise c_err_to_py(err) - */ - goto __pyx_L4; - } - - /* "src/questdb/pandas_helpers.pxi":565 - * raise c_err_to_py(err) - * else: - * if not line_sender_buffer_at_now(impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - /*else*/ { - __pyx_t_1 = ((!(line_sender_buffer_at_now(__pyx_v_impl, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "src/questdb/pandas_helpers.pxi":566 - * else: - * if not line_sender_buffer_at_now(impl, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return True - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 566, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(2, 566, __pyx_L1_error) - - /* "src/questdb/pandas_helpers.pxi":565 - * raise c_err_to_py(err) - * else: - * if not line_sender_buffer_at_now(impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - } - } - __pyx_L4:; - - /* "src/questdb/pandas_helpers.pxi":567 - * if not line_sender_buffer_at_now(impl, &err): - * raise c_err_to_py(err) - * return True # <<<<<<<<<<<<<< - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "src/questdb/pandas_helpers.pxi":547 - * - * - * cdef bint _pandas_row_at( # <<<<<<<<<<<<<< - * line_sender_buffer* impl, - * dtype_t* dtypes, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress._pandas_row_at", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":73 - * TlsError = line_sender_error_tls_error - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """Return the name of the enum.""" - * return self.name - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_16IngressErrorCode_1__str__(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_7questdb_7ingress_16IngressErrorCode___str__[] = "Return the name of the enum."; -static PyMethodDef __pyx_mdef_7questdb_7ingress_16IngressErrorCode_1__str__ = {"__str__", (PyCFunction)__pyx_pw_7questdb_7ingress_16IngressErrorCode_1__str__, METH_O, __pyx_doc_7questdb_7ingress_16IngressErrorCode___str__}; -static PyObject *__pyx_pw_7questdb_7ingress_16IngressErrorCode_1__str__(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_16IngressErrorCode___str__(__pyx_self, ((PyObject *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_16IngressErrorCode___str__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__str__", 0); - - /* "questdb/ingress.pyx":75 - * def __str__(self) -> str: - * """Return the name of the enum.""" - * return self.name # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 75, __pyx_L1_error) - __pyx_r = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":73 - * TlsError = line_sender_error_tls_error - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """Return the name of the enum.""" - * return self.name - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.IngressErrorCode.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":80 - * class IngressError(Exception): - * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" - * def __init__(self, code, msg): # <<<<<<<<<<<<<< - * super().__init__(msg) - * self._code = code - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_12IngressError_1__init__ = {"__init__", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_12IngressError_1__init__, METH_VARARGS|METH_KEYWORDS, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_self = 0; - PyObject *__pyx_v_code = 0; - PyObject *__pyx_v_msg = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_code,&__pyx_n_s_msg,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_code)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); __PYX_ERR(0, 80, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_msg)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); __PYX_ERR(0, 80, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 80, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v_self = values[0]; - __pyx_v_code = values[1]; - __pyx_v_msg = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 80, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.IngressError.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7questdb_7ingress_12IngressError___init__(__pyx_self, __pyx_v_self, __pyx_v_code, __pyx_v_msg); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_12IngressError___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_code, PyObject *__pyx_v_msg) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__init__", 0); - - /* "questdb/ingress.pyx":81 - * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" - * def __init__(self, code, msg): - * super().__init__(msg) # <<<<<<<<<<<<<< - * self._code = code - * - */ - __pyx_t_2 = __Pyx_CyFunction_GetClassObj(__pyx_self); - if (!__pyx_t_2) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 81, __pyx_L1_error) } - __Pyx_INCREF(__pyx_t_2); - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 81, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); - __Pyx_INCREF(__pyx_v_self); - __Pyx_GIVEREF(__pyx_v_self); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self); - __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 81, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 81, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_2)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_v_msg) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_msg); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":82 - * def __init__(self, code, msg): - * super().__init__(msg) - * self._code = code # <<<<<<<<<<<<<< - * - * @property - */ - if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_code_2, __pyx_v_code) < 0) __PYX_ERR(0, 82, __pyx_L1_error) - - /* "questdb/ingress.pyx":80 - * class IngressError(Exception): - * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" - * def __init__(self, code, msg): # <<<<<<<<<<<<<< - * super().__init__(msg) - * self._code = code - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress.IngressError.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":85 - * - * @property - * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< - * """Return the error code.""" - * return self._code - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_3code(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_7questdb_7ingress_12IngressError_2code[] = "Return the error code."; -static PyMethodDef __pyx_mdef_7questdb_7ingress_12IngressError_3code = {"code", (PyCFunction)__pyx_pw_7questdb_7ingress_12IngressError_3code, METH_O, __pyx_doc_7questdb_7ingress_12IngressError_2code}; -static PyObject *__pyx_pw_7questdb_7ingress_12IngressError_3code(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("code (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_12IngressError_2code(__pyx_self, ((PyObject *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_12IngressError_2code(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("code", 0); - - /* "questdb/ingress.pyx":87 - * def code(self) -> IngressErrorCode: - * """Return the error code.""" - * return self._code # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_code_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":85 - * - * @property - * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< - * """Return the error code.""" - * return self._code - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.IngressError.code", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":90 - * - * - * cdef inline object c_err_code_to_py(line_sender_error_code code): # <<<<<<<<<<<<<< - * if code == line_sender_error_could_not_resolve_addr: - * return IngressErrorCode.CouldNotResolveAddr - */ - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_code_to_py(enum line_sender_error_code __pyx_v_code) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("c_err_code_to_py", 0); - - /* "questdb/ingress.pyx":91 - * - * cdef inline object c_err_code_to_py(line_sender_error_code code): - * if code == line_sender_error_could_not_resolve_addr: # <<<<<<<<<<<<<< - * return IngressErrorCode.CouldNotResolveAddr - * elif code == line_sender_error_invalid_api_call: - */ - switch (__pyx_v_code) { - case line_sender_error_could_not_resolve_addr: - - /* "questdb/ingress.pyx":92 - * cdef inline object c_err_code_to_py(line_sender_error_code code): - * if code == line_sender_error_could_not_resolve_addr: - * return IngressErrorCode.CouldNotResolveAddr # <<<<<<<<<<<<<< - * elif code == line_sender_error_invalid_api_call: - * return IngressErrorCode.InvalidApiCall - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CouldNotResolveAddr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 92, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":91 - * - * cdef inline object c_err_code_to_py(line_sender_error_code code): - * if code == line_sender_error_could_not_resolve_addr: # <<<<<<<<<<<<<< - * return IngressErrorCode.CouldNotResolveAddr - * elif code == line_sender_error_invalid_api_call: - */ - break; - case line_sender_error_invalid_api_call: - - /* "questdb/ingress.pyx":94 - * return IngressErrorCode.CouldNotResolveAddr - * elif code == line_sender_error_invalid_api_call: - * return IngressErrorCode.InvalidApiCall # <<<<<<<<<<<<<< - * elif code == line_sender_error_socket_error: - * return IngressErrorCode.SocketError - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 94, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_InvalidApiCall); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":93 - * if code == line_sender_error_could_not_resolve_addr: - * return IngressErrorCode.CouldNotResolveAddr - * elif code == line_sender_error_invalid_api_call: # <<<<<<<<<<<<<< - * return IngressErrorCode.InvalidApiCall - * elif code == line_sender_error_socket_error: - */ - break; - case line_sender_error_socket_error: - - /* "questdb/ingress.pyx":96 - * return IngressErrorCode.InvalidApiCall - * elif code == line_sender_error_socket_error: - * return IngressErrorCode.SocketError # <<<<<<<<<<<<<< - * elif code == line_sender_error_invalid_utf8: - * return IngressErrorCode.InvalidUtf8 - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 96, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SocketError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 96, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":95 - * elif code == line_sender_error_invalid_api_call: - * return IngressErrorCode.InvalidApiCall - * elif code == line_sender_error_socket_error: # <<<<<<<<<<<<<< - * return IngressErrorCode.SocketError - * elif code == line_sender_error_invalid_utf8: - */ - break; - case line_sender_error_invalid_utf8: - - /* "questdb/ingress.pyx":98 - * return IngressErrorCode.SocketError - * elif code == line_sender_error_invalid_utf8: - * return IngressErrorCode.InvalidUtf8 # <<<<<<<<<<<<<< - * elif code == line_sender_error_invalid_name: - * return IngressErrorCode.InvalidName - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 98, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_InvalidUtf8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":97 - * elif code == line_sender_error_socket_error: - * return IngressErrorCode.SocketError - * elif code == line_sender_error_invalid_utf8: # <<<<<<<<<<<<<< - * return IngressErrorCode.InvalidUtf8 - * elif code == line_sender_error_invalid_name: - */ - break; - case line_sender_error_invalid_name: - - /* "questdb/ingress.pyx":100 - * return IngressErrorCode.InvalidUtf8 - * elif code == line_sender_error_invalid_name: - * return IngressErrorCode.InvalidName # <<<<<<<<<<<<<< - * elif code == line_sender_error_invalid_timestamp: - * return IngressErrorCode.InvalidTimestamp - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_InvalidName); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 100, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":99 - * elif code == line_sender_error_invalid_utf8: - * return IngressErrorCode.InvalidUtf8 - * elif code == line_sender_error_invalid_name: # <<<<<<<<<<<<<< - * return IngressErrorCode.InvalidName - * elif code == line_sender_error_invalid_timestamp: - */ - break; - case line_sender_error_invalid_timestamp: - - /* "questdb/ingress.pyx":102 - * return IngressErrorCode.InvalidName - * elif code == line_sender_error_invalid_timestamp: - * return IngressErrorCode.InvalidTimestamp # <<<<<<<<<<<<<< - * elif code == line_sender_error_auth_error: - * return IngressErrorCode.AuthError - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 102, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_InvalidTimestamp); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":101 - * elif code == line_sender_error_invalid_name: - * return IngressErrorCode.InvalidName - * elif code == line_sender_error_invalid_timestamp: # <<<<<<<<<<<<<< - * return IngressErrorCode.InvalidTimestamp - * elif code == line_sender_error_auth_error: - */ - break; - case line_sender_error_auth_error: - - /* "questdb/ingress.pyx":104 - * return IngressErrorCode.InvalidTimestamp - * elif code == line_sender_error_auth_error: - * return IngressErrorCode.AuthError # <<<<<<<<<<<<<< - * elif code == line_sender_error_tls_error: - * return IngressErrorCode.TlsError - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AuthError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":103 - * elif code == line_sender_error_invalid_timestamp: - * return IngressErrorCode.InvalidTimestamp - * elif code == line_sender_error_auth_error: # <<<<<<<<<<<<<< - * return IngressErrorCode.AuthError - * elif code == line_sender_error_tls_error: - */ - break; - case line_sender_error_tls_error: - - /* "questdb/ingress.pyx":106 - * return IngressErrorCode.AuthError - * elif code == line_sender_error_tls_error: - * return IngressErrorCode.TlsError # <<<<<<<<<<<<<< - * else: - * raise ValueError('Internal error converting error code.') - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_TlsError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":105 - * elif code == line_sender_error_auth_error: - * return IngressErrorCode.AuthError - * elif code == line_sender_error_tls_error: # <<<<<<<<<<<<<< - * return IngressErrorCode.TlsError - * else: - */ - break; - default: - - /* "questdb/ingress.pyx":108 - * return IngressErrorCode.TlsError - * else: - * raise ValueError('Internal error converting error code.') # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 108, __pyx_L1_error) - break; - } - - /* "questdb/ingress.pyx":90 - * - * - * cdef inline object c_err_code_to_py(line_sender_error_code code): # <<<<<<<<<<<<<< - * if code == line_sender_error_could_not_resolve_addr: - * return IngressErrorCode.CouldNotResolveAddr - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.c_err_code_to_py", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":111 - * - * - * cdef inline object c_err_to_code_and_msg(line_sender_error* err): # <<<<<<<<<<<<<< - * """Construct a ``SenderError`` from a C error, which will be freed.""" - * cdef line_sender_error_code code = line_sender_error_get_code(err) - */ - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_code_and_msg(struct line_sender_error *__pyx_v_err) { - enum line_sender_error_code __pyx_v_code; - size_t __pyx_v_c_len; - char const *__pyx_v_c_msg; - PyObject *__pyx_v_py_msg = 0; - PyObject *__pyx_v_py_code = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int __pyx_t_3; - char const *__pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("c_err_to_code_and_msg", 0); - - /* "questdb/ingress.pyx":113 - * cdef inline object c_err_to_code_and_msg(line_sender_error* err): - * """Construct a ``SenderError`` from a C error, which will be freed.""" - * cdef line_sender_error_code code = line_sender_error_get_code(err) # <<<<<<<<<<<<<< - * cdef size_t c_len = 0 - * cdef const char* c_msg = line_sender_error_msg(err, &c_len) - */ - __pyx_v_code = line_sender_error_get_code(__pyx_v_err); - - /* "questdb/ingress.pyx":114 - * """Construct a ``SenderError`` from a C error, which will be freed.""" - * cdef line_sender_error_code code = line_sender_error_get_code(err) - * cdef size_t c_len = 0 # <<<<<<<<<<<<<< - * cdef const char* c_msg = line_sender_error_msg(err, &c_len) - * cdef object py_err - */ - __pyx_v_c_len = 0; - - /* "questdb/ingress.pyx":115 - * cdef line_sender_error_code code = line_sender_error_get_code(err) - * cdef size_t c_len = 0 - * cdef const char* c_msg = line_sender_error_msg(err, &c_len) # <<<<<<<<<<<<<< - * cdef object py_err - * cdef object py_msg - */ - __pyx_v_c_msg = line_sender_error_msg(__pyx_v_err, (&__pyx_v_c_len)); - - /* "questdb/ingress.pyx":119 - * cdef object py_msg - * cdef object py_code - * try: # <<<<<<<<<<<<<< - * py_code = c_err_code_to_py(code) - * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) - */ - /*try:*/ { - - /* "questdb/ingress.pyx":120 - * cdef object py_code - * try: - * py_code = c_err_code_to_py(code) # <<<<<<<<<<<<<< - * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) - * return (py_code, py_msg) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_code_to_py(__pyx_v_code); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 120, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_py_code = __pyx_t_1; - __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":121 - * try: - * py_code = c_err_code_to_py(code) - * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) # <<<<<<<<<<<<<< - * return (py_code, py_msg) - * finally: - */ - __pyx_t_1 = PyUnicode_FromStringAndSize(__pyx_v_c_msg, ((Py_ssize_t)__pyx_v_c_len)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 121, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_py_msg = __pyx_t_1; - __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":122 - * py_code = c_err_code_to_py(code) - * py_msg = PyUnicode_FromStringAndSize(c_msg, c_len) - * return (py_code, py_msg) # <<<<<<<<<<<<<< - * finally: - * line_sender_error_free(err) - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 122, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_v_py_code); - __Pyx_GIVEREF(__pyx_v_py_code); - PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_py_code); - __Pyx_INCREF(__pyx_v_py_msg); - __Pyx_GIVEREF(__pyx_v_py_msg); - PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_py_msg); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L3_return; - } - - /* "questdb/ingress.pyx":124 - * return (py_code, py_msg) - * finally: - * line_sender_error_free(err) # <<<<<<<<<<<<<< - * - * - */ - /*finally:*/ { - __pyx_L4_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0)) __Pyx_ErrFetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_5); - __Pyx_XGOTREF(__pyx_t_6); - __Pyx_XGOTREF(__pyx_t_7); - __Pyx_XGOTREF(__pyx_t_8); - __Pyx_XGOTREF(__pyx_t_9); - __Pyx_XGOTREF(__pyx_t_10); - __pyx_t_2 = __pyx_lineno; __pyx_t_3 = __pyx_clineno; __pyx_t_4 = __pyx_filename; - { - line_sender_error_free(__pyx_v_err); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_8); - __Pyx_XGIVEREF(__pyx_t_9); - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); - } - __Pyx_XGIVEREF(__pyx_t_5); - __Pyx_XGIVEREF(__pyx_t_6); - __Pyx_XGIVEREF(__pyx_t_7); - __Pyx_ErrRestore(__pyx_t_5, __pyx_t_6, __pyx_t_7); - __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; - __pyx_lineno = __pyx_t_2; __pyx_clineno = __pyx_t_3; __pyx_filename = __pyx_t_4; - goto __pyx_L1_error; - } - __pyx_L3_return: { - __pyx_t_10 = __pyx_r; - __pyx_r = 0; - line_sender_error_free(__pyx_v_err); - __pyx_r = __pyx_t_10; - __pyx_t_10 = 0; - goto __pyx_L0; - } - } - - /* "questdb/ingress.pyx":111 - * - * - * cdef inline object c_err_to_code_and_msg(line_sender_error* err): # <<<<<<<<<<<<<< - * """Construct a ``SenderError`` from a C error, which will be freed.""" - * cdef line_sender_error_code code = line_sender_error_get_code(err) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.c_err_to_code_and_msg", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_py_msg); - __Pyx_XDECREF(__pyx_v_py_code); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":127 - * - * - * cdef inline object c_err_to_py(line_sender_error* err): # <<<<<<<<<<<<<< - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) - */ - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py(struct line_sender_error *__pyx_v_err) { - PyObject *__pyx_v_tup = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("c_err_to_py", 0); - - /* "questdb/ingress.pyx":129 - * cdef inline object c_err_to_py(line_sender_error* err): - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) # <<<<<<<<<<<<<< - * return IngressError(tup[0], tup[1]) - * - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_to_code_and_msg(__pyx_v_err); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_tup = __pyx_t_1; - __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":130 - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) - * return IngressError(tup[0], tup[1]) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 130, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_tup, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 130, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_tup, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 130, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = NULL; - __pyx_t_6 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - __pyx_t_6 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - } else - #endif - { - __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 130, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (__pyx_t_5) { - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL; - } - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4); - __pyx_t_3 = 0; - __pyx_t_4 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 130, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":127 - * - * - * cdef inline object c_err_to_py(line_sender_error* err): # <<<<<<<<<<<<<< - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress.c_err_to_py", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_tup); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":133 - * - * - * cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): # <<<<<<<<<<<<<< - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) - */ - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_c_err_to_py_fmt(struct line_sender_error *__pyx_v_err, PyObject *__pyx_v_fmt) { - PyObject *__pyx_v_tup = 0; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("c_err_to_py_fmt", 0); - - /* "questdb/ingress.pyx":135 - * cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) # <<<<<<<<<<<<<< - * return IngressError(tup[0], fmt.format(tup[1])) - * - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_to_code_and_msg(__pyx_v_err); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 135, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_tup = __pyx_t_1; - __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":136 - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) - * return IngressError(tup[0], fmt.format(tup[1])) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_tup, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_tup, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PyUnicode_Type_format, __pyx_v_fmt, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - __pyx_t_6 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - __pyx_t_6 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_5}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - { - __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (__pyx_t_4) { - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL; - } - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_5); - __pyx_t_3 = 0; - __pyx_t_5 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":133 - * - * - * cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): # <<<<<<<<<<<<<< - * """Construct an ``IngressError`` from a C error, which will be freed.""" - * cdef object tup = c_err_to_code_and_msg(err) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress.c_err_to_py_fmt", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_tup); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":139 - * - * - * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): # <<<<<<<<<<<<<< - * return IngressError( - * IngressErrorCode.InvalidUtf8, - */ - -static PyObject *__pyx_f_7questdb_7ingress__utf8_decode_error(PyObject *__pyx_v_string, uint32_t __pyx_v_bad_codepoint) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - Py_ssize_t __pyx_t_5; - Py_UCS4 __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_utf8_decode_error", 0); - - /* "questdb/ingress.pyx":140 - * - * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): - * return IngressError( # <<<<<<<<<<<<<< - * IngressErrorCode.InvalidUtf8, - * f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 140, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - - /* "questdb/ingress.pyx":141 - * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): - * return IngressError( - * IngressErrorCode.InvalidUtf8, # <<<<<<<<<<<<<< - * f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + - * 'Cannot be encoded as UTF-8.') - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 141, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_InvalidUtf8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 141, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":142 - * return IngressError( - * IngressErrorCode.InvalidUtf8, - * f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + # <<<<<<<<<<<<<< - * 'Cannot be encoded as UTF-8.') - * - */ - __pyx_t_3 = PyTuple_New(5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = 0; - __pyx_t_6 = 127; - __Pyx_INCREF(__pyx_kp_u_Invalid_codepoint_0x); - __pyx_t_5 += 20; - __Pyx_GIVEREF(__pyx_kp_u_Invalid_codepoint_0x); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Invalid_codepoint_0x); - __pyx_t_7 = __Pyx_PyInt_From_uint32_t(__pyx_v_bad_codepoint); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyObject_Format(__pyx_t_7, __pyx_n_u_x); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_6; - __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_8); - __pyx_t_8 = 0; - __Pyx_INCREF(__pyx_kp_u_in_string); - __pyx_t_5 += 11; - __Pyx_GIVEREF(__pyx_kp_u_in_string); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u_in_string); - __pyx_t_8 = __Pyx_PyObject_FormatSimpleAndDecref(PyObject_Repr(__pyx_v_string), __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_6; - __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_3, 3, __pyx_t_8); - __pyx_t_8 = 0; - __Pyx_INCREF(__pyx_kp_u__17); - __pyx_t_5 += 2; - __Pyx_GIVEREF(__pyx_kp_u__17); - PyTuple_SET_ITEM(__pyx_t_3, 4, __pyx_kp_u__17); - __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_3, 5, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_8, __pyx_kp_u_Cannot_be_encoded_as_UTF_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 142, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_t_8 = NULL; - __pyx_t_9 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_8)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_8); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - __pyx_t_9 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_8, __pyx_t_4, __pyx_t_3}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_8, __pyx_t_4, __pyx_t_3}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else - #endif - { - __pyx_t_7 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 140, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (__pyx_t_8) { - __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8); __pyx_t_8 = NULL; - } - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_9, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_9, __pyx_t_3); - __pyx_t_4 = 0; - __pyx_t_3 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":139 - * - * - * cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): # <<<<<<<<<<<<<< - * return IngressError( - * IngressErrorCode.InvalidUtf8, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("questdb.ingress._utf8_decode_error", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":146 - * - * - * cdef bint str_to_utf8( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * str string, - */ - -static int __pyx_f_7questdb_7ingress_str_to_utf8(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_string, struct line_sender_utf8 *__pyx_v_utf8_out) { - size_t __pyx_v_count; - int __pyx_v_kind; - uint32_t __pyx_v_bad_codepoint; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t __pyx_t_4; - Py_UCS4 __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("str_to_utf8", 0); - - /* "questdb/ingress.pyx":160 - * cdef size_t count - * cdef int kind - * cdef uint32_t bad_codepoint = 0 # <<<<<<<<<<<<<< - * PyUnicode_READY(string) - * count = (PyUnicode_GET_LENGTH(string)) - */ - __pyx_v_bad_codepoint = 0; - - /* "questdb/ingress.pyx":161 - * cdef int kind - * cdef uint32_t bad_codepoint = 0 - * PyUnicode_READY(string) # <<<<<<<<<<<<<< - * count = (PyUnicode_GET_LENGTH(string)) - * - */ - __pyx_t_1 = PyUnicode_READY(__pyx_v_string); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 161, __pyx_L1_error) - - /* "questdb/ingress.pyx":162 - * cdef uint32_t bad_codepoint = 0 - * PyUnicode_READY(string) - * count = (PyUnicode_GET_LENGTH(string)) # <<<<<<<<<<<<<< - * - * # We optimize the common case of ASCII strings. - */ - __pyx_v_count = ((size_t)PyUnicode_GET_LENGTH(__pyx_v_string)); - - /* "questdb/ingress.pyx":167 - * # This avoid memory allocations and copies altogether. - * # We get away with this because ASCII is a subset of UTF-8. - * if PyUnicode_IS_COMPACT_ASCII(string): # <<<<<<<<<<<<<< - * utf8_out.len = count - * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) - */ - __pyx_t_2 = (PyUnicode_IS_COMPACT_ASCII(__pyx_v_string) != 0); - if (__pyx_t_2) { - - /* "questdb/ingress.pyx":168 - * # We get away with this because ASCII is a subset of UTF-8. - * if PyUnicode_IS_COMPACT_ASCII(string): - * utf8_out.len = count # <<<<<<<<<<<<<< - * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) - * return True - */ - __pyx_v_utf8_out->len = __pyx_v_count; - - /* "questdb/ingress.pyx":169 - * if PyUnicode_IS_COMPACT_ASCII(string): - * utf8_out.len = count - * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_v_utf8_out->buf = ((char const *)PyUnicode_1BYTE_DATA(__pyx_v_string)); - - /* "questdb/ingress.pyx":170 - * utf8_out.len = count - * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) - * return True # <<<<<<<<<<<<<< - * - * kind = PyUnicode_KIND(string) - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "questdb/ingress.pyx":167 - * # This avoid memory allocations and copies altogether. - * # We get away with this because ASCII is a subset of UTF-8. - * if PyUnicode_IS_COMPACT_ASCII(string): # <<<<<<<<<<<<<< - * utf8_out.len = count - * utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) - */ - } - - /* "questdb/ingress.pyx":172 - * return True - * - * kind = PyUnicode_KIND(string) # <<<<<<<<<<<<<< - * if kind == PyUnicode_1BYTE_KIND: - * # No error handling for UCS1: All code points translate into valid UTF8. - */ - __pyx_v_kind = PyUnicode_KIND(__pyx_v_string); - - /* "questdb/ingress.pyx":173 - * - * kind = PyUnicode_KIND(string) - * if kind == PyUnicode_1BYTE_KIND: # <<<<<<<<<<<<<< - * # No error handling for UCS1: All code points translate into valid UTF8. - * qdb_ucs1_to_utf8( - */ - switch (__pyx_v_kind) { - case PyUnicode_1BYTE_KIND: - - /* "questdb/ingress.pyx":175 - * if kind == PyUnicode_1BYTE_KIND: - * # No error handling for UCS1: All code points translate into valid UTF8. - * qdb_ucs1_to_utf8( # <<<<<<<<<<<<<< - * b, - * count, - */ - qdb_ucs1_to_utf8(__pyx_v_b, __pyx_v_count, PyUnicode_1BYTE_DATA(__pyx_v_string), (&__pyx_v_utf8_out->len), (&__pyx_v_utf8_out->buf)); - - /* "questdb/ingress.pyx":173 - * - * kind = PyUnicode_KIND(string) - * if kind == PyUnicode_1BYTE_KIND: # <<<<<<<<<<<<<< - * # No error handling for UCS1: All code points translate into valid UTF8. - * qdb_ucs1_to_utf8( - */ - break; - case PyUnicode_2BYTE_KIND: - - /* "questdb/ingress.pyx":182 - * &utf8_out.buf) - * elif kind == PyUnicode_2BYTE_KIND: - * if not qdb_ucs2_to_utf8( # <<<<<<<<<<<<<< - * b, - * count, - */ - __pyx_t_2 = ((!(qdb_ucs2_to_utf8(__pyx_v_b, __pyx_v_count, PyUnicode_2BYTE_DATA(__pyx_v_string), (&__pyx_v_utf8_out->len), (&__pyx_v_utf8_out->buf), (&__pyx_v_bad_codepoint)) != 0)) != 0); - if (unlikely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":189 - * &utf8_out.buf, - * &bad_codepoint): - * raise _utf8_decode_error(string, bad_codepoint) # <<<<<<<<<<<<<< - * elif kind == PyUnicode_4BYTE_KIND: - * if not qdb_ucs4_to_utf8( - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress__utf8_decode_error(__pyx_v_string, __pyx_v_bad_codepoint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 189, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 189, __pyx_L1_error) - - /* "questdb/ingress.pyx":182 - * &utf8_out.buf) - * elif kind == PyUnicode_2BYTE_KIND: - * if not qdb_ucs2_to_utf8( # <<<<<<<<<<<<<< - * b, - * count, - */ - } - - /* "questdb/ingress.pyx":181 - * &utf8_out.len, - * &utf8_out.buf) - * elif kind == PyUnicode_2BYTE_KIND: # <<<<<<<<<<<<<< - * if not qdb_ucs2_to_utf8( - * b, - */ - break; - case PyUnicode_4BYTE_KIND: - - /* "questdb/ingress.pyx":191 - * raise _utf8_decode_error(string, bad_codepoint) - * elif kind == PyUnicode_4BYTE_KIND: - * if not qdb_ucs4_to_utf8( # <<<<<<<<<<<<<< - * b, - * count, - */ - __pyx_t_2 = ((!(qdb_ucs4_to_utf8(__pyx_v_b, __pyx_v_count, ((uint32_t const *)PyUnicode_4BYTE_DATA(__pyx_v_string)), (&__pyx_v_utf8_out->len), (&__pyx_v_utf8_out->buf), (&__pyx_v_bad_codepoint)) != 0)) != 0); - if (unlikely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":203 - * &utf8_out.buf, - * &bad_codepoint): - * raise _utf8_decode_error(string, bad_codepoint) # <<<<<<<<<<<<<< - * else: - * raise ValueError(f'Unknown UCS kind: {kind}.') - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress__utf8_decode_error(__pyx_v_string, __pyx_v_bad_codepoint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 203, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 203, __pyx_L1_error) - - /* "questdb/ingress.pyx":191 - * raise _utf8_decode_error(string, bad_codepoint) - * elif kind == PyUnicode_4BYTE_KIND: - * if not qdb_ucs4_to_utf8( # <<<<<<<<<<<<<< - * b, - * count, - */ - } - - /* "questdb/ingress.pyx":190 - * &bad_codepoint): - * raise _utf8_decode_error(string, bad_codepoint) - * elif kind == PyUnicode_4BYTE_KIND: # <<<<<<<<<<<<<< - * if not qdb_ucs4_to_utf8( - * b, - */ - break; - default: - - /* "questdb/ingress.pyx":205 - * raise _utf8_decode_error(string, bad_codepoint) - * else: - * raise ValueError(f'Unknown UCS kind: {kind}.') # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 205, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_Unknown_UCS_kind); - __pyx_t_4 += 18; - __Pyx_GIVEREF(__pyx_kp_u_Unknown_UCS_kind); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_Unknown_UCS_kind); - __pyx_t_6 = __Pyx_PyUnicode_From_int(__pyx_v_kind, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 205, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__6); - __pyx_t_4 += 1; - __Pyx_GIVEREF(__pyx_kp_u__6); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__6); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 205, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 205, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 205, __pyx_L1_error) - break; - } - - /* "questdb/ingress.pyx":206 - * else: - * raise ValueError(f'Unknown UCS kind: {kind}.') - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "questdb/ingress.pyx":146 - * - * - * cdef bint str_to_utf8( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * str string, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("questdb.ingress.str_to_utf8", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":209 - * - * - * cdef bint str_to_table_name( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * str string, - */ - -static int __pyx_f_7questdb_7ingress_str_to_table_name(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_string, struct line_sender_table_name *__pyx_v_name_out) { - struct line_sender_error *__pyx_v_err; - struct line_sender_utf8 __pyx_v_utf8; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("str_to_table_name", 0); - - /* "questdb/ingress.pyx":217 - * Also see `str_to_utf8`. - * """ - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":219 - * cdef line_sender_error* err = NULL - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) # <<<<<<<<<<<<<< - * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_string, (&__pyx_v_utf8)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 219, __pyx_L1_error) - - /* "questdb/ingress.pyx":220 - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) - * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - __pyx_t_1 = ((!(line_sender_table_name_init(__pyx_v_name_out, __pyx_v_utf8.len, __pyx_v_utf8.buf, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":221 - * str_to_utf8(b, string, &utf8) - * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 221, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 221, __pyx_L1_error) - - /* "questdb/ingress.pyx":220 - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) - * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - } - - /* "questdb/ingress.pyx":222 - * if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "questdb/ingress.pyx":209 - * - * - * cdef bint str_to_table_name( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * str string, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.str_to_table_name", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":225 - * - * - * cdef bint str_to_column_name( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * str string, - */ - -static int __pyx_f_7questdb_7ingress_str_to_column_name(struct qdb_pystr_buf *__pyx_v_b, PyObject *__pyx_v_string, struct line_sender_column_name *__pyx_v_name_out) { - struct line_sender_error *__pyx_v_err; - struct line_sender_utf8 __pyx_v_utf8; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("str_to_column_name", 0); - - /* "questdb/ingress.pyx":233 - * Also see `str_to_utf8`. - * """ - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":235 - * cdef line_sender_error* err = NULL - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) # <<<<<<<<<<<<<< - * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_string, (&__pyx_v_utf8)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 235, __pyx_L1_error) - - /* "questdb/ingress.pyx":236 - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) - * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - __pyx_t_1 = ((!(line_sender_column_name_init(__pyx_v_name_out, __pyx_v_utf8.len, __pyx_v_utf8.buf, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":237 - * str_to_utf8(b, string, &utf8) - * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return True - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 237, __pyx_L1_error) - - /* "questdb/ingress.pyx":236 - * cdef line_sender_utf8 utf8 - * str_to_utf8(b, string, &utf8) - * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return True - */ - } - - /* "questdb/ingress.pyx":238 - * if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): - * raise c_err_to_py(err) - * return True # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = 1; - goto __pyx_L0; - - /* "questdb/ingress.pyx":225 - * - * - * cdef bint str_to_column_name( # <<<<<<<<<<<<<< - * qdb_pystr_buf* b, - * str string, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.str_to_column_name", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":241 - * - * - * cdef int64_t datetime_to_micros(datetime dt): # <<<<<<<<<<<<<< - * """ - * Convert a `datetime.datetime` to microseconds since the epoch. - */ - -static int64_t __pyx_f_7questdb_7ingress_datetime_to_micros(PyDateTime_DateTime *__pyx_v_dt) { - int64_t __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int64_t __pyx_t_4; - int64_t __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("datetime_to_micros", 0); - - /* "questdb/ingress.pyx":246 - * """ - * return ( - * (dt.timestamp()) * # <<<<<<<<<<<<<< - * (1000000) + - * (dt.microsecond)) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_timestamp); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 246, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 246, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_4 = __Pyx_PyInt_As_int64_t(__pyx_t_1); if (unlikely((__pyx_t_4 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 246, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":248 - * (dt.timestamp()) * - * (1000000) + - * (dt.microsecond)) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_microsecond); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 248, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_1); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 248, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":247 - * return ( - * (dt.timestamp()) * - * (1000000) + # <<<<<<<<<<<<<< - * (dt.microsecond)) - * - */ - __pyx_r = ((((int64_t)__pyx_t_4) * ((int64_t)0xF4240)) + ((int64_t)__pyx_t_5)); - goto __pyx_L0; - - /* "questdb/ingress.pyx":241 - * - * - * cdef int64_t datetime_to_micros(datetime dt): # <<<<<<<<<<<<<< - * """ - * Convert a `datetime.datetime` to microseconds since the epoch. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_WriteUnraisable("questdb.ingress.datetime_to_micros", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":251 - * - * - * cdef int64_t datetime_to_nanos(datetime dt): # <<<<<<<<<<<<<< - * """ - * Convert a `datetime.datetime` to nanoseconds since the epoch. - */ - -static int64_t __pyx_f_7questdb_7ingress_datetime_to_nanos(PyDateTime_DateTime *__pyx_v_dt) { - int64_t __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int64_t __pyx_t_4; - int64_t __pyx_t_5; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("datetime_to_nanos", 0); - - /* "questdb/ingress.pyx":256 - * """ - * return ( - * (dt.timestamp()) * # <<<<<<<<<<<<<< - * (1000000000) + - * (dt.microsecond * 1000)) - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_timestamp); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 256, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 256, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_4 = __Pyx_PyInt_As_int64_t(__pyx_t_1); if (unlikely((__pyx_t_4 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 256, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":258 - * (dt.timestamp()) * - * (1000000000) + - * (dt.microsecond * 1000)) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_dt), __pyx_n_s_microsecond); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 258, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyNumber_Multiply(__pyx_t_1, __pyx_int_1000); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 258, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_5 = __Pyx_PyInt_As_int64_t(__pyx_t_2); if (unlikely((__pyx_t_5 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 258, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":257 - * return ( - * (dt.timestamp()) * - * (1000000000) + # <<<<<<<<<<<<<< - * (dt.microsecond * 1000)) - * - */ - __pyx_r = ((((int64_t)__pyx_t_4) * ((int64_t)0x3B9ACA00)) + ((int64_t)__pyx_t_5)); - goto __pyx_L0; - - /* "questdb/ingress.pyx":251 - * - * - * cdef int64_t datetime_to_nanos(datetime dt): # <<<<<<<<<<<<<< - * """ - * Convert a `datetime.datetime` to nanoseconds since the epoch. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_WriteUnraisable("questdb.ingress.datetime_to_nanos", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); - __pyx_r = 0; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":292 - * cdef int64_t _value - * - * def __cinit__(self, value: int): # <<<<<<<<<<<<<< - * if value < 0: - * raise ValueError('value must positive integer.') - */ - -/* Python wrapper */ -static int __pyx_pw_7questdb_7ingress_15TimestampMicros_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7questdb_7ingress_15TimestampMicros_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_value = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_value_2,0}; - PyObject* values[1] = {0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_value_2)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 292, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - } - __pyx_v_value = values[0]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 292, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros___cinit__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self), __pyx_v_value); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7questdb_7ingress_15TimestampMicros___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int64_t __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - - /* "questdb/ingress.pyx":293 - * - * def __cinit__(self, value: int): - * if value < 0: # <<<<<<<<<<<<<< - * raise ValueError('value must positive integer.') - * self._value = value - */ - __pyx_t_1 = PyObject_RichCompare(__pyx_v_value, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 293, __pyx_L1_error) - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 293, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":294 - * def __cinit__(self, value: int): - * if value < 0: - * raise ValueError('value must positive integer.') # <<<<<<<<<<<<<< - * self._value = value - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 294, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 294, __pyx_L1_error) - - /* "questdb/ingress.pyx":293 - * - * def __cinit__(self, value: int): - * if value < 0: # <<<<<<<<<<<<<< - * raise ValueError('value must positive integer.') - * self._value = value - */ - } - - /* "questdb/ingress.pyx":295 - * if value < 0: - * raise ValueError('value must positive integer.') - * self._value = value # <<<<<<<<<<<<<< - * - * @classmethod - */ - __pyx_t_3 = __Pyx_PyInt_As_int64_t(__pyx_v_value); if (unlikely((__pyx_t_3 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 295, __pyx_L1_error) - __pyx_v_self->_value = __pyx_t_3; - - /* "questdb/ingress.pyx":292 - * cdef int64_t _value - * - * def __cinit__(self, value: int): # <<<<<<<<<<<<<< - * if value < 0: - * raise ValueError('value must positive integer.') - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":298 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt); /*proto*/ -static char __pyx_doc_7questdb_7ingress_15TimestampMicros_2from_datetime[] = "\n Construct a ``TimestampMicros`` from a ``datetime.datetime`` object.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_15TimestampMicros_3from_datetime = {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_15TimestampMicros_2from_datetime}; -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt) { - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("from_datetime (wrapper)", 0); - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime, 1, "dt", 0))) __PYX_ERR(0, 298, __pyx_L1_error) - __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_2from_datetime(((PyTypeObject*)__pyx_v_cls), ((PyDateTime_DateTime *)__pyx_v_dt)); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("from_datetime", 0); - - /* "questdb/ingress.pyx":302 - * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. - * """ - * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< - * raise TypeError('dt must be a datetime object.') - * return cls(datetime_to_micros(dt)) - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime); - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (unlikely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":303 - * """ - * if not isinstance(dt, datetime): - * raise TypeError('dt must be a datetime object.') # <<<<<<<<<<<<<< - * return cls(datetime_to_micros(dt)) - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 303, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 303, __pyx_L1_error) - - /* "questdb/ingress.pyx":302 - * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. - * """ - * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< - * raise TypeError('dt must be a datetime object.') - * return cls(datetime_to_micros(dt)) - */ - } - - /* "questdb/ingress.pyx":304 - * if not isinstance(dt, datetime): - * raise TypeError('dt must be a datetime object.') - * return cls(datetime_to_micros(dt)) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_f_7questdb_7ingress_datetime_to_micros(__pyx_v_dt)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 304, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_v_cls), __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 304, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":298 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("questdb.ingress.TimestampMicros.from_datetime", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":307 - * - * @property - * def value(self) -> int: # <<<<<<<<<<<<<< - * """Number of microseconds.""" - * return self._value - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5value_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5value_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_5value___get__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "questdb/ingress.pyx":309 - * def value(self) -> int: - * """Number of microseconds.""" - * return self._value # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 309, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":307 - * - * @property - * def value(self) -> int: # <<<<<<<<<<<<<< - * """Number of microseconds.""" - * return self._value - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampMicros.value.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_15TimestampMicros_5__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__, METH_NOARGS, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_4__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_15TimestampMicros_7__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__, METH_O, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_15TimestampMicros_6__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_15TimestampMicros_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampMicros.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":343 - * cdef int64_t _value - * - * def __cinit__(self, value: int): # <<<<<<<<<<<<<< - * if value < 0: - * raise ValueError('value must positive integer.') - */ - -/* Python wrapper */ -static int __pyx_pw_7questdb_7ingress_14TimestampNanos_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7questdb_7ingress_14TimestampNanos_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_value = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_value_2,0}; - PyObject* values[1] = {0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_value_2)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 343, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - } - __pyx_v_value = values[0]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 343, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos___cinit__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self), __pyx_v_value); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7questdb_7ingress_14TimestampNanos___cinit__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, PyObject *__pyx_v_value) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - int64_t __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - - /* "questdb/ingress.pyx":344 - * - * def __cinit__(self, value: int): - * if value < 0: # <<<<<<<<<<<<<< - * raise ValueError('value must positive integer.') - * self._value = value - */ - __pyx_t_1 = PyObject_RichCompare(__pyx_v_value, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 344, __pyx_L1_error) - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 344, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":345 - * def __cinit__(self, value: int): - * if value < 0: - * raise ValueError('value must positive integer.') # <<<<<<<<<<<<<< - * self._value = value - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 345, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 345, __pyx_L1_error) - - /* "questdb/ingress.pyx":344 - * - * def __cinit__(self, value: int): - * if value < 0: # <<<<<<<<<<<<<< - * raise ValueError('value must positive integer.') - * self._value = value - */ - } - - /* "questdb/ingress.pyx":346 - * if value < 0: - * raise ValueError('value must positive integer.') - * self._value = value # <<<<<<<<<<<<<< - * - * @classmethod - */ - __pyx_t_3 = __Pyx_PyInt_As_int64_t(__pyx_v_value); if (unlikely((__pyx_t_3 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 346, __pyx_L1_error) - __pyx_v_self->_value = __pyx_t_3; - - /* "questdb/ingress.pyx":343 - * cdef int64_t _value - * - * def __cinit__(self, value: int): # <<<<<<<<<<<<<< - * if value < 0: - * raise ValueError('value must positive integer.') - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":349 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt); /*proto*/ -static char __pyx_doc_7questdb_7ingress_14TimestampNanos_2from_datetime[] = "\n Construct a ``TimestampNanos`` from a ``datetime.datetime`` object.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_14TimestampNanos_3from_datetime = {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_14TimestampNanos_2from_datetime}; -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime(PyObject *__pyx_v_cls, PyObject *__pyx_v_dt) { - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("from_datetime (wrapper)", 0); - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime, 1, "dt", 0))) __PYX_ERR(0, 349, __pyx_L1_error) - __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_2from_datetime(((PyTypeObject*)__pyx_v_cls), ((PyDateTime_DateTime *)__pyx_v_dt)); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_2from_datetime(PyTypeObject *__pyx_v_cls, PyDateTime_DateTime *__pyx_v_dt) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("from_datetime", 0); - - /* "questdb/ingress.pyx":353 - * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. - * """ - * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< - * raise TypeError('dt must be a datetime object.') - * return cls(datetime_to_nanos(dt)) - */ - __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_dt), __pyx_ptype_7cpython_8datetime_datetime); - __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); - if (unlikely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":354 - * """ - * if not isinstance(dt, datetime): - * raise TypeError('dt must be a datetime object.') # <<<<<<<<<<<<<< - * return cls(datetime_to_nanos(dt)) - * - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 354, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(0, 354, __pyx_L1_error) - - /* "questdb/ingress.pyx":353 - * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. - * """ - * if not isinstance(dt, datetime): # <<<<<<<<<<<<<< - * raise TypeError('dt must be a datetime object.') - * return cls(datetime_to_nanos(dt)) - */ - } - - /* "questdb/ingress.pyx":355 - * if not isinstance(dt, datetime): - * raise TypeError('dt must be a datetime object.') - * return cls(datetime_to_nanos(dt)) # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = __Pyx_PyInt_From_int64_t(__pyx_f_7questdb_7ingress_datetime_to_nanos(__pyx_v_dt)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 355, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_v_cls), __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 355, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_4; - __pyx_t_4 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":349 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("questdb.ingress.TimestampNanos.from_datetime", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":358 - * - * @property - * def value(self) -> int: # <<<<<<<<<<<<<< - * """Number of nanoseconds.""" - * return self._value - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5value_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5value_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_5value___get__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_5value___get__(struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "questdb/ingress.pyx":360 - * def value(self) -> int: - * """Number of nanoseconds.""" - * return self._value # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 360, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":358 - * - * @property - * def value(self) -> int: # <<<<<<<<<<<<<< - * """Number of nanoseconds.""" - * return self._value - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampNanos.value.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_14TimestampNanos_5__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__, METH_NOARGS, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_4__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_14TimestampNanos_7__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__, METH_O, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_14TimestampNanos_6__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_14TimestampNanos_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.TimestampNanos.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":363 - * - * - * cdef _check_is_pandas_dataframe(data): # <<<<<<<<<<<<<< - * exp_mod = 'pandas.core.frame' - * exp_name = 'DataFrame' - */ - -static PyObject *__pyx_f_7questdb_7ingress__check_is_pandas_dataframe(PyObject *__pyx_v_data) { - PyObject *__pyx_v_exp_mod = NULL; - PyObject *__pyx_v_exp_name = NULL; - PyTypeObject *__pyx_v_t = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_t_3; - Py_ssize_t __pyx_t_4; - Py_UCS4 __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_check_is_pandas_dataframe", 0); - - /* "questdb/ingress.pyx":364 - * - * cdef _check_is_pandas_dataframe(data): - * exp_mod = 'pandas.core.frame' # <<<<<<<<<<<<<< - * exp_name = 'DataFrame' - * t = type(data) - */ - __Pyx_INCREF(__pyx_kp_u_pandas_core_frame); - __pyx_v_exp_mod = __pyx_kp_u_pandas_core_frame; - - /* "questdb/ingress.pyx":365 - * cdef _check_is_pandas_dataframe(data): - * exp_mod = 'pandas.core.frame' - * exp_name = 'DataFrame' # <<<<<<<<<<<<<< - * t = type(data) - * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): - */ - __Pyx_INCREF(__pyx_n_u_DataFrame); - __pyx_v_exp_name = __pyx_n_u_DataFrame; - - /* "questdb/ingress.pyx":366 - * exp_mod = 'pandas.core.frame' - * exp_name = 'DataFrame' - * t = type(data) # <<<<<<<<<<<<<< - * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): - * raise TypeError( - */ - __Pyx_INCREF(((PyObject *)Py_TYPE(__pyx_v_data))); - __pyx_v_t = ((PyTypeObject*)((PyObject *)Py_TYPE(__pyx_v_data))); - - /* "questdb/ingress.pyx":367 - * exp_name = 'DataFrame' - * t = type(data) - * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): # <<<<<<<<<<<<<< - * raise TypeError( - * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_module); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 367, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = (__Pyx_PyUnicode_Equals(__pyx_t_2, __pyx_v_exp_mod, Py_NE)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 367, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (!__pyx_t_3) { - } else { - __pyx_t_1 = __pyx_t_3; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_qualname); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 367, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = (__Pyx_PyUnicode_Equals(__pyx_t_2, __pyx_v_exp_name, Py_NE)); if (unlikely(__pyx_t_3 < 0)) __PYX_ERR(0, 367, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_1 = __pyx_t_3; - __pyx_L4_bool_binop_done:; - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":369 - * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): - * raise TypeError( - * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + # <<<<<<<<<<<<<< - * f'not {t.__module__}.{t.__qualname__}.') - * - */ - __pyx_t_2 = PyTuple_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 369, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_Bad_argument_data_Expected); - __pyx_t_4 += 30; - __Pyx_GIVEREF(__pyx_kp_u_Bad_argument_data_Expected); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_Bad_argument_data_Expected); - __Pyx_INCREF(__pyx_v_exp_mod); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_mod) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_mod) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_exp_mod); - __Pyx_GIVEREF(__pyx_v_exp_mod); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_exp_mod); - __Pyx_INCREF(__pyx_kp_u__6); - __pyx_t_4 += 1; - __Pyx_GIVEREF(__pyx_kp_u__6); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); - __Pyx_INCREF(__pyx_v_exp_name); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_name) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_exp_name) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_exp_name); - __Pyx_GIVEREF(__pyx_v_exp_name); - PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_v_exp_name); - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_kp_u__24); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 5, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 369, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":370 - * raise TypeError( - * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + - * f'not {t.__module__}.{t.__qualname__}.') # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_2 = PyTuple_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 370, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_not); - __pyx_t_4 += 4; - __Pyx_GIVEREF(__pyx_kp_u_not); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_not); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_module); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 370, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 370, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8); - __Pyx_GIVEREF(__pyx_t_8); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_8); - __pyx_t_8 = 0; - __Pyx_INCREF(__pyx_kp_u__6); - __pyx_t_4 += 1; - __Pyx_GIVEREF(__pyx_kp_u__6); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__6); - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_t), __pyx_n_s_qualname); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 370, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 370, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_7); - __pyx_t_7 = 0; - __Pyx_INCREF(__pyx_kp_u__6); - __pyx_t_4 += 1; - __Pyx_GIVEREF(__pyx_kp_u__6); - PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_kp_u__6); - __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_2, 5, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 370, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":369 - * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): - * raise TypeError( - * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + # <<<<<<<<<<<<<< - * f'not {t.__module__}.{t.__qualname__}.') - * - */ - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 369, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":368 - * t = type(data) - * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + - * f'not {t.__module__}.{t.__qualname__}.') - */ - __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 368, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_7, 0, 0, 0); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __PYX_ERR(0, 368, __pyx_L1_error) - - /* "questdb/ingress.pyx":367 - * exp_name = 'DataFrame' - * t = type(data) - * if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): # <<<<<<<<<<<<<< - * raise TypeError( - * f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + - */ - } - - /* "questdb/ingress.pyx":363 - * - * - * cdef _check_is_pandas_dataframe(data): # <<<<<<<<<<<<<< - * exp_mod = 'pandas.core.frame' - * exp_name = 'DataFrame' - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("questdb.ingress._check_is_pandas_dataframe", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_exp_mod); - __Pyx_XDECREF(__pyx_v_exp_name); - __Pyx_XDECREF(__pyx_v_t); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":377 - * - * - * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: # <<<<<<<<<<<<<< - * if sender._auto_flush_enabled: - * if len(buffer) >= sender._auto_flush_watermark: - */ - -static int __pyx_f_7questdb_7ingress_may_flush_on_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer, struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_sender) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - struct __pyx_opt_args_7questdb_7ingress_6Sender_flush __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("may_flush_on_row_complete", 0); - - /* "questdb/ingress.pyx":378 - * - * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: - * if sender._auto_flush_enabled: # <<<<<<<<<<<<<< - * if len(buffer) >= sender._auto_flush_watermark: - * sender.flush(buffer) - */ - __pyx_t_1 = (__pyx_v_sender->_auto_flush_enabled != 0); - if (__pyx_t_1) { - - /* "questdb/ingress.pyx":379 - * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: - * if sender._auto_flush_enabled: - * if len(buffer) >= sender._auto_flush_watermark: # <<<<<<<<<<<<<< - * sender.flush(buffer) - * - */ - __pyx_t_2 = PyObject_Length(((PyObject *)__pyx_v_buffer)); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 379, __pyx_L1_error) - __pyx_t_1 = ((__pyx_t_2 >= __pyx_v_sender->_auto_flush_watermark) != 0); - if (__pyx_t_1) { - - /* "questdb/ingress.pyx":380 - * if sender._auto_flush_enabled: - * if len(buffer) >= sender._auto_flush_watermark: - * sender.flush(buffer) # <<<<<<<<<<<<<< - * - * - */ - __pyx_t_4.__pyx_n = 1; - __pyx_t_4.buffer = __pyx_v_buffer; - __pyx_t_3 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_sender->__pyx_vtab)->flush(__pyx_v_sender, 0, &__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 380, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":379 - * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: - * if sender._auto_flush_enabled: - * if len(buffer) >= sender._auto_flush_watermark: # <<<<<<<<<<<<<< - * sender.flush(buffer) - * - */ - } - - /* "questdb/ingress.pyx":378 - * - * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: - * if sender._auto_flush_enabled: # <<<<<<<<<<<<<< - * if len(buffer) >= sender._auto_flush_watermark: - * sender.flush(buffer) - */ - } - - /* "questdb/ingress.pyx":377 - * - * - * cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: # <<<<<<<<<<<<<< - * if sender._auto_flush_enabled: - * if len(buffer) >= sender._auto_flush_watermark: - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress.may_flush_on_row_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":453 - * cdef object _row_complete_sender - * - * def __cinit__(self, init_capacity: int=65536, max_name_len: int=127): # <<<<<<<<<<<<<< - * """ - * Create a new buffer with the an initial capacity and max name length. - */ - -/* Python wrapper */ -static int __pyx_pw_7questdb_7ingress_6Buffer_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7questdb_7ingress_6Buffer_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_init_capacity = 0; - PyObject *__pyx_v_max_name_len = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_init_capacity,&__pyx_n_s_max_name_len,0}; - PyObject* values[2] = {0,0}; - values[0] = ((PyObject *)__pyx_int_65536); - values[1] = ((PyObject *)__pyx_int_127); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_init_capacity); - if (value) { values[0] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 1: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_name_len); - if (value) { values[1] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 453, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_init_capacity = values[0]; - __pyx_v_max_name_len = values[1]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 453, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Buffer.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer___cinit__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), __pyx_v_init_capacity, __pyx_v_max_name_len); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7questdb_7ingress_6Buffer___cinit__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_init_capacity, PyObject *__pyx_v_max_name_len) { - int __pyx_r; - __Pyx_RefNannyDeclarations - size_t __pyx_t_1; - size_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - - /* "questdb/ingress.pyx":459 - * :param int max_name_len: Maximum length of a table or column name. - * """ - * self._cinit_impl(init_capacity, max_name_len) # <<<<<<<<<<<<<< - * - * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): - */ - __pyx_t_1 = __Pyx_PyInt_As_size_t(__pyx_v_init_capacity); if (unlikely((__pyx_t_1 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 459, __pyx_L1_error) - __pyx_t_2 = __Pyx_PyInt_As_size_t(__pyx_v_max_name_len); if (unlikely((__pyx_t_2 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 459, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__cinit_impl(__pyx_v_self, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 459, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":453 - * cdef object _row_complete_sender - * - * def __cinit__(self, init_capacity: int=65536, max_name_len: int=127): # <<<<<<<<<<<<<< - * """ - * Create a new buffer with the an initial capacity and max name length. - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress.Buffer.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":461 - * self._cinit_impl(init_capacity, max_name_len) - * - * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): # <<<<<<<<<<<<<< - * self._impl = line_sender_buffer_with_max_name_len(max_name_len) - * self._b = qdb_pystr_buf_new() - */ - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__cinit_impl(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, size_t __pyx_v_init_capacity, size_t __pyx_v_max_name_len) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_cinit_impl", 0); - - /* "questdb/ingress.pyx":462 - * - * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): - * self._impl = line_sender_buffer_with_max_name_len(max_name_len) # <<<<<<<<<<<<<< - * self._b = qdb_pystr_buf_new() - * line_sender_buffer_reserve(self._impl, init_capacity) - */ - __pyx_v_self->_impl = line_sender_buffer_with_max_name_len(__pyx_v_max_name_len); - - /* "questdb/ingress.pyx":463 - * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): - * self._impl = line_sender_buffer_with_max_name_len(max_name_len) - * self._b = qdb_pystr_buf_new() # <<<<<<<<<<<<<< - * line_sender_buffer_reserve(self._impl, init_capacity) - * self._init_capacity = init_capacity - */ - __pyx_v_self->_b = qdb_pystr_buf_new(); - - /* "questdb/ingress.pyx":464 - * self._impl = line_sender_buffer_with_max_name_len(max_name_len) - * self._b = qdb_pystr_buf_new() - * line_sender_buffer_reserve(self._impl, init_capacity) # <<<<<<<<<<<<<< - * self._init_capacity = init_capacity - * self._max_name_len = max_name_len - */ - line_sender_buffer_reserve(__pyx_v_self->_impl, __pyx_v_init_capacity); - - /* "questdb/ingress.pyx":465 - * self._b = qdb_pystr_buf_new() - * line_sender_buffer_reserve(self._impl, init_capacity) - * self._init_capacity = init_capacity # <<<<<<<<<<<<<< - * self._max_name_len = max_name_len - * self._row_complete_sender = None - */ - __pyx_v_self->_init_capacity = __pyx_v_init_capacity; - - /* "questdb/ingress.pyx":466 - * line_sender_buffer_reserve(self._impl, init_capacity) - * self._init_capacity = init_capacity - * self._max_name_len = max_name_len # <<<<<<<<<<<<<< - * self._row_complete_sender = None - * - */ - __pyx_v_self->_max_name_len = __pyx_v_max_name_len; - - /* "questdb/ingress.pyx":467 - * self._init_capacity = init_capacity - * self._max_name_len = max_name_len - * self._row_complete_sender = None # <<<<<<<<<<<<<< - * - * def __dealloc__(self): - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_row_complete_sender); - __Pyx_DECREF(__pyx_v_self->_row_complete_sender); - __pyx_v_self->_row_complete_sender = Py_None; - - /* "questdb/ingress.pyx":461 - * self._cinit_impl(init_capacity, max_name_len) - * - * cdef inline _cinit_impl(self, size_t init_capacity, size_t max_name_len): # <<<<<<<<<<<<<< - * self._impl = line_sender_buffer_with_max_name_len(max_name_len) - * self._b = qdb_pystr_buf_new() - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":469 - * self._row_complete_sender = None - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * self._row_complete_sender = None - * qdb_pystr_buf_free(self._b) - */ - -/* Python wrapper */ -static void __pyx_pw_7questdb_7ingress_6Buffer_3__dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_pw_7questdb_7ingress_6Buffer_3__dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_pf_7questdb_7ingress_6Buffer_2__dealloc__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_pf_7questdb_7ingress_6Buffer_2__dealloc__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "questdb/ingress.pyx":470 - * - * def __dealloc__(self): - * self._row_complete_sender = None # <<<<<<<<<<<<<< - * qdb_pystr_buf_free(self._b) - * line_sender_buffer_free(self._impl) - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_row_complete_sender); - __Pyx_DECREF(__pyx_v_self->_row_complete_sender); - __pyx_v_self->_row_complete_sender = Py_None; - - /* "questdb/ingress.pyx":471 - * def __dealloc__(self): - * self._row_complete_sender = None - * qdb_pystr_buf_free(self._b) # <<<<<<<<<<<<<< - * line_sender_buffer_free(self._impl) - * - */ - qdb_pystr_buf_free(__pyx_v_self->_b); - - /* "questdb/ingress.pyx":472 - * self._row_complete_sender = None - * qdb_pystr_buf_free(self._b) - * line_sender_buffer_free(self._impl) # <<<<<<<<<<<<<< - * - * @property - */ - line_sender_buffer_free(__pyx_v_self->_impl); - - /* "questdb/ingress.pyx":469 - * self._row_complete_sender = None - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * self._row_complete_sender = None - * qdb_pystr_buf_free(self._b) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "questdb/ingress.pyx":475 - * - * @property - * def init_capacity(self) -> int: # <<<<<<<<<<<<<< - * """ - * The initial capacity of the buffer when first created. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13init_capacity_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13init_capacity_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_13init_capacity___get__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "questdb/ingress.pyx":481 - * This may grow over time, see ``capacity()``. - * """ - * return self._init_capacity # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_init_capacity); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 481, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":475 - * - * @property - * def init_capacity(self) -> int: # <<<<<<<<<<<<<< - * """ - * The initial capacity of the buffer when first created. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer.init_capacity.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":489 - * - * @property - * def max_name_len(self) -> int: # <<<<<<<<<<<<<< - * """Maximum length of a table or column name.""" - * return self._max_name_len - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_12max_name_len_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_12max_name_len_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_12max_name_len___get__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "questdb/ingress.pyx":491 - * def max_name_len(self) -> int: - * """Maximum length of a table or column name.""" - * return self._max_name_len # <<<<<<<<<<<<<< - * - * def reserve(self, additional: int): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_max_name_len); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 491, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":489 - * - * @property - * def max_name_len(self) -> int: # <<<<<<<<<<<<<< - * """Maximum length of a table or column name.""" - * return self._max_name_len - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer.max_name_len.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":493 - * return self._max_name_len - * - * def reserve(self, additional: int): # <<<<<<<<<<<<<< - * """ - * Ensure the buffer has at least `additional` bytes of future capacity. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_5reserve(PyObject *__pyx_v_self, PyObject *__pyx_v_additional); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Buffer_4reserve[] = "\n Ensure the buffer has at least `additional` bytes of future capacity.\n\n :param int additional: Additional bytes to reserve.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_5reserve = {"reserve", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_5reserve, METH_O, __pyx_doc_7questdb_7ingress_6Buffer_4reserve}; -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_5reserve(PyObject *__pyx_v_self, PyObject *__pyx_v_additional) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("reserve (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_4reserve(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), ((PyObject *)__pyx_v_additional)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_4reserve(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_additional) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - size_t __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("reserve", 0); - - /* "questdb/ingress.pyx":499 - * :param int additional: Additional bytes to reserve. - * """ - * if additional < 0: # <<<<<<<<<<<<<< - * raise ValueError('additional must be non-negative.') - * line_sender_buffer_reserve(self._impl, additional) - */ - __pyx_t_1 = PyObject_RichCompare(__pyx_v_additional, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 499, __pyx_L1_error) - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 499, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":500 - * """ - * if additional < 0: - * raise ValueError('additional must be non-negative.') # <<<<<<<<<<<<<< - * line_sender_buffer_reserve(self._impl, additional) - * - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 500, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 500, __pyx_L1_error) - - /* "questdb/ingress.pyx":499 - * :param int additional: Additional bytes to reserve. - * """ - * if additional < 0: # <<<<<<<<<<<<<< - * raise ValueError('additional must be non-negative.') - * line_sender_buffer_reserve(self._impl, additional) - */ - } - - /* "questdb/ingress.pyx":501 - * if additional < 0: - * raise ValueError('additional must be non-negative.') - * line_sender_buffer_reserve(self._impl, additional) # <<<<<<<<<<<<<< - * - * def capacity(self) -> int: - */ - __pyx_t_3 = __Pyx_PyInt_As_size_t(__pyx_v_additional); if (unlikely((__pyx_t_3 == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 501, __pyx_L1_error) - line_sender_buffer_reserve(__pyx_v_self->_impl, __pyx_t_3); - - /* "questdb/ingress.pyx":493 - * return self._max_name_len - * - * def reserve(self, additional: int): # <<<<<<<<<<<<<< - * """ - * Ensure the buffer has at least `additional` bytes of future capacity. - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer.reserve", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":503 - * line_sender_buffer_reserve(self._impl, additional) - * - * def capacity(self) -> int: # <<<<<<<<<<<<<< - * """The current buffer capacity.""" - * return line_sender_buffer_capacity(self._impl) - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_7capacity(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Buffer_6capacity[] = "The current buffer capacity."; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_7capacity = {"capacity", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_7capacity, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_6capacity}; -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_7capacity(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("capacity (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_6capacity(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_6capacity(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("capacity", 0); - - /* "questdb/ingress.pyx":505 - * def capacity(self) -> int: - * """The current buffer capacity.""" - * return line_sender_buffer_capacity(self._impl) # <<<<<<<<<<<<<< - * - * def clear(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_FromSize_t(line_sender_buffer_capacity(__pyx_v_self->_impl)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 505, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":503 - * line_sender_buffer_reserve(self._impl, additional) - * - * def capacity(self) -> int: # <<<<<<<<<<<<<< - * """The current buffer capacity.""" - * return line_sender_buffer_capacity(self._impl) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer.capacity", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":507 - * return line_sender_buffer_capacity(self._impl) - * - * def clear(self): # <<<<<<<<<<<<<< - * """ - * Reset the buffer. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_9clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Buffer_8clear[] = "\n Reset the buffer.\n\n Note that flushing a buffer will (unless otherwise specified)\n also automatically clear it.\n\n This method is designed to be called only in conjunction with\n ``sender.flush(buffer, clear=False)``.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_9clear = {"clear", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_9clear, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_8clear}; -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_9clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("clear (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_8clear(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_8clear(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("clear", 0); - - /* "questdb/ingress.pyx":517 - * ``sender.flush(buffer, clear=False)``. - * """ - * line_sender_buffer_clear(self._impl) # <<<<<<<<<<<<<< - * qdb_pystr_buf_clear(self._b) - * - */ - line_sender_buffer_clear(__pyx_v_self->_impl); - - /* "questdb/ingress.pyx":518 - * """ - * line_sender_buffer_clear(self._impl) - * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< - * - * def __len__(self) -> int: - */ - qdb_pystr_buf_clear(__pyx_v_self->_b); - - /* "questdb/ingress.pyx":507 - * return line_sender_buffer_capacity(self._impl) - * - * def clear(self): # <<<<<<<<<<<<<< - * """ - * Reset the buffer. - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":520 - * qdb_pystr_buf_clear(self._b) - * - * def __len__(self) -> int: # <<<<<<<<<<<<<< - * """ - * The current number of bytes currently in the buffer. - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_pw_7questdb_7ingress_6Buffer_11__len__(PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Buffer_10__len__[] = "\n The current number of bytes currently in the buffer.\n\n Equivalent (but cheaper) to ``len(str(sender))``.\n "; -#if CYTHON_UPDATE_DESCRIPTOR_DOC -struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__; -#endif -static Py_ssize_t __pyx_pw_7questdb_7ingress_6Buffer_11__len__(PyObject *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_10__len__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static Py_ssize_t __pyx_pf_7questdb_7ingress_6Buffer_10__len__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__", 0); - - /* "questdb/ingress.pyx":526 - * Equivalent (but cheaper) to ``len(str(sender))``. - * """ - * return line_sender_buffer_size(self._impl) # <<<<<<<<<<<<<< - * - * def __str__(self) -> str: - */ - __pyx_r = line_sender_buffer_size(__pyx_v_self->_impl); - goto __pyx_L0; - - /* "questdb/ingress.pyx":520 - * qdb_pystr_buf_clear(self._b) - * - * def __len__(self) -> int: # <<<<<<<<<<<<<< - * """ - * The current number of bytes currently in the buffer. - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":528 - * return line_sender_buffer_size(self._impl) - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """Return the constructed buffer as a string. Use for debugging.""" - * return self._to_str() - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13__str__(PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Buffer_12__str__[] = "Return the constructed buffer as a string. Use for debugging."; -#if CYTHON_UPDATE_DESCRIPTOR_DOC -struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__; -#endif -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_13__str__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_12__str__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_12__str__(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__str__", 0); - - /* "questdb/ingress.pyx":530 - * def __str__(self) -> str: - * """Return the constructed buffer as a string. Use for debugging.""" - * return self._to_str() # <<<<<<<<<<<<<< - * - * cdef inline object _to_str(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__to_str(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 530, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":528 - * return line_sender_buffer_size(self._impl) - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """Return the constructed buffer as a string. Use for debugging.""" - * return self._to_str() - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":532 - * return self._to_str() - * - * cdef inline object _to_str(self): # <<<<<<<<<<<<<< - * cdef size_t size = 0 - * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) - */ - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__to_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - size_t __pyx_v_size; - char const *__pyx_v_utf8; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_to_str", 0); - - /* "questdb/ingress.pyx":533 - * - * cdef inline object _to_str(self): - * cdef size_t size = 0 # <<<<<<<<<<<<<< - * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) - * return PyUnicode_FromStringAndSize(utf8, size) - */ - __pyx_v_size = 0; - - /* "questdb/ingress.pyx":534 - * cdef inline object _to_str(self): - * cdef size_t size = 0 - * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) # <<<<<<<<<<<<<< - * return PyUnicode_FromStringAndSize(utf8, size) - * - */ - __pyx_v_utf8 = line_sender_buffer_peek(__pyx_v_self->_impl, (&__pyx_v_size)); - - /* "questdb/ingress.pyx":535 - * cdef size_t size = 0 - * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) - * return PyUnicode_FromStringAndSize(utf8, size) # <<<<<<<<<<<<<< - * - * cdef inline int _set_marker(self) except -1: - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyUnicode_FromStringAndSize(__pyx_v_utf8, ((Py_ssize_t)__pyx_v_size)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 535, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":532 - * return self._to_str() - * - * cdef inline object _to_str(self): # <<<<<<<<<<<<<< - * cdef size_t size = 0 - * cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer._to_str", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":537 - * return PyUnicode_FromStringAndSize(utf8, size) - * - * cdef inline int _set_marker(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_set_marker(self._impl, &err): - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__set_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_set_marker", 0); - - /* "questdb/ingress.pyx":538 - * - * cdef inline int _set_marker(self) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_set_marker(self._impl, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":539 - * cdef inline int _set_marker(self) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_set_marker(self._impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * - */ - __pyx_t_1 = ((!(line_sender_buffer_set_marker(__pyx_v_self->_impl, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":540 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_set_marker(self._impl, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * - * cdef inline int _rewind_to_marker(self) except -1: - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 540, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 540, __pyx_L1_error) - - /* "questdb/ingress.pyx":539 - * cdef inline int _set_marker(self) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_set_marker(self._impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * - */ - } - - /* "questdb/ingress.pyx":537 - * return PyUnicode_FromStringAndSize(utf8, size) - * - * cdef inline int _set_marker(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_set_marker(self._impl, &err): - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._set_marker", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":542 - * raise c_err_to_py(err) - * - * cdef inline int _rewind_to_marker(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_rewind_to_marker(self._impl, &err): - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_rewind_to_marker", 0); - - /* "questdb/ingress.pyx":543 - * - * cdef inline int _rewind_to_marker(self) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_rewind_to_marker(self._impl, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":544 - * cdef inline int _rewind_to_marker(self) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_rewind_to_marker(self._impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * - */ - __pyx_t_1 = ((!(line_sender_buffer_rewind_to_marker(__pyx_v_self->_impl, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":545 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_rewind_to_marker(self._impl, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * - * cdef inline _clear_marker(self): - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 545, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 545, __pyx_L1_error) - - /* "questdb/ingress.pyx":544 - * cdef inline int _rewind_to_marker(self) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_rewind_to_marker(self._impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * - */ - } - - /* "questdb/ingress.pyx":542 - * raise c_err_to_py(err) - * - * cdef inline int _rewind_to_marker(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_rewind_to_marker(self._impl, &err): - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._rewind_to_marker", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":547 - * raise c_err_to_py(err) - * - * cdef inline _clear_marker(self): # <<<<<<<<<<<<<< - * line_sender_buffer_clear_marker(self._impl) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_7questdb_7ingress_6Buffer__clear_marker(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_clear_marker", 0); - - /* "questdb/ingress.pyx":548 - * - * cdef inline _clear_marker(self): - * line_sender_buffer_clear_marker(self._impl) # <<<<<<<<<<<<<< - * - * cdef inline int _table(self, str table_name) except -1: - */ - line_sender_buffer_clear_marker(__pyx_v_self->_impl); - - /* "questdb/ingress.pyx":547 - * raise c_err_to_py(err) - * - * cdef inline _clear_marker(self): # <<<<<<<<<<<<<< - * line_sender_buffer_clear_marker(self._impl) - * - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":550 - * line_sender_buffer_clear_marker(self._impl) - * - * cdef inline int _table(self, str table_name) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * cdef line_sender_table_name c_table_name - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__table(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name) { - struct line_sender_error *__pyx_v_err; - struct line_sender_table_name __pyx_v_c_table_name; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_table", 0); - - /* "questdb/ingress.pyx":551 - * - * cdef inline int _table(self, str table_name) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef line_sender_table_name c_table_name - * str_to_table_name(self._cleared_b(), table_name, &c_table_name) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":553 - * cdef line_sender_error* err = NULL - * cdef line_sender_table_name c_table_name - * str_to_table_name(self._cleared_b(), table_name, &c_table_name) # <<<<<<<<<<<<<< - * if not line_sender_buffer_table(self._impl, c_table_name, &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_table_name(__pyx_f_7questdb_7ingress_6Buffer__cleared_b(__pyx_v_self), __pyx_v_table_name, (&__pyx_v_c_table_name)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 553, __pyx_L1_error) - - /* "questdb/ingress.pyx":554 - * cdef line_sender_table_name c_table_name - * str_to_table_name(self._cleared_b(), table_name, &c_table_name) - * if not line_sender_buffer_table(self._impl, c_table_name, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_table(__pyx_v_self->_impl, __pyx_v_c_table_name, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":555 - * str_to_table_name(self._cleared_b(), table_name, &c_table_name) - * if not line_sender_buffer_table(self._impl, c_table_name, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 555, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 555, __pyx_L1_error) - - /* "questdb/ingress.pyx":554 - * cdef line_sender_table_name c_table_name - * str_to_table_name(self._cleared_b(), table_name, &c_table_name) - * if not line_sender_buffer_table(self._impl, c_table_name, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":556 - * if not line_sender_buffer_table(self._impl, c_table_name, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline qdb_pystr_buf* _cleared_b(self): - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":550 - * line_sender_buffer_clear_marker(self._impl) - * - * cdef inline int _table(self, str table_name) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * cdef line_sender_table_name c_table_name - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._table", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":558 - * return 0 - * - * cdef inline qdb_pystr_buf* _cleared_b(self): # <<<<<<<<<<<<<< - * qdb_pystr_buf_clear(self._b) - * return self._b - */ - -static CYTHON_INLINE struct qdb_pystr_buf *__pyx_f_7questdb_7ingress_6Buffer__cleared_b(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - struct qdb_pystr_buf *__pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_cleared_b", 0); - - /* "questdb/ingress.pyx":559 - * - * cdef inline qdb_pystr_buf* _cleared_b(self): - * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< - * return self._b - * - */ - qdb_pystr_buf_clear(__pyx_v_self->_b); - - /* "questdb/ingress.pyx":560 - * cdef inline qdb_pystr_buf* _cleared_b(self): - * qdb_pystr_buf_clear(self._b) - * return self._b # <<<<<<<<<<<<<< - * - * cdef inline int _symbol(self, str name, str value) except -1: - */ - __pyx_r = __pyx_v_self->_b; - goto __pyx_L0; - - /* "questdb/ingress.pyx":558 - * return 0 - * - * cdef inline qdb_pystr_buf* _cleared_b(self): # <<<<<<<<<<<<<< - * qdb_pystr_buf_clear(self._b) - * return self._b - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":562 - * return self._b - * - * cdef inline int _symbol(self, str name, str value) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * cdef line_sender_column_name c_name - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__symbol(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value) { - struct line_sender_error *__pyx_v_err; - struct line_sender_column_name __pyx_v_c_name; - struct line_sender_utf8 __pyx_v_c_value; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_symbol", 0); - - /* "questdb/ingress.pyx":563 - * - * cdef inline int _symbol(self, str name, str value) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef line_sender_column_name c_name - * cdef line_sender_utf8 c_value - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":566 - * cdef line_sender_column_name c_name - * cdef line_sender_utf8 c_value - * str_to_column_name(self._cleared_b(), name, &c_name) # <<<<<<<<<<<<<< - * str_to_utf8(self._b, value, &c_value) - * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_f_7questdb_7ingress_6Buffer__cleared_b(__pyx_v_self), __pyx_v_name, (&__pyx_v_c_name)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 566, __pyx_L1_error) - - /* "questdb/ingress.pyx":567 - * cdef line_sender_utf8 c_value - * str_to_column_name(self._cleared_b(), name, &c_name) - * str_to_utf8(self._b, value, &c_value) # <<<<<<<<<<<<<< - * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_self->_b, __pyx_v_value, (&__pyx_v_c_value)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 567, __pyx_L1_error) - - /* "questdb/ingress.pyx":568 - * str_to_column_name(self._cleared_b(), name, &c_name) - * str_to_utf8(self._b, value, &c_value) - * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_symbol(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_c_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":569 - * str_to_utf8(self._b, value, &c_value) - * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 569, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 569, __pyx_L1_error) - - /* "questdb/ingress.pyx":568 - * str_to_column_name(self._cleared_b(), name, &c_name) - * str_to_utf8(self._b, value, &c_value) - * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":570 - * if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _column_bool( - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":562 - * return self._b - * - * cdef inline int _symbol(self, str name, str value) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * cdef line_sender_column_name c_name - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._symbol", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":572 - * return 0 - * - * cdef inline int _column_bool( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, bint value) except -1: - * cdef line_sender_error* err = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_bool(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int __pyx_v_value) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_column_bool", 0); - - /* "questdb/ingress.pyx":574 - * cdef inline int _column_bool( - * self, line_sender_column_name c_name, bint value) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":575 - * self, line_sender_column_name c_name, bint value) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_column_bool(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":576 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 576, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 576, __pyx_L1_error) - - /* "questdb/ingress.pyx":575 - * self, line_sender_column_name c_name, bint value) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":577 - * if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _column_i64( - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":572 - * return 0 - * - * cdef inline int _column_bool( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, bint value) except -1: - * cdef line_sender_error* err = NULL - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._column_bool", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":579 - * return 0 - * - * cdef inline int _column_i64( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, int64_t value) except -1: - * cdef line_sender_error* err = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_i64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, int64_t __pyx_v_value) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_column_i64", 0); - - /* "questdb/ingress.pyx":581 - * cdef inline int _column_i64( - * self, line_sender_column_name c_name, int64_t value) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":582 - * self, line_sender_column_name c_name, int64_t value) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_column_i64(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":583 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 583, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 583, __pyx_L1_error) - - /* "questdb/ingress.pyx":582 - * self, line_sender_column_name c_name, int64_t value) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":584 - * if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _column_f64( - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":579 - * return 0 - * - * cdef inline int _column_i64( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, int64_t value) except -1: - * cdef line_sender_error* err = NULL - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._column_i64", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":586 - * return 0 - * - * cdef inline int _column_f64( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, double value) except -1: - * cdef line_sender_error* err = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_f64(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, double __pyx_v_value) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_column_f64", 0); - - /* "questdb/ingress.pyx":588 - * cdef inline int _column_f64( - * self, line_sender_column_name c_name, double value) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":589 - * self, line_sender_column_name c_name, double value) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_column_f64(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":590 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 590, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 590, __pyx_L1_error) - - /* "questdb/ingress.pyx":589 - * self, line_sender_column_name c_name, double value) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":591 - * if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _column_str( - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":586 - * return 0 - * - * cdef inline int _column_f64( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, double value) except -1: - * cdef line_sender_error* err = NULL - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._column_f64", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":593 - * return 0 - * - * cdef inline int _column_str( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, str value) except -1: - * cdef line_sender_error* err = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_str(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyObject *__pyx_v_value) { - struct line_sender_error *__pyx_v_err; - struct line_sender_utf8 __pyx_v_c_value; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_column_str", 0); - - /* "questdb/ingress.pyx":595 - * cdef inline int _column_str( - * self, line_sender_column_name c_name, str value) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef line_sender_utf8 c_value - * str_to_utf8(self._b, value, &c_value) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":597 - * cdef line_sender_error* err = NULL - * cdef line_sender_utf8 c_value - * str_to_utf8(self._b, value, &c_value) # <<<<<<<<<<<<<< - * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_self->_b, __pyx_v_value, (&__pyx_v_c_value)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 597, __pyx_L1_error) - - /* "questdb/ingress.pyx":598 - * cdef line_sender_utf8 c_value - * str_to_utf8(self._b, value, &c_value) - * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_column_str(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_c_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":599 - * str_to_utf8(self._b, value, &c_value) - * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 599, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 599, __pyx_L1_error) - - /* "questdb/ingress.pyx":598 - * cdef line_sender_utf8 c_value - * str_to_utf8(self._b, value, &c_value) - * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":600 - * if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _column_ts( - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":593 - * return 0 - * - * cdef inline int _column_str( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, str value) except -1: - * cdef line_sender_error* err = NULL - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._column_str", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":602 - * return 0 - * - * cdef inline int _column_ts( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, TimestampMicros ts) except -1: - * cdef line_sender_error* err = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *__pyx_v_ts) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_column_ts", 0); - - /* "questdb/ingress.pyx":604 - * cdef inline int _column_ts( - * self, line_sender_column_name c_name, TimestampMicros ts) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":605 - * self, line_sender_column_name c_name, TimestampMicros ts) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_column_ts(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_v_ts->_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":606 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 606, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 606, __pyx_L1_error) - - /* "questdb/ingress.pyx":605 - * self, line_sender_column_name c_name, TimestampMicros ts) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":607 - * if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _column_dt( - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":602 - * return 0 - * - * cdef inline int _column_ts( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, TimestampMicros ts) except -1: - * cdef line_sender_error* err = NULL - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._column_ts", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":609 - * return 0 - * - * cdef inline int _column_dt( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, datetime dt) except -1: - * cdef line_sender_error* err = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct line_sender_column_name __pyx_v_c_name, PyDateTime_DateTime *__pyx_v_dt) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_column_dt", 0); - - /* "questdb/ingress.pyx":611 - * cdef inline int _column_dt( - * self, line_sender_column_name c_name, datetime dt) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_column_ts( - * self._impl, c_name, datetime_to_micros(dt), &err): - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":612 - * self, line_sender_column_name c_name, datetime dt) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_ts( # <<<<<<<<<<<<<< - * self._impl, c_name, datetime_to_micros(dt), &err): - * raise c_err_to_py(err) - */ - __pyx_t_1 = ((!(line_sender_buffer_column_ts(__pyx_v_self->_impl, __pyx_v_c_name, __pyx_f_7questdb_7ingress_datetime_to_micros(__pyx_v_dt), (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":614 - * if not line_sender_buffer_column_ts( - * self._impl, c_name, datetime_to_micros(dt), &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 614, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 614, __pyx_L1_error) - - /* "questdb/ingress.pyx":612 - * self, line_sender_column_name c_name, datetime dt) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_column_ts( # <<<<<<<<<<<<<< - * self._impl, c_name, datetime_to_micros(dt), &err): - * raise c_err_to_py(err) - */ - } - - /* "questdb/ingress.pyx":615 - * self._impl, c_name, datetime_to_micros(dt), &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _column(self, str name, object value) except -1: - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":609 - * return 0 - * - * cdef inline int _column_dt( # <<<<<<<<<<<<<< - * self, line_sender_column_name c_name, datetime dt) except -1: - * cdef line_sender_error* err = NULL - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._column_dt", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":617 - * return 0 - * - * cdef inline int _column(self, str name, object value) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_column_name c_name - * str_to_column_name(self._cleared_b(), name, &c_name) - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__column(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_value) { - struct line_sender_column_name __pyx_v_c_name; - PyObject *__pyx_v_valid = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int64_t __pyx_t_3; - double __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - Py_ssize_t __pyx_t_7; - Py_UCS4 __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_column", 0); - - /* "questdb/ingress.pyx":619 - * cdef inline int _column(self, str name, object value) except -1: - * cdef line_sender_column_name c_name - * str_to_column_name(self._cleared_b(), name, &c_name) # <<<<<<<<<<<<<< - * if PyBool_Check(value): - * return self._column_bool(c_name, value) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_str_to_column_name(__pyx_f_7questdb_7ingress_6Buffer__cleared_b(__pyx_v_self), __pyx_v_name, (&__pyx_v_c_name)); if (unlikely(__pyx_t_1 == ((int)0))) __PYX_ERR(0, 619, __pyx_L1_error) - - /* "questdb/ingress.pyx":620 - * cdef line_sender_column_name c_name - * str_to_column_name(self._cleared_b(), name, &c_name) - * if PyBool_Check(value): # <<<<<<<<<<<<<< - * return self._column_bool(c_name, value) - * elif PyInt_Check(value): - */ - __pyx_t_1 = (PyBool_Check(__pyx_v_value) != 0); - if (__pyx_t_1) { - - /* "questdb/ingress.pyx":621 - * str_to_column_name(self._cleared_b(), name, &c_name) - * if PyBool_Check(value): - * return self._column_bool(c_name, value) # <<<<<<<<<<<<<< - * elif PyInt_Check(value): - * return self._column_i64(c_name, value) - */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_value); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 621, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_bool(__pyx_v_self, __pyx_v_c_name, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 621, __pyx_L1_error) - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "questdb/ingress.pyx":620 - * cdef line_sender_column_name c_name - * str_to_column_name(self._cleared_b(), name, &c_name) - * if PyBool_Check(value): # <<<<<<<<<<<<<< - * return self._column_bool(c_name, value) - * elif PyInt_Check(value): - */ - } - - /* "questdb/ingress.pyx":622 - * if PyBool_Check(value): - * return self._column_bool(c_name, value) - * elif PyInt_Check(value): # <<<<<<<<<<<<<< - * return self._column_i64(c_name, value) - * elif PyFloat_Check(value): - */ - __pyx_t_1 = (PyInt_Check(__pyx_v_value) != 0); - if (__pyx_t_1) { - - /* "questdb/ingress.pyx":623 - * return self._column_bool(c_name, value) - * elif PyInt_Check(value): - * return self._column_i64(c_name, value) # <<<<<<<<<<<<<< - * elif PyFloat_Check(value): - * return self._column_f64(c_name, value) - */ - __pyx_t_3 = __Pyx_PyInt_As_int64_t(__pyx_v_value); if (unlikely((__pyx_t_3 == ((int64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 623, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_i64(__pyx_v_self, __pyx_v_c_name, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 623, __pyx_L1_error) - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "questdb/ingress.pyx":622 - * if PyBool_Check(value): - * return self._column_bool(c_name, value) - * elif PyInt_Check(value): # <<<<<<<<<<<<<< - * return self._column_i64(c_name, value) - * elif PyFloat_Check(value): - */ - } - - /* "questdb/ingress.pyx":624 - * elif PyInt_Check(value): - * return self._column_i64(c_name, value) - * elif PyFloat_Check(value): # <<<<<<<<<<<<<< - * return self._column_f64(c_name, value) - * elif PyUnicode_Check(value): - */ - __pyx_t_1 = (PyFloat_Check(__pyx_v_value) != 0); - if (__pyx_t_1) { - - /* "questdb/ingress.pyx":625 - * return self._column_i64(c_name, value) - * elif PyFloat_Check(value): - * return self._column_f64(c_name, value) # <<<<<<<<<<<<<< - * elif PyUnicode_Check(value): - * return self._column_str(c_name, value) - */ - __pyx_t_4 = __pyx_PyFloat_AsDouble(__pyx_v_value); if (unlikely((__pyx_t_4 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 625, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_f64(__pyx_v_self, __pyx_v_c_name, __pyx_t_4); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 625, __pyx_L1_error) - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "questdb/ingress.pyx":624 - * elif PyInt_Check(value): - * return self._column_i64(c_name, value) - * elif PyFloat_Check(value): # <<<<<<<<<<<<<< - * return self._column_f64(c_name, value) - * elif PyUnicode_Check(value): - */ - } - - /* "questdb/ingress.pyx":626 - * elif PyFloat_Check(value): - * return self._column_f64(c_name, value) - * elif PyUnicode_Check(value): # <<<<<<<<<<<<<< - * return self._column_str(c_name, value) - * elif isinstance(value, TimestampMicros): - */ - __pyx_t_1 = (PyUnicode_Check(__pyx_v_value) != 0); - if (__pyx_t_1) { - - /* "questdb/ingress.pyx":627 - * return self._column_f64(c_name, value) - * elif PyUnicode_Check(value): - * return self._column_str(c_name, value) # <<<<<<<<<<<<<< - * elif isinstance(value, TimestampMicros): - * return self._column_ts(c_name, value) - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_value))||((__pyx_v_value) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_value)->tp_name), 0))) __PYX_ERR(0, 627, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_str(__pyx_v_self, __pyx_v_c_name, ((PyObject*)__pyx_v_value)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 627, __pyx_L1_error) - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "questdb/ingress.pyx":626 - * elif PyFloat_Check(value): - * return self._column_f64(c_name, value) - * elif PyUnicode_Check(value): # <<<<<<<<<<<<<< - * return self._column_str(c_name, value) - * elif isinstance(value, TimestampMicros): - */ - } - - /* "questdb/ingress.pyx":628 - * elif PyUnicode_Check(value): - * return self._column_str(c_name, value) - * elif isinstance(value, TimestampMicros): # <<<<<<<<<<<<<< - * return self._column_ts(c_name, value) - * elif isinstance(value, datetime): - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_value, __pyx_ptype_7questdb_7ingress_TimestampMicros); - __pyx_t_5 = (__pyx_t_1 != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":629 - * return self._column_str(c_name, value) - * elif isinstance(value, TimestampMicros): - * return self._column_ts(c_name, value) # <<<<<<<<<<<<<< - * elif isinstance(value, datetime): - * return self._column_dt(c_name, value) - */ - if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_7questdb_7ingress_TimestampMicros))))) __PYX_ERR(0, 629, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_ts(__pyx_v_self, __pyx_v_c_name, ((struct __pyx_obj_7questdb_7ingress_TimestampMicros *)__pyx_v_value)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 629, __pyx_L1_error) - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "questdb/ingress.pyx":628 - * elif PyUnicode_Check(value): - * return self._column_str(c_name, value) - * elif isinstance(value, TimestampMicros): # <<<<<<<<<<<<<< - * return self._column_ts(c_name, value) - * elif isinstance(value, datetime): - */ - } - - /* "questdb/ingress.pyx":630 - * elif isinstance(value, TimestampMicros): - * return self._column_ts(c_name, value) - * elif isinstance(value, datetime): # <<<<<<<<<<<<<< - * return self._column_dt(c_name, value) - * else: - */ - __pyx_t_5 = __Pyx_TypeCheck(__pyx_v_value, __pyx_ptype_7cpython_8datetime_datetime); - __pyx_t_1 = (__pyx_t_5 != 0); - if (likely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":631 - * return self._column_ts(c_name, value) - * elif isinstance(value, datetime): - * return self._column_dt(c_name, value) # <<<<<<<<<<<<<< - * else: - * valid = ', '.join(( - */ - if (!(likely(((__pyx_v_value) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_value, __pyx_ptype_7cpython_8datetime_datetime))))) __PYX_ERR(0, 631, __pyx_L1_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_6Buffer__column_dt(__pyx_v_self, __pyx_v_c_name, ((PyDateTime_DateTime *)__pyx_v_value)); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 631, __pyx_L1_error) - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "questdb/ingress.pyx":630 - * elif isinstance(value, TimestampMicros): - * return self._column_ts(c_name, value) - * elif isinstance(value, datetime): # <<<<<<<<<<<<<< - * return self._column_dt(c_name, value) - * else: - */ - } - - /* "questdb/ingress.pyx":633 - * return self._column_dt(c_name, value) - * else: - * valid = ', '.join(( # <<<<<<<<<<<<<< - * 'bool', - * 'int', - */ - /*else*/ { - - /* "questdb/ingress.pyx":634 - * else: - * valid = ', '.join(( - * 'bool', # <<<<<<<<<<<<<< - * 'int', - * 'float', - */ - __pyx_t_6 = PyUnicode_Join(__pyx_kp_u__24, __pyx_tuple__26); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 633, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_v_valid = ((PyObject*)__pyx_t_6); - __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":641 - * 'datetime.datetime')) - * raise TypeError( - * f'Unsupported type: {type(value)}. Must be one of: {valid}') # <<<<<<<<<<<<<< - * - * cdef inline int _may_trigger_row_complete(self) except -1: - */ - __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 641, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = 0; - __pyx_t_8 = 127; - __Pyx_INCREF(__pyx_kp_u_Unsupported_type); - __pyx_t_7 += 18; - __Pyx_GIVEREF(__pyx_kp_u_Unsupported_type); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_Unsupported_type); - __pyx_t_9 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_value)), __pyx_empty_unicode); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 641, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) : __pyx_t_8; - __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); - __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_9); - __pyx_t_9 = 0; - __Pyx_INCREF(__pyx_kp_u_Must_be_one_of); - __pyx_t_7 += 18; - __Pyx_GIVEREF(__pyx_kp_u_Must_be_one_of); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u_Must_be_one_of); - __pyx_t_9 = __Pyx_PyUnicode_Unicode(__pyx_v_valid); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 641, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_9) : __pyx_t_8; - __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); - __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_9); - __pyx_t_9 = 0; - __pyx_t_9 = __Pyx_PyUnicode_Join(__pyx_t_6, 4, __pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 641, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":640 - * 'TimestampMicros', - * 'datetime.datetime')) - * raise TypeError( # <<<<<<<<<<<<<< - * f'Unsupported type: {type(value)}. Must be one of: {valid}') - * - */ - __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_9); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 640, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(0, 640, __pyx_L1_error) - } - - /* "questdb/ingress.pyx":617 - * return 0 - * - * cdef inline int _column(self, str name, object value) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_column_name c_name - * str_to_column_name(self._cleared_b(), name, &c_name) - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_AddTraceback("questdb.ingress.Buffer._column", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_valid); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":643 - * f'Unsupported type: {type(value)}. Must be one of: {valid}') - * - * cdef inline int _may_trigger_row_complete(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * cdef PyObject* sender = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - CYTHON_UNUSED struct line_sender_error *__pyx_v_err; - PyObject *__pyx_v_sender; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_t_2; - PyObject *__pyx_t_3; - int __pyx_t_4; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_may_trigger_row_complete", 0); - - /* "questdb/ingress.pyx":644 - * - * cdef inline int _may_trigger_row_complete(self) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef PyObject* sender = NULL - * if self._row_complete_sender != None: - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":645 - * cdef inline int _may_trigger_row_complete(self) except -1: - * cdef line_sender_error* err = NULL - * cdef PyObject* sender = NULL # <<<<<<<<<<<<<< - * if self._row_complete_sender != None: - * sender = PyWeakref_GetObject(self._row_complete_sender) - */ - __pyx_v_sender = NULL; - - /* "questdb/ingress.pyx":646 - * cdef line_sender_error* err = NULL - * cdef PyObject* sender = NULL - * if self._row_complete_sender != None: # <<<<<<<<<<<<<< - * sender = PyWeakref_GetObject(self._row_complete_sender) - * if sender != NULL: - */ - __pyx_t_1 = PyObject_RichCompare(__pyx_v_self->_row_complete_sender, Py_None, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 646, __pyx_L1_error) - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 646, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (__pyx_t_2) { - - /* "questdb/ingress.pyx":647 - * cdef PyObject* sender = NULL - * if self._row_complete_sender != None: - * sender = PyWeakref_GetObject(self._row_complete_sender) # <<<<<<<<<<<<<< - * if sender != NULL: - * may_flush_on_row_complete(self, sender) - */ - __pyx_t_1 = __pyx_v_self->_row_complete_sender; - __Pyx_INCREF(__pyx_t_1); - __pyx_t_3 = PyWeakref_GetObject(__pyx_t_1); if (unlikely(__pyx_t_3 == ((PyObject *)NULL))) __PYX_ERR(0, 647, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_sender = __pyx_t_3; - - /* "questdb/ingress.pyx":648 - * if self._row_complete_sender != None: - * sender = PyWeakref_GetObject(self._row_complete_sender) - * if sender != NULL: # <<<<<<<<<<<<<< - * may_flush_on_row_complete(self, sender) - * - */ - __pyx_t_2 = ((__pyx_v_sender != NULL) != 0); - if (__pyx_t_2) { - - /* "questdb/ingress.pyx":649 - * sender = PyWeakref_GetObject(self._row_complete_sender) - * if sender != NULL: - * may_flush_on_row_complete(self, sender) # <<<<<<<<<<<<<< - * - * cdef inline int _at_ts(self, TimestampNanos ts) except -1: - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_may_flush_on_row_complete(__pyx_v_self, ((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_sender)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 649, __pyx_L1_error) - - /* "questdb/ingress.pyx":648 - * if self._row_complete_sender != None: - * sender = PyWeakref_GetObject(self._row_complete_sender) - * if sender != NULL: # <<<<<<<<<<<<<< - * may_flush_on_row_complete(self, sender) - * - */ - } - - /* "questdb/ingress.pyx":646 - * cdef line_sender_error* err = NULL - * cdef PyObject* sender = NULL - * if self._row_complete_sender != None: # <<<<<<<<<<<<<< - * sender = PyWeakref_GetObject(self._row_complete_sender) - * if sender != NULL: - */ - } - - /* "questdb/ingress.pyx":643 - * f'Unsupported type: {type(value)}. Must be one of: {valid}') - * - * cdef inline int _may_trigger_row_complete(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * cdef PyObject* sender = NULL - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer._may_trigger_row_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":651 - * may_flush_on_row_complete(self, sender) - * - * cdef inline int _at_ts(self, TimestampNanos ts) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, ts._value, &err): - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_ts(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_TimestampNanos *__pyx_v_ts) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_at_ts", 0); - - /* "questdb/ingress.pyx":652 - * - * cdef inline int _at_ts(self, TimestampNanos ts) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_at(self._impl, ts._value, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":653 - * cdef inline int _at_ts(self, TimestampNanos ts) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, ts._value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_at(__pyx_v_self->_impl, __pyx_v_ts->_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":654 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, ts._value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 654, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 654, __pyx_L1_error) - - /* "questdb/ingress.pyx":653 - * cdef inline int _at_ts(self, TimestampNanos ts) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, ts._value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":655 - * if not line_sender_buffer_at(self._impl, ts._value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _at_dt(self, datetime dt) except -1: - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":651 - * may_flush_on_row_complete(self, sender) - * - * cdef inline int _at_ts(self, TimestampNanos ts) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, ts._value, &err): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._at_ts", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":657 - * return 0 - * - * cdef inline int _at_dt(self, datetime dt) except -1: # <<<<<<<<<<<<<< - * cdef int64_t value = datetime_to_nanos(dt) - * cdef line_sender_error* err = NULL - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_dt(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyDateTime_DateTime *__pyx_v_dt) { - int64_t __pyx_v_value; - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_at_dt", 0); - - /* "questdb/ingress.pyx":658 - * - * cdef inline int _at_dt(self, datetime dt) except -1: - * cdef int64_t value = datetime_to_nanos(dt) # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, value, &err): - */ - __pyx_v_value = __pyx_f_7questdb_7ingress_datetime_to_nanos(__pyx_v_dt); - - /* "questdb/ingress.pyx":659 - * cdef inline int _at_dt(self, datetime dt) except -1: - * cdef int64_t value = datetime_to_nanos(dt) - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_at(self._impl, value, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":660 - * cdef int64_t value = datetime_to_nanos(dt) - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_at(__pyx_v_self->_impl, __pyx_v_value, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":661 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, value, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 661, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 661, __pyx_L1_error) - - /* "questdb/ingress.pyx":660 - * cdef int64_t value = datetime_to_nanos(dt) - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at(self._impl, value, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":662 - * if not line_sender_buffer_at(self._impl, value, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _at_now(self) except -1: - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":657 - * return 0 - * - * cdef inline int _at_dt(self, datetime dt) except -1: # <<<<<<<<<<<<<< - * cdef int64_t value = datetime_to_nanos(dt) - * cdef line_sender_error* err = NULL - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._at_dt", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":664 - * return 0 - * - * cdef inline int _at_now(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at_now(self._impl, &err): - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at_now(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - struct line_sender_error *__pyx_v_err; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_at_now", 0); - - /* "questdb/ingress.pyx":665 - * - * cdef inline int _at_now(self) except -1: - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if not line_sender_buffer_at_now(self._impl, &err): - * raise c_err_to_py(err) - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":666 - * cdef inline int _at_now(self) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at_now(self._impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - __pyx_t_1 = ((!(line_sender_buffer_at_now(__pyx_v_self->_impl, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":667 - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at_now(self._impl, &err): - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * return 0 - * - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 667, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 667, __pyx_L1_error) - - /* "questdb/ingress.pyx":666 - * cdef inline int _at_now(self) except -1: - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at_now(self._impl, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * return 0 - */ - } - - /* "questdb/ingress.pyx":668 - * if not line_sender_buffer_at_now(self._impl, &err): - * raise c_err_to_py(err) - * return 0 # <<<<<<<<<<<<<< - * - * cdef inline int _at(self, object ts) except -1: - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":664 - * return 0 - * - * cdef inline int _at_now(self) except -1: # <<<<<<<<<<<<<< - * cdef line_sender_error* err = NULL - * if not line_sender_buffer_at_now(self._impl, &err): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Buffer._at_now", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":670 - * return 0 - * - * cdef inline int _at(self, object ts) except -1: # <<<<<<<<<<<<<< - * if ts is None: - * return self._at_now() - */ - -static CYTHON_INLINE int __pyx_f_7questdb_7ingress_6Buffer__at(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_ts) { - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - PyObject *__pyx_t_4 = NULL; - Py_ssize_t __pyx_t_5; - Py_UCS4 __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_at", 0); - - /* "questdb/ingress.pyx":671 - * - * cdef inline int _at(self, object ts) except -1: - * if ts is None: # <<<<<<<<<<<<<< - * return self._at_now() - * elif isinstance(ts, TimestampNanos): - */ - __pyx_t_1 = (__pyx_v_ts == Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "questdb/ingress.pyx":672 - * cdef inline int _at(self, object ts) except -1: - * if ts is None: - * return self._at_now() # <<<<<<<<<<<<<< - * elif isinstance(ts, TimestampNanos): - * return self._at_ts(ts) - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__at_now(__pyx_v_self); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 672, __pyx_L1_error) - __pyx_r = __pyx_t_3; - goto __pyx_L0; - - /* "questdb/ingress.pyx":671 - * - * cdef inline int _at(self, object ts) except -1: - * if ts is None: # <<<<<<<<<<<<<< - * return self._at_now() - * elif isinstance(ts, TimestampNanos): - */ - } - - /* "questdb/ingress.pyx":673 - * if ts is None: - * return self._at_now() - * elif isinstance(ts, TimestampNanos): # <<<<<<<<<<<<<< - * return self._at_ts(ts) - * elif isinstance(ts, datetime): - */ - __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_ts, __pyx_ptype_7questdb_7ingress_TimestampNanos); - __pyx_t_1 = (__pyx_t_2 != 0); - if (__pyx_t_1) { - - /* "questdb/ingress.pyx":674 - * return self._at_now() - * elif isinstance(ts, TimestampNanos): - * return self._at_ts(ts) # <<<<<<<<<<<<<< - * elif isinstance(ts, datetime): - * return self._at_dt(ts) - */ - if (!(likely(((__pyx_v_ts) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_ts, __pyx_ptype_7questdb_7ingress_TimestampNanos))))) __PYX_ERR(0, 674, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__at_ts(__pyx_v_self, ((struct __pyx_obj_7questdb_7ingress_TimestampNanos *)__pyx_v_ts)); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 674, __pyx_L1_error) - __pyx_r = __pyx_t_3; - goto __pyx_L0; - - /* "questdb/ingress.pyx":673 - * if ts is None: - * return self._at_now() - * elif isinstance(ts, TimestampNanos): # <<<<<<<<<<<<<< - * return self._at_ts(ts) - * elif isinstance(ts, datetime): - */ - } - - /* "questdb/ingress.pyx":675 - * elif isinstance(ts, TimestampNanos): - * return self._at_ts(ts) - * elif isinstance(ts, datetime): # <<<<<<<<<<<<<< - * return self._at_dt(ts) - * else: - */ - __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_ts, __pyx_ptype_7cpython_8datetime_datetime); - __pyx_t_2 = (__pyx_t_1 != 0); - if (likely(__pyx_t_2)) { - - /* "questdb/ingress.pyx":676 - * return self._at_ts(ts) - * elif isinstance(ts, datetime): - * return self._at_dt(ts) # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - if (!(likely(((__pyx_v_ts) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_ts, __pyx_ptype_7cpython_8datetime_datetime))))) __PYX_ERR(0, 676, __pyx_L1_error) - __pyx_t_3 = __pyx_f_7questdb_7ingress_6Buffer__at_dt(__pyx_v_self, ((PyDateTime_DateTime *)__pyx_v_ts)); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 676, __pyx_L1_error) - __pyx_r = __pyx_t_3; - goto __pyx_L0; - - /* "questdb/ingress.pyx":675 - * elif isinstance(ts, TimestampNanos): - * return self._at_ts(ts) - * elif isinstance(ts, datetime): # <<<<<<<<<<<<<< - * return self._at_dt(ts) - * else: - */ - } - - /* "questdb/ingress.pyx":678 - * return self._at_dt(ts) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Unsupported type: {type(ts)}. Must be one of: ' + - * 'TimestampNanos, datetime, None') - */ - /*else*/ { - - /* "questdb/ingress.pyx":679 - * else: - * raise TypeError( - * f'Unsupported type: {type(ts)}. Must be one of: ' + # <<<<<<<<<<<<<< - * 'TimestampNanos, datetime, None') - * - */ - __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = 0; - __pyx_t_6 = 127; - __Pyx_INCREF(__pyx_kp_u_Unsupported_type); - __pyx_t_5 += 18; - __Pyx_GIVEREF(__pyx_kp_u_Unsupported_type); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_kp_u_Unsupported_type); - __pyx_t_7 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_ts)), __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_6 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_6) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_6; - __pyx_t_5 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_7); - __pyx_t_7 = 0; - __Pyx_INCREF(__pyx_kp_u_Must_be_one_of); - __pyx_t_5 += 18; - __Pyx_GIVEREF(__pyx_kp_u_Must_be_one_of); - PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_kp_u_Must_be_one_of); - __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_4, 3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_kp_u_TimestampNanos_datetime_None); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":678 - * return self._at_dt(ts) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Unsupported type: {type(ts)}. Must be one of: ' + - * 'TimestampNanos, datetime, None') - */ - __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 678, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_7, 0, 0, 0); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __PYX_ERR(0, 678, __pyx_L1_error) - } - - /* "questdb/ingress.pyx":670 - * return 0 - * - * cdef inline int _at(self, object ts) except -1: # <<<<<<<<<<<<<< - * if ts is None: - * return self._at_now() - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress.Buffer._at", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":682 - * 'TimestampNanos, datetime, None') - * - * cdef int _row( # <<<<<<<<<<<<<< - * self, - * str table_name, - */ - -static int __pyx_f_7questdb_7ingress_6Buffer__row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args) { - - /* "questdb/ingress.pyx":685 - * self, - * str table_name, - * dict symbols=None, # <<<<<<<<<<<<<< - * dict columns=None, - * object at=None) except -1: - */ - PyObject *__pyx_v_symbols = ((PyObject*)Py_None); - - /* "questdb/ingress.pyx":686 - * str table_name, - * dict symbols=None, - * dict columns=None, # <<<<<<<<<<<<<< - * object at=None) except -1: - * """ - */ - PyObject *__pyx_v_columns = ((PyObject*)Py_None); - - /* "questdb/ingress.pyx":687 - * dict symbols=None, - * dict columns=None, - * object at=None) except -1: # <<<<<<<<<<<<<< - * """ - * Add a row to the buffer. - */ - PyObject *__pyx_v_at = ((PyObject *)Py_None); - int __pyx_v_wrote_fields; - PyObject *__pyx_v_name = NULL; - PyObject *__pyx_v_value = NULL; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - Py_ssize_t __pyx_t_8; - Py_ssize_t __pyx_t_9; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - int __pyx_t_12; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_row", 0); - if (__pyx_optional_args) { - if (__pyx_optional_args->__pyx_n > 0) { - __pyx_v_symbols = __pyx_optional_args->symbols; - if (__pyx_optional_args->__pyx_n > 1) { - __pyx_v_columns = __pyx_optional_args->columns; - if (__pyx_optional_args->__pyx_n > 2) { - __pyx_v_at = __pyx_optional_args->at; - } - } - } - } - - /* "questdb/ingress.pyx":691 - * Add a row to the buffer. - * """ - * cdef bint wrote_fields = False # <<<<<<<<<<<<<< - * self._set_marker() - * try: - */ - __pyx_v_wrote_fields = 0; - - /* "questdb/ingress.pyx":692 - * """ - * cdef bint wrote_fields = False - * self._set_marker() # <<<<<<<<<<<<<< - * try: - * self._table(table_name) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__set_marker(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 692, __pyx_L1_error) - - /* "questdb/ingress.pyx":693 - * cdef bint wrote_fields = False - * self._set_marker() - * try: # <<<<<<<<<<<<<< - * self._table(table_name) - * if symbols is not None: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_4); - /*try:*/ { - - /* "questdb/ingress.pyx":694 - * self._set_marker() - * try: - * self._table(table_name) # <<<<<<<<<<<<<< - * if symbols is not None: - * for name, value in symbols.items(): - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__table(__pyx_v_self, __pyx_v_table_name); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 694, __pyx_L3_error) - - /* "questdb/ingress.pyx":695 - * try: - * self._table(table_name) - * if symbols is not None: # <<<<<<<<<<<<<< - * for name, value in symbols.items(): - * if value is not None: - */ - __pyx_t_5 = (__pyx_v_symbols != ((PyObject*)Py_None)); - __pyx_t_6 = (__pyx_t_5 != 0); - if (__pyx_t_6) { - - /* "questdb/ingress.pyx":696 - * self._table(table_name) - * if symbols is not None: - * for name, value in symbols.items(): # <<<<<<<<<<<<<< - * if value is not None: - * self._symbol(name, value) - */ - __pyx_t_8 = 0; - if (unlikely(__pyx_v_symbols == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items"); - __PYX_ERR(0, 696, __pyx_L3_error) - } - __pyx_t_10 = __Pyx_dict_iterator(__pyx_v_symbols, 1, __pyx_n_s_items, (&__pyx_t_9), (&__pyx_t_1)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 696, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_7); - __pyx_t_7 = __pyx_t_10; - __pyx_t_10 = 0; - while (1) { - __pyx_t_12 = __Pyx_dict_iter_next(__pyx_t_7, __pyx_t_9, &__pyx_t_8, &__pyx_t_10, &__pyx_t_11, NULL, __pyx_t_1); - if (unlikely(__pyx_t_12 == 0)) break; - if (unlikely(__pyx_t_12 == -1)) __PYX_ERR(0, 696, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GOTREF(__pyx_t_11); - __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_10); - __pyx_t_10 = 0; - __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_11); - __pyx_t_11 = 0; - - /* "questdb/ingress.pyx":697 - * if symbols is not None: - * for name, value in symbols.items(): - * if value is not None: # <<<<<<<<<<<<<< - * self._symbol(name, value) - * wrote_fields = True - */ - __pyx_t_6 = (__pyx_v_value != Py_None); - __pyx_t_5 = (__pyx_t_6 != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":698 - * for name, value in symbols.items(): - * if value is not None: - * self._symbol(name, value) # <<<<<<<<<<<<<< - * wrote_fields = True - * if columns is not None: - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_name))||((__pyx_v_name) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_name)->tp_name), 0))) __PYX_ERR(0, 698, __pyx_L3_error) - if (!(likely(PyUnicode_CheckExact(__pyx_v_value))||((__pyx_v_value) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_value)->tp_name), 0))) __PYX_ERR(0, 698, __pyx_L3_error) - __pyx_t_12 = __pyx_f_7questdb_7ingress_6Buffer__symbol(__pyx_v_self, ((PyObject*)__pyx_v_name), ((PyObject*)__pyx_v_value)); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 698, __pyx_L3_error) - - /* "questdb/ingress.pyx":699 - * if value is not None: - * self._symbol(name, value) - * wrote_fields = True # <<<<<<<<<<<<<< - * if columns is not None: - * for name, value in columns.items(): - */ - __pyx_v_wrote_fields = 1; - - /* "questdb/ingress.pyx":697 - * if symbols is not None: - * for name, value in symbols.items(): - * if value is not None: # <<<<<<<<<<<<<< - * self._symbol(name, value) - * wrote_fields = True - */ - } - } - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":695 - * try: - * self._table(table_name) - * if symbols is not None: # <<<<<<<<<<<<<< - * for name, value in symbols.items(): - * if value is not None: - */ - } - - /* "questdb/ingress.pyx":700 - * self._symbol(name, value) - * wrote_fields = True - * if columns is not None: # <<<<<<<<<<<<<< - * for name, value in columns.items(): - * if value is not None: - */ - __pyx_t_5 = (__pyx_v_columns != ((PyObject*)Py_None)); - __pyx_t_6 = (__pyx_t_5 != 0); - if (__pyx_t_6) { - - /* "questdb/ingress.pyx":701 - * wrote_fields = True - * if columns is not None: - * for name, value in columns.items(): # <<<<<<<<<<<<<< - * if value is not None: - * self._column(name, value) - */ - __pyx_t_9 = 0; - if (unlikely(__pyx_v_columns == Py_None)) { - PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items"); - __PYX_ERR(0, 701, __pyx_L3_error) - } - __pyx_t_11 = __Pyx_dict_iterator(__pyx_v_columns, 1, __pyx_n_s_items, (&__pyx_t_8), (&__pyx_t_1)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 701, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_XDECREF(__pyx_t_7); - __pyx_t_7 = __pyx_t_11; - __pyx_t_11 = 0; - while (1) { - __pyx_t_12 = __Pyx_dict_iter_next(__pyx_t_7, __pyx_t_8, &__pyx_t_9, &__pyx_t_11, &__pyx_t_10, NULL, __pyx_t_1); - if (unlikely(__pyx_t_12 == 0)) break; - if (unlikely(__pyx_t_12 == -1)) __PYX_ERR(0, 701, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_GOTREF(__pyx_t_10); - __Pyx_XDECREF_SET(__pyx_v_name, __pyx_t_11); - __pyx_t_11 = 0; - __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_10); - __pyx_t_10 = 0; - - /* "questdb/ingress.pyx":702 - * if columns is not None: - * for name, value in columns.items(): - * if value is not None: # <<<<<<<<<<<<<< - * self._column(name, value) - * wrote_fields = True - */ - __pyx_t_6 = (__pyx_v_value != Py_None); - __pyx_t_5 = (__pyx_t_6 != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":703 - * for name, value in columns.items(): - * if value is not None: - * self._column(name, value) # <<<<<<<<<<<<<< - * wrote_fields = True - * if wrote_fields: - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_name))||((__pyx_v_name) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_name)->tp_name), 0))) __PYX_ERR(0, 703, __pyx_L3_error) - __pyx_t_12 = __pyx_f_7questdb_7ingress_6Buffer__column(__pyx_v_self, ((PyObject*)__pyx_v_name), __pyx_v_value); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 703, __pyx_L3_error) - - /* "questdb/ingress.pyx":704 - * if value is not None: - * self._column(name, value) - * wrote_fields = True # <<<<<<<<<<<<<< - * if wrote_fields: - * self._at(at) - */ - __pyx_v_wrote_fields = 1; - - /* "questdb/ingress.pyx":702 - * if columns is not None: - * for name, value in columns.items(): - * if value is not None: # <<<<<<<<<<<<<< - * self._column(name, value) - * wrote_fields = True - */ - } - } - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":700 - * self._symbol(name, value) - * wrote_fields = True - * if columns is not None: # <<<<<<<<<<<<<< - * for name, value in columns.items(): - * if value is not None: - */ - } - - /* "questdb/ingress.pyx":705 - * self._column(name, value) - * wrote_fields = True - * if wrote_fields: # <<<<<<<<<<<<<< - * self._at(at) - * self._clear_marker() - */ - __pyx_t_5 = (__pyx_v_wrote_fields != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":706 - * wrote_fields = True - * if wrote_fields: - * self._at(at) # <<<<<<<<<<<<<< - * self._clear_marker() - * else: - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__at(__pyx_v_self, __pyx_v_at); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 706, __pyx_L3_error) - - /* "questdb/ingress.pyx":707 - * if wrote_fields: - * self._at(at) - * self._clear_marker() # <<<<<<<<<<<<<< - * else: - * self._rewind_to_marker() - */ - __pyx_t_7 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 707, __pyx_L3_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":705 - * self._column(name, value) - * wrote_fields = True - * if wrote_fields: # <<<<<<<<<<<<<< - * self._at(at) - * self._clear_marker() - */ - goto __pyx_L17; - } - - /* "questdb/ingress.pyx":709 - * self._clear_marker() - * else: - * self._rewind_to_marker() # <<<<<<<<<<<<<< - * except: - * self._rewind_to_marker() - */ - /*else*/ { - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 709, __pyx_L3_error) - } - __pyx_L17:; - - /* "questdb/ingress.pyx":693 - * cdef bint wrote_fields = False - * self._set_marker() - * try: # <<<<<<<<<<<<<< - * self._table(table_name) - * if symbols is not None: - */ - } - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":710 - * else: - * self._rewind_to_marker() - * except: # <<<<<<<<<<<<<< - * self._rewind_to_marker() - * raise - */ - /*except:*/ { - __Pyx_AddTraceback("questdb.ingress.Buffer._row", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_10, &__pyx_t_11) < 0) __PYX_ERR(0, 710, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_10); - __Pyx_GOTREF(__pyx_t_11); - - /* "questdb/ingress.pyx":711 - * self._rewind_to_marker() - * except: - * self._rewind_to_marker() # <<<<<<<<<<<<<< - * raise - * if wrote_fields: - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 711, __pyx_L5_except_error) - - /* "questdb/ingress.pyx":712 - * except: - * self._rewind_to_marker() - * raise # <<<<<<<<<<<<<< - * if wrote_fields: - * self._may_trigger_row_complete() - */ - __Pyx_GIVEREF(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_10); - __Pyx_XGIVEREF(__pyx_t_11); - __Pyx_ErrRestoreWithState(__pyx_t_7, __pyx_t_10, __pyx_t_11); - __pyx_t_7 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; - __PYX_ERR(0, 712, __pyx_L5_except_error) - } - __pyx_L5_except_error:; - - /* "questdb/ingress.pyx":693 - * cdef bint wrote_fields = False - * self._set_marker() - * try: # <<<<<<<<<<<<<< - * self._table(table_name) - * if symbols is not None: - */ - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_XGIVEREF(__pyx_t_4); - __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "questdb/ingress.pyx":713 - * self._rewind_to_marker() - * raise - * if wrote_fields: # <<<<<<<<<<<<<< - * self._may_trigger_row_complete() - * - */ - __pyx_t_5 = (__pyx_v_wrote_fields != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":714 - * raise - * if wrote_fields: - * self._may_trigger_row_complete() # <<<<<<<<<<<<<< - * - * def row( - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete(__pyx_v_self); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 714, __pyx_L1_error) - - /* "questdb/ingress.pyx":713 - * self._rewind_to_marker() - * raise - * if wrote_fields: # <<<<<<<<<<<<<< - * self._may_trigger_row_complete() - * - */ - } - - /* "questdb/ingress.pyx":682 - * 'TimestampNanos, datetime, None') - * - * cdef int _row( # <<<<<<<<<<<<<< - * self, - * str table_name, - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("questdb.ingress.Buffer._row", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_name); - __Pyx_XDECREF(__pyx_v_value); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":716 - * self._may_trigger_row_complete() - * - * def row( # <<<<<<<<<<<<<< - * self, - * table_name: str, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_15row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Buffer_14row[] = "\n Add a single row (line) to the buffer.\n\n .. code-block:: python\n\n # All fields specified.\n buffer.row(\n 'table_name',\n symbols={'sym1': 'abc', 'sym2': 'def', 'sym3': None},\n columns={\n 'col1': True,\n 'col2': 123,\n 'col3': 3.14,\n 'col4': 'xyz',\n 'col5': TimestampMicros(123456789),\n 'col6': datetime(2019, 1, 1, 12, 0, 0),\n 'col7': None},\n at=TimestampNanos(123456789))\n\n # Only symbols specified. Designated timestamp assigned by the db.\n buffer.row(\n 'table_name',\n symbols={'sym1': 'abc', 'sym2': 'def'})\n\n # Float columns and timestamp specified as `datetime.datetime`.\n # Pay special attention to the timezone, which if unspecified is\n # assumed to be the local timezone (and not UTC).\n buffer.row(\n 'sensor data',\n columns={\n 'temperature': 24.5,\n 'humidity': 0.5},\n at=datetime.datetime.utcnow())\n\n\n Python strings passed as values to ``symbols`` are going to be encoded\n as the ``SYMBOL`` type in QuestDB, whilst Python strings passed as\n values to ``columns`` are going to be encoded as the ``STRING`` type.\n\n Refer to the\n `QuestDB documentation `_ to\n understand the difference between the ``SYMBOL`` and ``STRING`` types\n (TL;DR: symbols are interned strings).\n\n Column values can be specified with Python types directly and map as so:\n\n .. list-table::\n :header-rows: 1\n\n * - Python type\n - Serialized as ILP type\n * - ``bool``\n - `BOOLEAN `_\n * - ``int``\n - `INTEGER `_\n * - ``float``\n - `FLOAT `_\n * - ``str``\n - `STRING `_\n * - ``datetime.datetime`` and ``TimestampMicros``\n - `TIMESTAMP `_\n * - ``None``\n - *Column is skipped and not serialized.*\n\n If the destination table was already created, then the columns types\n will be cast to the types of the existing columns whenever possible\n (Refer to the QuestDB documentation pages linked above).\n\n :param table_name: The name of the table to which the row belongs.\n :param symbols: A dictionary of symbol column names to ``str`` values.\n As a convenience, you can also pass a ``None`` value which will\n have the same effect as skipping the key: If the column already\n existed, it will be recorded as ``NULL``, otherwise it will not be\n created.\n :param columns: A dictionary of column names to ``bool``, ``int``,\n ``float``, ``str``, ``TimestampMicros`` or ``datetime`` values.\n As a convenience, you can also pass a ``None`` value which will\n have the same effect as skipping the key: If the column already\n existed, it will be recorded as ``NULL``, otherwise it will not be\n created.\n :param at: The timestamp of the row. If ``None``, timestamp is assigned\n by the server. If ``datetime``, the timestamp is converted to\n nanoseconds. A nanosecond unix epoch timestamp can be passed\n explicitly as a ``TimestampNanos`` object.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_15row = {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_15row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_14row}; -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_15row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_table_name = 0; - PyObject *__pyx_v_symbols = 0; - PyObject *__pyx_v_columns = 0; - PyObject *__pyx_v_at = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("row (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_table_name,&__pyx_n_s_symbols,&__pyx_n_s_columns,&__pyx_n_s_at,0}; - PyObject* values[4] = {0,0,0,0}; - - /* "questdb/ingress.pyx":720 - * table_name: str, - * *, - * symbols: Optional[Dict[str, Optional[str]]]=None, # <<<<<<<<<<<<<< - * columns: Optional[Dict[ - * str, - */ - values[1] = ((PyObject *)Py_None); - - /* "questdb/ingress.pyx":724 - * str, - * Union[None, bool, int, float, str, TimestampMicros, datetime]] - * ]=None, # <<<<<<<<<<<<<< - * at: Union[None, TimestampNanos, datetime]=None): - * """ - */ - values[2] = ((PyObject *)Py_None); - - /* "questdb/ingress.pyx":725 - * Union[None, bool, int, float, str, TimestampMicros, datetime]] - * ]=None, - * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< - * """ - * Add a single row (line) to the buffer. - */ - values[3] = ((PyObject *)Py_None); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_table_name)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (kw_args > 0 && likely(kw_args <= 3)) { - Py_ssize_t index; - for (index = 1; index < 4 && kw_args > 0; index++) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); - if (value) { values[index] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "row") < 0)) __PYX_ERR(0, 716, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - } - __pyx_v_table_name = ((PyObject*)values[0]); - __pyx_v_symbols = values[1]; - __pyx_v_columns = values[2]; - __pyx_v_at = values[3]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("row", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 716, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Buffer.row", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_table_name), (&PyUnicode_Type), 1, "table_name", 1))) __PYX_ERR(0, 718, __pyx_L1_error) - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_14row(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), __pyx_v_table_name, __pyx_v_symbols, __pyx_v_columns, __pyx_v_at); - - /* "questdb/ingress.pyx":716 - * self._may_trigger_row_complete() - * - * def row( # <<<<<<<<<<<<<< - * self, - * table_name: str, - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_14row(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - struct __pyx_opt_args_7questdb_7ingress_6Buffer__row __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("row", 0); - - /* "questdb/ingress.pyx":811 - * explicitly as a ``TimestampNanos`` object. - * """ - * self._row(table_name, symbols, columns, at) # <<<<<<<<<<<<<< - * return self - * - */ - if (!(likely(PyDict_CheckExact(__pyx_v_symbols))||((__pyx_v_symbols) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "dict", Py_TYPE(__pyx_v_symbols)->tp_name), 0))) __PYX_ERR(0, 811, __pyx_L1_error) - if (!(likely(PyDict_CheckExact(__pyx_v_columns))||((__pyx_v_columns) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "dict", Py_TYPE(__pyx_v_columns)->tp_name), 0))) __PYX_ERR(0, 811, __pyx_L1_error) - __pyx_t_2.__pyx_n = 3; - __pyx_t_2.symbols = ((PyObject*)__pyx_v_symbols); - __pyx_t_2.columns = ((PyObject*)__pyx_v_columns); - __pyx_t_2.at = __pyx_v_at; - __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Buffer *)__pyx_v_self->__pyx_vtab)->_row(__pyx_v_self, __pyx_v_table_name, &__pyx_t_2); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 811, __pyx_L1_error) - - /* "questdb/ingress.pyx":812 - * """ - * self._row(table_name, symbols, columns, at) - * return self # <<<<<<<<<<<<<< - * - * # def tabular( - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __pyx_r = ((PyObject *)__pyx_v_self); - goto __pyx_L0; - - /* "questdb/ingress.pyx":716 - * self._may_trigger_row_complete() - * - * def row( # <<<<<<<<<<<<<< - * self, - * table_name: str, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_AddTraceback("questdb.ingress.Buffer.row", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":978 - * # raise ValueError('nyi') - * - * cdef bint _pandas( # <<<<<<<<<<<<<< - * self, - * object data, - */ - -static int __pyx_f_7questdb_7ingress_6Buffer__pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, CYTHON_UNUSED int __pyx_v_sort) { - size_t __pyx_v_col_count; - Py_ssize_t __pyx_v_name_col; - struct line_sender_table_name __pyx_v_c_table_name; - __pyx_t_7questdb_7ingress_size_t_vec __pyx_v_symbol_indices; - __pyx_t_7questdb_7ingress_size_t_vec __pyx_v_field_indices; - Py_ssize_t __pyx_v_at_col; - int64_t __pyx_v_at_value; - __pyx_t_7questdb_7ingress_column_name_vec __pyx_v_symbol_names; - __pyx_t_7questdb_7ingress_column_name_vec __pyx_v_field_names; - struct __pyx_t_7questdb_7ingress_dtype_t *__pyx_v_dtypes; - size_t __pyx_v_set_buf_count; - Py_buffer *__pyx_v_col_buffers; - size_t __pyx_v_col_index; - struct qdb_pystr_pos __pyx_v_str_buf_marker; - size_t __pyx_v_row_count; - PyObject *__pyx_v_sys = NULL; - size_t __pyx_v_row_index; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - Py_ssize_t __pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - Py_UCS4 __pyx_t_8; - PyObject *__pyx_t_9 = NULL; - PyObject *__pyx_t_10 = NULL; - PyObject *__pyx_t_11 = NULL; - size_t __pyx_t_12; - size_t __pyx_t_13; - size_t __pyx_t_14; - PyObject *__pyx_t_15 = NULL; - PyObject *__pyx_t_16 = NULL; - PyObject *__pyx_t_17 = NULL; - int __pyx_t_18; - char const *__pyx_t_19; - PyObject *__pyx_t_20 = NULL; - PyObject *__pyx_t_21 = NULL; - PyObject *__pyx_t_22 = NULL; - int __pyx_t_23; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("_pandas", 0); - - /* "questdb/ingress.pyx":994 - * cdef ssize_t name_col - * cdef line_sender_table_name c_table_name - * cdef size_t_vec symbol_indices = size_t_vec_new() # <<<<<<<<<<<<<< - * cdef size_t_vec field_indices = size_t_vec_new() - * cdef ssize_t at_col - */ - __pyx_v_symbol_indices = __pyx_f_7questdb_7ingress_size_t_vec_new(); - - /* "questdb/ingress.pyx":995 - * cdef line_sender_table_name c_table_name - * cdef size_t_vec symbol_indices = size_t_vec_new() - * cdef size_t_vec field_indices = size_t_vec_new() # <<<<<<<<<<<<<< - * cdef ssize_t at_col - * cdef int64_t at_value = 0 - */ - __pyx_v_field_indices = __pyx_f_7questdb_7ingress_size_t_vec_new(); - - /* "questdb/ingress.pyx":997 - * cdef size_t_vec field_indices = size_t_vec_new() - * cdef ssize_t at_col - * cdef int64_t at_value = 0 # <<<<<<<<<<<<<< - * cdef column_name_vec symbol_names = column_name_vec_new() - * cdef column_name_vec field_names = column_name_vec_new() - */ - __pyx_v_at_value = 0; - - /* "questdb/ingress.pyx":998 - * cdef ssize_t at_col - * cdef int64_t at_value = 0 - * cdef column_name_vec symbol_names = column_name_vec_new() # <<<<<<<<<<<<<< - * cdef column_name_vec field_names = column_name_vec_new() - * cdef dtype_t* dtypes = NULL - */ - __pyx_v_symbol_names = __pyx_f_7questdb_7ingress_column_name_vec_new(); - - /* "questdb/ingress.pyx":999 - * cdef int64_t at_value = 0 - * cdef column_name_vec symbol_names = column_name_vec_new() - * cdef column_name_vec field_names = column_name_vec_new() # <<<<<<<<<<<<<< - * cdef dtype_t* dtypes = NULL - * cdef size_t set_buf_count = 0 - */ - __pyx_v_field_names = __pyx_f_7questdb_7ingress_column_name_vec_new(); - - /* "questdb/ingress.pyx":1000 - * cdef column_name_vec symbol_names = column_name_vec_new() - * cdef column_name_vec field_names = column_name_vec_new() - * cdef dtype_t* dtypes = NULL # <<<<<<<<<<<<<< - * cdef size_t set_buf_count = 0 - * cdef Py_buffer* col_buffers = NULL - */ - __pyx_v_dtypes = NULL; - - /* "questdb/ingress.pyx":1001 - * cdef column_name_vec field_names = column_name_vec_new() - * cdef dtype_t* dtypes = NULL - * cdef size_t set_buf_count = 0 # <<<<<<<<<<<<<< - * cdef Py_buffer* col_buffers = NULL - * cdef size_t col_index - */ - __pyx_v_set_buf_count = 0; - - /* "questdb/ingress.pyx":1002 - * cdef dtype_t* dtypes = NULL - * cdef size_t set_buf_count = 0 - * cdef Py_buffer* col_buffers = NULL # <<<<<<<<<<<<<< - * cdef size_t col_index - * cdef qdb_pystr_pos str_buf_marker - */ - __pyx_v_col_buffers = NULL; - - /* "questdb/ingress.pyx":1007 - * cdef size_t row_count - * cdef Py_buffer* cur_col - * _pandas_may_set_na_type() # <<<<<<<<<<<<<< - * try: - * _check_is_pandas_dataframe(data) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress__pandas_may_set_na_type(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1007, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1008 - * cdef Py_buffer* cur_col - * _pandas_may_set_na_type() - * try: # <<<<<<<<<<<<<< - * _check_is_pandas_dataframe(data) - * col_count = len(data.columns) - */ - /*try:*/ { - - /* "questdb/ingress.pyx":1009 - * _pandas_may_set_na_type() - * try: - * _check_is_pandas_dataframe(data) # <<<<<<<<<<<<<< - * col_count = len(data.columns) - * qdb_pystr_buf_clear(self._b) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress__check_is_pandas_dataframe(__pyx_v_data); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1009, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1010 - * try: - * _check_is_pandas_dataframe(data) - * col_count = len(data.columns) # <<<<<<<<<<<<<< - * qdb_pystr_buf_clear(self._b) - * name_col = _pandas_resolve_table_name( - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1010, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1010, __pyx_L4_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_v_col_count = __pyx_t_2; - - /* "questdb/ingress.pyx":1011 - * _check_is_pandas_dataframe(data) - * col_count = len(data.columns) - * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< - * name_col = _pandas_resolve_table_name( - * self._b, - */ - qdb_pystr_buf_clear(__pyx_v_self->_b); - - /* "questdb/ingress.pyx":1012 - * col_count = len(data.columns) - * qdb_pystr_buf_clear(self._b) - * name_col = _pandas_resolve_table_name( # <<<<<<<<<<<<<< - * self._b, - * data, table_name, table_name_col, col_count, &c_table_name) - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress__pandas_resolve_table_name(__pyx_v_self->_b, __pyx_v_data, __pyx_v_table_name, __pyx_v_table_name_col, __pyx_v_col_count, (&__pyx_v_c_table_name)); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-2L))) __PYX_ERR(0, 1012, __pyx_L4_error) - __pyx_v_name_col = __pyx_t_3; - - /* "questdb/ingress.pyx":1015 - * self._b, - * data, table_name, table_name_col, col_count, &c_table_name) - * at_col = _pandas_resolve_at(data, at, col_count, &at_value) # <<<<<<<<<<<<<< - * _pandas_resolve_symbols( - * data, name_col, at_col, symbols, col_count, &symbol_indices) - */ - __pyx_t_3 = __pyx_f_7questdb_7ingress__pandas_resolve_at(__pyx_v_data, __pyx_v_at, __pyx_v_col_count, (&__pyx_v_at_value)); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-2L))) __PYX_ERR(0, 1015, __pyx_L4_error) - __pyx_v_at_col = __pyx_t_3; - - /* "questdb/ingress.pyx":1016 - * data, table_name, table_name_col, col_count, &c_table_name) - * at_col = _pandas_resolve_at(data, at, col_count, &at_value) - * _pandas_resolve_symbols( # <<<<<<<<<<<<<< - * data, name_col, at_col, symbols, col_count, &symbol_indices) - * _pandas_resolve_fields( - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress__pandas_resolve_symbols(__pyx_v_data, __pyx_v_name_col, __pyx_v_at_col, __pyx_v_symbols, __pyx_v_col_count, (&__pyx_v_symbol_indices)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1016, __pyx_L4_error) - - /* "questdb/ingress.pyx":1018 - * _pandas_resolve_symbols( - * data, name_col, at_col, symbols, col_count, &symbol_indices) - * _pandas_resolve_fields( # <<<<<<<<<<<<<< - * name_col, &symbol_indices, at_col, col_count, &field_indices) - * _pandas_resolve_col_names( - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress__pandas_resolve_fields(__pyx_v_name_col, (&__pyx_v_symbol_indices), __pyx_v_at_col, __pyx_v_col_count, (&__pyx_v_field_indices)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1018, __pyx_L4_error) - - /* "questdb/ingress.pyx":1020 - * _pandas_resolve_fields( - * name_col, &symbol_indices, at_col, col_count, &field_indices) - * _pandas_resolve_col_names( # <<<<<<<<<<<<<< - * self._b, - * data, &symbol_indices, &field_indices, - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_resolve_col_names(__pyx_v_self->_b, __pyx_v_data, (&__pyx_v_symbol_indices), (&__pyx_v_field_indices), (&__pyx_v_symbol_names), (&__pyx_v_field_names)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1020, __pyx_L4_error) - - /* "questdb/ingress.pyx":1024 - * data, &symbol_indices, &field_indices, - * &symbol_names, &field_names) - * dtypes = calloc(col_count, sizeof(dtype_t)) # <<<<<<<<<<<<<< - * _pandas_resolve_dtypes(data, col_count, dtypes) - * col_buffers = calloc(col_count, sizeof(Py_buffer)) - */ - __pyx_v_dtypes = ((struct __pyx_t_7questdb_7ingress_dtype_t *)calloc(__pyx_v_col_count, (sizeof(struct __pyx_t_7questdb_7ingress_dtype_t)))); - - /* "questdb/ingress.pyx":1025 - * &symbol_names, &field_names) - * dtypes = calloc(col_count, sizeof(dtype_t)) - * _pandas_resolve_dtypes(data, col_count, dtypes) # <<<<<<<<<<<<<< - * col_buffers = calloc(col_count, sizeof(Py_buffer)) - * _pandas_resolve_col_buffers( - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_resolve_dtypes(__pyx_v_data, __pyx_v_col_count, __pyx_v_dtypes); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1025, __pyx_L4_error) - - /* "questdb/ingress.pyx":1026 - * dtypes = calloc(col_count, sizeof(dtype_t)) - * _pandas_resolve_dtypes(data, col_count, dtypes) - * col_buffers = calloc(col_count, sizeof(Py_buffer)) # <<<<<<<<<<<<<< - * _pandas_resolve_col_buffers( - * data, col_count, dtypes, col_buffers, &set_buf_count) - */ - __pyx_v_col_buffers = ((Py_buffer *)calloc(__pyx_v_col_count, (sizeof(Py_buffer)))); - - /* "questdb/ingress.pyx":1027 - * _pandas_resolve_dtypes(data, col_count, dtypes) - * col_buffers = calloc(col_count, sizeof(Py_buffer)) - * _pandas_resolve_col_buffers( # <<<<<<<<<<<<<< - * data, col_count, dtypes, col_buffers, &set_buf_count) - * - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_resolve_col_buffers(__pyx_v_data, __pyx_v_col_count, __pyx_v_dtypes, __pyx_v_col_buffers, (&__pyx_v_set_buf_count)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1027, __pyx_L4_error) - - /* "questdb/ingress.pyx":1033 - * # Instead of clearing it (which would clear the headers' memory) - * # we will truncate (rewind) back to this position. - * str_buf_marker = qdb_pystr_buf_tell(self._b) # <<<<<<<<<<<<<< - * - * import sys - */ - __pyx_v_str_buf_marker = qdb_pystr_buf_tell(__pyx_v_self->_b); - - /* "questdb/ingress.pyx":1035 - * str_buf_marker = qdb_pystr_buf_tell(self._b) - * - * import sys # <<<<<<<<<<<<<< - * sys.stderr.write('_pandas :: (A) ' + - * f'name_col: {name_col}, ' + - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1035, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_sys = __pyx_t_1; - __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1036 - * - * import sys - * sys.stderr.write('_pandas :: (A) ' + # <<<<<<<<<<<<<< - * f'name_col: {name_col}, ' + - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_sys, __pyx_n_s_stderr); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1036, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_write); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1036, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1037 - * import sys - * sys.stderr.write('_pandas :: (A) ' + - * f'name_col: {name_col}, ' + # <<<<<<<<<<<<<< - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - * f'at_col: {at_col}, ' + - */ - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1037, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = 0; - __pyx_t_8 = 127; - __Pyx_INCREF(__pyx_kp_u_name_col); - __pyx_t_2 += 10; - __Pyx_GIVEREF(__pyx_kp_u_name_col); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_name_col); - __pyx_t_9 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_name_col, 0, ' ', 'd'); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1037, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_9); - __Pyx_GIVEREF(__pyx_t_9); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_9); - __pyx_t_9 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_2 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); - __pyx_t_9 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1037, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1036 - * - * import sys - * sys.stderr.write('_pandas :: (A) ' + # <<<<<<<<<<<<<< - * f'name_col: {name_col}, ' + - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - */ - __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_pandas_A, __pyx_t_9); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1036, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "questdb/ingress.pyx":1038 - * sys.stderr.write('_pandas :: (A) ' + - * f'name_col: {name_col}, ' + - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + # <<<<<<<<<<<<<< - * f'at_col: {at_col}, ' + - * f'at_value: {at_value}, ' + - */ - __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1038, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_2 = 0; - __pyx_t_8 = 127; - __Pyx_INCREF(__pyx_kp_u_symbol_indices); - __pyx_t_2 += 16; - __Pyx_GIVEREF(__pyx_kp_u_symbol_indices); - PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_symbol_indices); - __pyx_t_10 = __pyx_f_7questdb_7ingress_size_t_vec_str((&__pyx_v_symbol_indices)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1038, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_10); - __pyx_t_11 = __Pyx_PyUnicode_Unicode(__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1038, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) : __pyx_t_8; - __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_11); - __Pyx_GIVEREF(__pyx_t_11); - PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_11); - __pyx_t_11 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_2 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u__24); - __pyx_t_11 = __Pyx_PyUnicode_Join(__pyx_t_9, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1038, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "questdb/ingress.pyx":1037 - * import sys - * sys.stderr.write('_pandas :: (A) ' + - * f'name_col: {name_col}, ' + # <<<<<<<<<<<<<< - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - * f'at_col: {at_col}, ' + - */ - __pyx_t_9 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_11); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1037, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_9); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - - /* "questdb/ingress.pyx":1039 - * f'name_col: {name_col}, ' + - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - * f'at_col: {at_col}, ' + # <<<<<<<<<<<<<< - * f'at_value: {at_value}, ' + - * f'field_indices: {size_t_vec_str(&field_indices)}' + - */ - __pyx_t_11 = PyTuple_New(3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1039, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_11); - __pyx_t_2 = 0; - __pyx_t_8 = 127; - __Pyx_INCREF(__pyx_kp_u_at_col); - __pyx_t_2 += 8; - __Pyx_GIVEREF(__pyx_kp_u_at_col); - PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_kp_u_at_col); - __pyx_t_6 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_at_col, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1039, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_2 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_kp_u__24); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_11, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1039, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - - /* "questdb/ingress.pyx":1038 - * sys.stderr.write('_pandas :: (A) ' + - * f'name_col: {name_col}, ' + - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + # <<<<<<<<<<<<<< - * f'at_col: {at_col}, ' + - * f'at_value: {at_value}, ' + - */ - __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_t_9, __pyx_t_6); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1038, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1040 - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - * f'at_col: {at_col}, ' + - * f'at_value: {at_value}, ' + # <<<<<<<<<<<<<< - * f'field_indices: {size_t_vec_str(&field_indices)}' + - * '\n') - */ - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1040, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = 0; - __pyx_t_8 = 127; - __Pyx_INCREF(__pyx_kp_u_at_value); - __pyx_t_2 += 10; - __Pyx_GIVEREF(__pyx_kp_u_at_value); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_at_value); - __pyx_t_9 = __Pyx_PyInt_From_int64_t(__pyx_v_at_value); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1040, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_9); - __pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_t_9, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1040, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; - __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) : __pyx_t_8; - __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_10); - __Pyx_GIVEREF(__pyx_t_10); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_10); - __pyx_t_10 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_2 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); - __pyx_t_10 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_2, __pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1040, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1039 - * f'name_col: {name_col}, ' + - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - * f'at_col: {at_col}, ' + # <<<<<<<<<<<<<< - * f'at_value: {at_value}, ' + - * f'field_indices: {size_t_vec_str(&field_indices)}' + - */ - __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_11, __pyx_t_10); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1039, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "questdb/ingress.pyx":1041 - * f'at_col: {at_col}, ' + - * f'at_value: {at_value}, ' + - * f'field_indices: {size_t_vec_str(&field_indices)}' + # <<<<<<<<<<<<<< - * '\n') - * row_count = len(data) - */ - __pyx_t_10 = __pyx_f_7questdb_7ingress_size_t_vec_str((&__pyx_v_field_indices)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1041, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_10); - __pyx_t_11 = __Pyx_PyUnicode_Unicode(__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1041, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_kp_u_field_indices, __pyx_t_11); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1041, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - - /* "questdb/ingress.pyx":1040 - * f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - * f'at_col: {at_col}, ' + - * f'at_value: {at_value}, ' + # <<<<<<<<<<<<<< - * f'field_indices: {size_t_vec_str(&field_indices)}' + - * '\n') - */ - __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1040, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_11); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "questdb/ingress.pyx":1041 - * f'at_col: {at_col}, ' + - * f'at_value: {at_value}, ' + - * f'field_indices: {size_t_vec_str(&field_indices)}' + # <<<<<<<<<<<<<< - * '\n') - * row_count = len(data) - */ - __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_t_11, __pyx_kp_u__27); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1041, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; - __pyx_t_11 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_11)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_11); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_1 = (__pyx_t_11) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_11, __pyx_t_10) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1036, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1043 - * f'field_indices: {size_t_vec_str(&field_indices)}' + - * '\n') - * row_count = len(data) # <<<<<<<<<<<<<< - * self._clear_marker() - * for row_index in range(row_count): - */ - __pyx_t_2 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1043, __pyx_L4_error) - __pyx_v_row_count = __pyx_t_2; - - /* "questdb/ingress.pyx":1044 - * '\n') - * row_count = len(data) - * self._clear_marker() # <<<<<<<<<<<<<< - * for row_index in range(row_count): - * qdb_pystr_buf_truncate(self._b, str_buf_marker) - */ - __pyx_t_1 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1044, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1045 - * row_count = len(data) - * self._clear_marker() - * for row_index in range(row_count): # <<<<<<<<<<<<<< - * qdb_pystr_buf_truncate(self._b, str_buf_marker) - * try: - */ - __pyx_t_12 = __pyx_v_row_count; - __pyx_t_13 = __pyx_t_12; - for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { - __pyx_v_row_index = __pyx_t_14; - - /* "questdb/ingress.pyx":1046 - * self._clear_marker() - * for row_index in range(row_count): - * qdb_pystr_buf_truncate(self._b, str_buf_marker) # <<<<<<<<<<<<<< - * try: - * self._set_marker() - */ - qdb_pystr_buf_truncate(__pyx_v_self->_b, __pyx_v_str_buf_marker); - - /* "questdb/ingress.pyx":1047 - * for row_index in range(row_count): - * qdb_pystr_buf_truncate(self._b, str_buf_marker) - * try: # <<<<<<<<<<<<<< - * self._set_marker() - * _pandas_row_table_name( - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_15, &__pyx_t_16, &__pyx_t_17); - __Pyx_XGOTREF(__pyx_t_15); - __Pyx_XGOTREF(__pyx_t_16); - __Pyx_XGOTREF(__pyx_t_17); - /*try:*/ { - - /* "questdb/ingress.pyx":1048 - * qdb_pystr_buf_truncate(self._b, str_buf_marker) - * try: - * self._set_marker() # <<<<<<<<<<<<<< - * _pandas_row_table_name( - * self._impl, - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_6Buffer__set_marker(__pyx_v_self); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1048, __pyx_L8_error) - - /* "questdb/ingress.pyx":1049 - * try: - * self._set_marker() - * _pandas_row_table_name( # <<<<<<<<<<<<<< - * self._impl, - * self._b, - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_row_table_name(__pyx_v_self->_impl, __pyx_v_self->_b, __pyx_v_dtypes, __pyx_v_col_buffers, __pyx_v_name_col, __pyx_v_row_index, __pyx_v_c_table_name); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1049, __pyx_L8_error) - - /* "questdb/ingress.pyx":1057 - * row_index, - * c_table_name) - * _pandas_row_symbols( # <<<<<<<<<<<<<< - * self._impl, - * self._b, - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_row_symbols(__pyx_v_self->_impl, __pyx_v_self->_b, __pyx_v_dtypes, __pyx_v_col_buffers, __pyx_v_row_index, (&__pyx_v_symbol_names), (&__pyx_v_symbol_indices)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1057, __pyx_L8_error) - - /* "questdb/ingress.pyx":1066 - * &symbol_indices) - * # _pandas_row_fields(...) # TODO [amunra]: implement - * _pandas_row_at( # <<<<<<<<<<<<<< - * self._impl, - * dtypes, - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress__pandas_row_at(__pyx_v_self->_impl, __pyx_v_dtypes, __pyx_v_col_buffers, __pyx_v_row_index, __pyx_v_at_col, __pyx_v_at_value); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1066, __pyx_L8_error) - - /* "questdb/ingress.pyx":1047 - * for row_index in range(row_count): - * qdb_pystr_buf_truncate(self._b, str_buf_marker) - * try: # <<<<<<<<<<<<<< - * self._set_marker() - * _pandas_row_table_name( - */ - } - __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; - __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; - __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; - goto __pyx_L15_try_end; - __pyx_L8_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - - /* "questdb/ingress.pyx":1073 - * at_col, - * at_value) - * except: # <<<<<<<<<<<<<< - * self._rewind_to_marker() - * raise - */ - /*except:*/ { - __Pyx_AddTraceback("questdb.ingress.Buffer._pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_7, &__pyx_t_10) < 0) __PYX_ERR(0, 1073, __pyx_L10_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GOTREF(__pyx_t_10); - - /* "questdb/ingress.pyx":1074 - * at_value) - * except: - * self._rewind_to_marker() # <<<<<<<<<<<<<< - * raise - * return True - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker(__pyx_v_self); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1074, __pyx_L10_except_error) - - /* "questdb/ingress.pyx":1075 - * except: - * self._rewind_to_marker() - * raise # <<<<<<<<<<<<<< - * return True - * finally: - */ - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_7); - __Pyx_XGIVEREF(__pyx_t_10); - __Pyx_ErrRestoreWithState(__pyx_t_1, __pyx_t_7, __pyx_t_10); - __pyx_t_1 = 0; __pyx_t_7 = 0; __pyx_t_10 = 0; - __PYX_ERR(0, 1075, __pyx_L10_except_error) - } - __pyx_L10_except_error:; - - /* "questdb/ingress.pyx":1047 - * for row_index in range(row_count): - * qdb_pystr_buf_truncate(self._b, str_buf_marker) - * try: # <<<<<<<<<<<<<< - * self._set_marker() - * _pandas_row_table_name( - */ - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_XGIVEREF(__pyx_t_16); - __Pyx_XGIVEREF(__pyx_t_17); - __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_16, __pyx_t_17); - goto __pyx_L4_error; - __pyx_L15_try_end:; - } - } - - /* "questdb/ingress.pyx":1076 - * self._rewind_to_marker() - * raise - * return True # <<<<<<<<<<<<<< - * finally: - * self._clear_marker() - */ - __pyx_r = 1; - goto __pyx_L3_return; - } - - /* "questdb/ingress.pyx":1078 - * return True - * finally: - * self._clear_marker() # <<<<<<<<<<<<<< - * if col_buffers != NULL: - * for col_index in range(set_buf_count): - */ - /*finally:*/ { - __pyx_L4_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_17 = 0; __pyx_t_16 = 0; __pyx_t_15 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; - __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_20, &__pyx_t_21, &__pyx_t_22); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_17, &__pyx_t_16, &__pyx_t_15) < 0)) __Pyx_ErrFetch(&__pyx_t_17, &__pyx_t_16, &__pyx_t_15); - __Pyx_XGOTREF(__pyx_t_17); - __Pyx_XGOTREF(__pyx_t_16); - __Pyx_XGOTREF(__pyx_t_15); - __Pyx_XGOTREF(__pyx_t_20); - __Pyx_XGOTREF(__pyx_t_21); - __Pyx_XGOTREF(__pyx_t_22); - __pyx_t_4 = __pyx_lineno; __pyx_t_18 = __pyx_clineno; __pyx_t_19 = __pyx_filename; - { - __pyx_t_10 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1078, __pyx_L19_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "questdb/ingress.pyx":1079 - * finally: - * self._clear_marker() - * if col_buffers != NULL: # <<<<<<<<<<<<<< - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) - */ - __pyx_t_5 = ((__pyx_v_col_buffers != NULL) != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":1080 - * self._clear_marker() - * if col_buffers != NULL: - * for col_index in range(set_buf_count): # <<<<<<<<<<<<<< - * PyBuffer_Release(&col_buffers[col_index]) - * free(col_buffers) - */ - __pyx_t_12 = __pyx_v_set_buf_count; - __pyx_t_13 = __pyx_t_12; - for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { - __pyx_v_col_index = __pyx_t_14; - - /* "questdb/ingress.pyx":1081 - * if col_buffers != NULL: - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) # <<<<<<<<<<<<<< - * free(col_buffers) - * free(dtypes) - */ - PyBuffer_Release((&(__pyx_v_col_buffers[__pyx_v_col_index]))); - } - - /* "questdb/ingress.pyx":1082 - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) - * free(col_buffers) # <<<<<<<<<<<<<< - * free(dtypes) - * column_name_vec_free(&field_names) - */ - free(__pyx_v_col_buffers); - - /* "questdb/ingress.pyx":1079 - * finally: - * self._clear_marker() - * if col_buffers != NULL: # <<<<<<<<<<<<<< - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) - */ - } - - /* "questdb/ingress.pyx":1083 - * PyBuffer_Release(&col_buffers[col_index]) - * free(col_buffers) - * free(dtypes) # <<<<<<<<<<<<<< - * column_name_vec_free(&field_names) - * column_name_vec_free(&symbol_names) - */ - free(__pyx_v_dtypes); - - /* "questdb/ingress.pyx":1084 - * free(col_buffers) - * free(dtypes) - * column_name_vec_free(&field_names) # <<<<<<<<<<<<<< - * column_name_vec_free(&symbol_names) - * size_t_vec_free(&field_indices) - */ - __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_field_names)); - - /* "questdb/ingress.pyx":1085 - * free(dtypes) - * column_name_vec_free(&field_names) - * column_name_vec_free(&symbol_names) # <<<<<<<<<<<<<< - * size_t_vec_free(&field_indices) - * size_t_vec_free(&symbol_indices) - */ - __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_symbol_names)); - - /* "questdb/ingress.pyx":1086 - * column_name_vec_free(&field_names) - * column_name_vec_free(&symbol_names) - * size_t_vec_free(&field_indices) # <<<<<<<<<<<<<< - * size_t_vec_free(&symbol_indices) - * qdb_pystr_buf_clear(self._b) - */ - __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_field_indices)); - - /* "questdb/ingress.pyx":1087 - * column_name_vec_free(&symbol_names) - * size_t_vec_free(&field_indices) - * size_t_vec_free(&symbol_indices) # <<<<<<<<<<<<<< - * qdb_pystr_buf_clear(self._b) - * - */ - __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_symbol_indices)); - - /* "questdb/ingress.pyx":1088 - * size_t_vec_free(&field_indices) - * size_t_vec_free(&symbol_indices) - * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< - * - * def pandas( - */ - qdb_pystr_buf_clear(__pyx_v_self->_b); - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_20); - __Pyx_XGIVEREF(__pyx_t_21); - __Pyx_XGIVEREF(__pyx_t_22); - __Pyx_ExceptionReset(__pyx_t_20, __pyx_t_21, __pyx_t_22); - } - __Pyx_XGIVEREF(__pyx_t_17); - __Pyx_XGIVEREF(__pyx_t_16); - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_ErrRestore(__pyx_t_17, __pyx_t_16, __pyx_t_15); - __pyx_t_17 = 0; __pyx_t_16 = 0; __pyx_t_15 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; - __pyx_lineno = __pyx_t_4; __pyx_clineno = __pyx_t_18; __pyx_filename = __pyx_t_19; - goto __pyx_L1_error; - __pyx_L19_error:; - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_20); - __Pyx_XGIVEREF(__pyx_t_21); - __Pyx_XGIVEREF(__pyx_t_22); - __Pyx_ExceptionReset(__pyx_t_20, __pyx_t_21, __pyx_t_22); - } - __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; - __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; - __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; - __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; - goto __pyx_L1_error; - } - __pyx_L3_return: { - __pyx_t_5 = __pyx_r; - - /* "questdb/ingress.pyx":1078 - * return True - * finally: - * self._clear_marker() # <<<<<<<<<<<<<< - * if col_buffers != NULL: - * for col_index in range(set_buf_count): - */ - __pyx_t_10 = __pyx_f_7questdb_7ingress_6Buffer__clear_marker(__pyx_v_self); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1078, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_10); - __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; - - /* "questdb/ingress.pyx":1079 - * finally: - * self._clear_marker() - * if col_buffers != NULL: # <<<<<<<<<<<<<< - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) - */ - __pyx_t_23 = ((__pyx_v_col_buffers != NULL) != 0); - if (__pyx_t_23) { - - /* "questdb/ingress.pyx":1080 - * self._clear_marker() - * if col_buffers != NULL: - * for col_index in range(set_buf_count): # <<<<<<<<<<<<<< - * PyBuffer_Release(&col_buffers[col_index]) - * free(col_buffers) - */ - __pyx_t_12 = __pyx_v_set_buf_count; - __pyx_t_13 = __pyx_t_12; - for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) { - __pyx_v_col_index = __pyx_t_14; - - /* "questdb/ingress.pyx":1081 - * if col_buffers != NULL: - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) # <<<<<<<<<<<<<< - * free(col_buffers) - * free(dtypes) - */ - PyBuffer_Release((&(__pyx_v_col_buffers[__pyx_v_col_index]))); - } - - /* "questdb/ingress.pyx":1082 - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) - * free(col_buffers) # <<<<<<<<<<<<<< - * free(dtypes) - * column_name_vec_free(&field_names) - */ - free(__pyx_v_col_buffers); - - /* "questdb/ingress.pyx":1079 - * finally: - * self._clear_marker() - * if col_buffers != NULL: # <<<<<<<<<<<<<< - * for col_index in range(set_buf_count): - * PyBuffer_Release(&col_buffers[col_index]) - */ - } - - /* "questdb/ingress.pyx":1083 - * PyBuffer_Release(&col_buffers[col_index]) - * free(col_buffers) - * free(dtypes) # <<<<<<<<<<<<<< - * column_name_vec_free(&field_names) - * column_name_vec_free(&symbol_names) - */ - free(__pyx_v_dtypes); - - /* "questdb/ingress.pyx":1084 - * free(col_buffers) - * free(dtypes) - * column_name_vec_free(&field_names) # <<<<<<<<<<<<<< - * column_name_vec_free(&symbol_names) - * size_t_vec_free(&field_indices) - */ - __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_field_names)); - - /* "questdb/ingress.pyx":1085 - * free(dtypes) - * column_name_vec_free(&field_names) - * column_name_vec_free(&symbol_names) # <<<<<<<<<<<<<< - * size_t_vec_free(&field_indices) - * size_t_vec_free(&symbol_indices) - */ - __pyx_f_7questdb_7ingress_column_name_vec_free((&__pyx_v_symbol_names)); - - /* "questdb/ingress.pyx":1086 - * column_name_vec_free(&field_names) - * column_name_vec_free(&symbol_names) - * size_t_vec_free(&field_indices) # <<<<<<<<<<<<<< - * size_t_vec_free(&symbol_indices) - * qdb_pystr_buf_clear(self._b) - */ - __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_field_indices)); - - /* "questdb/ingress.pyx":1087 - * column_name_vec_free(&symbol_names) - * size_t_vec_free(&field_indices) - * size_t_vec_free(&symbol_indices) # <<<<<<<<<<<<<< - * qdb_pystr_buf_clear(self._b) - * - */ - __pyx_f_7questdb_7ingress_size_t_vec_free((&__pyx_v_symbol_indices)); - - /* "questdb/ingress.pyx":1088 - * size_t_vec_free(&field_indices) - * size_t_vec_free(&symbol_indices) - * qdb_pystr_buf_clear(self._b) # <<<<<<<<<<<<<< - * - * def pandas( - */ - qdb_pystr_buf_clear(__pyx_v_self->_b); - __pyx_r = __pyx_t_5; - goto __pyx_L0; - } - } - - /* "questdb/ingress.pyx":978 - * # raise ValueError('nyi') - * - * cdef bint _pandas( # <<<<<<<<<<<<<< - * self, - * object data, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_9); - __Pyx_XDECREF(__pyx_t_10); - __Pyx_XDECREF(__pyx_t_11); - __Pyx_AddTraceback("questdb.ingress.Buffer._pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_sys); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1090 - * qdb_pystr_buf_clear(self._b) - * - * def pandas( # <<<<<<<<<<<<<< - * self, - * data, # : pd.DataFrame - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_17pandas(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Buffer_16pandas[] = "\n Add a pandas DataFrame to the buffer.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_17pandas = {"pandas", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_17pandas, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_16pandas}; -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_17pandas(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_data = 0; - PyObject *__pyx_v_table_name = 0; - PyObject *__pyx_v_table_name_col = 0; - PyObject *__pyx_v_symbols = 0; - PyObject *__pyx_v_at = 0; - PyBoolObject *__pyx_v_sort = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("pandas (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_table_name,&__pyx_n_s_table_name_col,&__pyx_n_s_symbols,&__pyx_n_s_at,&__pyx_n_s_sort,0}; - PyObject* values[6] = {0,0,0,0,0,0}; - - /* "questdb/ingress.pyx":1094 - * data, # : pd.DataFrame - * *, - * table_name: Optional[str] = None, # <<<<<<<<<<<<<< - * table_name_col: Union[None, int, str] = None, - * symbols: Union[bool, List[int], List[str]] = False, - */ - values[1] = ((PyObject *)Py_None); - - /* "questdb/ingress.pyx":1095 - * *, - * table_name: Optional[str] = None, - * table_name_col: Union[None, int, str] = None, # <<<<<<<<<<<<<< - * symbols: Union[bool, List[int], List[str]] = False, - * at: Union[None, int, str, TimestampNanos, datetime] = None, - */ - values[2] = ((PyObject *)Py_None); - - /* "questdb/ingress.pyx":1096 - * table_name: Optional[str] = None, - * table_name_col: Union[None, int, str] = None, - * symbols: Union[bool, List[int], List[str]] = False, # <<<<<<<<<<<<<< - * at: Union[None, int, str, TimestampNanos, datetime] = None, - * sort: bool = True): - */ - values[3] = ((PyObject *)Py_False); - - /* "questdb/ingress.pyx":1097 - * table_name_col: Union[None, int, str] = None, - * symbols: Union[bool, List[int], List[str]] = False, - * at: Union[None, int, str, TimestampNanos, datetime] = None, # <<<<<<<<<<<<<< - * sort: bool = True): - * """ - */ - values[4] = ((PyObject *)Py_None); - - /* "questdb/ingress.pyx":1098 - * symbols: Union[bool, List[int], List[str]] = False, - * at: Union[None, int, str, TimestampNanos, datetime] = None, - * sort: bool = True): # <<<<<<<<<<<<<< - * """ - * Add a pandas DataFrame to the buffer. - */ - values[5] = (PyObject *)((PyBoolObject *)Py_True); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (kw_args > 0 && likely(kw_args <= 5)) { - Py_ssize_t index; - for (index = 1; index < 6 && kw_args > 0; index++) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); - if (value) { values[index] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "pandas") < 0)) __PYX_ERR(0, 1090, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - } - __pyx_v_data = values[0]; - __pyx_v_table_name = values[1]; - __pyx_v_table_name_col = values[2]; - __pyx_v_symbols = values[3]; - __pyx_v_at = values[4]; - __pyx_v_sort = ((PyBoolObject *)values[5]); - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("pandas", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1090, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Buffer.pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sort), __pyx_ptype_7cpython_4bool_bool, 1, "sort", 0))) __PYX_ERR(0, 1098, __pyx_L1_error) - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_16pandas(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), __pyx_v_data, __pyx_v_table_name, __pyx_v_table_name_col, __pyx_v_symbols, __pyx_v_at, __pyx_v_sort); - - /* "questdb/ingress.pyx":1090 - * qdb_pystr_buf_clear(self._b) - * - * def pandas( # <<<<<<<<<<<<<< - * self, - * data, # : pd.DataFrame - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_16pandas(struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_table_name, PyObject *__pyx_v_table_name_col, PyObject *__pyx_v_symbols, PyObject *__pyx_v_at, PyBoolObject *__pyx_v_sort) { - PyObject *__pyx_v_sys = NULL; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - Py_ssize_t __pyx_t_4; - Py_UCS4 __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("pandas", 0); - - /* "questdb/ingress.pyx":1104 - * # See https://cython.readthedocs.io/en/latest/src/userguide/ - * # numpy_tutorial.html#numpy-tutorial - * import sys # <<<<<<<<<<<<<< - * sys.stderr.write('pandas :: (A) ' + - * f'table_name: {table_name}, ' + - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1104, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_v_sys = __pyx_t_1; - __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1105 - * # numpy_tutorial.html#numpy-tutorial - * import sys - * sys.stderr.write('pandas :: (A) ' + # <<<<<<<<<<<<<< - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_sys, __pyx_n_s_stderr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1105, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_write); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1105, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1106 - * import sys - * sys.stderr.write('pandas :: (A) ' + - * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - */ - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_table_name_2); - __pyx_t_4 += 12; - __Pyx_GIVEREF(__pyx_kp_u_table_name_2); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_table_name_2); - __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__24); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1105 - * # numpy_tutorial.html#numpy-tutorial - * import sys - * sys.stderr.write('pandas :: (A) ' + # <<<<<<<<<<<<<< - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - */ - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_pandas_A_2, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1105, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1107 - * sys.stderr.write('pandas :: (A) ' + - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - */ - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1107, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_table_name_col_2); - __pyx_t_4 += 16; - __Pyx_GIVEREF(__pyx_kp_u_table_name_col_2); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_table_name_col_2); - __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1107, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_7); - __pyx_t_7 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); - __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1107, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1106 - * import sys - * sys.stderr.write('pandas :: (A) ' + - * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - */ - __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1106, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":1108 - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< - * f'at: {at}, ' + - * f'sort: {sort}' + - */ - __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_symbols_2); - __pyx_t_4 += 9; - __Pyx_GIVEREF(__pyx_kp_u_symbols_2); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_kp_u_symbols_2); - __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_symbols, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_2); - __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_kp_u__24); - __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_7, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":1107 - * sys.stderr.write('pandas :: (A) ' + - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - */ - __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1107, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1109 - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + # <<<<<<<<<<<<<< - * f'sort: {sort}' + - * '\n') - */ - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_at_2); - __pyx_t_4 += 4; - __Pyx_GIVEREF(__pyx_kp_u_at_2); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_at_2); - __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_at, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__24); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1108 - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< - * f'at: {at}, ' + - * f'sort: {sort}' + - */ - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1110 - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - * f'sort: {sort}' + # <<<<<<<<<<<<<< - * '\n') - * self._pandas(data, table_name, table_name_col, symbols, at, sort) - */ - __pyx_t_6 = __Pyx_PyObject_FormatSimple(((PyObject *)__pyx_v_sort), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_sort_2, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1109 - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + # <<<<<<<<<<<<<< - * f'sort: {sort}' + - * '\n') - */ - __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1109, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":1110 - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - * f'sort: {sort}' + # <<<<<<<<<<<<<< - * '\n') - * self._pandas(data, table_name, table_name_col, symbols, at, sort) - */ - __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_kp_u__27); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - } - } - __pyx_t_1 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_6, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_7); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1105, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1112 - * f'sort: {sort}' + - * '\n') - * self._pandas(data, table_name, table_name_col, symbols, at, sort) # <<<<<<<<<<<<<< - * sys.stderr.write('pandas :: (B) ' + - * f'table_name: {table_name}, ' + - */ - __pyx_t_8 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_sort)); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1112, __pyx_L1_error) - __pyx_t_9 = ((struct __pyx_vtabstruct_7questdb_7ingress_Buffer *)__pyx_v_self->__pyx_vtab)->_pandas(__pyx_v_self, __pyx_v_data, __pyx_v_table_name, __pyx_v_table_name_col, __pyx_v_symbols, __pyx_v_at, __pyx_t_8); if (unlikely(__pyx_t_9 == ((int)0))) __PYX_ERR(0, 1112, __pyx_L1_error) - - /* "questdb/ingress.pyx":1113 - * '\n') - * self._pandas(data, table_name, table_name_col, symbols, at, sort) - * sys.stderr.write('pandas :: (B) ' + # <<<<<<<<<<<<<< - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_sys, __pyx_n_s_stderr); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_write); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":1114 - * self._pandas(data, table_name, table_name_col, symbols, at, sort) - * sys.stderr.write('pandas :: (B) ' + - * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - */ - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_table_name_2); - __pyx_t_4 += 12; - __Pyx_GIVEREF(__pyx_kp_u_table_name_2); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_table_name_2); - __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__24); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":1113 - * '\n') - * self._pandas(data, table_name, table_name_col, symbols, at, sort) - * sys.stderr.write('pandas :: (B) ' + # <<<<<<<<<<<<<< - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - */ - __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_kp_u_pandas_B, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1115 - * sys.stderr.write('pandas :: (B) ' + - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - */ - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_table_name_col_2); - __pyx_t_4 += 16; - __Pyx_GIVEREF(__pyx_kp_u_table_name_col_2); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_table_name_col_2); - __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_table_name_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2); - __pyx_t_2 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__24); - __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_6, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1114 - * self._pandas(data, table_name, table_name_col, symbols, at, sort) - * sys.stderr.write('pandas :: (B) ' + - * f'table_name: {table_name}, ' + # <<<<<<<<<<<<<< - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - */ - __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1114, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1116 - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< - * f'at: {at}, ' + - * f'sort: {sort}' + - */ - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_symbols_2); - __pyx_t_4 += 9; - __Pyx_GIVEREF(__pyx_kp_u_symbols_2); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_symbols_2); - __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_v_symbols, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3); - __pyx_t_3 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__24); - __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1115 - * sys.stderr.write('pandas :: (B) ' + - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + # <<<<<<<<<<<<<< - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - */ - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":1117 - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + # <<<<<<<<<<<<<< - * f'sort: {sort}' + - * '\n') - */ - __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = 0; - __pyx_t_5 = 127; - __Pyx_INCREF(__pyx_kp_u_at_2); - __pyx_t_4 += 4; - __Pyx_GIVEREF(__pyx_kp_u_at_2); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_kp_u_at_2); - __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_at, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_5) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_5; - __pyx_t_4 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); - __pyx_t_6 = 0; - __Pyx_INCREF(__pyx_kp_u__24); - __pyx_t_4 += 2; - __Pyx_GIVEREF(__pyx_kp_u__24); - PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_kp_u__24); - __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_3, 3, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":1116 - * f'table_name: {table_name}, ' + - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + # <<<<<<<<<<<<<< - * f'at: {at}, ' + - * f'sort: {sort}' + - */ - __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1116, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1118 - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - * f'sort: {sort}' + # <<<<<<<<<<<<<< - * '\n') - * - */ - __pyx_t_6 = __Pyx_PyObject_FormatSimple(((PyObject *)__pyx_v_sort), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_sort_2, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1117 - * f'table_name_col: {table_name_col}, ' + - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + # <<<<<<<<<<<<<< - * f'sort: {sort}' + - * '\n') - */ - __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1117, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1118 - * f'symbols: {symbols}, ' + - * f'at: {at}, ' + - * f'sort: {sort}' + # <<<<<<<<<<<<<< - * '\n') - * - */ - __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_6, __pyx_kp_u__27); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1118, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7); - if (likely(__pyx_t_6)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_7, function); - } - } - __pyx_t_1 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_6, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1090 - * qdb_pystr_buf_clear(self._b) - * - * def pandas( # <<<<<<<<<<<<<< - * self, - * data, # : pd.DataFrame - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress.Buffer.pandas", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_sys); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_19__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__, METH_NOARGS, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_18__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_18__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Buffer_21__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__, METH_O, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Buffer_20__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Buffer_20__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Buffer.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1266 - * cdef size_t _max_name_len - * - * def __cinit__( # <<<<<<<<<<<<<< - * self, - * str host, - */ - -/* Python wrapper */ -static int __pyx_pw_7questdb_7ingress_6Sender_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static int __pyx_pw_7questdb_7ingress_6Sender_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_host = 0; - PyObject *__pyx_v_port = 0; - PyObject *__pyx_v_interface = 0; - PyObject *__pyx_v_auth = 0; - PyObject *__pyx_v_tls = 0; - uint64_t __pyx_v_read_timeout; - uint64_t __pyx_v_init_capacity; - uint64_t __pyx_v_max_name_len; - PyObject *__pyx_v_auto_flush = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_host,&__pyx_n_s_port,&__pyx_n_s_interface,&__pyx_n_s_auth,&__pyx_n_s_tls,&__pyx_n_s_read_timeout,&__pyx_n_s_init_capacity,&__pyx_n_s_max_name_len,&__pyx_n_s_auto_flush,0}; - PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; - - /* "questdb/ingress.pyx":1271 - * object port, - * *, - * str interface=None, # <<<<<<<<<<<<<< - * tuple auth=None, - * object tls=False, - */ - values[2] = ((PyObject*)Py_None); - - /* "questdb/ingress.pyx":1272 - * *, - * str interface=None, - * tuple auth=None, # <<<<<<<<<<<<<< - * object tls=False, - * uint64_t read_timeout=15000, - */ - values[3] = ((PyObject*)Py_None); - - /* "questdb/ingress.pyx":1273 - * str interface=None, - * tuple auth=None, - * object tls=False, # <<<<<<<<<<<<<< - * uint64_t read_timeout=15000, - * uint64_t init_capacity=65536, # 64KiB - */ - values[4] = ((PyObject *)Py_False); - values[8] = ((PyObject *)__pyx_int_64512); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_host)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_port)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, 1); __PYX_ERR(0, 1266, __pyx_L3_error) - } - } - if (kw_args > 0 && likely(kw_args <= 7)) { - Py_ssize_t index; - for (index = 2; index < 9 && kw_args > 0; index++) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); - if (value) { values[index] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 1266, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - } - __pyx_v_host = ((PyObject*)values[0]); - __pyx_v_port = values[1]; - __pyx_v_interface = ((PyObject*)values[2]); - __pyx_v_auth = ((PyObject*)values[3]); - __pyx_v_tls = values[4]; - if (values[5]) { - __pyx_v_read_timeout = __Pyx_PyInt_As_uint64_t(values[5]); if (unlikely((__pyx_v_read_timeout == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1274, __pyx_L3_error) - } else { - __pyx_v_read_timeout = ((uint64_t)0x3A98); - } - if (values[6]) { - __pyx_v_init_capacity = __Pyx_PyInt_As_uint64_t(values[6]); if (unlikely((__pyx_v_init_capacity == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1275, __pyx_L3_error) - } else { - __pyx_v_init_capacity = ((uint64_t)0x10000); - } - if (values[7]) { - __pyx_v_max_name_len = __Pyx_PyInt_As_uint64_t(values[7]); if (unlikely((__pyx_v_max_name_len == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 1276, __pyx_L3_error) - } else { - __pyx_v_max_name_len = ((uint64_t)0x7F); - } - __pyx_v_auto_flush = values[8]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1266, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Sender.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return -1; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_host), (&PyUnicode_Type), 1, "host", 1))) __PYX_ERR(0, 1268, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_interface), (&PyUnicode_Type), 1, "interface", 1))) __PYX_ERR(0, 1271, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_auth), (&PyTuple_Type), 1, "auth", 1))) __PYX_ERR(0, 1272, __pyx_L1_error) - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender___cinit__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_host, __pyx_v_port, __pyx_v_interface, __pyx_v_auth, __pyx_v_tls, __pyx_v_read_timeout, __pyx_v_init_capacity, __pyx_v_max_name_len, __pyx_v_auto_flush); - - /* "questdb/ingress.pyx":1266 - * cdef size_t _max_name_len - * - * def __cinit__( # <<<<<<<<<<<<<< - * self, - * str host, - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_7questdb_7ingress_6Sender___cinit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_host, PyObject *__pyx_v_port, PyObject *__pyx_v_interface, PyObject *__pyx_v_auth, PyObject *__pyx_v_tls, uint64_t __pyx_v_read_timeout, uint64_t __pyx_v_init_capacity, uint64_t __pyx_v_max_name_len, PyObject *__pyx_v_auto_flush) { - CYTHON_UNUSED struct line_sender_error *__pyx_v_err; - struct line_sender_utf8 __pyx_v_host_utf8; - PyObject *__pyx_v_port_str = 0; - struct line_sender_utf8 __pyx_v_port_utf8; - struct line_sender_utf8 __pyx_v_interface_utf8; - PyObject *__pyx_v_a_key_id = 0; - struct line_sender_utf8 __pyx_v_a_key_id_utf8; - PyObject *__pyx_v_a_priv_key = 0; - struct line_sender_utf8 __pyx_v_a_priv_key_utf8; - PyObject *__pyx_v_a_pub_key_x = 0; - struct line_sender_utf8 __pyx_v_a_pub_key_x_utf8; - PyObject *__pyx_v_a_pub_key_y = 0; - struct line_sender_utf8 __pyx_v_a_pub_key_y_utf8; - struct line_sender_utf8 __pyx_v_ca_utf8; - struct qdb_pystr_buf *__pyx_v_b; - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - struct qdb_pystr_buf *__pyx_t_3; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - Py_ssize_t __pyx_t_8; - Py_ssize_t __pyx_t_9; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__cinit__", 0); - __Pyx_INCREF(__pyx_v_tls); - - /* "questdb/ingress.pyx":1278 - * uint64_t max_name_len=127, - * object auto_flush=64512): # 63KiB - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * - * cdef line_sender_utf8 host_utf8 - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":1308 - * cdef qdb_pystr_buf* b - * - * self._opts = NULL # <<<<<<<<<<<<<< - * self._impl = NULL - * - */ - __pyx_v_self->_opts = NULL; - - /* "questdb/ingress.pyx":1309 - * - * self._opts = NULL - * self._impl = NULL # <<<<<<<<<<<<<< - * - * self._init_capacity = init_capacity - */ - __pyx_v_self->_impl = NULL; - - /* "questdb/ingress.pyx":1311 - * self._impl = NULL - * - * self._init_capacity = init_capacity # <<<<<<<<<<<<<< - * self._max_name_len = max_name_len - * - */ - __pyx_v_self->_init_capacity = __pyx_v_init_capacity; - - /* "questdb/ingress.pyx":1312 - * - * self._init_capacity = init_capacity - * self._max_name_len = max_name_len # <<<<<<<<<<<<<< - * - * self._buffer = Buffer( - */ - __pyx_v_self->_max_name_len = __pyx_v_max_name_len; - - /* "questdb/ingress.pyx":1315 - * - * self._buffer = Buffer( - * init_capacity=init_capacity, # <<<<<<<<<<<<<< - * max_name_len=max_name_len) - * - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1315, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_v_init_capacity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1315, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_init_capacity, __pyx_t_2) < 0) __PYX_ERR(0, 1315, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1316 - * self._buffer = Buffer( - * init_capacity=init_capacity, - * max_name_len=max_name_len) # <<<<<<<<<<<<<< - * - * b = self._buffer._b - */ - __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_v_max_name_len); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1316, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_max_name_len, __pyx_t_2) < 0) __PYX_ERR(0, 1315, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1314 - * self._max_name_len = max_name_len - * - * self._buffer = Buffer( # <<<<<<<<<<<<<< - * init_capacity=init_capacity, - * max_name_len=max_name_len) - */ - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer), __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1314, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->_buffer); - __Pyx_DECREF(((PyObject *)__pyx_v_self->_buffer)); - __pyx_v_self->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)__pyx_t_2); - __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1318 - * max_name_len=max_name_len) - * - * b = self._buffer._b # <<<<<<<<<<<<<< - * - * if PyInt_Check(port): - */ - __pyx_t_3 = __pyx_v_self->_buffer->_b; - __pyx_v_b = __pyx_t_3; - - /* "questdb/ingress.pyx":1320 - * b = self._buffer._b - * - * if PyInt_Check(port): # <<<<<<<<<<<<<< - * port_str = str(port) - * elif PyUnicode_Check(port): - */ - __pyx_t_4 = (PyInt_Check(__pyx_v_port) != 0); - if (__pyx_t_4) { - - /* "questdb/ingress.pyx":1321 - * - * if PyInt_Check(port): - * port_str = str(port) # <<<<<<<<<<<<<< - * elif PyUnicode_Check(port): - * port_str = port - */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_port); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1321, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_v_port_str = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1320 - * b = self._buffer._b - * - * if PyInt_Check(port): # <<<<<<<<<<<<<< - * port_str = str(port) - * elif PyUnicode_Check(port): - */ - goto __pyx_L3; - } - - /* "questdb/ingress.pyx":1322 - * if PyInt_Check(port): - * port_str = str(port) - * elif PyUnicode_Check(port): # <<<<<<<<<<<<<< - * port_str = port - * else: - */ - __pyx_t_4 = (PyUnicode_Check(__pyx_v_port) != 0); - if (likely(__pyx_t_4)) { - - /* "questdb/ingress.pyx":1323 - * port_str = str(port) - * elif PyUnicode_Check(port): - * port_str = port # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_port))||((__pyx_v_port) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_port)->tp_name), 0))) __PYX_ERR(0, 1323, __pyx_L1_error) - __pyx_t_2 = __pyx_v_port; - __Pyx_INCREF(__pyx_t_2); - __pyx_v_port_str = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1322 - * if PyInt_Check(port): - * port_str = str(port) - * elif PyUnicode_Check(port): # <<<<<<<<<<<<<< - * port_str = port - * else: - */ - goto __pyx_L3; - } - - /* "questdb/ingress.pyx":1325 - * port_str = port - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'port must be an integer or a string, not {type(port)}') - * - */ - /*else*/ { - - /* "questdb/ingress.pyx":1326 - * else: - * raise TypeError( - * f'port must be an integer or a string, not {type(port)}') # <<<<<<<<<<<<<< - * - * str_to_utf8(b, host, &host_utf8) - */ - __pyx_t_2 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_port)), __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1326, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_kp_u_port_must_be_an_integer_or_a_str, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1326, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1325 - * port_str = port - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'port must be an integer or a string, not {type(port)}') - * - */ - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1325, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 1325, __pyx_L1_error) - } - __pyx_L3:; - - /* "questdb/ingress.pyx":1328 - * f'port must be an integer or a string, not {type(port)}') - * - * str_to_utf8(b, host, &host_utf8) # <<<<<<<<<<<<<< - * str_to_utf8(b, port_str, &port_utf8) - * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_host, (&__pyx_v_host_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1328, __pyx_L1_error) - - /* "questdb/ingress.pyx":1329 - * - * str_to_utf8(b, host, &host_utf8) - * str_to_utf8(b, port_str, &port_utf8) # <<<<<<<<<<<<<< - * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) - * - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_port_str, (&__pyx_v_port_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1329, __pyx_L1_error) - - /* "questdb/ingress.pyx":1330 - * str_to_utf8(b, host, &host_utf8) - * str_to_utf8(b, port_str, &port_utf8) - * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) # <<<<<<<<<<<<<< - * - * if interface is not None: - */ - __pyx_v_self->_opts = line_sender_opts_new_service(__pyx_v_host_utf8, __pyx_v_port_utf8); - - /* "questdb/ingress.pyx":1332 - * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) - * - * if interface is not None: # <<<<<<<<<<<<<< - * str_to_utf8(b, interface, &interface_utf8) - * line_sender_opts_net_interface(self._opts, interface_utf8) - */ - __pyx_t_4 = (__pyx_v_interface != ((PyObject*)Py_None)); - __pyx_t_5 = (__pyx_t_4 != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":1333 - * - * if interface is not None: - * str_to_utf8(b, interface, &interface_utf8) # <<<<<<<<<<<<<< - * line_sender_opts_net_interface(self._opts, interface_utf8) - * - */ - __pyx_t_5 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_interface, (&__pyx_v_interface_utf8)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1333, __pyx_L1_error) - - /* "questdb/ingress.pyx":1334 - * if interface is not None: - * str_to_utf8(b, interface, &interface_utf8) - * line_sender_opts_net_interface(self._opts, interface_utf8) # <<<<<<<<<<<<<< - * - * if auth is not None: - */ - line_sender_opts_net_interface(__pyx_v_self->_opts, __pyx_v_interface_utf8); - - /* "questdb/ingress.pyx":1332 - * self._opts = line_sender_opts_new_service(host_utf8, port_utf8) - * - * if interface is not None: # <<<<<<<<<<<<<< - * str_to_utf8(b, interface, &interface_utf8) - * line_sender_opts_net_interface(self._opts, interface_utf8) - */ - } - - /* "questdb/ingress.pyx":1336 - * line_sender_opts_net_interface(self._opts, interface_utf8) - * - * if auth is not None: # <<<<<<<<<<<<<< - * (a_key_id, - * a_priv_key, - */ - __pyx_t_5 = (__pyx_v_auth != ((PyObject*)Py_None)); - __pyx_t_4 = (__pyx_t_5 != 0); - if (__pyx_t_4) { - - /* "questdb/ingress.pyx":1340 - * a_priv_key, - * a_pub_key_x, - * a_pub_key_y) = auth # <<<<<<<<<<<<<< - * str_to_utf8(b, a_key_id, &a_key_id_utf8) - * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) - */ - if (likely(__pyx_v_auth != Py_None)) { - PyObject* sequence = __pyx_v_auth; - Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); - if (unlikely(size != 4)) { - if (size > 4) __Pyx_RaiseTooManyValuesError(4); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(0, 1337, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1); - __pyx_t_6 = PyTuple_GET_ITEM(sequence, 2); - __pyx_t_7 = PyTuple_GET_ITEM(sequence, 3); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(__pyx_t_1); - __Pyx_INCREF(__pyx_t_6); - __Pyx_INCREF(__pyx_t_7); - #else - { - Py_ssize_t i; - PyObject** temps[4] = {&__pyx_t_2,&__pyx_t_1,&__pyx_t_6,&__pyx_t_7}; - for (i=0; i < 4; i++) { - PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) __PYX_ERR(0, 1337, __pyx_L1_error) - __Pyx_GOTREF(item); - *(temps[i]) = item; - } - } - #endif - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(0, 1337, __pyx_L1_error) - } - - /* "questdb/ingress.pyx":1337 - * - * if auth is not None: - * (a_key_id, # <<<<<<<<<<<<<< - * a_priv_key, - * a_pub_key_x, - */ - if (!(likely(PyUnicode_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) - if (!(likely(PyUnicode_CheckExact(__pyx_t_6))||((__pyx_t_6) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_6)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) - if (!(likely(PyUnicode_CheckExact(__pyx_t_7))||((__pyx_t_7) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_7)->tp_name), 0))) __PYX_ERR(0, 1337, __pyx_L1_error) - __pyx_v_a_key_id = ((PyObject*)__pyx_t_2); - __pyx_t_2 = 0; - __pyx_v_a_priv_key = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; - __pyx_v_a_pub_key_x = ((PyObject*)__pyx_t_6); - __pyx_t_6 = 0; - __pyx_v_a_pub_key_y = ((PyObject*)__pyx_t_7); - __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":1341 - * a_pub_key_x, - * a_pub_key_y) = auth - * str_to_utf8(b, a_key_id, &a_key_id_utf8) # <<<<<<<<<<<<<< - * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) - * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_key_id, (&__pyx_v_a_key_id_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1341, __pyx_L1_error) - - /* "questdb/ingress.pyx":1342 - * a_pub_key_y) = auth - * str_to_utf8(b, a_key_id, &a_key_id_utf8) - * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) # <<<<<<<<<<<<<< - * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) - * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_priv_key, (&__pyx_v_a_priv_key_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1342, __pyx_L1_error) - - /* "questdb/ingress.pyx":1343 - * str_to_utf8(b, a_key_id, &a_key_id_utf8) - * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) - * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) # <<<<<<<<<<<<<< - * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) - * line_sender_opts_auth( - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_pub_key_x, (&__pyx_v_a_pub_key_x_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1343, __pyx_L1_error) - - /* "questdb/ingress.pyx":1344 - * str_to_utf8(b, a_priv_key, &a_priv_key_utf8) - * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) - * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) # <<<<<<<<<<<<<< - * line_sender_opts_auth( - * self._opts, - */ - __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, __pyx_v_a_pub_key_y, (&__pyx_v_a_pub_key_y_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1344, __pyx_L1_error) - - /* "questdb/ingress.pyx":1345 - * str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) - * str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) - * line_sender_opts_auth( # <<<<<<<<<<<<<< - * self._opts, - * a_key_id_utf8, - */ - line_sender_opts_auth(__pyx_v_self->_opts, __pyx_v_a_key_id_utf8, __pyx_v_a_priv_key_utf8, __pyx_v_a_pub_key_x_utf8, __pyx_v_a_pub_key_y_utf8); - - /* "questdb/ingress.pyx":1336 - * line_sender_opts_net_interface(self._opts, interface_utf8) - * - * if auth is not None: # <<<<<<<<<<<<<< - * (a_key_id, - * a_priv_key, - */ - } - - /* "questdb/ingress.pyx":1352 - * a_pub_key_y_utf8) - * - * if tls: # <<<<<<<<<<<<<< - * if tls is True: - * line_sender_opts_tls(self._opts) - */ - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_tls); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1352, __pyx_L1_error) - if (__pyx_t_4) { - - /* "questdb/ingress.pyx":1353 - * - * if tls: - * if tls is True: # <<<<<<<<<<<<<< - * line_sender_opts_tls(self._opts) - * elif isinstance(tls, str): - */ - __pyx_t_4 = (__pyx_v_tls == Py_True); - __pyx_t_5 = (__pyx_t_4 != 0); - if (__pyx_t_5) { - - /* "questdb/ingress.pyx":1354 - * if tls: - * if tls is True: - * line_sender_opts_tls(self._opts) # <<<<<<<<<<<<<< - * elif isinstance(tls, str): - * if tls == 'insecure_skip_verify': - */ - line_sender_opts_tls(__pyx_v_self->_opts); - - /* "questdb/ingress.pyx":1353 - * - * if tls: - * if tls is True: # <<<<<<<<<<<<<< - * line_sender_opts_tls(self._opts) - * elif isinstance(tls, str): - */ - goto __pyx_L7; - } - - /* "questdb/ingress.pyx":1355 - * if tls is True: - * line_sender_opts_tls(self._opts) - * elif isinstance(tls, str): # <<<<<<<<<<<<<< - * if tls == 'insecure_skip_verify': - * line_sender_opts_tls_insecure_skip_verify(self._opts) - */ - __pyx_t_5 = PyUnicode_Check(__pyx_v_tls); - __pyx_t_4 = (__pyx_t_5 != 0); - if (__pyx_t_4) { - - /* "questdb/ingress.pyx":1356 - * line_sender_opts_tls(self._opts) - * elif isinstance(tls, str): - * if tls == 'insecure_skip_verify': # <<<<<<<<<<<<<< - * line_sender_opts_tls_insecure_skip_verify(self._opts) - * else: - */ - __pyx_t_4 = (__Pyx_PyUnicode_Equals(__pyx_v_tls, __pyx_n_u_insecure_skip_verify, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1356, __pyx_L1_error) - if (__pyx_t_4) { - - /* "questdb/ingress.pyx":1357 - * elif isinstance(tls, str): - * if tls == 'insecure_skip_verify': - * line_sender_opts_tls_insecure_skip_verify(self._opts) # <<<<<<<<<<<<<< - * else: - * str_to_utf8(b, tls, &ca_utf8) - */ - line_sender_opts_tls_insecure_skip_verify(__pyx_v_self->_opts); - - /* "questdb/ingress.pyx":1356 - * line_sender_opts_tls(self._opts) - * elif isinstance(tls, str): - * if tls == 'insecure_skip_verify': # <<<<<<<<<<<<<< - * line_sender_opts_tls_insecure_skip_verify(self._opts) - * else: - */ - goto __pyx_L8; - } - - /* "questdb/ingress.pyx":1359 - * line_sender_opts_tls_insecure_skip_verify(self._opts) - * else: - * str_to_utf8(b, tls, &ca_utf8) # <<<<<<<<<<<<<< - * line_sender_opts_tls_ca(self._opts, ca_utf8) - * elif isinstance(tls, pathlib.Path): - */ - /*else*/ { - if (!(likely(PyUnicode_CheckExact(__pyx_v_tls))||((__pyx_v_tls) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_tls)->tp_name), 0))) __PYX_ERR(0, 1359, __pyx_L1_error) - __pyx_t_4 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, ((PyObject*)__pyx_v_tls), (&__pyx_v_ca_utf8)); if (unlikely(__pyx_t_4 == ((int)0))) __PYX_ERR(0, 1359, __pyx_L1_error) - - /* "questdb/ingress.pyx":1360 - * else: - * str_to_utf8(b, tls, &ca_utf8) - * line_sender_opts_tls_ca(self._opts, ca_utf8) # <<<<<<<<<<<<<< - * elif isinstance(tls, pathlib.Path): - * tls = str(tls) - */ - line_sender_opts_tls_ca(__pyx_v_self->_opts, __pyx_v_ca_utf8); - } - __pyx_L8:; - - /* "questdb/ingress.pyx":1355 - * if tls is True: - * line_sender_opts_tls(self._opts) - * elif isinstance(tls, str): # <<<<<<<<<<<<<< - * if tls == 'insecure_skip_verify': - * line_sender_opts_tls_insecure_skip_verify(self._opts) - */ - goto __pyx_L7; - } - - /* "questdb/ingress.pyx":1361 - * str_to_utf8(b, tls, &ca_utf8) - * line_sender_opts_tls_ca(self._opts, ca_utf8) - * elif isinstance(tls, pathlib.Path): # <<<<<<<<<<<<<< - * tls = str(tls) - * str_to_utf8(b, tls, &ca_utf8) - */ - __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1361, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_Path); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1361, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_4 = PyObject_IsInstance(__pyx_v_tls, __pyx_t_6); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 1361, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_5 = (__pyx_t_4 != 0); - if (likely(__pyx_t_5)) { - - /* "questdb/ingress.pyx":1362 - * line_sender_opts_tls_ca(self._opts, ca_utf8) - * elif isinstance(tls, pathlib.Path): - * tls = str(tls) # <<<<<<<<<<<<<< - * str_to_utf8(b, tls, &ca_utf8) - * line_sender_opts_tls_ca(self._opts, ca_utf8) - */ - __pyx_t_6 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_tls); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1362, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF_SET(__pyx_v_tls, __pyx_t_6); - __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1363 - * elif isinstance(tls, pathlib.Path): - * tls = str(tls) - * str_to_utf8(b, tls, &ca_utf8) # <<<<<<<<<<<<<< - * line_sender_opts_tls_ca(self._opts, ca_utf8) - * else: - */ - if (!(likely(PyUnicode_CheckExact(__pyx_v_tls))||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_tls)->tp_name), 0))) __PYX_ERR(0, 1363, __pyx_L1_error) - __pyx_t_5 = __pyx_f_7questdb_7ingress_str_to_utf8(__pyx_v_b, ((PyObject*)__pyx_v_tls), (&__pyx_v_ca_utf8)); if (unlikely(__pyx_t_5 == ((int)0))) __PYX_ERR(0, 1363, __pyx_L1_error) - - /* "questdb/ingress.pyx":1364 - * tls = str(tls) - * str_to_utf8(b, tls, &ca_utf8) - * line_sender_opts_tls_ca(self._opts, ca_utf8) # <<<<<<<<<<<<<< - * else: - * raise TypeError( - */ - line_sender_opts_tls_ca(__pyx_v_self->_opts, __pyx_v_ca_utf8); - - /* "questdb/ingress.pyx":1361 - * str_to_utf8(b, tls, &ca_utf8) - * line_sender_opts_tls_ca(self._opts, ca_utf8) - * elif isinstance(tls, pathlib.Path): # <<<<<<<<<<<<<< - * tls = str(tls) - * str_to_utf8(b, tls, &ca_utf8) - */ - goto __pyx_L7; - } - - /* "questdb/ingress.pyx":1366 - * line_sender_opts_tls_ca(self._opts, ca_utf8) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * 'tls must be a bool, a path or string pointing to CA file ' - * f'or "insecure_skip_verify", not {type(tls)}') - */ - /*else*/ { - - /* "questdb/ingress.pyx":1368 - * raise TypeError( - * 'tls must be a bool, a path or string pointing to CA file ' - * f'or "insecure_skip_verify", not {type(tls)}') # <<<<<<<<<<<<<< - * - * if read_timeout is not None: - */ - __pyx_t_6 = __Pyx_PyObject_FormatSimple(((PyObject *)Py_TYPE(__pyx_v_tls)), __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1368, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - - /* "questdb/ingress.pyx":1367 - * else: - * raise TypeError( - * 'tls must be a bool, a path or string pointing to CA file ' # <<<<<<<<<<<<<< - * f'or "insecure_skip_verify", not {type(tls)}') - * - */ - __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_tls_must_be_a_bool_a_path_or_str, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1367, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1366 - * line_sender_opts_tls_ca(self._opts, ca_utf8) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * 'tls must be a bool, a path or string pointing to CA file ' - * f'or "insecure_skip_verify", not {type(tls)}') - */ - __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1366, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(0, 1366, __pyx_L1_error) - } - __pyx_L7:; - - /* "questdb/ingress.pyx":1352 - * a_pub_key_y_utf8) - * - * if tls: # <<<<<<<<<<<<<< - * if tls is True: - * line_sender_opts_tls(self._opts) - */ - } - - /* "questdb/ingress.pyx":1370 - * f'or "insecure_skip_verify", not {type(tls)}') - * - * if read_timeout is not None: # <<<<<<<<<<<<<< - * line_sender_opts_read_timeout(self._opts, read_timeout) - * - */ - __pyx_t_6 = __Pyx_PyInt_From_uint64_t(__pyx_v_read_timeout); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1370, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = (__pyx_t_6 != Py_None); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_4 = (__pyx_t_5 != 0); - if (__pyx_t_4) { - - /* "questdb/ingress.pyx":1371 - * - * if read_timeout is not None: - * line_sender_opts_read_timeout(self._opts, read_timeout) # <<<<<<<<<<<<<< - * - * self._auto_flush_enabled = not not auto_flush - */ - line_sender_opts_read_timeout(__pyx_v_self->_opts, __pyx_v_read_timeout); - - /* "questdb/ingress.pyx":1370 - * f'or "insecure_skip_verify", not {type(tls)}') - * - * if read_timeout is not None: # <<<<<<<<<<<<<< - * line_sender_opts_read_timeout(self._opts, read_timeout) - * - */ - } - - /* "questdb/ingress.pyx":1373 - * line_sender_opts_read_timeout(self._opts, read_timeout) - * - * self._auto_flush_enabled = not not auto_flush # <<<<<<<<<<<<<< - * self._auto_flush_watermark = int(auto_flush) \ - * if self._auto_flush_enabled else 0 - */ - __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_auto_flush); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1373, __pyx_L1_error) - __pyx_v_self->_auto_flush_enabled = (!((!__pyx_t_4) != 0)); - - /* "questdb/ingress.pyx":1375 - * self._auto_flush_enabled = not not auto_flush - * self._auto_flush_watermark = int(auto_flush) \ - * if self._auto_flush_enabled else 0 # <<<<<<<<<<<<<< - * if self._auto_flush_watermark < 0: - * raise ValueError( - */ - if ((__pyx_v_self->_auto_flush_enabled != 0)) { - - /* "questdb/ingress.pyx":1374 - * - * self._auto_flush_enabled = not not auto_flush - * self._auto_flush_watermark = int(auto_flush) \ # <<<<<<<<<<<<<< - * if self._auto_flush_enabled else 0 - * if self._auto_flush_watermark < 0: - */ - __pyx_t_6 = __Pyx_PyNumber_Int(__pyx_v_auto_flush); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1374, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_9 = PyInt_AsSsize_t(__pyx_t_6); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 1374, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_8 = __pyx_t_9; - } else { - __pyx_t_8 = 0; - } - __pyx_v_self->_auto_flush_watermark = __pyx_t_8; - - /* "questdb/ingress.pyx":1376 - * self._auto_flush_watermark = int(auto_flush) \ - * if self._auto_flush_enabled else 0 - * if self._auto_flush_watermark < 0: # <<<<<<<<<<<<<< - * raise ValueError( - * 'auto_flush_watermark must be >= 0, ' - */ - __pyx_t_4 = ((__pyx_v_self->_auto_flush_watermark < 0) != 0); - if (unlikely(__pyx_t_4)) { - - /* "questdb/ingress.pyx":1379 - * raise ValueError( - * 'auto_flush_watermark must be >= 0, ' - * f'not {self._auto_flush_watermark}') # <<<<<<<<<<<<<< - * - * qdb_pystr_buf_clear(b) - */ - __pyx_t_6 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_self->_auto_flush_watermark, 0, ' ', 'd'); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1379, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - - /* "questdb/ingress.pyx":1378 - * if self._auto_flush_watermark < 0: - * raise ValueError( - * 'auto_flush_watermark must be >= 0, ' # <<<<<<<<<<<<<< - * f'not {self._auto_flush_watermark}') - * - */ - __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_auto_flush_watermark_must_be_0_n, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1378, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1377 - * if self._auto_flush_enabled else 0 - * if self._auto_flush_watermark < 0: - * raise ValueError( # <<<<<<<<<<<<<< - * 'auto_flush_watermark must be >= 0, ' - * f'not {self._auto_flush_watermark}') - */ - __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_ValueError, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1377, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(0, 1377, __pyx_L1_error) - - /* "questdb/ingress.pyx":1376 - * self._auto_flush_watermark = int(auto_flush) \ - * if self._auto_flush_enabled else 0 - * if self._auto_flush_watermark < 0: # <<<<<<<<<<<<<< - * raise ValueError( - * 'auto_flush_watermark must be >= 0, ' - */ - } - - /* "questdb/ingress.pyx":1381 - * f'not {self._auto_flush_watermark}') - * - * qdb_pystr_buf_clear(b) # <<<<<<<<<<<<<< - * - * def new_buffer(self): - */ - qdb_pystr_buf_clear(__pyx_v_b); - - /* "questdb/ingress.pyx":1266 - * cdef size_t _max_name_len - * - * def __cinit__( # <<<<<<<<<<<<<< - * self, - * str host, - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress.Sender.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_XDECREF(__pyx_v_port_str); - __Pyx_XDECREF(__pyx_v_a_key_id); - __Pyx_XDECREF(__pyx_v_a_priv_key); - __Pyx_XDECREF(__pyx_v_a_pub_key_x); - __Pyx_XDECREF(__pyx_v_a_pub_key_y); - __Pyx_XDECREF(__pyx_v_tls); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1383 - * qdb_pystr_buf_clear(b) - * - * def new_buffer(self): # <<<<<<<<<<<<<< - * """ - * Make a new configured buffer. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_3new_buffer(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_2new_buffer[] = "\n Make a new configured buffer.\n\n The buffer is set up with the configured `init_capacity` and\n `max_name_len`.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_3new_buffer = {"new_buffer", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_3new_buffer, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_2new_buffer}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_3new_buffer(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("new_buffer (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_2new_buffer(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_2new_buffer(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("new_buffer", 0); - - /* "questdb/ingress.pyx":1390 - * `max_name_len`. - * """ - * return Buffer( # <<<<<<<<<<<<<< - * init_capacity=self._init_capacity, - * max_name_len=self._max_name_len) - */ - __Pyx_XDECREF(__pyx_r); - - /* "questdb/ingress.pyx":1391 - * """ - * return Buffer( - * init_capacity=self._init_capacity, # <<<<<<<<<<<<<< - * max_name_len=self._max_name_len) - * - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1391, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_init_capacity); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1391, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_init_capacity, __pyx_t_2) < 0) __PYX_ERR(0, 1391, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1392 - * return Buffer( - * init_capacity=self._init_capacity, - * max_name_len=self._max_name_len) # <<<<<<<<<<<<<< - * - * @property - */ - __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_max_name_len); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1392, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_max_name_len, __pyx_t_2) < 0) __PYX_ERR(0, 1391, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1390 - * `max_name_len`. - * """ - * return Buffer( # <<<<<<<<<<<<<< - * init_capacity=self._init_capacity, - * max_name_len=self._max_name_len) - */ - __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer), __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1390, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":1383 - * qdb_pystr_buf_clear(b) - * - * def new_buffer(self): # <<<<<<<<<<<<<< - * """ - * Make a new configured buffer. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Sender.new_buffer", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1395 - * - * @property - * def init_capacity(self) -> int: # <<<<<<<<<<<<<< - * """The initial capacity of the sender's internal buffer.""" - * return self._init_capacity - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13init_capacity_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13init_capacity_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_13init_capacity___get__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_13init_capacity___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "questdb/ingress.pyx":1397 - * def init_capacity(self) -> int: - * """The initial capacity of the sender's internal buffer.""" - * return self._init_capacity # <<<<<<<<<<<<<< - * - * @property - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_init_capacity); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1397, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":1395 - * - * @property - * def init_capacity(self) -> int: # <<<<<<<<<<<<<< - * """The initial capacity of the sender's internal buffer.""" - * return self._init_capacity - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.init_capacity.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1400 - * - * @property - * def max_name_len(self) -> int: # <<<<<<<<<<<<<< - * """Maximum length of a table or column name.""" - * return self._max_name_len - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_12max_name_len_1__get__(PyObject *__pyx_v_self); /*proto*/ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_12max_name_len_1__get__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_12max_name_len___get__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12max_name_len___get__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__get__", 0); - - /* "questdb/ingress.pyx":1402 - * def max_name_len(self) -> int: - * """Maximum length of a table or column name.""" - * return self._max_name_len # <<<<<<<<<<<<<< - * - * def connect(self): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->_max_name_len); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1402, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":1400 - * - * @property - * def max_name_len(self) -> int: # <<<<<<<<<<<<<< - * """Maximum length of a table or column name.""" - * return self._max_name_len - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.max_name_len.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1404 - * return self._max_name_len - * - * def connect(self): # <<<<<<<<<<<<<< - * """ - * Connect to the QuestDB server. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_5connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_4connect[] = "\n Connect to the QuestDB server.\n\n This method is synchronous and will block until the connection is\n established.\n\n If the connection is set up with authentication and/or TLS, this\n method will return only *after* the handshake(s) is/are complete.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_5connect = {"connect", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_5connect, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_4connect}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_5connect(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("connect (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_4connect(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_4connect(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - struct line_sender_error *__pyx_v_err; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("connect", 0); - - /* "questdb/ingress.pyx":1414 - * method will return only *after* the handshake(s) is/are complete. - * """ - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * if self._opts == NULL: - * raise IngressError( - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":1415 - * """ - * cdef line_sender_error* err = NULL - * if self._opts == NULL: # <<<<<<<<<<<<<< - * raise IngressError( - * IngressErrorCode.InvalidApiCall, - */ - __pyx_t_1 = ((__pyx_v_self->_opts == NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":1416 - * cdef line_sender_error* err = NULL - * if self._opts == NULL: - * raise IngressError( # <<<<<<<<<<<<<< - * IngressErrorCode.InvalidApiCall, - * 'connect() can\'t be called after close().') - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1416, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - - /* "questdb/ingress.pyx":1417 - * if self._opts == NULL: - * raise IngressError( - * IngressErrorCode.InvalidApiCall, # <<<<<<<<<<<<<< - * 'connect() can\'t be called after close().') - * self._impl = line_sender_connect(self._opts, &err) - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1417, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_InvalidApiCall); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1417, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - __pyx_t_6 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_3, function); - __pyx_t_6 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_5, __pyx_kp_u_connect_can_t_be_called_after_cl}; - __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1416, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_5, __pyx_kp_u_connect_can_t_be_called_after_cl}; - __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1416, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - } else - #endif - { - __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1416, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (__pyx_t_4) { - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL; - } - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_5); - __Pyx_INCREF(__pyx_kp_u_connect_can_t_be_called_after_cl); - __Pyx_GIVEREF(__pyx_kp_u_connect_can_t_be_called_after_cl); - PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_kp_u_connect_can_t_be_called_after_cl); - __pyx_t_5 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1416, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 1416, __pyx_L1_error) - - /* "questdb/ingress.pyx":1415 - * """ - * cdef line_sender_error* err = NULL - * if self._opts == NULL: # <<<<<<<<<<<<<< - * raise IngressError( - * IngressErrorCode.InvalidApiCall, - */ - } - - /* "questdb/ingress.pyx":1419 - * IngressErrorCode.InvalidApiCall, - * 'connect() can\'t be called after close().') - * self._impl = line_sender_connect(self._opts, &err) # <<<<<<<<<<<<<< - * if self._impl == NULL: - * raise c_err_to_py(err) - */ - __pyx_v_self->_impl = line_sender_connect(__pyx_v_self->_opts, (&__pyx_v_err)); - - /* "questdb/ingress.pyx":1420 - * 'connect() can\'t be called after close().') - * self._impl = line_sender_connect(self._opts, &err) - * if self._impl == NULL: # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * line_sender_opts_free(self._opts) - */ - __pyx_t_1 = ((__pyx_v_self->_impl == NULL) != 0); - if (unlikely(__pyx_t_1)) { - - /* "questdb/ingress.pyx":1421 - * self._impl = line_sender_connect(self._opts, &err) - * if self._impl == NULL: - * raise c_err_to_py(err) # <<<<<<<<<<<<<< - * line_sender_opts_free(self._opts) - * self._opts = NULL - */ - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py(__pyx_v_err); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1421, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 1421, __pyx_L1_error) - - /* "questdb/ingress.pyx":1420 - * 'connect() can\'t be called after close().') - * self._impl = line_sender_connect(self._opts, &err) - * if self._impl == NULL: # <<<<<<<<<<<<<< - * raise c_err_to_py(err) - * line_sender_opts_free(self._opts) - */ - } - - /* "questdb/ingress.pyx":1422 - * if self._impl == NULL: - * raise c_err_to_py(err) - * line_sender_opts_free(self._opts) # <<<<<<<<<<<<<< - * self._opts = NULL - * - */ - line_sender_opts_free(__pyx_v_self->_opts); - - /* "questdb/ingress.pyx":1423 - * raise c_err_to_py(err) - * line_sender_opts_free(self._opts) - * self._opts = NULL # <<<<<<<<<<<<<< - * - * # Request callbacks when rows are complete. - */ - __pyx_v_self->_opts = NULL; - - /* "questdb/ingress.pyx":1426 - * - * # Request callbacks when rows are complete. - * if self._buffer is not None: # <<<<<<<<<<<<<< - * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) - * - */ - __pyx_t_1 = (((PyObject *)__pyx_v_self->_buffer) != Py_None); - __pyx_t_8 = (__pyx_t_1 != 0); - if (__pyx_t_8) { - - /* "questdb/ingress.pyx":1427 - * # Request callbacks when rows are complete. - * if self._buffer is not None: - * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) # <<<<<<<<<<<<<< - * - * def __enter__(self) -> Sender: - */ - __pyx_t_2 = PyWeakref_NewRef(((PyObject *)__pyx_v_self), Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1427, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_v_self->_buffer->_row_complete_sender); - __Pyx_DECREF(__pyx_v_self->_buffer->_row_complete_sender); - __pyx_v_self->_buffer->_row_complete_sender = __pyx_t_2; - __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1426 - * - * # Request callbacks when rows are complete. - * if self._buffer is not None: # <<<<<<<<<<<<<< - * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) - * - */ - } - - /* "questdb/ingress.pyx":1404 - * return self._max_name_len - * - * def connect(self): # <<<<<<<<<<<<<< - * """ - * Connect to the QuestDB server. - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress.Sender.connect", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1429 - * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) - * - * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< - * """Call :func:`Sender.connect` at the start of a ``with`` block.""" - * self.connect() - */ - -/* Python wrapper */ -static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pw_7questdb_7ingress_6Sender_7__enter__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_6__enter__[] = "Call :func:`Sender.connect` at the start of a ``with`` block."; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_7__enter__ = {"__enter__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_7__enter__, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_6__enter__}; -static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pw_7questdb_7ingress_6Sender_7__enter__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - struct __pyx_obj_7questdb_7ingress_Sender *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__enter__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_6__enter__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static struct __pyx_obj_7questdb_7ingress_Sender *__pyx_pf_7questdb_7ingress_6Sender_6__enter__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - struct __pyx_obj_7questdb_7ingress_Sender *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__enter__", 0); - - /* "questdb/ingress.pyx":1431 - * def __enter__(self) -> Sender: - * """Call :func:`Sender.connect` at the start of a ``with`` block.""" - * self.connect() # <<<<<<<<<<<<<< - * return self - * - */ - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_connect); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1431, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_3 = NULL; - if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_3)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - } - } - __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1431, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1432 - * """Call :func:`Sender.connect` at the start of a ``with`` block.""" - * self.connect() - * return self # <<<<<<<<<<<<<< - * - * def __str__(self) -> str: - */ - __Pyx_XDECREF(((PyObject *)__pyx_r)); - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __pyx_r = __pyx_v_self; - goto __pyx_L0; - - /* "questdb/ingress.pyx":1429 - * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) - * - * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< - * """Call :func:`Sender.connect` at the start of a ``with`` block.""" - * self.connect() - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_AddTraceback("questdb.ingress.Sender.__enter__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF((PyObject *)__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1434 - * return self - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """ - * Inspect the contents of the internal buffer. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_9__str__(PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_8__str__[] = "\n Inspect the contents of the internal buffer.\n\n The ``str`` value returned represents the unsent data.\n\n Also see :func:`Sender.__len__`.\n "; -#if CYTHON_UPDATE_DESCRIPTOR_DOC -struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__; -#endif -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_9__str__(PyObject *__pyx_v_self) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_8__str__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_8__str__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__str__", 0); - - /* "questdb/ingress.pyx":1442 - * Also see :func:`Sender.__len__`. - * """ - * return str(self._buffer) # <<<<<<<<<<<<<< - * - * def __len__(self) -> int: - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), ((PyObject *)__pyx_v_self->_buffer)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1442, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "questdb/ingress.pyx":1434 - * return self - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """ - * Inspect the contents of the internal buffer. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1444 - * return str(self._buffer) - * - * def __len__(self) -> int: # <<<<<<<<<<<<<< - * """ - * Number of bytes of unsent data in the internal buffer. - */ - -/* Python wrapper */ -static Py_ssize_t __pyx_pw_7questdb_7ingress_6Sender_11__len__(PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_10__len__[] = "\n Number of bytes of unsent data in the internal buffer.\n\n Equivalent (but cheaper) to ``len(str(sender))``.\n "; -#if CYTHON_UPDATE_DESCRIPTOR_DOC -struct wrapperbase __pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__; -#endif -static Py_ssize_t __pyx_pw_7questdb_7ingress_6Sender_11__len__(PyObject *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_10__len__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static Py_ssize_t __pyx_pf_7questdb_7ingress_6Sender_10__len__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - Py_ssize_t __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__len__", 0); - - /* "questdb/ingress.pyx":1450 - * Equivalent (but cheaper) to ``len(str(sender))``. - * """ - * return len(self._buffer) # <<<<<<<<<<<<<< - * - * def row(self, - */ - __pyx_t_1 = ((PyObject *)__pyx_v_self->_buffer); - __Pyx_INCREF(__pyx_t_1); - __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1450, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_r = __pyx_t_2; - goto __pyx_L0; - - /* "questdb/ingress.pyx":1444 - * return str(self._buffer) - * - * def __len__(self) -> int: # <<<<<<<<<<<<<< - * """ - * Number of bytes of unsent data in the internal buffer. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1452 - * return len(self._buffer) - * - * def row(self, # <<<<<<<<<<<<<< - * table_name: str, - * *, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_12row[] = "\n Write a row to the internal buffer.\n\n This may be sent automatically depending on the ``auto_flush`` setting\n in the constructor.\n\n Refer to the :func:`Buffer.row` documentation for details on arguments.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_13row = {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_13row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_12row}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_13row(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_table_name = 0; - PyObject *__pyx_v_symbols = 0; - PyObject *__pyx_v_columns = 0; - PyObject *__pyx_v_at = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("row (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_table_name,&__pyx_n_s_symbols,&__pyx_n_s_columns,&__pyx_n_s_at,0}; - PyObject* values[4] = {0,0,0,0}; - - /* "questdb/ingress.pyx":1455 - * table_name: str, - * *, - * symbols: Optional[Dict[str, str]]=None, # <<<<<<<<<<<<<< - * columns: Optional[Dict[ - * str, - */ - values[1] = ((PyObject *)Py_None); - - /* "questdb/ingress.pyx":1458 - * columns: Optional[Dict[ - * str, - * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, # <<<<<<<<<<<<<< - * at: Union[None, TimestampNanos, datetime]=None): - * """ - */ - values[2] = ((PyObject *)Py_None); - - /* "questdb/ingress.pyx":1459 - * str, - * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, - * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< - * """ - * Write a row to the internal buffer. - */ - values[3] = ((PyObject *)Py_None); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_table_name)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - } - if (kw_args > 0 && likely(kw_args <= 3)) { - Py_ssize_t index; - for (index = 1; index < 4 && kw_args > 0; index++) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, *__pyx_pyargnames[index]); - if (value) { values[index] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "row") < 0)) __PYX_ERR(0, 1452, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - } - __pyx_v_table_name = ((PyObject*)values[0]); - __pyx_v_symbols = values[1]; - __pyx_v_columns = values[2]; - __pyx_v_at = values[3]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("row", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1452, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Sender.row", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_table_name), (&PyUnicode_Type), 1, "table_name", 1))) __PYX_ERR(0, 1453, __pyx_L1_error) - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_12row(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_table_name, __pyx_v_symbols, __pyx_v_columns, __pyx_v_at); - - /* "questdb/ingress.pyx":1452 - * return len(self._buffer) - * - * def row(self, # <<<<<<<<<<<<<< - * table_name: str, - * *, - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_12row(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_table_name, PyObject *__pyx_v_symbols, PyObject *__pyx_v_columns, PyObject *__pyx_v_at) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("row", 0); - - /* "questdb/ingress.pyx":1468 - * Refer to the :func:`Buffer.row` documentation for details on arguments. - * """ - * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) # <<<<<<<<<<<<<< - * - * cpdef flush(self, Buffer buffer=None, bint clear=True): - */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self->_buffer), __pyx_n_s_row); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1468, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1468, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_v_table_name); - __Pyx_GIVEREF(__pyx_v_table_name); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_table_name); - __pyx_t_3 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1468, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_symbols, __pyx_v_symbols) < 0) __PYX_ERR(0, 1468, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_columns, __pyx_v_columns) < 0) __PYX_ERR(0, 1468, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_at, __pyx_v_at) < 0) __PYX_ERR(0, 1468, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1468, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":1452 - * return len(self._buffer) - * - * def row(self, # <<<<<<<<<<<<<< - * table_name: str, - * *, - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("questdb.ingress.Sender.row", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1470 - * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) - * - * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< - * """ - * If called with no arguments, immediately flushes the internal buffer. - */ - -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_15flush(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress_6Sender_flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args) { - struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); - int __pyx_v_clear = ((int)1); - struct line_sender_error *__pyx_v_err; - struct line_sender_buffer *__pyx_v_c_buf; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - struct line_sender_buffer *__pyx_t_11; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("flush", 0); - if (__pyx_optional_args) { - if (__pyx_optional_args->__pyx_n > 0) { - __pyx_v_buffer = __pyx_optional_args->buffer; - if (__pyx_optional_args->__pyx_n > 1) { - __pyx_v_clear = __pyx_optional_args->clear; - } - } - } - /* Check if called by wrapper */ - if (unlikely(__pyx_skip_dispatch)) ; - /* Check if overridden in Python */ - else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) { - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS - static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; - if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) { - PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); - #endif - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_flush); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7questdb_7ingress_6Sender_15flush)) { - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_clear); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_1); - __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL; - __pyx_t_6 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - __pyx_t_6 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, ((PyObject *)__pyx_v_buffer), __pyx_t_3}; - __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { - PyObject *__pyx_temp[3] = {__pyx_t_5, ((PyObject *)__pyx_v_buffer), __pyx_t_3}; - __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } else - #endif - { - __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - if (__pyx_t_5) { - __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL; - } - __Pyx_INCREF(((PyObject *)__pyx_v_buffer)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_buffer)); - PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, ((PyObject *)__pyx_v_buffer)); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3); - __pyx_t_3 = 0; - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - goto __pyx_L0; - } - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS - __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); - __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self)); - if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) { - __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; - } - #endif - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS - } - #endif - } - - /* "questdb/ingress.pyx":1490 - * specified. - * """ - * if buffer is None and not clear: # <<<<<<<<<<<<<< - * raise ValueError('The internal buffer must always be cleared.') - * - */ - __pyx_t_9 = (((PyObject *)__pyx_v_buffer) == Py_None); - __pyx_t_10 = (__pyx_t_9 != 0); - if (__pyx_t_10) { - } else { - __pyx_t_8 = __pyx_t_10; - goto __pyx_L4_bool_binop_done; - } - __pyx_t_10 = ((!(__pyx_v_clear != 0)) != 0); - __pyx_t_8 = __pyx_t_10; - __pyx_L4_bool_binop_done:; - if (unlikely(__pyx_t_8)) { - - /* "questdb/ingress.pyx":1491 - * """ - * if buffer is None and not clear: - * raise ValueError('The internal buffer must always be cleared.') # <<<<<<<<<<<<<< - * - * cdef line_sender_error* err = NULL - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1491, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 1491, __pyx_L1_error) - - /* "questdb/ingress.pyx":1490 - * specified. - * """ - * if buffer is None and not clear: # <<<<<<<<<<<<<< - * raise ValueError('The internal buffer must always be cleared.') - * - */ - } - - /* "questdb/ingress.pyx":1493 - * raise ValueError('The internal buffer must always be cleared.') - * - * cdef line_sender_error* err = NULL # <<<<<<<<<<<<<< - * cdef line_sender_buffer* c_buf = NULL - * if self._impl == NULL: - */ - __pyx_v_err = NULL; - - /* "questdb/ingress.pyx":1494 - * - * cdef line_sender_error* err = NULL - * cdef line_sender_buffer* c_buf = NULL # <<<<<<<<<<<<<< - * if self._impl == NULL: - * raise IngressError( - */ - __pyx_v_c_buf = NULL; - - /* "questdb/ingress.pyx":1495 - * cdef line_sender_error* err = NULL - * cdef line_sender_buffer* c_buf = NULL - * if self._impl == NULL: # <<<<<<<<<<<<<< - * raise IngressError( - * IngressErrorCode.InvalidApiCall, - */ - __pyx_t_8 = ((__pyx_v_self->_impl == NULL) != 0); - if (unlikely(__pyx_t_8)) { - - /* "questdb/ingress.pyx":1496 - * cdef line_sender_buffer* c_buf = NULL - * if self._impl == NULL: - * raise IngressError( # <<<<<<<<<<<<<< - * IngressErrorCode.InvalidApiCall, - * 'flush() can\'t be called: Not connected.') - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_IngressError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1496, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - - /* "questdb/ingress.pyx":1497 - * if self._impl == NULL: - * raise IngressError( - * IngressErrorCode.InvalidApiCall, # <<<<<<<<<<<<<< - * 'flush() can\'t be called: Not connected.') - * if buffer is not None: - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1497, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_InvalidApiCall); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1497, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = NULL; - __pyx_t_6 = 0; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - if (likely(__pyx_t_4)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_2, function); - __pyx_t_6 = 1; - } - } - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_7, __pyx_kp_u_flush_can_t_be_called_Not_connec}; - __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1496, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } else - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { - PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_7, __pyx_kp_u_flush_can_t_be_called_Not_connec}; - __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1496, __pyx_L1_error) - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - } else - #endif - { - __pyx_t_3 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1496, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (__pyx_t_4) { - __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = NULL; - } - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_6, __pyx_t_7); - __Pyx_INCREF(__pyx_kp_u_flush_can_t_be_called_Not_connec); - __Pyx_GIVEREF(__pyx_kp_u_flush_can_t_be_called_Not_connec); - PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_6, __pyx_kp_u_flush_can_t_be_called_Not_connec); - __pyx_t_7 = 0; - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1496, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - } - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 1496, __pyx_L1_error) - - /* "questdb/ingress.pyx":1495 - * cdef line_sender_error* err = NULL - * cdef line_sender_buffer* c_buf = NULL - * if self._impl == NULL: # <<<<<<<<<<<<<< - * raise IngressError( - * IngressErrorCode.InvalidApiCall, - */ - } - - /* "questdb/ingress.pyx":1499 - * IngressErrorCode.InvalidApiCall, - * 'flush() can\'t be called: Not connected.') - * if buffer is not None: # <<<<<<<<<<<<<< - * c_buf = buffer._impl - * else: - */ - __pyx_t_8 = (((PyObject *)__pyx_v_buffer) != Py_None); - __pyx_t_10 = (__pyx_t_8 != 0); - if (__pyx_t_10) { - - /* "questdb/ingress.pyx":1500 - * 'flush() can\'t be called: Not connected.') - * if buffer is not None: - * c_buf = buffer._impl # <<<<<<<<<<<<<< - * else: - * c_buf = self._buffer._impl - */ - __pyx_t_11 = __pyx_v_buffer->_impl; - __pyx_v_c_buf = __pyx_t_11; - - /* "questdb/ingress.pyx":1499 - * IngressErrorCode.InvalidApiCall, - * 'flush() can\'t be called: Not connected.') - * if buffer is not None: # <<<<<<<<<<<<<< - * c_buf = buffer._impl - * else: - */ - goto __pyx_L7; - } - - /* "questdb/ingress.pyx":1502 - * c_buf = buffer._impl - * else: - * c_buf = self._buffer._impl # <<<<<<<<<<<<<< - * if line_sender_buffer_size(c_buf) == 0: - * return - */ - /*else*/ { - __pyx_t_11 = __pyx_v_self->_buffer->_impl; - __pyx_v_c_buf = __pyx_t_11; - } - __pyx_L7:; - - /* "questdb/ingress.pyx":1503 - * else: - * c_buf = self._buffer._impl - * if line_sender_buffer_size(c_buf) == 0: # <<<<<<<<<<<<<< - * return - * - */ - __pyx_t_10 = ((line_sender_buffer_size(__pyx_v_c_buf) == 0) != 0); - if (__pyx_t_10) { - - /* "questdb/ingress.pyx":1504 - * c_buf = self._buffer._impl - * if line_sender_buffer_size(c_buf) == 0: - * return # <<<<<<<<<<<<<< - * - * try: - */ - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - - /* "questdb/ingress.pyx":1503 - * else: - * c_buf = self._buffer._impl - * if line_sender_buffer_size(c_buf) == 0: # <<<<<<<<<<<<<< - * return - * - */ - } - - /* "questdb/ingress.pyx":1506 - * return - * - * try: # <<<<<<<<<<<<<< - * if clear: - * if not line_sender_flush(self._impl, c_buf, &err): - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14); - __Pyx_XGOTREF(__pyx_t_12); - __Pyx_XGOTREF(__pyx_t_13); - __Pyx_XGOTREF(__pyx_t_14); - /*try:*/ { - - /* "questdb/ingress.pyx":1507 - * - * try: - * if clear: # <<<<<<<<<<<<<< - * if not line_sender_flush(self._impl, c_buf, &err): - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - */ - __pyx_t_10 = (__pyx_v_clear != 0); - if (__pyx_t_10) { - - /* "questdb/ingress.pyx":1508 - * try: - * if clear: - * if not line_sender_flush(self._impl, c_buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - * else: - */ - __pyx_t_10 = ((!(line_sender_flush(__pyx_v_self->_impl, __pyx_v_c_buf, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_10)) { - - /* "questdb/ingress.pyx":1509 - * if clear: - * if not line_sender_flush(self._impl, c_buf, &err): - * raise c_err_to_py_fmt(err, _FLUSH_FMT) # <<<<<<<<<<<<<< - * else: - * if not line_sender_flush_and_keep(self._impl, c_buf, &err): - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_FLUSH_FMT); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1509, __pyx_L9_error) - __Pyx_GOTREF(__pyx_t_1); - if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 1509, __pyx_L9_error) - __pyx_t_2 = __pyx_f_7questdb_7ingress_c_err_to_py_fmt(__pyx_v_err, ((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1509, __pyx_L9_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_Raise(__pyx_t_2, 0, 0, 0); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __PYX_ERR(0, 1509, __pyx_L9_error) - - /* "questdb/ingress.pyx":1508 - * try: - * if clear: - * if not line_sender_flush(self._impl, c_buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - * else: - */ - } - - /* "questdb/ingress.pyx":1507 - * - * try: - * if clear: # <<<<<<<<<<<<<< - * if not line_sender_flush(self._impl, c_buf, &err): - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - */ - goto __pyx_L15; - } - - /* "questdb/ingress.pyx":1511 - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - * else: - * if not line_sender_flush_and_keep(self._impl, c_buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - * except: - */ - /*else*/ { - __pyx_t_10 = ((!(line_sender_flush_and_keep(__pyx_v_self->_impl, __pyx_v_c_buf, (&__pyx_v_err)) != 0)) != 0); - if (unlikely(__pyx_t_10)) { - - /* "questdb/ingress.pyx":1512 - * else: - * if not line_sender_flush_and_keep(self._impl, c_buf, &err): - * raise c_err_to_py_fmt(err, _FLUSH_FMT) # <<<<<<<<<<<<<< - * except: - * # Prevent a follow-up call to `.close(flush=True)` (as is usually - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_FLUSH_FMT); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1512, __pyx_L9_error) - __Pyx_GOTREF(__pyx_t_2); - if (!(likely(PyUnicode_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1512, __pyx_L9_error) - __pyx_t_1 = __pyx_f_7questdb_7ingress_c_err_to_py_fmt(__pyx_v_err, ((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1512, __pyx_L9_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(0, 1512, __pyx_L9_error) - - /* "questdb/ingress.pyx":1511 - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - * else: - * if not line_sender_flush_and_keep(self._impl, c_buf, &err): # <<<<<<<<<<<<<< - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - * except: - */ - } - } - __pyx_L15:; - - /* "questdb/ingress.pyx":1506 - * return - * - * try: # <<<<<<<<<<<<<< - * if clear: - * if not line_sender_flush(self._impl, c_buf, &err): - */ - } - __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - goto __pyx_L14_try_end; - __pyx_L9_error:; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "questdb/ingress.pyx":1513 - * if not line_sender_flush_and_keep(self._impl, c_buf, &err): - * raise c_err_to_py_fmt(err, _FLUSH_FMT) - * except: # <<<<<<<<<<<<<< - * # Prevent a follow-up call to `.close(flush=True)` (as is usually - * # called from `__exit__`) to raise after the sender entered an error - */ - /*except:*/ { - __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3) < 0) __PYX_ERR(0, 1513, __pyx_L11_except_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GOTREF(__pyx_t_3); - - /* "questdb/ingress.pyx":1517 - * # called from `__exit__`) to raise after the sender entered an error - * # state following a failed call to `.flush()`. - * if c_buf == self._buffer._impl: # <<<<<<<<<<<<<< - * line_sender_buffer_clear(c_buf) - * raise - */ - __pyx_t_10 = ((__pyx_v_c_buf == __pyx_v_self->_buffer->_impl) != 0); - if (__pyx_t_10) { - - /* "questdb/ingress.pyx":1518 - * # state following a failed call to `.flush()`. - * if c_buf == self._buffer._impl: - * line_sender_buffer_clear(c_buf) # <<<<<<<<<<<<<< - * raise - * - */ - line_sender_buffer_clear(__pyx_v_c_buf); - - /* "questdb/ingress.pyx":1517 - * # called from `__exit__`) to raise after the sender entered an error - * # state following a failed call to `.flush()`. - * if c_buf == self._buffer._impl: # <<<<<<<<<<<<<< - * line_sender_buffer_clear(c_buf) - * raise - */ - } - - /* "questdb/ingress.pyx":1519 - * if c_buf == self._buffer._impl: - * line_sender_buffer_clear(c_buf) - * raise # <<<<<<<<<<<<<< - * - * cdef _close(self): - */ - __Pyx_GIVEREF(__pyx_t_1); - __Pyx_GIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ErrRestoreWithState(__pyx_t_1, __pyx_t_2, __pyx_t_3); - __pyx_t_1 = 0; __pyx_t_2 = 0; __pyx_t_3 = 0; - __PYX_ERR(0, 1519, __pyx_L11_except_error) - } - __pyx_L11_except_error:; - - /* "questdb/ingress.pyx":1506 - * return - * - * try: # <<<<<<<<<<<<<< - * if clear: - * if not line_sender_flush(self._impl, c_buf, &err): - */ - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_XGIVEREF(__pyx_t_13); - __Pyx_XGIVEREF(__pyx_t_14); - __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14); - goto __pyx_L1_error; - __pyx_L14_try_end:; - } - - /* "questdb/ingress.pyx":1470 - * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) - * - * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< - * """ - * If called with no arguments, immediately flushes the internal buffer. - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_15flush(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_14flush[] = "\n If called with no arguments, immediately flushes the internal buffer.\n\n Alternatively you can flush a buffer that was constructed explicitly\n by passing ``buffer``.\n\n The buffer will be cleared by default, unless ``clear`` is set to\n ``False``.\n\n This method does nothing if the provided or internal buffer is empty.\n\n :param buffer: The buffer to flush. If ``None``, the internal buffer\n is flushed.\n\n :param clear: If ``True``, the flushed buffer is cleared (default).\n If ``False``, the flushed buffer is left in the internal buffer.\n Note that ``clear=False`` is only supported if ``buffer`` is also\n specified.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_15flush = {"flush", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_15flush, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_14flush}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_15flush(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer = 0; - int __pyx_v_clear; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("flush (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_buffer,&__pyx_n_s_clear,0}; - PyObject* values[2] = {0,0}; - values[0] = (PyObject *)((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_buffer); - if (value) { values[0] = value; kw_args--; } - } - CYTHON_FALLTHROUGH; - case 1: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_clear); - if (value) { values[1] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "flush") < 0)) __PYX_ERR(0, 1470, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - } - __pyx_v_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)values[0]); - if (values[1]) { - __pyx_v_clear = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_clear == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1470, __pyx_L3_error) - } else { - __pyx_v_clear = ((int)1); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("flush", 0, 0, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1470, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_buffer), __pyx_ptype_7questdb_7ingress_Buffer, 1, "buffer", 0))) __PYX_ERR(0, 1470, __pyx_L1_error) - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_14flush(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_buffer, __pyx_v_clear); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_14flush(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, struct __pyx_obj_7questdb_7ingress_Buffer *__pyx_v_buffer, int __pyx_v_clear) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - struct __pyx_opt_args_7questdb_7ingress_6Sender_flush __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("flush", 0); - __Pyx_XDECREF(__pyx_r); - __pyx_t_2.__pyx_n = 2; - __pyx_t_2.buffer = __pyx_v_buffer; - __pyx_t_2.clear = __pyx_v_clear; - __pyx_t_1 = __pyx_vtabptr_7questdb_7ingress_Sender->flush(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.flush", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1521 - * raise - * - * cdef _close(self): # <<<<<<<<<<<<<< - * self._buffer = None - * line_sender_opts_free(self._opts) - */ - -static PyObject *__pyx_f_7questdb_7ingress_6Sender__close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("_close", 0); - - /* "questdb/ingress.pyx":1522 - * - * cdef _close(self): - * self._buffer = None # <<<<<<<<<<<<<< - * line_sender_opts_free(self._opts) - * self._opts = NULL - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_self->_buffer); - __Pyx_DECREF(((PyObject *)__pyx_v_self->_buffer)); - __pyx_v_self->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); - - /* "questdb/ingress.pyx":1523 - * cdef _close(self): - * self._buffer = None - * line_sender_opts_free(self._opts) # <<<<<<<<<<<<<< - * self._opts = NULL - * line_sender_close(self._impl) - */ - line_sender_opts_free(__pyx_v_self->_opts); - - /* "questdb/ingress.pyx":1524 - * self._buffer = None - * line_sender_opts_free(self._opts) - * self._opts = NULL # <<<<<<<<<<<<<< - * line_sender_close(self._impl) - * self._impl = NULL - */ - __pyx_v_self->_opts = NULL; - - /* "questdb/ingress.pyx":1525 - * line_sender_opts_free(self._opts) - * self._opts = NULL - * line_sender_close(self._impl) # <<<<<<<<<<<<<< - * self._impl = NULL - * - */ - line_sender_close(__pyx_v_self->_impl); - - /* "questdb/ingress.pyx":1526 - * self._opts = NULL - * line_sender_close(self._impl) - * self._impl = NULL # <<<<<<<<<<<<<< - * - * cpdef close(self, bint flush=True): - */ - __pyx_v_self->_impl = NULL; - - /* "questdb/ingress.pyx":1521 - * raise - * - * cdef _close(self): # <<<<<<<<<<<<<< - * self._buffer = None - * line_sender_opts_free(self._opts) - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1528 - * self._impl = NULL - * - * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< - * """ - * Disconnect. - */ - -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_17close(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_f_7questdb_7ingress_6Sender_close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args) { - int __pyx_v_flush = ((int)1); - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - int __pyx_t_6; - int __pyx_t_7; - struct __pyx_opt_args_7questdb_7ingress_6Sender_flush __pyx_t_8; - int __pyx_t_9; - int __pyx_t_10; - char const *__pyx_t_11; - PyObject *__pyx_t_12 = NULL; - PyObject *__pyx_t_13 = NULL; - PyObject *__pyx_t_14 = NULL; - PyObject *__pyx_t_15 = NULL; - PyObject *__pyx_t_16 = NULL; - PyObject *__pyx_t_17 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("close", 0); - if (__pyx_optional_args) { - if (__pyx_optional_args->__pyx_n > 0) { - __pyx_v_flush = __pyx_optional_args->flush; - } - } - /* Check if called by wrapper */ - if (unlikely(__pyx_skip_dispatch)) ; - /* Check if overridden in Python */ - else if (unlikely((Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0) || (Py_TYPE(((PyObject *)__pyx_v_self))->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)))) { - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS - static PY_UINT64_T __pyx_tp_dict_version = __PYX_DICT_VERSION_INIT, __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; - if (unlikely(!__Pyx_object_dict_version_matches(((PyObject *)__pyx_v_self), __pyx_tp_dict_version, __pyx_obj_dict_version))) { - PY_UINT64_T __pyx_type_dict_guard = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); - #endif - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_close); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1528, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)(void*)__pyx_pw_7questdb_7ingress_6Sender_17close)) { - __Pyx_XDECREF(__pyx_r); - __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_flush); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1528, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_1); - __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); - if (likely(__pyx_t_5)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); - __Pyx_INCREF(__pyx_t_5); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_4, function); - } - } - __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1528, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_r = __pyx_t_2; - __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - goto __pyx_L0; - } - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS - __pyx_tp_dict_version = __Pyx_get_tp_dict_version(((PyObject *)__pyx_v_self)); - __pyx_obj_dict_version = __Pyx_get_object_dict_version(((PyObject *)__pyx_v_self)); - if (unlikely(__pyx_type_dict_guard != __pyx_tp_dict_version)) { - __pyx_tp_dict_version = __pyx_obj_dict_version = __PYX_DICT_VERSION_INIT; - } - #endif - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - #if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS - } - #endif - } - - /* "questdb/ingress.pyx":1538 - * :param bool flush: If ``True``, flush the internal buffer before closing. - * """ - * try: # <<<<<<<<<<<<<< - * if (flush and (self._impl != NULL) and - * (not line_sender_must_close(self._impl))): - */ - /*try:*/ { - - /* "questdb/ingress.pyx":1539 - * """ - * try: - * if (flush and (self._impl != NULL) and # <<<<<<<<<<<<<< - * (not line_sender_must_close(self._impl))): - * self.flush(None, True) - */ - __pyx_t_7 = (__pyx_v_flush != 0); - if (__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_7 = ((__pyx_v_self->_impl != NULL) != 0); - if (__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - - /* "questdb/ingress.pyx":1540 - * try: - * if (flush and (self._impl != NULL) and - * (not line_sender_must_close(self._impl))): # <<<<<<<<<<<<<< - * self.flush(None, True) - * finally: - */ - __pyx_t_7 = ((!(line_sender_must_close(__pyx_v_self->_impl) != 0)) != 0); - __pyx_t_6 = __pyx_t_7; - __pyx_L7_bool_binop_done:; - - /* "questdb/ingress.pyx":1539 - * """ - * try: - * if (flush and (self._impl != NULL) and # <<<<<<<<<<<<<< - * (not line_sender_must_close(self._impl))): - * self.flush(None, True) - */ - if (__pyx_t_6) { - - /* "questdb/ingress.pyx":1541 - * if (flush and (self._impl != NULL) and - * (not line_sender_must_close(self._impl))): - * self.flush(None, True) # <<<<<<<<<<<<<< - * finally: - * self._close() - */ - __pyx_t_8.__pyx_n = 2; - __pyx_t_8.buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); - __pyx_t_8.clear = 1; - __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->flush(__pyx_v_self, 0, &__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1541, __pyx_L4_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1539 - * """ - * try: - * if (flush and (self._impl != NULL) and # <<<<<<<<<<<<<< - * (not line_sender_must_close(self._impl))): - * self.flush(None, True) - */ - } - } - - /* "questdb/ingress.pyx":1543 - * self.flush(None, True) - * finally: - * self._close() # <<<<<<<<<<<<<< - * - * def __exit__(self, exc_type, _exc_val, _exc_tb): - */ - /*finally:*/ { - /*normal exit:*/{ - __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->_close(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1543, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - goto __pyx_L5; - } - __pyx_L4_error:; - /*exception exit:*/{ - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_15, &__pyx_t_16, &__pyx_t_17); - if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14) < 0)) __Pyx_ErrFetch(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14); - __Pyx_XGOTREF(__pyx_t_12); - __Pyx_XGOTREF(__pyx_t_13); - __Pyx_XGOTREF(__pyx_t_14); - __Pyx_XGOTREF(__pyx_t_15); - __Pyx_XGOTREF(__pyx_t_16); - __Pyx_XGOTREF(__pyx_t_17); - __pyx_t_9 = __pyx_lineno; __pyx_t_10 = __pyx_clineno; __pyx_t_11 = __pyx_filename; - { - __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->_close(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1543, __pyx_L11_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - } - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_XGIVEREF(__pyx_t_16); - __Pyx_XGIVEREF(__pyx_t_17); - __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_16, __pyx_t_17); - } - __Pyx_XGIVEREF(__pyx_t_12); - __Pyx_XGIVEREF(__pyx_t_13); - __Pyx_XGIVEREF(__pyx_t_14); - __Pyx_ErrRestore(__pyx_t_12, __pyx_t_13, __pyx_t_14); - __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; - __pyx_lineno = __pyx_t_9; __pyx_clineno = __pyx_t_10; __pyx_filename = __pyx_t_11; - goto __pyx_L1_error; - __pyx_L11_error:; - if (PY_MAJOR_VERSION >= 3) { - __Pyx_XGIVEREF(__pyx_t_15); - __Pyx_XGIVEREF(__pyx_t_16); - __Pyx_XGIVEREF(__pyx_t_17); - __Pyx_ExceptionReset(__pyx_t_15, __pyx_t_16, __pyx_t_17); - } - __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; - __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; - __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; - __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; - goto __pyx_L1_error; - } - __pyx_L5:; - } - - /* "questdb/ingress.pyx":1528 - * self._impl = NULL - * - * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< - * """ - * Disconnect. - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("questdb.ingress.Sender.close", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_17close(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_16close[] = "\n Disconnect.\n\n This method is idempotent and can be called repeatedly.\n\n Once a sender is closed, it can't be re-used.\n\n :param bool flush: If ``True``, flush the internal buffer before closing.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_17close = {"close", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_17close, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_16close}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_17close(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - int __pyx_v_flush; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("close (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_flush,0}; - PyObject* values[1] = {0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (kw_args > 0) { - PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_flush); - if (value) { values[0] = value; kw_args--; } - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "close") < 0)) __PYX_ERR(0, 1528, __pyx_L3_error) - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - } - if (values[0]) { - __pyx_v_flush = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_flush == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1528, __pyx_L3_error) - } else { - __pyx_v_flush = ((int)1); - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("close", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1528, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Sender.close", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_16close(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_flush); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_16close(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, int __pyx_v_flush) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - struct __pyx_opt_args_7questdb_7ingress_6Sender_close __pyx_t_2; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("close", 0); - __Pyx_XDECREF(__pyx_r); - __pyx_t_2.__pyx_n = 1; - __pyx_t_2.flush = __pyx_v_flush; - __pyx_t_1 = __pyx_vtabptr_7questdb_7ingress_Sender->close(__pyx_v_self, 1, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1528, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.close", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1545 - * self._close() - * - * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< - * """ - * Flush pending and disconnect at the end of a ``with`` block. - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_19__exit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_7questdb_7ingress_6Sender_18__exit__[] = "\n Flush pending and disconnect at the end of a ``with`` block.\n\n If the ``with`` block raises an exception, any pending data will\n *NOT* be flushed.\n\n This is implemented by calling :func:`Sender.close`.\n "; -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_19__exit__ = {"__exit__", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_19__exit__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_18__exit__}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_19__exit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_exc_type = 0; - CYTHON_UNUSED PyObject *__pyx_v__exc_val = 0; - CYTHON_UNUSED PyObject *__pyx_v__exc_tb = 0; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__exit__ (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_exc_type,&__pyx_n_s_exc_val,&__pyx_n_s_exc_tb,0}; - PyObject* values[3] = {0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_type)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_val)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 1); __PYX_ERR(0, 1545, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_tb)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 2); __PYX_ERR(0, 1545, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__exit__") < 0)) __PYX_ERR(0, 1545, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - } - __pyx_v_exc_type = values[0]; - __pyx_v__exc_val = values[1]; - __pyx_v__exc_tb = values[2]; - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1545, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("questdb.ingress.Sender.__exit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_18__exit__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), __pyx_v_exc_type, __pyx_v__exc_val, __pyx_v__exc_tb); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_18__exit__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, PyObject *__pyx_v_exc_type, CYTHON_UNUSED PyObject *__pyx_v__exc_val, CYTHON_UNUSED PyObject *__pyx_v__exc_tb) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - PyObject *__pyx_t_2 = NULL; - struct __pyx_opt_args_7questdb_7ingress_6Sender_close __pyx_t_3; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__exit__", 0); - - /* "questdb/ingress.pyx":1554 - * This is implemented by calling :func:`Sender.close`. - * """ - * self.close(not exc_type) # <<<<<<<<<<<<<< - * - * def __dealloc__(self): - */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_exc_type); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 1554, __pyx_L1_error) - __pyx_t_3.__pyx_n = 1; - __pyx_t_3.flush = (!__pyx_t_1); - __pyx_t_2 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->close(__pyx_v_self, 0, &__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1554, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1545 - * self._close() - * - * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< - * """ - * Flush pending and disconnect at the end of a ``with`` block. - */ - - /* function exit code */ - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_2); - __Pyx_AddTraceback("questdb.ingress.Sender.__exit__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "questdb/ingress.pyx":1556 - * self.close(not exc_type) - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * self._close() - */ - -/* Python wrapper */ -static void __pyx_pw_7questdb_7ingress_6Sender_21__dealloc__(PyObject *__pyx_v_self); /*proto*/ -static void __pyx_pw_7questdb_7ingress_6Sender_21__dealloc__(PyObject *__pyx_v_self) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); - __pyx_pf_7questdb_7ingress_6Sender_20__dealloc__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_pf_7questdb_7ingress_6Sender_20__dealloc__(struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__dealloc__", 0); - - /* "questdb/ingress.pyx":1557 - * - * def __dealloc__(self): - * self._close() # <<<<<<<<<<<<<< - */ - __pyx_t_1 = ((struct __pyx_vtabstruct_7questdb_7ingress_Sender *)__pyx_v_self->__pyx_vtab)->_close(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1557, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":1556 - * self.close(not exc_type) - * - * def __dealloc__(self): # <<<<<<<<<<<<<< - * self._close() - */ - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_WriteUnraisable("questdb.ingress.Sender.__dealloc__", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); - __pyx_L0:; - __Pyx_RefNannyFinishContext(); -} - -/* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_23__reduce_cython__ = {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__, METH_NOARGS, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_22__reduce_cython__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_22__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__reduce_cython__", 0); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 2, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ -static PyMethodDef __pyx_mdef_7questdb_7ingress_6Sender_25__setstate_cython__ = {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__, METH_O, 0}; -static PyObject *__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); - __pyx_r = __pyx_pf_7questdb_7ingress_6Sender_24__setstate_cython__(((struct __pyx_obj_7questdb_7ingress_Sender *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_7questdb_7ingress_6Sender_24__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7questdb_7ingress_Sender *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__setstate_cython__", 0); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_Raise(__pyx_t_1, 0, 0, 0); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __PYX_ERR(3, 4, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("questdb.ingress.Sender.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":104 - * # Datetime C API initialization function. - * # You have to call it before any usage of DateTime CAPI functions. - * cdef inline void import_datetime(): # <<<<<<<<<<<<<< - * PyDateTime_IMPORT - * - */ - -static CYTHON_INLINE void __pyx_f_7cpython_8datetime_import_datetime(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("import_datetime", 0); - - /* "cpython/datetime.pxd":105 - * # You have to call it before any usage of DateTime CAPI functions. - * cdef inline void import_datetime(): - * PyDateTime_IMPORT # <<<<<<<<<<<<<< - * - * # Create date object using DateTime CAPI factory function. - */ - (void)(PyDateTime_IMPORT); - - /* "cpython/datetime.pxd":104 - * # Datetime C API initialization function. - * # You have to call it before any usage of DateTime CAPI functions. - * cdef inline void import_datetime(): # <<<<<<<<<<<<<< - * PyDateTime_IMPORT - * - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "cpython/datetime.pxd":109 - * # Create date object using DateTime CAPI factory function. - * # Note, there are no range checks for any of the arguments. - * cdef inline object date_new(int year, int month, int day): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_date_new(int __pyx_v_year, int __pyx_v_month, int __pyx_v_day) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("date_new", 0); - - /* "cpython/datetime.pxd":110 - * # Note, there are no range checks for any of the arguments. - * cdef inline object date_new(int year, int month, int day): - * return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) # <<<<<<<<<<<<<< - * - * # Create time object using DateTime CAPI factory function - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyDateTimeAPI->Date_FromDate(__pyx_v_year, __pyx_v_month, __pyx_v_day, PyDateTimeAPI->DateType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "cpython/datetime.pxd":109 - * # Create date object using DateTime CAPI factory function. - * # Note, there are no range checks for any of the arguments. - * cdef inline object date_new(int year, int month, int day): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("cpython.datetime.date_new", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":114 - * # Create time object using DateTime CAPI factory function - * # Note, there are no range checks for any of the arguments. - * cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_time_new(int __pyx_v_hour, int __pyx_v_minute, int __pyx_v_second, int __pyx_v_microsecond, PyObject *__pyx_v_tz) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("time_new", 0); - - /* "cpython/datetime.pxd":115 - * # Note, there are no range checks for any of the arguments. - * cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): - * return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) # <<<<<<<<<<<<<< - * - * # Create datetime object using DateTime CAPI factory function. - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyDateTimeAPI->Time_FromTime(__pyx_v_hour, __pyx_v_minute, __pyx_v_second, __pyx_v_microsecond, __pyx_v_tz, PyDateTimeAPI->TimeType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 115, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "cpython/datetime.pxd":114 - * # Create time object using DateTime CAPI factory function - * # Note, there are no range checks for any of the arguments. - * cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("cpython.datetime.time_new", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":119 - * # Create datetime object using DateTime CAPI factory function. - * # Note, there are no range checks for any of the arguments. - * cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_datetime_new(int __pyx_v_year, int __pyx_v_month, int __pyx_v_day, int __pyx_v_hour, int __pyx_v_minute, int __pyx_v_second, int __pyx_v_microsecond, PyObject *__pyx_v_tz) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("datetime_new", 0); - - /* "cpython/datetime.pxd":120 - * # Note, there are no range checks for any of the arguments. - * cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): - * return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) # <<<<<<<<<<<<<< - * - * # Create timedelta object using DateTime CAPI factory function. - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyDateTimeAPI->DateTime_FromDateAndTime(__pyx_v_year, __pyx_v_month, __pyx_v_day, __pyx_v_hour, __pyx_v_minute, __pyx_v_second, __pyx_v_microsecond, __pyx_v_tz, PyDateTimeAPI->DateTimeType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 120, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "cpython/datetime.pxd":119 - * # Create datetime object using DateTime CAPI factory function. - * # Note, there are no range checks for any of the arguments. - * cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("cpython.datetime.datetime_new", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":124 - * # Create timedelta object using DateTime CAPI factory function. - * # Note, there are no range checks for any of the arguments. - * cdef inline object timedelta_new(int days, int seconds, int useconds): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_timedelta_new(int __pyx_v_days, int __pyx_v_seconds, int __pyx_v_useconds) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("timedelta_new", 0); - - /* "cpython/datetime.pxd":125 - * # Note, there are no range checks for any of the arguments. - * cdef inline object timedelta_new(int days, int seconds, int useconds): - * return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) # <<<<<<<<<<<<<< - * - * # More recognizable getters for date/time/datetime/timedelta. - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyDateTimeAPI->Delta_FromDelta(__pyx_v_days, __pyx_v_seconds, __pyx_v_useconds, 1, PyDateTimeAPI->DeltaType); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 125, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "cpython/datetime.pxd":124 - * # Create timedelta object using DateTime CAPI factory function. - * # Note, there are no range checks for any of the arguments. - * cdef inline object timedelta_new(int days, int seconds, int useconds): # <<<<<<<<<<<<<< - * return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("cpython.datetime.timedelta_new", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":133 - * - * # Get tzinfo of time - * cdef inline object time_tzinfo(object o): # <<<<<<<<<<<<<< - * if (o).hastzinfo: - * return (o).tzinfo - */ - -static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_time_tzinfo(PyObject *__pyx_v_o) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("time_tzinfo", 0); - - /* "cpython/datetime.pxd":134 - * # Get tzinfo of time - * cdef inline object time_tzinfo(object o): - * if (o).hastzinfo: # <<<<<<<<<<<<<< - * return (o).tzinfo - * else: - */ - __pyx_t_1 = (((PyDateTime_Time *)__pyx_v_o)->hastzinfo != 0); - if (__pyx_t_1) { - - /* "cpython/datetime.pxd":135 - * cdef inline object time_tzinfo(object o): - * if (o).hastzinfo: - * return (o).tzinfo # <<<<<<<<<<<<<< - * else: - * return None - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)((PyDateTime_Time *)__pyx_v_o)->tzinfo)); - __pyx_r = ((PyObject *)((PyDateTime_Time *)__pyx_v_o)->tzinfo); - goto __pyx_L0; - - /* "cpython/datetime.pxd":134 - * # Get tzinfo of time - * cdef inline object time_tzinfo(object o): - * if (o).hastzinfo: # <<<<<<<<<<<<<< - * return (o).tzinfo - * else: - */ - } - - /* "cpython/datetime.pxd":137 - * return (o).tzinfo - * else: - * return None # <<<<<<<<<<<<<< - * - * # Get tzinfo of datetime - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - } - - /* "cpython/datetime.pxd":133 - * - * # Get tzinfo of time - * cdef inline object time_tzinfo(object o): # <<<<<<<<<<<<<< - * if (o).hastzinfo: - * return (o).tzinfo - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":140 - * - * # Get tzinfo of datetime - * cdef inline object datetime_tzinfo(object o): # <<<<<<<<<<<<<< - * if (o).hastzinfo: - * return (o).tzinfo - */ - -static CYTHON_INLINE PyObject *__pyx_f_7cpython_8datetime_datetime_tzinfo(PyObject *__pyx_v_o) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("datetime_tzinfo", 0); - - /* "cpython/datetime.pxd":141 - * # Get tzinfo of datetime - * cdef inline object datetime_tzinfo(object o): - * if (o).hastzinfo: # <<<<<<<<<<<<<< - * return (o).tzinfo - * else: - */ - __pyx_t_1 = (((PyDateTime_DateTime *)__pyx_v_o)->hastzinfo != 0); - if (__pyx_t_1) { - - /* "cpython/datetime.pxd":142 - * cdef inline object datetime_tzinfo(object o): - * if (o).hastzinfo: - * return (o).tzinfo # <<<<<<<<<<<<<< - * else: - * return None - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)((PyDateTime_DateTime *)__pyx_v_o)->tzinfo)); - __pyx_r = ((PyObject *)((PyDateTime_DateTime *)__pyx_v_o)->tzinfo); - goto __pyx_L0; - - /* "cpython/datetime.pxd":141 - * # Get tzinfo of datetime - * cdef inline object datetime_tzinfo(object o): - * if (o).hastzinfo: # <<<<<<<<<<<<<< - * return (o).tzinfo - * else: - */ - } - - /* "cpython/datetime.pxd":144 - * return (o).tzinfo - * else: - * return None # <<<<<<<<<<<<<< - * - * # Get year of date - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __pyx_r = Py_None; __Pyx_INCREF(Py_None); - goto __pyx_L0; - } - - /* "cpython/datetime.pxd":140 - * - * # Get tzinfo of datetime - * cdef inline object datetime_tzinfo(object o): # <<<<<<<<<<<<<< - * if (o).hastzinfo: - * return (o).tzinfo - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":147 - * - * # Get year of date - * cdef inline int date_year(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_YEAR(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_date_year(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("date_year", 0); - - /* "cpython/datetime.pxd":148 - * # Get year of date - * cdef inline int date_year(object o): - * return PyDateTime_GET_YEAR(o) # <<<<<<<<<<<<<< - * - * # Get month of date - */ - __pyx_r = PyDateTime_GET_YEAR(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":147 - * - * # Get year of date - * cdef inline int date_year(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_YEAR(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":151 - * - * # Get month of date - * cdef inline int date_month(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_MONTH(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_date_month(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("date_month", 0); - - /* "cpython/datetime.pxd":152 - * # Get month of date - * cdef inline int date_month(object o): - * return PyDateTime_GET_MONTH(o) # <<<<<<<<<<<<<< - * - * # Get day of date - */ - __pyx_r = PyDateTime_GET_MONTH(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":151 - * - * # Get month of date - * cdef inline int date_month(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_MONTH(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":155 - * - * # Get day of date - * cdef inline int date_day(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_DAY(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_date_day(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("date_day", 0); - - /* "cpython/datetime.pxd":156 - * # Get day of date - * cdef inline int date_day(object o): - * return PyDateTime_GET_DAY(o) # <<<<<<<<<<<<<< - * - * # Get year of datetime - */ - __pyx_r = PyDateTime_GET_DAY(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":155 - * - * # Get day of date - * cdef inline int date_day(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_DAY(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":159 - * - * # Get year of datetime - * cdef inline int datetime_year(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_YEAR(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_year(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("datetime_year", 0); - - /* "cpython/datetime.pxd":160 - * # Get year of datetime - * cdef inline int datetime_year(object o): - * return PyDateTime_GET_YEAR(o) # <<<<<<<<<<<<<< - * - * # Get month of datetime - */ - __pyx_r = PyDateTime_GET_YEAR(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":159 - * - * # Get year of datetime - * cdef inline int datetime_year(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_YEAR(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":163 - * - * # Get month of datetime - * cdef inline int datetime_month(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_MONTH(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_month(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("datetime_month", 0); - - /* "cpython/datetime.pxd":164 - * # Get month of datetime - * cdef inline int datetime_month(object o): - * return PyDateTime_GET_MONTH(o) # <<<<<<<<<<<<<< - * - * # Get day of datetime - */ - __pyx_r = PyDateTime_GET_MONTH(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":163 - * - * # Get month of datetime - * cdef inline int datetime_month(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_MONTH(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":167 - * - * # Get day of datetime - * cdef inline int datetime_day(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_DAY(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_day(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("datetime_day", 0); - - /* "cpython/datetime.pxd":168 - * # Get day of datetime - * cdef inline int datetime_day(object o): - * return PyDateTime_GET_DAY(o) # <<<<<<<<<<<<<< - * - * # Get hour of time - */ - __pyx_r = PyDateTime_GET_DAY(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":167 - * - * # Get day of datetime - * cdef inline int datetime_day(object o): # <<<<<<<<<<<<<< - * return PyDateTime_GET_DAY(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":171 - * - * # Get hour of time - * cdef inline int time_hour(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_HOUR(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_hour(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("time_hour", 0); - - /* "cpython/datetime.pxd":172 - * # Get hour of time - * cdef inline int time_hour(object o): - * return PyDateTime_TIME_GET_HOUR(o) # <<<<<<<<<<<<<< - * - * # Get minute of time - */ - __pyx_r = PyDateTime_TIME_GET_HOUR(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":171 - * - * # Get hour of time - * cdef inline int time_hour(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_HOUR(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":175 - * - * # Get minute of time - * cdef inline int time_minute(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_MINUTE(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_minute(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("time_minute", 0); - - /* "cpython/datetime.pxd":176 - * # Get minute of time - * cdef inline int time_minute(object o): - * return PyDateTime_TIME_GET_MINUTE(o) # <<<<<<<<<<<<<< - * - * # Get second of time - */ - __pyx_r = PyDateTime_TIME_GET_MINUTE(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":175 - * - * # Get minute of time - * cdef inline int time_minute(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_MINUTE(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":179 - * - * # Get second of time - * cdef inline int time_second(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_SECOND(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_second(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("time_second", 0); - - /* "cpython/datetime.pxd":180 - * # Get second of time - * cdef inline int time_second(object o): - * return PyDateTime_TIME_GET_SECOND(o) # <<<<<<<<<<<<<< - * - * # Get microsecond of time - */ - __pyx_r = PyDateTime_TIME_GET_SECOND(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":179 - * - * # Get second of time - * cdef inline int time_second(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_SECOND(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":183 - * - * # Get microsecond of time - * cdef inline int time_microsecond(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_MICROSECOND(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_time_microsecond(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("time_microsecond", 0); - - /* "cpython/datetime.pxd":184 - * # Get microsecond of time - * cdef inline int time_microsecond(object o): - * return PyDateTime_TIME_GET_MICROSECOND(o) # <<<<<<<<<<<<<< - * - * # Get hour of datetime - */ - __pyx_r = PyDateTime_TIME_GET_MICROSECOND(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":183 - * - * # Get microsecond of time - * cdef inline int time_microsecond(object o): # <<<<<<<<<<<<<< - * return PyDateTime_TIME_GET_MICROSECOND(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":187 - * - * # Get hour of datetime - * cdef inline int datetime_hour(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_HOUR(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_hour(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("datetime_hour", 0); - - /* "cpython/datetime.pxd":188 - * # Get hour of datetime - * cdef inline int datetime_hour(object o): - * return PyDateTime_DATE_GET_HOUR(o) # <<<<<<<<<<<<<< - * - * # Get minute of datetime - */ - __pyx_r = PyDateTime_DATE_GET_HOUR(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":187 - * - * # Get hour of datetime - * cdef inline int datetime_hour(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_HOUR(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":191 - * - * # Get minute of datetime - * cdef inline int datetime_minute(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_MINUTE(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_minute(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("datetime_minute", 0); - - /* "cpython/datetime.pxd":192 - * # Get minute of datetime - * cdef inline int datetime_minute(object o): - * return PyDateTime_DATE_GET_MINUTE(o) # <<<<<<<<<<<<<< - * - * # Get second of datetime - */ - __pyx_r = PyDateTime_DATE_GET_MINUTE(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":191 - * - * # Get minute of datetime - * cdef inline int datetime_minute(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_MINUTE(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":195 - * - * # Get second of datetime - * cdef inline int datetime_second(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_SECOND(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_second(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("datetime_second", 0); - - /* "cpython/datetime.pxd":196 - * # Get second of datetime - * cdef inline int datetime_second(object o): - * return PyDateTime_DATE_GET_SECOND(o) # <<<<<<<<<<<<<< - * - * # Get microsecond of datetime - */ - __pyx_r = PyDateTime_DATE_GET_SECOND(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":195 - * - * # Get second of datetime - * cdef inline int datetime_second(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_SECOND(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":199 - * - * # Get microsecond of datetime - * cdef inline int datetime_microsecond(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_MICROSECOND(o) - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_datetime_microsecond(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("datetime_microsecond", 0); - - /* "cpython/datetime.pxd":200 - * # Get microsecond of datetime - * cdef inline int datetime_microsecond(object o): - * return PyDateTime_DATE_GET_MICROSECOND(o) # <<<<<<<<<<<<<< - * - * # Get days of timedelta - */ - __pyx_r = PyDateTime_DATE_GET_MICROSECOND(__pyx_v_o); - goto __pyx_L0; - - /* "cpython/datetime.pxd":199 - * - * # Get microsecond of datetime - * cdef inline int datetime_microsecond(object o): # <<<<<<<<<<<<<< - * return PyDateTime_DATE_GET_MICROSECOND(o) - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":203 - * - * # Get days of timedelta - * cdef inline int timedelta_days(object o): # <<<<<<<<<<<<<< - * return (o).days - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_timedelta_days(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("timedelta_days", 0); - - /* "cpython/datetime.pxd":204 - * # Get days of timedelta - * cdef inline int timedelta_days(object o): - * return (o).days # <<<<<<<<<<<<<< - * - * # Get seconds of timedelta - */ - __pyx_r = ((PyDateTime_Delta *)__pyx_v_o)->days; - goto __pyx_L0; - - /* "cpython/datetime.pxd":203 - * - * # Get days of timedelta - * cdef inline int timedelta_days(object o): # <<<<<<<<<<<<<< - * return (o).days - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":207 - * - * # Get seconds of timedelta - * cdef inline int timedelta_seconds(object o): # <<<<<<<<<<<<<< - * return (o).seconds - * - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_timedelta_seconds(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("timedelta_seconds", 0); - - /* "cpython/datetime.pxd":208 - * # Get seconds of timedelta - * cdef inline int timedelta_seconds(object o): - * return (o).seconds # <<<<<<<<<<<<<< - * - * # Get microseconds of timedelta - */ - __pyx_r = ((PyDateTime_Delta *)__pyx_v_o)->seconds; - goto __pyx_L0; - - /* "cpython/datetime.pxd":207 - * - * # Get seconds of timedelta - * cdef inline int timedelta_seconds(object o): # <<<<<<<<<<<<<< - * return (o).seconds - * - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "cpython/datetime.pxd":211 - * - * # Get microseconds of timedelta - * cdef inline int timedelta_microseconds(object o): # <<<<<<<<<<<<<< - * return (o).microseconds - */ - -static CYTHON_INLINE int __pyx_f_7cpython_8datetime_timedelta_microseconds(PyObject *__pyx_v_o) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("timedelta_microseconds", 0); - - /* "cpython/datetime.pxd":212 - * # Get microseconds of timedelta - * cdef inline int timedelta_microseconds(object o): - * return (o).microseconds # <<<<<<<<<<<<<< - */ - __pyx_r = ((PyDateTime_Delta *)__pyx_v_o)->microseconds; - goto __pyx_L0; - - /* "cpython/datetime.pxd":211 - * - * # Get microseconds of timedelta - * cdef inline int timedelta_microseconds(object o): # <<<<<<<<<<<<<< - * return (o).microseconds - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampMicros(PyTypeObject *t, PyObject *a, PyObject *k) { - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - if (unlikely(__pyx_pw_7questdb_7ingress_15TimestampMicros_1__cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_7questdb_7ingress_TimestampMicros(PyObject *o) { - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - (*Py_TYPE(o)->tp_free)(o); -} - -static PyObject *__pyx_getprop_7questdb_7ingress_15TimestampMicros_value(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7questdb_7ingress_15TimestampMicros_5value_1__get__(o); -} - -static PyMethodDef __pyx_methods_7questdb_7ingress_TimestampMicros[] = { - {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_15TimestampMicros_2from_datetime}, - {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_5__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_15TimestampMicros_7__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_TimestampMicros[] = { - {(char *)"value", __pyx_getprop_7questdb_7ingress_15TimestampMicros_value, 0, (char *)"Number of microseconds.", 0}, - {0, 0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7questdb_7ingress_TimestampMicros = { - PyVarObject_HEAD_INIT(0, 0) - "questdb.ingress.TimestampMicros", /*tp_name*/ - sizeof(struct __pyx_obj_7questdb_7ingress_TimestampMicros), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7questdb_7ingress_TimestampMicros, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "\n A timestamp in microseconds since the UNIX epoch.\n\n You may construct a ``TimestampMicros`` from an integer or a ``datetime``.\n\n .. code-block:: python\n\n # Can't be negative.\n TimestampMicros(1657888365426838016)\n\n # Careful with the timezeone!\n TimestampMicros.from_datetime(datetime.datetime.utcnow())\n\n When constructing from a ``datetime``, you should take extra care\n to ensure that the timezone is correct.\n\n For example, ``datetime.now()`` implies the `local` timezone which\n is probably not what you want.\n\n When constructing the ``datetime`` object explicity, you pass in the\n timezone to use.\n\n .. code-block:: python\n\n TimestampMicros.from_datetime(\n datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc))\n\n ", /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7questdb_7ingress_TimestampMicros, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7questdb_7ingress_TimestampMicros, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7questdb_7ingress_TimestampMicros, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; - -static PyObject *__pyx_tp_new_7questdb_7ingress_TimestampNanos(PyTypeObject *t, PyObject *a, PyObject *k) { - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - if (unlikely(__pyx_pw_7questdb_7ingress_14TimestampNanos_1__cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_7questdb_7ingress_TimestampNanos(PyObject *o) { - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - (*Py_TYPE(o)->tp_free)(o); -} - -static PyObject *__pyx_getprop_7questdb_7ingress_14TimestampNanos_value(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7questdb_7ingress_14TimestampNanos_5value_1__get__(o); -} - -static PyMethodDef __pyx_methods_7questdb_7ingress_TimestampNanos[] = { - {"from_datetime", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_3from_datetime, METH_O, __pyx_doc_7questdb_7ingress_14TimestampNanos_2from_datetime}, - {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_5__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_14TimestampNanos_7__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_TimestampNanos[] = { - {(char *)"value", __pyx_getprop_7questdb_7ingress_14TimestampNanos_value, 0, (char *)"Number of nanoseconds.", 0}, - {0, 0, 0, 0, 0} -}; - -static PyTypeObject __pyx_type_7questdb_7ingress_TimestampNanos = { - PyVarObject_HEAD_INIT(0, 0) - "questdb.ingress.TimestampNanos", /*tp_name*/ - sizeof(struct __pyx_obj_7questdb_7ingress_TimestampNanos), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7questdb_7ingress_TimestampNanos, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "\n A timestamp in nanoseconds since the UNIX epoch.\n\n You may construct a ``TimestampNanos`` from an integer or a ``datetime``.\n\n .. code-block:: python\n\n # Can't be negative.\n TimestampNanos(1657888365426838016)\n\n # Careful with the timezeone!\n TimestampNanos.from_datetime(datetime.datetime.utcnow())\n\n When constructing from a ``datetime``, you should take extra care\n to ensure that the timezone is correct.\n\n For example, ``datetime.now()`` implies the `local` timezone which\n is probably not what you want.\n\n When constructing the ``datetime`` object explicity, you pass in the\n timezone to use.\n\n .. code-block:: python\n\n TimestampMicros.from_datetime(\n datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc))\n\n ", /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7questdb_7ingress_TimestampNanos, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7questdb_7ingress_TimestampNanos, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7questdb_7ingress_TimestampNanos, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; -static struct __pyx_vtabstruct_7questdb_7ingress_Sender __pyx_vtable_7questdb_7ingress_Sender; - -static PyObject *__pyx_tp_new_7questdb_7ingress_Sender(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_obj_7questdb_7ingress_Sender *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_obj_7questdb_7ingress_Sender *)o); - p->__pyx_vtab = __pyx_vtabptr_7questdb_7ingress_Sender; - p->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); Py_INCREF(Py_None); - if (unlikely(__pyx_pw_7questdb_7ingress_6Sender_1__cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_7questdb_7ingress_Sender(PyObject *o) { - struct __pyx_obj_7questdb_7ingress_Sender *p = (struct __pyx_obj_7questdb_7ingress_Sender *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_pw_7questdb_7ingress_6Sender_21__dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - if (p->__weakref__) PyObject_ClearWeakRefs(o); - Py_CLEAR(p->_buffer); - (*Py_TYPE(o)->tp_free)(o); -} - -static int __pyx_tp_traverse_7questdb_7ingress_Sender(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7questdb_7ingress_Sender *p = (struct __pyx_obj_7questdb_7ingress_Sender *)o; - if (p->_buffer) { - e = (*v)(((PyObject *)p->_buffer), a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7questdb_7ingress_Sender(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7questdb_7ingress_Sender *p = (struct __pyx_obj_7questdb_7ingress_Sender *)o; - tmp = ((PyObject*)p->_buffer); - p->_buffer = ((struct __pyx_obj_7questdb_7ingress_Buffer *)Py_None); Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyObject *__pyx_getprop_7questdb_7ingress_6Sender_init_capacity(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7questdb_7ingress_6Sender_13init_capacity_1__get__(o); -} - -static PyObject *__pyx_getprop_7questdb_7ingress_6Sender_max_name_len(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7questdb_7ingress_6Sender_12max_name_len_1__get__(o); -} - -static PyMethodDef __pyx_methods_7questdb_7ingress_Sender[] = { - {"new_buffer", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_3new_buffer, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_2new_buffer}, - {"connect", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_5connect, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_4connect}, - {"__enter__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_7__enter__, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Sender_6__enter__}, - {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_13row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_12row}, - {"__exit__", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Sender_19__exit__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Sender_18__exit__}, - {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_23__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Sender_25__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_Sender[] = { - {(char *)"init_capacity", __pyx_getprop_7questdb_7ingress_6Sender_init_capacity, 0, (char *)"The initial capacity of the sender's internal buffer.", 0}, - {(char *)"max_name_len", __pyx_getprop_7questdb_7ingress_6Sender_max_name_len, 0, (char *)"Maximum length of a table or column name.", 0}, - {0, 0, 0, 0, 0} -}; - -static PySequenceMethods __pyx_tp_as_sequence_Sender = { - __pyx_pw_7questdb_7ingress_6Sender_11__len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - 0, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; - -static PyMappingMethods __pyx_tp_as_mapping_Sender = { - __pyx_pw_7questdb_7ingress_6Sender_11__len__, /*mp_length*/ - 0, /*mp_subscript*/ - 0, /*mp_ass_subscript*/ -}; - -static PyTypeObject __pyx_type_7questdb_7ingress_Sender = { - PyVarObject_HEAD_INIT(0, 0) - "questdb.ingress.Sender", /*tp_name*/ - sizeof(struct __pyx_obj_7questdb_7ingress_Sender), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7questdb_7ingress_Sender, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_Sender, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_Sender, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - __pyx_pw_7questdb_7ingress_6Sender_9__str__, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - "\n A sender is a client that inserts rows into QuestDB via the ILP protocol.\n\n **Inserting two rows**\n\n In this example, data will be flushed and sent at the end of the ``with``\n block.\n\n .. code-block:: python\n\n with Sender('localhost', 9009) as sender:\n sender.row(\n 'weather_sensor',\n symbols={'id': 'toronto1'},\n columns={'temperature': 23.5, 'humidity': 0.49})\n sensor.row(\n 'weather_sensor',\n symbols={'id': 'dubai2'},\n columns={'temperature': 41.2, 'humidity': 0.34})\n\n The ``Sender`` object holds an internal buffer. The call to ``.row()``\n simply forwards all arguments to the :func:`Buffer.row` method.\n\n\n **Explicit flushing**\n\n An explicit call to :func:`Sender.flush` will send any pending data\n immediately.\n\n .. code-block:: python\n\n with Sender('localhost', 9009) as sender:\n sender.row(\n 'weather_sensor',\n symbols={'id': 'toronto1'},\n columns={'temperature': 23.5, 'humidity': 0.49})\n sender.flush()\n sender.row(\n 'weather_sensor',\n symbols={'id': 'dubai2'},\n columns={'temperature': 41.2, 'humidity': 0.34})\n sender.flush()\n\n\n **Auto-flushing (on by default, watermark at 63KiB)**\n\n To avoid accumulating very large buffers, the sender will flush the buffer\n automatically once its buffer reaches a certain byte-size watermark.\n\n You can control this behavior by setting the ``auto_flush`` argument.\n\n .. code-block:: python\n\n # Never flushes automatically.\n sender = Sender('localhost', 9009, auto_flush=False)\n sender = Sender('localhost', 9009, auto_flush=None) # Ditto.\n sender = Sender('localhost', 9009, auto_flush=0) # Ditto.\n\n # Flushes automatically when the buffer reach""es 1KiB.\n sender = Sender('localhost', 9009, auto_flush=1024)\n\n # Flushes automatically after every row.\n sender = Sender('localhost', 9009, auto_flush=True)\n sender = Sender('localhost', 9009, auto_flush=1) # Ditto.\n\n\n **Authentication and TLS Encryption**\n\n This implementation supports authentication and TLS full-connection\n encryption.\n\n The ``Sender(.., auth=..)`` argument is a tuple of ``(kid, d, x, y)`` as\n documented on the `QuestDB ILP authentication\n `_ documentation.\n Authentication is optional and disabled by default.\n\n The ``Sender(.., tls=..)`` argument is one of:\n\n * ``False``: No TLS encryption (default).\n\n * ``True``: TLS encryption, accepting all common certificates as recognized\n by the `webpki-roots `_ Rust crate\n which in turn relies on https://mkcert.org/.\n\n * A ``str`` or ``pathlib.Path``: Path to a PEM-encoded certificate authority\n file. This is useful for testing with self-signed certificates.\n\n * A special ``'insecure_skip_verify'`` string: Dangerously disable all\n TLS certificate verification (do *NOT* use in production environments).\n\n **Positional constructor arguments for the Sender(..)**\n\n * ``host``: Hostname or IP address of the QuestDB server.\n\n * ``port``: Port number of the QuestDB server.\n\n\n **Keyword-only constructor arguments for the Sender(..)**\n\n * ``interface`` (``str``): Network interface to bind to.\n Set this if you have an accelerated network interface (e.g. Solarflare)\n and want to use it.\n\n * ``auth`` (``tuple``): Authentication tuple or ``None`` (default).\n *See above for details*.\n\n * ``tls`` (``bool``, ``pathlib.Path`` or ``str``): TLS configuration or\n ``False`` (default). *See above for details*.\n\n * ``read_timeout`` (``int``): How long to wait ""for messages from the QuestDB server\n during the TLS handshake or authentication process.\n This field is expressed in milliseconds. The default is 15 seconds.\n\n * ``init_capacity`` (``int``): Initial buffer capacity of the internal buffer.\n *Default: 65536 (64KiB).*\n *See Buffer's constructor for more details.*\n\n * ``max_name_length`` (``int``): Maximum length of a table or column name.\n *See Buffer's constructor for more details.*\n\n * ``auto_flush`` (``bool`` or ``int``): Whether to automatically flush the\n buffer when it reaches a certain byte-size watermark.\n *Default: 64512 (63KiB).*\n *See above for details.*\n ", /*tp_doc*/ - __pyx_tp_traverse_7questdb_7ingress_Sender, /*tp_traverse*/ - __pyx_tp_clear_7questdb_7ingress_Sender, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7questdb_7ingress_Sender, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7questdb_7ingress_Sender, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7questdb_7ingress_Sender, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; -static struct __pyx_vtabstruct_7questdb_7ingress_Buffer __pyx_vtable_7questdb_7ingress_Buffer; - -static PyObject *__pyx_tp_new_7questdb_7ingress_Buffer(PyTypeObject *t, PyObject *a, PyObject *k) { - struct __pyx_obj_7questdb_7ingress_Buffer *p; - PyObject *o; - if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { - o = (*t->tp_alloc)(t, 0); - } else { - o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); - } - if (unlikely(!o)) return 0; - p = ((struct __pyx_obj_7questdb_7ingress_Buffer *)o); - p->__pyx_vtab = __pyx_vtabptr_7questdb_7ingress_Buffer; - p->_row_complete_sender = Py_None; Py_INCREF(Py_None); - if (unlikely(__pyx_pw_7questdb_7ingress_6Buffer_1__cinit__(o, a, k) < 0)) goto bad; - return o; - bad: - Py_DECREF(o); o = 0; - return NULL; -} - -static void __pyx_tp_dealloc_7questdb_7ingress_Buffer(PyObject *o) { - struct __pyx_obj_7questdb_7ingress_Buffer *p = (struct __pyx_obj_7questdb_7ingress_Buffer *)o; - #if CYTHON_USE_TP_FINALIZE - if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { - if (PyObject_CallFinalizerFromDealloc(o)) return; - } - #endif - PyObject_GC_UnTrack(o); - { - PyObject *etype, *eval, *etb; - PyErr_Fetch(&etype, &eval, &etb); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); - __pyx_pw_7questdb_7ingress_6Buffer_3__dealloc__(o); - __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); - PyErr_Restore(etype, eval, etb); - } - Py_CLEAR(p->_row_complete_sender); - (*Py_TYPE(o)->tp_free)(o); -} - -static int __pyx_tp_traverse_7questdb_7ingress_Buffer(PyObject *o, visitproc v, void *a) { - int e; - struct __pyx_obj_7questdb_7ingress_Buffer *p = (struct __pyx_obj_7questdb_7ingress_Buffer *)o; - if (p->_row_complete_sender) { - e = (*v)(p->_row_complete_sender, a); if (e) return e; - } - return 0; -} - -static int __pyx_tp_clear_7questdb_7ingress_Buffer(PyObject *o) { - PyObject* tmp; - struct __pyx_obj_7questdb_7ingress_Buffer *p = (struct __pyx_obj_7questdb_7ingress_Buffer *)o; - tmp = ((PyObject*)p->_row_complete_sender); - p->_row_complete_sender = Py_None; Py_INCREF(Py_None); - Py_XDECREF(tmp); - return 0; -} - -static PyObject *__pyx_getprop_7questdb_7ingress_6Buffer_init_capacity(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7questdb_7ingress_6Buffer_13init_capacity_1__get__(o); -} - -static PyObject *__pyx_getprop_7questdb_7ingress_6Buffer_max_name_len(PyObject *o, CYTHON_UNUSED void *x) { - return __pyx_pw_7questdb_7ingress_6Buffer_12max_name_len_1__get__(o); -} - -static PyMethodDef __pyx_methods_7questdb_7ingress_Buffer[] = { - {"reserve", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_5reserve, METH_O, __pyx_doc_7questdb_7ingress_6Buffer_4reserve}, - {"capacity", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_7capacity, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_6capacity}, - {"clear", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_9clear, METH_NOARGS, __pyx_doc_7questdb_7ingress_6Buffer_8clear}, - {"row", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_15row, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_14row}, - {"pandas", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7questdb_7ingress_6Buffer_17pandas, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7questdb_7ingress_6Buffer_16pandas}, - {"__reduce_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_19__reduce_cython__, METH_NOARGS, 0}, - {"__setstate_cython__", (PyCFunction)__pyx_pw_7questdb_7ingress_6Buffer_21__setstate_cython__, METH_O, 0}, - {0, 0, 0, 0} -}; - -static struct PyGetSetDef __pyx_getsets_7questdb_7ingress_Buffer[] = { - {(char *)"init_capacity", __pyx_getprop_7questdb_7ingress_6Buffer_init_capacity, 0, (char *)"\n The initial capacity of the buffer when first created.\n\n This may grow over time, see ``capacity()``.\n ", 0}, - {(char *)"max_name_len", __pyx_getprop_7questdb_7ingress_6Buffer_max_name_len, 0, (char *)"Maximum length of a table or column name.", 0}, - {0, 0, 0, 0, 0} -}; - -static PySequenceMethods __pyx_tp_as_sequence_Buffer = { - __pyx_pw_7questdb_7ingress_6Buffer_11__len__, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - 0, /*sq_item*/ - 0, /*sq_slice*/ - 0, /*sq_ass_item*/ - 0, /*sq_ass_slice*/ - 0, /*sq_contains*/ - 0, /*sq_inplace_concat*/ - 0, /*sq_inplace_repeat*/ -}; - -static PyMappingMethods __pyx_tp_as_mapping_Buffer = { - __pyx_pw_7questdb_7ingress_6Buffer_11__len__, /*mp_length*/ - 0, /*mp_subscript*/ - 0, /*mp_ass_subscript*/ -}; - -static PyTypeObject __pyx_type_7questdb_7ingress_Buffer = { - PyVarObject_HEAD_INIT(0, 0) - "questdb.ingress.Buffer", /*tp_name*/ - sizeof(struct __pyx_obj_7questdb_7ingress_Buffer), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - __pyx_tp_dealloc_7questdb_7ingress_Buffer, /*tp_dealloc*/ - #if PY_VERSION_HEX < 0x030800b4 - 0, /*tp_print*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 - 0, /*tp_vectorcall_offset*/ - #endif - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - #if PY_MAJOR_VERSION < 3 - 0, /*tp_compare*/ - #endif - #if PY_MAJOR_VERSION >= 3 - 0, /*tp_as_async*/ - #endif - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - &__pyx_tp_as_sequence_Buffer, /*tp_as_sequence*/ - &__pyx_tp_as_mapping_Buffer, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - __pyx_pw_7questdb_7ingress_6Buffer_13__str__, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - "\n Construct QuestDB-flavored InfluxDB Line Protocol (ILP) messages.\n\n The :func:`Buffer.row` method is used to add a row to the buffer.\n\n You can call this many times.\n\n .. code-block:: python\n\n from questdb.ingress import Buffer\n\n buf = Buffer()\n buf.row(\n 'table_name1',\n symbols={'s1', 'v1', 's2', 'v2'},\n columns={'c1': True, 'c2': 0.5})\n\n buf.row(\n 'table_name2',\n symbols={'questdb': '\342\235\244\357\270\217'},\n columns={'like': 100000})\n\n # Append any additional rows then, once ready, call\n sender.flush(buffer) # a `Sender` instance.\n\n # The sender auto-cleared the buffer, ready for reuse.\n\n buf.row(\n 'table_name1',\n symbols={'s1', 'v1', 's2', 'v2'},\n columns={'c1': True, 'c2': 0.5})\n\n # etc.\n\n\n Buffer Constructor Arguments:\n * ``init_capacity`` (``int``): Initial capacity of the buffer in bytes.\n Defaults to ``65536`` (64KiB).\n * ``max_name_len`` (``int``): Maximum length of a column name.\n Defaults to ``127`` which is the same default value as QuestDB.\n This should match the ``cairo.max.file.name.length`` setting of the\n QuestDB instance you're connecting to.\n\n .. code-block:: python\n\n # These two buffer constructions are equivalent.\n buf1 = Buffer()\n buf2 = Buffer(init_capacity=65536, max_name_len=127)\n\n To avoid having to manually set these arguments every time, you can call\n the sender's ``new_buffer()`` method instead.\n\n .. code-block:: python\n\n from questdb.ingress import Sender, Buffer\n\n sender = Sender(host='localhost', port=9009,\n init_capacity=16384, max_name_len=64)\n buf = sender.new_buffer()\n assert buf.init_capacity == 16384\n assert buf.max_name_len == 64\n\n ", /*tp_doc*/ - __pyx_tp_traverse_7questdb_7ingress_Buffer, /*tp_traverse*/ - __pyx_tp_clear_7questdb_7ingress_Buffer, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - __pyx_methods_7questdb_7ingress_Buffer, /*tp_methods*/ - 0, /*tp_members*/ - __pyx_getsets_7questdb_7ingress_Buffer, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - __pyx_tp_new_7questdb_7ingress_Buffer, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_cache*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ - 0, /*tp_del*/ - 0, /*tp_version_tag*/ - #if PY_VERSION_HEX >= 0x030400a1 - 0, /*tp_finalize*/ - #endif - #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, /*tp_vectorcall*/ - #endif - #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, /*tp_print*/ - #endif - #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, /*tp_pypy_flags*/ - #endif -}; - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec_ingress(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec_ingress}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "ingress", - __pyx_k_API_for_fast_data_ingestion_int, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif -#ifndef CYTHON_SMALL_CODE -#if defined(__clang__) - #define CYTHON_SMALL_CODE -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) - #define CYTHON_SMALL_CODE __attribute__((cold)) -#else - #define CYTHON_SMALL_CODE -#endif -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_s_An_error_whilst_using_the_Sender, __pyx_k_An_error_whilst_using_the_Sender, sizeof(__pyx_k_An_error_whilst_using_the_Sender), 0, 0, 1, 0}, - {&__pyx_n_s_Any, __pyx_k_Any, sizeof(__pyx_k_Any), 0, 0, 1, 1}, - {&__pyx_n_s_AuthError, __pyx_k_AuthError, sizeof(__pyx_k_AuthError), 0, 0, 1, 1}, - {&__pyx_kp_u_Bad_argument, __pyx_k_Bad_argument, sizeof(__pyx_k_Bad_argument), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_at_Bad_dtype, __pyx_k_Bad_argument_at_Bad_dtype, sizeof(__pyx_k_Bad_argument_at_Bad_dtype), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_at_Unsupported_type, __pyx_k_Bad_argument_at_Unsupported_type, sizeof(__pyx_k_Bad_argument_at_Unsupported_type), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_data_Expected, __pyx_k_Bad_argument_data_Expected, sizeof(__pyx_k_Bad_argument_data_Expected), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_symbols_Cannot_use, __pyx_k_Bad_argument_symbols_Cannot_use, sizeof(__pyx_k_Bad_argument_symbols_Cannot_use), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_symbols_Cannot_use_2, __pyx_k_Bad_argument_symbols_Cannot_use_2, sizeof(__pyx_k_Bad_argument_symbols_Cannot_use_2), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_symbols_Elements_mu, __pyx_k_Bad_argument_symbols_Elements_mu, sizeof(__pyx_k_Bad_argument_symbols_Elements_mu), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_symbols_Must_be_a_b, __pyx_k_Bad_argument_symbols_Must_be_a_b, sizeof(__pyx_k_Bad_argument_symbols_Must_be_a_b), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_table_name, __pyx_k_Bad_argument_table_name, sizeof(__pyx_k_Bad_argument_table_name), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_table_name_Must_be, __pyx_k_Bad_argument_table_name_Must_be, sizeof(__pyx_k_Bad_argument_table_name_Must_be), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_table_name_col, __pyx_k_Bad_argument_table_name_col, sizeof(__pyx_k_Bad_argument_table_name_col), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_argument_table_name_col_must, __pyx_k_Bad_argument_table_name_col_must, sizeof(__pyx_k_Bad_argument_table_name_col_must), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_column_Expected_a_numpy_arra, __pyx_k_Bad_column_Expected_a_numpy_arra, sizeof(__pyx_k_Bad_column_Expected_a_numpy_arra), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_column_Expected_a_string, __pyx_k_Bad_column_Expected_a_string, sizeof(__pyx_k_Bad_column_Expected_a_string), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_dtype, __pyx_k_Bad_dtype, sizeof(__pyx_k_Bad_dtype), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_element_in_argument_symbols, __pyx_k_Bad_element_in_argument_symbols, sizeof(__pyx_k_Bad_element_in_argument_symbols), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_value_Negative_timestamp_got, __pyx_k_Bad_value_Negative_timestamp_got, sizeof(__pyx_k_Bad_value_Negative_timestamp_got), 0, 1, 0, 0}, - {&__pyx_kp_u_Bad_value_None_table_name_value, __pyx_k_Bad_value_None_table_name_value, sizeof(__pyx_k_Bad_value_None_table_name_value), 0, 1, 0, 0}, - {&__pyx_n_s_Buffer, __pyx_k_Buffer, sizeof(__pyx_k_Buffer), 0, 0, 1, 1}, - {&__pyx_n_s_Buffer___reduce_cython, __pyx_k_Buffer___reduce_cython, sizeof(__pyx_k_Buffer___reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_Buffer___setstate_cython, __pyx_k_Buffer___setstate_cython, sizeof(__pyx_k_Buffer___setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_Buffer_capacity, __pyx_k_Buffer_capacity, sizeof(__pyx_k_Buffer_capacity), 0, 0, 1, 1}, - {&__pyx_n_s_Buffer_clear, __pyx_k_Buffer_clear, sizeof(__pyx_k_Buffer_clear), 0, 0, 1, 1}, - {&__pyx_n_s_Buffer_pandas, __pyx_k_Buffer_pandas, sizeof(__pyx_k_Buffer_pandas), 0, 0, 1, 1}, - {&__pyx_n_s_Buffer_reserve, __pyx_k_Buffer_reserve, sizeof(__pyx_k_Buffer_reserve), 0, 0, 1, 1}, - {&__pyx_n_s_Buffer_row, __pyx_k_Buffer_row, sizeof(__pyx_k_Buffer_row), 0, 0, 1, 1}, - {&__pyx_n_s_Callable, __pyx_k_Callable, sizeof(__pyx_k_Callable), 0, 0, 1, 1}, - {&__pyx_kp_u_Can_specify_only_one_of_table_na, __pyx_k_Can_specify_only_one_of_table_na, sizeof(__pyx_k_Can_specify_only_one_of_table_na), 0, 1, 0, 0}, - {&__pyx_kp_u_Cannot_be_encoded_as_UTF_8, __pyx_k_Cannot_be_encoded_as_UTF_8, sizeof(__pyx_k_Cannot_be_encoded_as_UTF_8), 0, 1, 0, 0}, - {&__pyx_kp_s_Category_of_Error, __pyx_k_Category_of_Error, sizeof(__pyx_k_Category_of_Error), 0, 0, 1, 0}, - {&__pyx_kp_u_Character_out_of_ASCII_range_go, __pyx_k_Character_out_of_ASCII_range_go, sizeof(__pyx_k_Character_out_of_ASCII_range_go), 0, 1, 0, 0}, - {&__pyx_kp_u_Column, __pyx_k_Column, sizeof(__pyx_k_Column), 0, 1, 0, 0}, - {&__pyx_n_s_CouldNotResolveAddr, __pyx_k_CouldNotResolveAddr, sizeof(__pyx_k_CouldNotResolveAddr), 0, 0, 1, 1}, - {&__pyx_n_u_DataFrame, __pyx_k_DataFrame, sizeof(__pyx_k_DataFrame), 0, 1, 0, 1}, - {&__pyx_n_s_Dict, __pyx_k_Dict, sizeof(__pyx_k_Dict), 0, 0, 1, 1}, - {&__pyx_n_s_Enum, __pyx_k_Enum, sizeof(__pyx_k_Enum), 0, 0, 1, 1}, - {&__pyx_kp_u_Expected_a_single_character_got, __pyx_k_Expected_a_single_character_got, sizeof(__pyx_k_Expected_a_single_character_got), 0, 1, 0, 0}, - {&__pyx_n_s_FLUSH_FMT, __pyx_k_FLUSH_FMT, sizeof(__pyx_k_FLUSH_FMT), 0, 0, 1, 1}, - {&__pyx_kp_u_Found_non_string_value, __pyx_k_Found_non_string_value, sizeof(__pyx_k_Found_non_string_value), 0, 1, 0, 0}, - {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, - {&__pyx_n_s_IngressError, __pyx_k_IngressError, sizeof(__pyx_k_IngressError), 0, 0, 1, 1}, - {&__pyx_n_s_IngressErrorCode, __pyx_k_IngressErrorCode, sizeof(__pyx_k_IngressErrorCode), 0, 0, 1, 1}, - {&__pyx_n_s_IngressErrorCode___str, __pyx_k_IngressErrorCode___str, sizeof(__pyx_k_IngressErrorCode___str), 0, 0, 1, 1}, - {&__pyx_n_s_IngressError___init, __pyx_k_IngressError___init, sizeof(__pyx_k_IngressError___init), 0, 0, 1, 1}, - {&__pyx_n_s_IngressError_code, __pyx_k_IngressError_code, sizeof(__pyx_k_IngressError_code), 0, 0, 1, 1}, - {&__pyx_kp_u_Internal_error_converting_error, __pyx_k_Internal_error_converting_error, sizeof(__pyx_k_Internal_error_converting_error), 0, 1, 0, 0}, - {&__pyx_n_s_InvalidApiCall, __pyx_k_InvalidApiCall, sizeof(__pyx_k_InvalidApiCall), 0, 0, 1, 1}, - {&__pyx_n_s_InvalidName, __pyx_k_InvalidName, sizeof(__pyx_k_InvalidName), 0, 0, 1, 1}, - {&__pyx_n_s_InvalidTimestamp, __pyx_k_InvalidTimestamp, sizeof(__pyx_k_InvalidTimestamp), 0, 0, 1, 1}, - {&__pyx_n_s_InvalidUtf8, __pyx_k_InvalidUtf8, sizeof(__pyx_k_InvalidUtf8), 0, 0, 1, 1}, - {&__pyx_kp_u_Invalid_codepoint_0x, __pyx_k_Invalid_codepoint_0x, sizeof(__pyx_k_Invalid_codepoint_0x), 0, 1, 0, 0}, - {&__pyx_n_s_Iterable, __pyx_k_Iterable, sizeof(__pyx_k_Iterable), 0, 0, 1, 1}, - {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, - {&__pyx_n_s_List, __pyx_k_List, sizeof(__pyx_k_List), 0, 0, 1, 1}, - {&__pyx_n_u_M, __pyx_k_M, sizeof(__pyx_k_M), 0, 1, 0, 1}, - {&__pyx_kp_u_Must_be_one_of, __pyx_k_Must_be_one_of, sizeof(__pyx_k_Must_be_one_of), 0, 1, 0, 0}, - {&__pyx_kp_u_Must_be_one_of_None_TimestampNan, __pyx_k_Must_be_one_of_None_TimestampNan, sizeof(__pyx_k_Must_be_one_of_None_TimestampNan), 0, 1, 0, 0}, - {&__pyx_kp_u_Must_specify_at_least_one_of_tab, __pyx_k_Must_specify_at_least_one_of_tab, sizeof(__pyx_k_Must_specify_at_least_one_of_tab), 0, 1, 0, 0}, - {&__pyx_n_s_NA, __pyx_k_NA, sizeof(__pyx_k_NA), 0, 0, 1, 1}, - {&__pyx_kp_u_NOT_YET_IMPLEMENTED_Kind, __pyx_k_NOT_YET_IMPLEMENTED_Kind, sizeof(__pyx_k_NOT_YET_IMPLEMENTED_Kind), 0, 1, 0, 0}, - {&__pyx_kp_u_None, __pyx_k_None, sizeof(__pyx_k_None), 0, 1, 0, 0}, - {&__pyx_n_u_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 1, 0, 1}, - {&__pyx_n_s_Optional, __pyx_k_Optional, sizeof(__pyx_k_Optional), 0, 0, 1, 1}, - {&__pyx_n_s_Path, __pyx_k_Path, sizeof(__pyx_k_Path), 0, 0, 1, 1}, - {&__pyx_n_u_S, __pyx_k_S, sizeof(__pyx_k_S), 0, 1, 0, 1}, - {&__pyx_n_u_SO, __pyx_k_SO, sizeof(__pyx_k_SO), 0, 1, 0, 1}, - {&__pyx_kp_u_See_https_py_questdb_client_rea, __pyx_k_See_https_py_questdb_client_rea, sizeof(__pyx_k_See_https_py_questdb_client_rea), 0, 1, 0, 0}, - {&__pyx_n_s_Sender, __pyx_k_Sender, sizeof(__pyx_k_Sender), 0, 0, 1, 1}, - {&__pyx_n_u_Sender, __pyx_k_Sender, sizeof(__pyx_k_Sender), 0, 1, 0, 1}, - {&__pyx_n_s_Sender___enter, __pyx_k_Sender___enter, sizeof(__pyx_k_Sender___enter), 0, 0, 1, 1}, - {&__pyx_n_s_Sender___exit, __pyx_k_Sender___exit, sizeof(__pyx_k_Sender___exit), 0, 0, 1, 1}, - {&__pyx_n_s_Sender___reduce_cython, __pyx_k_Sender___reduce_cython, sizeof(__pyx_k_Sender___reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_Sender___setstate_cython, __pyx_k_Sender___setstate_cython, sizeof(__pyx_k_Sender___setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_s_Sender_close, __pyx_k_Sender_close, sizeof(__pyx_k_Sender_close), 0, 0, 1, 1}, - {&__pyx_n_s_Sender_connect, __pyx_k_Sender_connect, sizeof(__pyx_k_Sender_connect), 0, 0, 1, 1}, - {&__pyx_n_s_Sender_flush, __pyx_k_Sender_flush, sizeof(__pyx_k_Sender_flush), 0, 0, 1, 1}, - {&__pyx_n_s_Sender_new_buffer, __pyx_k_Sender_new_buffer, sizeof(__pyx_k_Sender_new_buffer), 0, 0, 1, 1}, - {&__pyx_n_s_Sender_row, __pyx_k_Sender_row, sizeof(__pyx_k_Sender_row), 0, 0, 1, 1}, - {&__pyx_n_s_SocketError, __pyx_k_SocketError, sizeof(__pyx_k_SocketError), 0, 0, 1, 1}, - {&__pyx_kp_u_The_internal_buffer_must_always, __pyx_k_The_internal_buffer_must_always, sizeof(__pyx_k_The_internal_buffer_must_always), 0, 1, 0, 0}, - {&__pyx_n_s_TimestampMicros, __pyx_k_TimestampMicros, sizeof(__pyx_k_TimestampMicros), 0, 0, 1, 1}, - {&__pyx_n_u_TimestampMicros, __pyx_k_TimestampMicros, sizeof(__pyx_k_TimestampMicros), 0, 1, 0, 1}, - {&__pyx_n_s_TimestampMicros___reduce_cython, __pyx_k_TimestampMicros___reduce_cython, sizeof(__pyx_k_TimestampMicros___reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_TimestampMicros___setstate_cytho, __pyx_k_TimestampMicros___setstate_cytho, sizeof(__pyx_k_TimestampMicros___setstate_cytho), 0, 0, 1, 1}, - {&__pyx_n_s_TimestampMicros_from_datetime, __pyx_k_TimestampMicros_from_datetime, sizeof(__pyx_k_TimestampMicros_from_datetime), 0, 0, 1, 1}, - {&__pyx_n_s_TimestampNanos, __pyx_k_TimestampNanos, sizeof(__pyx_k_TimestampNanos), 0, 0, 1, 1}, - {&__pyx_n_s_TimestampNanos___reduce_cython, __pyx_k_TimestampNanos___reduce_cython, sizeof(__pyx_k_TimestampNanos___reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_TimestampNanos___setstate_cython, __pyx_k_TimestampNanos___setstate_cython, sizeof(__pyx_k_TimestampNanos___setstate_cython), 0, 0, 1, 1}, - {&__pyx_kp_u_TimestampNanos_datetime_None, __pyx_k_TimestampNanos_datetime_None, sizeof(__pyx_k_TimestampNanos_datetime_None), 0, 1, 0, 0}, - {&__pyx_n_s_TimestampNanos_from_datetime, __pyx_k_TimestampNanos_from_datetime, sizeof(__pyx_k_TimestampNanos_from_datetime), 0, 0, 1, 1}, - {&__pyx_n_s_TlsError, __pyx_k_TlsError, sizeof(__pyx_k_TlsError), 0, 0, 1, 1}, - {&__pyx_n_s_Tuple, __pyx_k_Tuple, sizeof(__pyx_k_Tuple), 0, 0, 1, 1}, - {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, - {&__pyx_n_s_Union, __pyx_k_Union, sizeof(__pyx_k_Union), 0, 0, 1, 1}, - {&__pyx_kp_u_Unknown_UCS_kind, __pyx_k_Unknown_UCS_kind, sizeof(__pyx_k_Unknown_UCS_kind), 0, 1, 0, 0}, - {&__pyx_kp_u_Unsupported_type, __pyx_k_Unsupported_type, sizeof(__pyx_k_Unsupported_type), 0, 1, 0, 0}, - {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, - {&__pyx_kp_u__10, __pyx_k__10, sizeof(__pyx_k__10), 0, 1, 0, 0}, - {&__pyx_kp_u__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 1, 0, 0}, - {&__pyx_kp_u__12, __pyx_k__12, sizeof(__pyx_k__12), 0, 1, 0, 0}, - {&__pyx_kp_u__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 1, 0, 0}, - {&__pyx_kp_u__15, __pyx_k__15, sizeof(__pyx_k__15), 0, 1, 0, 0}, - {&__pyx_kp_u__17, __pyx_k__17, sizeof(__pyx_k__17), 0, 1, 0, 0}, - {&__pyx_kp_u__24, __pyx_k__24, sizeof(__pyx_k__24), 0, 1, 0, 0}, - {&__pyx_kp_u__27, __pyx_k__27, sizeof(__pyx_k__27), 0, 1, 0, 0}, - {&__pyx_kp_u__5, __pyx_k__5, sizeof(__pyx_k__5), 0, 1, 0, 0}, - {&__pyx_kp_u__6, __pyx_k__6, sizeof(__pyx_k__6), 0, 1, 0, 0}, - {&__pyx_kp_u__9, __pyx_k__9, sizeof(__pyx_k__9), 0, 1, 0, 0}, - {&__pyx_n_s_additional, __pyx_k_additional, sizeof(__pyx_k_additional), 0, 0, 1, 1}, - {&__pyx_kp_u_additional_must_be_non_negative, __pyx_k_additional_must_be_non_negative, sizeof(__pyx_k_additional_must_be_non_negative), 0, 1, 0, 0}, - {&__pyx_n_s_alignment, __pyx_k_alignment, sizeof(__pyx_k_alignment), 0, 0, 1, 1}, - {&__pyx_n_u_alignment, __pyx_k_alignment, sizeof(__pyx_k_alignment), 0, 1, 0, 1}, - {&__pyx_kp_u_as_a_symbol_column, __pyx_k_as_a_symbol_column, sizeof(__pyx_k_as_a_symbol_column), 0, 1, 0, 0}, - {&__pyx_kp_u_as_both_the_table_name_and_as_a, __pyx_k_as_both_the_table_name_and_as_a, sizeof(__pyx_k_as_both_the_table_name_and_as_a), 0, 1, 0, 0}, - {&__pyx_n_s_at, __pyx_k_at, sizeof(__pyx_k_at), 0, 0, 1, 1}, - {&__pyx_n_u_at, __pyx_k_at, sizeof(__pyx_k_at), 0, 1, 0, 1}, - {&__pyx_kp_u_at_2, __pyx_k_at_2, sizeof(__pyx_k_at_2), 0, 1, 0, 0}, - {&__pyx_kp_u_at_col, __pyx_k_at_col, sizeof(__pyx_k_at_col), 0, 1, 0, 0}, - {&__pyx_kp_u_at_value, __pyx_k_at_value, sizeof(__pyx_k_at_value), 0, 1, 0, 0}, - {&__pyx_n_s_auth, __pyx_k_auth, sizeof(__pyx_k_auth), 0, 0, 1, 1}, - {&__pyx_n_s_auto_flush, __pyx_k_auto_flush, sizeof(__pyx_k_auto_flush), 0, 0, 1, 1}, - {&__pyx_kp_u_auto_flush_watermark_must_be_0_n, __pyx_k_auto_flush_watermark_must_be_0_n, sizeof(__pyx_k_auto_flush_watermark_must_be_0_n), 0, 1, 0, 0}, - {&__pyx_n_u_bool, __pyx_k_bool, sizeof(__pyx_k_bool), 0, 1, 0, 1}, - {&__pyx_n_s_buffer, __pyx_k_buffer, sizeof(__pyx_k_buffer), 0, 0, 1, 1}, - {&__pyx_n_s_byteorder, __pyx_k_byteorder, sizeof(__pyx_k_byteorder), 0, 0, 1, 1}, - {&__pyx_n_u_byteorder, __pyx_k_byteorder, sizeof(__pyx_k_byteorder), 0, 1, 0, 1}, - {&__pyx_n_s_capacity, __pyx_k_capacity, sizeof(__pyx_k_capacity), 0, 0, 1, 1}, - {&__pyx_n_s_clear, __pyx_k_clear, sizeof(__pyx_k_clear), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1}, - {&__pyx_n_s_cls, __pyx_k_cls, sizeof(__pyx_k_cls), 0, 0, 1, 1}, - {&__pyx_n_s_code, __pyx_k_code, sizeof(__pyx_k_code), 0, 0, 1, 1}, - {&__pyx_n_s_code_2, __pyx_k_code_2, sizeof(__pyx_k_code_2), 0, 0, 1, 1}, - {&__pyx_kp_u_column_Must_be_a_datetime64_ns, __pyx_k_column_Must_be_a_datetime64_ns, sizeof(__pyx_k_column_Must_be_a_datetime64_ns), 0, 1, 0, 0}, - {&__pyx_kp_u_column_Must_be_a_strings_column, __pyx_k_column_Must_be_a_strings_column, sizeof(__pyx_k_column_Must_be_a_strings_column), 0, 1, 0, 0}, - {&__pyx_n_s_columns, __pyx_k_columns, sizeof(__pyx_k_columns), 0, 0, 1, 1}, - {&__pyx_n_s_connect, __pyx_k_connect, sizeof(__pyx_k_connect), 0, 0, 1, 1}, - {&__pyx_kp_u_connect_can_t_be_called_after_cl, __pyx_k_connect_can_t_be_called_after_cl, sizeof(__pyx_k_connect_can_t_be_called_after_cl), 0, 1, 0, 0}, - {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1}, - {&__pyx_n_u_datetime, __pyx_k_datetime, sizeof(__pyx_k_datetime), 0, 1, 0, 1}, - {&__pyx_kp_u_datetime_datetime, __pyx_k_datetime_datetime, sizeof(__pyx_k_datetime_datetime), 0, 1, 0, 0}, - {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1}, - {&__pyx_n_s_dt, __pyx_k_dt, sizeof(__pyx_k_dt), 0, 0, 1, 1}, - {&__pyx_kp_u_dt_must_be_a_datetime_object, __pyx_k_dt_must_be_a_datetime_object, sizeof(__pyx_k_dt_must_be_a_datetime_object), 0, 1, 0, 0}, - {&__pyx_kp_u_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 1, 0, 0}, - {&__pyx_n_s_dtypes, __pyx_k_dtypes, sizeof(__pyx_k_dtypes), 0, 0, 1, 1}, - {&__pyx_n_s_enter, __pyx_k_enter, sizeof(__pyx_k_enter), 0, 0, 1, 1}, - {&__pyx_n_s_enum, __pyx_k_enum, sizeof(__pyx_k_enum), 0, 0, 1, 1}, - {&__pyx_n_s_err, __pyx_k_err, sizeof(__pyx_k_err), 0, 0, 1, 1}, - {&__pyx_n_s_exc_tb, __pyx_k_exc_tb, sizeof(__pyx_k_exc_tb), 0, 0, 1, 1}, - {&__pyx_n_s_exc_type, __pyx_k_exc_type, sizeof(__pyx_k_exc_type), 0, 0, 1, 1}, - {&__pyx_n_s_exc_val, __pyx_k_exc_val, sizeof(__pyx_k_exc_val), 0, 0, 1, 1}, - {&__pyx_n_s_exit, __pyx_k_exit, sizeof(__pyx_k_exit), 0, 0, 1, 1}, - {&__pyx_kp_u_field_indices, __pyx_k_field_indices, sizeof(__pyx_k_field_indices), 0, 1, 0, 0}, - {&__pyx_n_u_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 1, 0, 1}, - {&__pyx_n_s_flush, __pyx_k_flush, sizeof(__pyx_k_flush), 0, 0, 1, 1}, - {&__pyx_kp_u_flush_can_t_be_called_Not_connec, __pyx_k_flush_can_t_be_called_Not_connec, sizeof(__pyx_k_flush_can_t_be_called_Not_connec), 0, 1, 0, 0}, - {&__pyx_kp_u_for_the, __pyx_k_for_the, sizeof(__pyx_k_for_the), 0, 1, 0, 0}, - {&__pyx_kp_u_for_the_2, __pyx_k_for_the_2, sizeof(__pyx_k_for_the_2), 0, 1, 0, 0}, - {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, - {&__pyx_n_s_from_datetime, __pyx_k_from_datetime, sizeof(__pyx_k_from_datetime), 0, 0, 1, 1}, - {&__pyx_n_s_get_loc, __pyx_k_get_loc, sizeof(__pyx_k_get_loc), 0, 0, 1, 1}, - {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, - {&__pyx_kp_u_got, __pyx_k_got, sizeof(__pyx_k_got), 0, 1, 0, 0}, - {&__pyx_n_s_hasobject, __pyx_k_hasobject, sizeof(__pyx_k_hasobject), 0, 0, 1, 1}, - {&__pyx_n_u_hasobject, __pyx_k_hasobject, sizeof(__pyx_k_hasobject), 0, 1, 0, 1}, - {&__pyx_n_s_host, __pyx_k_host, sizeof(__pyx_k_host), 0, 0, 1, 1}, - {&__pyx_n_s_iloc, __pyx_k_iloc, sizeof(__pyx_k_iloc), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_kp_u_in_column, __pyx_k_in_column, sizeof(__pyx_k_in_column), 0, 1, 0, 0}, - {&__pyx_kp_u_in_string, __pyx_k_in_string, sizeof(__pyx_k_in_string), 0, 1, 0, 0}, - {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1}, - {&__pyx_kp_u_index_out_of_range, __pyx_k_index_out_of_range, sizeof(__pyx_k_index_out_of_range), 0, 1, 0, 0}, - {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1}, - {&__pyx_n_s_init_capacity, __pyx_k_init_capacity, sizeof(__pyx_k_init_capacity), 0, 0, 1, 1}, - {&__pyx_n_u_insecure_skip_verify, __pyx_k_insecure_skip_verify, sizeof(__pyx_k_insecure_skip_verify), 0, 1, 0, 1}, - {&__pyx_n_u_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 1, 0, 1}, - {&__pyx_kp_u_int_column_index_str_colum_name, __pyx_k_int_column_index_str_colum_name, sizeof(__pyx_k_int_column_index_str_colum_name), 0, 1, 0, 0}, - {&__pyx_n_s_interface, __pyx_k_interface, sizeof(__pyx_k_interface), 0, 0, 1, 1}, - {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, - {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, - {&__pyx_n_u_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 1, 0, 1}, - {&__pyx_n_s_kind, __pyx_k_kind, sizeof(__pyx_k_kind), 0, 0, 1, 1}, - {&__pyx_n_u_kind, __pyx_k_kind, sizeof(__pyx_k_kind), 0, 1, 0, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_max_name_len, __pyx_k_max_name_len, sizeof(__pyx_k_max_name_len), 0, 0, 1, 1}, - {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1}, - {&__pyx_n_s_microsecond, __pyx_k_microsecond, sizeof(__pyx_k_microsecond), 0, 0, 1, 1}, - {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1}, - {&__pyx_n_s_msg, __pyx_k_msg, sizeof(__pyx_k_msg), 0, 0, 1, 1}, - {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, - {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, - {&__pyx_kp_u_name_col, __pyx_k_name_col, sizeof(__pyx_k_name_col), 0, 1, 0, 0}, - {&__pyx_n_s_new_buffer, __pyx_k_new_buffer, sizeof(__pyx_k_new_buffer), 0, 0, 1, 1}, - {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, - {&__pyx_kp_u_not, __pyx_k_not, sizeof(__pyx_k_not), 0, 1, 0, 0}, - {&__pyx_kp_u_not_found_in_the_dataframe, __pyx_k_not_found_in_the_dataframe, sizeof(__pyx_k_not_found_in_the_dataframe), 0, 1, 0, 0}, - {&__pyx_n_s_pandas, __pyx_k_pandas, sizeof(__pyx_k_pandas), 0, 0, 1, 1}, - {&__pyx_kp_u_pandas_A, __pyx_k_pandas_A, sizeof(__pyx_k_pandas_A), 0, 1, 0, 0}, - {&__pyx_kp_u_pandas_A_2, __pyx_k_pandas_A_2, sizeof(__pyx_k_pandas_A_2), 0, 1, 0, 0}, - {&__pyx_kp_u_pandas_B, __pyx_k_pandas_B, sizeof(__pyx_k_pandas_B), 0, 1, 0, 0}, - {&__pyx_kp_u_pandas_core_frame, __pyx_k_pandas_core_frame, sizeof(__pyx_k_pandas_core_frame), 0, 1, 0, 0}, - {&__pyx_n_s_pathlib, __pyx_k_pathlib, sizeof(__pyx_k_pathlib), 0, 0, 1, 1}, - {&__pyx_n_s_port, __pyx_k_port, sizeof(__pyx_k_port), 0, 0, 1, 1}, - {&__pyx_kp_u_port_must_be_an_integer_or_a_str, __pyx_k_port_must_be_an_integer_or_a_str, sizeof(__pyx_k_port_must_be_an_integer_or_a_str), 0, 1, 0, 0}, - {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1}, - {&__pyx_n_s_property, __pyx_k_property, sizeof(__pyx_k_property), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, - {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, - {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1}, - {&__pyx_n_s_questdb_ingress, __pyx_k_questdb_ingress, sizeof(__pyx_k_questdb_ingress), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_read_timeout, __pyx_k_read_timeout, sizeof(__pyx_k_read_timeout), 0, 0, 1, 1}, - {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, - {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, - {&__pyx_n_s_reserve, __pyx_k_reserve, sizeof(__pyx_k_reserve), 0, 0, 1, 1}, - {&__pyx_n_s_return, __pyx_k_return, sizeof(__pyx_k_return), 0, 0, 1, 1}, - {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1}, - {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1}, - {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, - {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, - {&__pyx_n_u_size_t_vec, __pyx_k_size_t_vec, sizeof(__pyx_k_size_t_vec), 0, 1, 0, 1}, - {&__pyx_n_s_sort, __pyx_k_sort, sizeof(__pyx_k_sort), 0, 0, 1, 1}, - {&__pyx_kp_u_sort_2, __pyx_k_sort_2, sizeof(__pyx_k_sort_2), 0, 1, 0, 0}, - {&__pyx_kp_s_src_questdb_ingress_pyx, __pyx_k_src_questdb_ingress_pyx, sizeof(__pyx_k_src_questdb_ingress_pyx), 0, 0, 1, 0}, - {&__pyx_n_s_stderr, __pyx_k_stderr, sizeof(__pyx_k_stderr), 0, 0, 1, 1}, - {&__pyx_n_u_str, __pyx_k_str, sizeof(__pyx_k_str), 0, 1, 0, 1}, - {&__pyx_n_s_str_2, __pyx_k_str_2, sizeof(__pyx_k_str_2), 0, 0, 1, 1}, - {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, - {&__pyx_n_s_super, __pyx_k_super, sizeof(__pyx_k_super), 0, 0, 1, 1}, - {&__pyx_n_u_symbol, __pyx_k_symbol, sizeof(__pyx_k_symbol), 0, 1, 0, 1}, - {&__pyx_kp_u_symbol_indices, __pyx_k_symbol_indices, sizeof(__pyx_k_symbol_indices), 0, 1, 0, 0}, - {&__pyx_n_s_symbols, __pyx_k_symbols, sizeof(__pyx_k_symbols), 0, 0, 1, 1}, - {&__pyx_n_u_symbols, __pyx_k_symbols, sizeof(__pyx_k_symbols), 0, 1, 0, 1}, - {&__pyx_kp_u_symbols_2, __pyx_k_symbols_2, sizeof(__pyx_k_symbols_2), 0, 1, 0, 0}, - {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1}, - {&__pyx_n_s_table_name, __pyx_k_table_name, sizeof(__pyx_k_table_name), 0, 0, 1, 1}, - {&__pyx_kp_u_table_name_2, __pyx_k_table_name_2, sizeof(__pyx_k_table_name_2), 0, 1, 0, 0}, - {&__pyx_n_s_table_name_col, __pyx_k_table_name_col, sizeof(__pyx_k_table_name_col), 0, 0, 1, 1}, - {&__pyx_n_u_table_name_col, __pyx_k_table_name_col, sizeof(__pyx_k_table_name_col), 0, 1, 0, 1}, - {&__pyx_kp_u_table_name_col_2, __pyx_k_table_name_col_2, sizeof(__pyx_k_table_name_col_2), 0, 1, 0, 0}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_n_s_timestamp, __pyx_k_timestamp, sizeof(__pyx_k_timestamp), 0, 0, 1, 1}, - {&__pyx_n_s_tls, __pyx_k_tls, sizeof(__pyx_k_tls), 0, 0, 1, 1}, - {&__pyx_kp_u_tls_must_be_a_bool_a_path_or_str, __pyx_k_tls_must_be_a_bool_a_path_or_str, sizeof(__pyx_k_tls_must_be_a_bool_a_path_or_str), 0, 1, 0, 0}, - {&__pyx_n_s_to_numpy, __pyx_k_to_numpy, sizeof(__pyx_k_to_numpy), 0, 0, 1, 1}, - {&__pyx_n_s_typing, __pyx_k_typing, sizeof(__pyx_k_typing), 0, 0, 1, 1}, - {&__pyx_n_u_unicode, __pyx_k_unicode, sizeof(__pyx_k_unicode), 0, 1, 0, 1}, - {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1}, - {&__pyx_n_s_value_2, __pyx_k_value_2, sizeof(__pyx_k_value_2), 0, 0, 1, 1}, - {&__pyx_kp_u_value_must_positive_integer, __pyx_k_value_must_positive_integer, sizeof(__pyx_k_value_must_positive_integer), 0, 1, 0, 0}, - {&__pyx_n_s_write, __pyx_k_write, sizeof(__pyx_k_write), 0, 0, 1, 1}, - {&__pyx_n_u_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 1, 0, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { - __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_n_s_property); if (!__pyx_builtin_property) __PYX_ERR(0, 84, __pyx_L1_error) - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(1, 21, __pyx_L1_error) - __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(2, 110, __pyx_L1_error) - __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(2, 119, __pyx_L1_error) - __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(2, 211, __pyx_L1_error) - __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(2, 316, __pyx_L1_error) - __pyx_builtin_super = __Pyx_GetBuiltinName(__pyx_n_s_super); if (!__pyx_builtin_super) __PYX_ERR(0, 81, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "src/questdb/pandas_helpers.pxi":110 - * if table_name is not None: - * if table_name_col is not None: - * raise ValueError( # <<<<<<<<<<<<<< - * 'Can specify only one of `table_name` or `table_name_col`.') - * if isinstance(table_name, str): - */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_Can_specify_only_one_of_table_na); if (unlikely(!__pyx_tuple_)) __PYX_ERR(2, 110, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "src/questdb/pandas_helpers.pxi":119 - * raise ValueError(f'Bad argument `table_name`: {ie}') - * else: - * raise TypeError('Bad argument `table_name`: Must be str.') # <<<<<<<<<<<<<< - * elif table_name_col is not None: - * if isinstance(table_name_col, str): - */ - __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_table_name_Must_be); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(2, 119, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); - - /* "src/questdb/pandas_helpers.pxi":127 - * 'table_name_col', table_name_col, col_count, &col_index) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * 'Bad argument `table_name_col`: ' + - * 'must be a column name (str) or index (int).') - */ - __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_table_name_col_must); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(2, 127, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__3); - __Pyx_GIVEREF(__pyx_tuple__3); - - /* "src/questdb/pandas_helpers.pxi":137 - * return col_index - * else: - * raise ValueError( # <<<<<<<<<<<<<< - * 'Must specify at least one of `table_name` or `table_name_col`.') - * - */ - __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Must_specify_at_least_one_of_tab); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(2, 137, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_GIVEREF(__pyx_tuple__4); - - /* "src/questdb/pandas_helpers.pxi":278 - * else: - * if not isinstance(symbols, (tuple, list)): - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `symbols`: Must be a bool or a tuple or list '+ - * 'of column names (str) or indices (int).') - */ - __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_symbols_Must_be_a_b); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(2, 278, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__7); - __Pyx_GIVEREF(__pyx_tuple__7); - - /* "src/questdb/pandas_helpers.pxi":287 - * _bind_col_index('symbol', symbol, col_count, &col_index) - * else: - * raise TypeError( # <<<<<<<<<<<<<< - * f'Bad argument `symbols`: Elements must ' + - * 'be a column name (str) or index (int).') - */ - __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Bad_argument_symbols_Elements_mu); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(2, 287, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); - - /* "src/questdb/pandas_helpers.pxi":418 - * cdef const dtype_t* dtype - * for col_index in range(col_count): - * nparr = data.iloc[:, col_index].to_numpy() # <<<<<<<<<<<<<< - * view = &col_buffers[col_index] - * dtype = &dtypes[col_index] - */ - __pyx_slice__13 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__13)) __PYX_ERR(2, 418, __pyx_L1_error) - __Pyx_GOTREF(__pyx_slice__13); - __Pyx_GIVEREF(__pyx_slice__13); - - /* "questdb/ingress.pyx":108 - * return IngressErrorCode.TlsError - * else: - * raise ValueError('Internal error converting error code.') # <<<<<<<<<<<<<< - * - * - */ - __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_u_Internal_error_converting_error); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 108, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__16); - __Pyx_GIVEREF(__pyx_tuple__16); - - /* "questdb/ingress.pyx":294 - * def __cinit__(self, value: int): - * if value < 0: - * raise ValueError('value must positive integer.') # <<<<<<<<<<<<<< - * self._value = value - * - */ - __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_u_value_must_positive_integer); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 294, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__18); - __Pyx_GIVEREF(__pyx_tuple__18); - - /* "questdb/ingress.pyx":303 - * """ - * if not isinstance(dt, datetime): - * raise TypeError('dt must be a datetime object.') # <<<<<<<<<<<<<< - * return cls(datetime_to_micros(dt)) - * - */ - __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_u_dt_must_be_a_datetime_object); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 303, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__19); - __Pyx_GIVEREF(__pyx_tuple__19); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__20); - __Pyx_GIVEREF(__pyx_tuple__20); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__21); - __Pyx_GIVEREF(__pyx_tuple__21); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__22); - __Pyx_GIVEREF(__pyx_tuple__22); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__23); - __Pyx_GIVEREF(__pyx_tuple__23); - - /* "questdb/ingress.pyx":500 - * """ - * if additional < 0: - * raise ValueError('additional must be non-negative.') # <<<<<<<<<<<<<< - * line_sender_buffer_reserve(self._impl, additional) - * - */ - __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_u_additional_must_be_non_negative); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 500, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__25); - __Pyx_GIVEREF(__pyx_tuple__25); - - /* "questdb/ingress.pyx":634 - * else: - * valid = ', '.join(( - * 'bool', # <<<<<<<<<<<<<< - * 'int', - * 'float', - */ - __pyx_tuple__26 = PyTuple_Pack(6, __pyx_n_u_bool, __pyx_n_u_int, __pyx_n_u_float, __pyx_n_u_str, __pyx_n_u_TimestampMicros, __pyx_kp_u_datetime_datetime); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 634, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__26); - __Pyx_GIVEREF(__pyx_tuple__26); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__28); - __Pyx_GIVEREF(__pyx_tuple__28); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__29); - __Pyx_GIVEREF(__pyx_tuple__29); - - /* "questdb/ingress.pyx":1491 - * """ - * if buffer is None and not clear: - * raise ValueError('The internal buffer must always be cleared.') # <<<<<<<<<<<<<< - * - * cdef line_sender_error* err = NULL - */ - __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_u_The_internal_buffer_must_always); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(0, 1491, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__30); - __Pyx_GIVEREF(__pyx_tuple__30); - - /* "(tree fragment)":2 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(3, 2, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__31); - __Pyx_GIVEREF(__pyx_tuple__31); - - /* "(tree fragment)":4 - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< - */ - __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(3, 4, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__32); - __Pyx_GIVEREF(__pyx_tuple__32); - - /* "questdb/ingress.pyx":73 - * TlsError = line_sender_error_tls_error - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """Return the name of the enum.""" - * return self.name - */ - __pyx_tuple__33 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__33); - __Pyx_GIVEREF(__pyx_tuple__33); - __pyx_codeobj__34 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__33, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_str_2, 73, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__34)) __PYX_ERR(0, 73, __pyx_L1_error) - - /* "questdb/ingress.pyx":80 - * class IngressError(Exception): - * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" - * def __init__(self, code, msg): # <<<<<<<<<<<<<< - * super().__init__(msg) - * self._code = code - */ - __pyx_tuple__35 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_code, __pyx_n_s_msg); if (unlikely(!__pyx_tuple__35)) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__35); - __Pyx_GIVEREF(__pyx_tuple__35); - __pyx_codeobj__36 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__35, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_init, 80, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__36)) __PYX_ERR(0, 80, __pyx_L1_error) - - /* "questdb/ingress.pyx":85 - * - * @property - * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< - * """Return the error code.""" - * return self._code - */ - __pyx_tuple__37 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__37); - __Pyx_GIVEREF(__pyx_tuple__37); - __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_code, 85, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) __PYX_ERR(0, 85, __pyx_L1_error) - - /* "questdb/ingress.pyx":298 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. - */ - __pyx_tuple__39 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_dt); if (unlikely(!__pyx_tuple__39)) __PYX_ERR(0, 298, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__39); - __Pyx_GIVEREF(__pyx_tuple__39); - __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_from_datetime, 298, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) __PYX_ERR(0, 298, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_tuple__41 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__41)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__41); - __Pyx_GIVEREF(__pyx_tuple__41); - __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) __PYX_ERR(3, 1, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__43 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__43)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__43); - __Pyx_GIVEREF(__pyx_tuple__43); - __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) __PYX_ERR(3, 3, __pyx_L1_error) - - /* "questdb/ingress.pyx":349 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. - */ - __pyx_tuple__45 = PyTuple_Pack(2, __pyx_n_s_cls, __pyx_n_s_dt); if (unlikely(!__pyx_tuple__45)) __PYX_ERR(0, 349, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__45); - __Pyx_GIVEREF(__pyx_tuple__45); - __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_from_datetime, 349, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) __PYX_ERR(0, 349, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_tuple__47 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__47)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__47); - __Pyx_GIVEREF(__pyx_tuple__47); - __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) __PYX_ERR(3, 1, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__49 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__49)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__49); - __Pyx_GIVEREF(__pyx_tuple__49); - __pyx_codeobj__50 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__49, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__50)) __PYX_ERR(3, 3, __pyx_L1_error) - - /* "questdb/ingress.pyx":493 - * return self._max_name_len - * - * def reserve(self, additional: int): # <<<<<<<<<<<<<< - * """ - * Ensure the buffer has at least `additional` bytes of future capacity. - */ - __pyx_tuple__51 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_additional); if (unlikely(!__pyx_tuple__51)) __PYX_ERR(0, 493, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__51); - __Pyx_GIVEREF(__pyx_tuple__51); - __pyx_codeobj__52 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__51, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_reserve, 493, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__52)) __PYX_ERR(0, 493, __pyx_L1_error) - - /* "questdb/ingress.pyx":503 - * line_sender_buffer_reserve(self._impl, additional) - * - * def capacity(self) -> int: # <<<<<<<<<<<<<< - * """The current buffer capacity.""" - * return line_sender_buffer_capacity(self._impl) - */ - __pyx_tuple__53 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__53)) __PYX_ERR(0, 503, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__53); - __Pyx_GIVEREF(__pyx_tuple__53); - __pyx_codeobj__54 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__53, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_capacity, 503, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__54)) __PYX_ERR(0, 503, __pyx_L1_error) - - /* "questdb/ingress.pyx":507 - * return line_sender_buffer_capacity(self._impl) - * - * def clear(self): # <<<<<<<<<<<<<< - * """ - * Reset the buffer. - */ - __pyx_tuple__55 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__55)) __PYX_ERR(0, 507, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__55); - __Pyx_GIVEREF(__pyx_tuple__55); - __pyx_codeobj__56 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__55, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_clear, 507, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__56)) __PYX_ERR(0, 507, __pyx_L1_error) - - /* "questdb/ingress.pyx":716 - * self._may_trigger_row_complete() - * - * def row( # <<<<<<<<<<<<<< - * self, - * table_name: str, - */ - __pyx_tuple__57 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_table_name, __pyx_n_s_symbols, __pyx_n_s_columns, __pyx_n_s_at); if (unlikely(!__pyx_tuple__57)) __PYX_ERR(0, 716, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__57); - __Pyx_GIVEREF(__pyx_tuple__57); - __pyx_codeobj__58 = (PyObject*)__Pyx_PyCode_New(2, 3, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__57, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_row, 716, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__58)) __PYX_ERR(0, 716, __pyx_L1_error) - - /* "questdb/ingress.pyx":1090 - * qdb_pystr_buf_clear(self._b) - * - * def pandas( # <<<<<<<<<<<<<< - * self, - * data, # : pd.DataFrame - */ - __pyx_tuple__59 = PyTuple_Pack(8, __pyx_n_s_self, __pyx_n_s_data, __pyx_n_s_table_name, __pyx_n_s_table_name_col, __pyx_n_s_symbols, __pyx_n_s_at, __pyx_n_s_sort, __pyx_n_s_sys); if (unlikely(!__pyx_tuple__59)) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__59); - __Pyx_GIVEREF(__pyx_tuple__59); - __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(2, 5, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_pandas, 1090, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) __PYX_ERR(0, 1090, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_tuple__61 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__61)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__61); - __Pyx_GIVEREF(__pyx_tuple__61); - __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) __PYX_ERR(3, 1, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__63 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__63); - __Pyx_GIVEREF(__pyx_tuple__63); - __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) __PYX_ERR(3, 3, __pyx_L1_error) - - /* "questdb/ingress.pyx":1383 - * qdb_pystr_buf_clear(b) - * - * def new_buffer(self): # <<<<<<<<<<<<<< - * """ - * Make a new configured buffer. - */ - __pyx_tuple__65 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 1383, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__65); - __Pyx_GIVEREF(__pyx_tuple__65); - __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_new_buffer, 1383, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 1383, __pyx_L1_error) - - /* "questdb/ingress.pyx":1404 - * return self._max_name_len - * - * def connect(self): # <<<<<<<<<<<<<< - * """ - * Connect to the QuestDB server. - */ - __pyx_tuple__67 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_err); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 1404, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__67); - __Pyx_GIVEREF(__pyx_tuple__67); - __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_connect, 1404, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 1404, __pyx_L1_error) - - /* "questdb/ingress.pyx":1429 - * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) - * - * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< - * """Call :func:`Sender.connect` at the start of a ``with`` block.""" - * self.connect() - */ - __pyx_tuple__69 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 1429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__69); - __Pyx_GIVEREF(__pyx_tuple__69); - __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_enter, 1429, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 1429, __pyx_L1_error) - - /* "questdb/ingress.pyx":1452 - * return len(self._buffer) - * - * def row(self, # <<<<<<<<<<<<<< - * table_name: str, - * *, - */ - __pyx_tuple__71 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_table_name, __pyx_n_s_symbols, __pyx_n_s_columns, __pyx_n_s_at); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 1452, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__71); - __Pyx_GIVEREF(__pyx_tuple__71); - __pyx_codeobj__72 = (PyObject*)__Pyx_PyCode_New(2, 3, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_row, 1452, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__72)) __PYX_ERR(0, 1452, __pyx_L1_error) - - /* "questdb/ingress.pyx":1470 - * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) - * - * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< - * """ - * If called with no arguments, immediately flushes the internal buffer. - */ - __pyx_tuple__73 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_buffer, __pyx_n_s_clear); if (unlikely(!__pyx_tuple__73)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__73); - __Pyx_GIVEREF(__pyx_tuple__73); - __pyx_codeobj__74 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__73, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_flush, 1470, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__74)) __PYX_ERR(0, 1470, __pyx_L1_error) - - /* "questdb/ingress.pyx":1528 - * self._impl = NULL - * - * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< - * """ - * Disconnect. - */ - __pyx_tuple__75 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_flush); if (unlikely(!__pyx_tuple__75)) __PYX_ERR(0, 1528, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__75); - __Pyx_GIVEREF(__pyx_tuple__75); - __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_close, 1528, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) __PYX_ERR(0, 1528, __pyx_L1_error) - - /* "questdb/ingress.pyx":1545 - * self._close() - * - * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< - * """ - * Flush pending and disconnect at the end of a ``with`` block. - */ - __pyx_tuple__77 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_exc_type, __pyx_n_s_exc_val, __pyx_n_s_exc_tb); if (unlikely(!__pyx_tuple__77)) __PYX_ERR(0, 1545, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__77); - __Pyx_GIVEREF(__pyx_tuple__77); - __pyx_codeobj__78 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__77, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_src_questdb_ingress_pyx, __pyx_n_s_exit, 1545, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__78)) __PYX_ERR(0, 1545, __pyx_L1_error) - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_tuple__79 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__79)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__79); - __Pyx_GIVEREF(__pyx_tuple__79); - __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_reduce_cython, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) __PYX_ERR(3, 1, __pyx_L1_error) - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_tuple__81 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_pyx_state); if (unlikely(!__pyx_tuple__81)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__81); - __Pyx_GIVEREF(__pyx_tuple__81); - __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_setstate_cython, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { - __pyx_umethod_PyUnicode_Type_format.type = (PyObject*)&PyUnicode_Type; - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_127 = PyInt_FromLong(127); if (unlikely(!__pyx_int_127)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_1000 = PyInt_FromLong(1000); if (unlikely(!__pyx_int_1000)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_64512 = PyInt_FromLong(64512L); if (unlikely(!__pyx_int_64512)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_int_65536 = PyInt_FromLong(65536L); if (unlikely(!__pyx_int_65536)) __PYX_ERR(0, 1, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ -static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ - -static int __Pyx_modinit_global_init_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); - /*--- Global init code ---*/ - __pyx_v_7questdb_7ingress__PANDAS_NA = Py_None; Py_INCREF(Py_None); - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_variable_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); - /*--- Variable export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_export_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); - /*--- Function export code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_type_init_code(void) { - __Pyx_RefNannyDeclarations - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); - /*--- Type init code ---*/ - if (PyType_Ready(&__pyx_type_7questdb_7ingress_TimestampMicros) < 0) __PYX_ERR(0, 261, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7questdb_7ingress_TimestampMicros.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_TimestampMicros.tp_dictoffset && __pyx_type_7questdb_7ingress_TimestampMicros.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7questdb_7ingress_TimestampMicros.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_TimestampMicros, (PyObject *)&__pyx_type_7questdb_7ingress_TimestampMicros) < 0) __PYX_ERR(0, 261, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_TimestampMicros) < 0) __PYX_ERR(0, 261, __pyx_L1_error) - __pyx_ptype_7questdb_7ingress_TimestampMicros = &__pyx_type_7questdb_7ingress_TimestampMicros; - if (PyType_Ready(&__pyx_type_7questdb_7ingress_TimestampNanos) < 0) __PYX_ERR(0, 312, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7questdb_7ingress_TimestampNanos.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_TimestampNanos.tp_dictoffset && __pyx_type_7questdb_7ingress_TimestampNanos.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7questdb_7ingress_TimestampNanos.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_TimestampNanos, (PyObject *)&__pyx_type_7questdb_7ingress_TimestampNanos) < 0) __PYX_ERR(0, 312, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_TimestampNanos) < 0) __PYX_ERR(0, 312, __pyx_L1_error) - __pyx_ptype_7questdb_7ingress_TimestampNanos = &__pyx_type_7questdb_7ingress_TimestampNanos; - __pyx_vtabptr_7questdb_7ingress_Sender = &__pyx_vtable_7questdb_7ingress_Sender; - __pyx_vtable_7questdb_7ingress_Sender.flush = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_flush *__pyx_optional_args))__pyx_f_7questdb_7ingress_6Sender_flush; - __pyx_vtable_7questdb_7ingress_Sender._close = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Sender *))__pyx_f_7questdb_7ingress_6Sender__close; - __pyx_vtable_7questdb_7ingress_Sender.close = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Sender *, int __pyx_skip_dispatch, struct __pyx_opt_args_7questdb_7ingress_6Sender_close *__pyx_optional_args))__pyx_f_7questdb_7ingress_6Sender_close; - if (PyType_Ready(&__pyx_type_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7questdb_7ingress_Sender.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_Sender.tp_dictoffset && __pyx_type_7questdb_7ingress_Sender.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7questdb_7ingress_Sender.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - #if CYTHON_UPDATE_DESCRIPTOR_DOC - { - PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Sender, "__str__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1127, __pyx_L1_error) - if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { - __pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__ = *((PyWrapperDescrObject *)wrapper)->d_base; - __pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__.doc = __pyx_doc_7questdb_7ingress_6Sender_8__str__; - ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Sender_8__str__; - } - } - #endif - #if CYTHON_UPDATE_DESCRIPTOR_DOC - { - PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Sender, "__len__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1127, __pyx_L1_error) - if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { - __pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__ = *((PyWrapperDescrObject *)wrapper)->d_base; - __pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__.doc = __pyx_doc_7questdb_7ingress_6Sender_10__len__; - ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Sender_10__len__; - } - } - #endif - if (__Pyx_SetVtable(__pyx_type_7questdb_7ingress_Sender.tp_dict, __pyx_vtabptr_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Sender, (PyObject *)&__pyx_type_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) - if (__pyx_type_7questdb_7ingress_Sender.tp_weaklistoffset == 0) __pyx_type_7questdb_7ingress_Sender.tp_weaklistoffset = offsetof(struct __pyx_obj_7questdb_7ingress_Sender, __weakref__); - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_Sender) < 0) __PYX_ERR(0, 1127, __pyx_L1_error) - __pyx_ptype_7questdb_7ingress_Sender = &__pyx_type_7questdb_7ingress_Sender; - __pyx_vtabptr_7questdb_7ingress_Buffer = &__pyx_vtable_7questdb_7ingress_Buffer; - __pyx_vtable_7questdb_7ingress_Buffer._cinit_impl = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *, size_t, size_t))__pyx_f_7questdb_7ingress_6Buffer__cinit_impl; - __pyx_vtable_7questdb_7ingress_Buffer._to_str = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__to_str; - __pyx_vtable_7questdb_7ingress_Buffer._set_marker = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__set_marker; - __pyx_vtable_7questdb_7ingress_Buffer._rewind_to_marker = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__rewind_to_marker; - __pyx_vtable_7questdb_7ingress_Buffer._clear_marker = (PyObject *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__clear_marker; - __pyx_vtable_7questdb_7ingress_Buffer._table = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__table; - __pyx_vtable_7questdb_7ingress_Buffer._cleared_b = (struct qdb_pystr_buf *(*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__cleared_b; - __pyx_vtable_7questdb_7ingress_Buffer._symbol = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__symbol; - __pyx_vtable_7questdb_7ingress_Buffer._column_bool = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int))__pyx_f_7questdb_7ingress_6Buffer__column_bool; - __pyx_vtable_7questdb_7ingress_Buffer._column_i64 = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, int64_t))__pyx_f_7questdb_7ingress_6Buffer__column_i64; - __pyx_vtable_7questdb_7ingress_Buffer._column_f64 = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, double))__pyx_f_7questdb_7ingress_6Buffer__column_f64; - __pyx_vtable_7questdb_7ingress_Buffer._column_str = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__column_str; - __pyx_vtable_7questdb_7ingress_Buffer._column_ts = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, struct __pyx_obj_7questdb_7ingress_TimestampMicros *))__pyx_f_7questdb_7ingress_6Buffer__column_ts; - __pyx_vtable_7questdb_7ingress_Buffer._column_dt = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct line_sender_column_name, PyDateTime_DateTime *))__pyx_f_7questdb_7ingress_6Buffer__column_dt; - __pyx_vtable_7questdb_7ingress_Buffer._column = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__column; - __pyx_vtable_7questdb_7ingress_Buffer._may_trigger_row_complete = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__may_trigger_row_complete; - __pyx_vtable_7questdb_7ingress_Buffer._at_ts = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, struct __pyx_obj_7questdb_7ingress_TimestampNanos *))__pyx_f_7questdb_7ingress_6Buffer__at_ts; - __pyx_vtable_7questdb_7ingress_Buffer._at_dt = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyDateTime_DateTime *))__pyx_f_7questdb_7ingress_6Buffer__at_dt; - __pyx_vtable_7questdb_7ingress_Buffer._at_now = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *))__pyx_f_7questdb_7ingress_6Buffer__at_now; - __pyx_vtable_7questdb_7ingress_Buffer._at = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *))__pyx_f_7questdb_7ingress_6Buffer__at; - __pyx_vtable_7questdb_7ingress_Buffer._row = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, struct __pyx_opt_args_7questdb_7ingress_6Buffer__row *__pyx_optional_args))__pyx_f_7questdb_7ingress_6Buffer__row; - __pyx_vtable_7questdb_7ingress_Buffer._pandas = (int (*)(struct __pyx_obj_7questdb_7ingress_Buffer *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int))__pyx_f_7questdb_7ingress_6Buffer__pandas; - if (PyType_Ready(&__pyx_type_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) - #if PY_VERSION_HEX < 0x030800B1 - __pyx_type_7questdb_7ingress_Buffer.tp_print = 0; - #endif - if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7questdb_7ingress_Buffer.tp_dictoffset && __pyx_type_7questdb_7ingress_Buffer.tp_getattro == PyObject_GenericGetAttr)) { - __pyx_type_7questdb_7ingress_Buffer.tp_getattro = __Pyx_PyObject_GenericGetAttr; - } - #if CYTHON_UPDATE_DESCRIPTOR_DOC - { - PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Buffer, "__len__"); if (unlikely(!wrapper)) __PYX_ERR(0, 383, __pyx_L1_error) - if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { - __pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__ = *((PyWrapperDescrObject *)wrapper)->d_base; - __pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__.doc = __pyx_doc_7questdb_7ingress_6Buffer_10__len__; - ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Buffer_10__len__; - } - } - #endif - #if CYTHON_UPDATE_DESCRIPTOR_DOC - { - PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_7questdb_7ingress_Buffer, "__str__"); if (unlikely(!wrapper)) __PYX_ERR(0, 383, __pyx_L1_error) - if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) { - __pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__ = *((PyWrapperDescrObject *)wrapper)->d_base; - __pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__.doc = __pyx_doc_7questdb_7ingress_6Buffer_12__str__; - ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_7questdb_7ingress_6Buffer_12__str__; - } - } - #endif - if (__Pyx_SetVtable(__pyx_type_7questdb_7ingress_Buffer.tp_dict, __pyx_vtabptr_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Buffer, (PyObject *)&__pyx_type_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) - if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7questdb_7ingress_Buffer) < 0) __PYX_ERR(0, 383, __pyx_L1_error) - __pyx_ptype_7questdb_7ingress_Buffer = &__pyx_type_7questdb_7ingress_Buffer; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_type_import_code(void) { - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); - /*--- Type import code ---*/ - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", - #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), - #else - sizeof(PyHeapTypeObject), - #endif - __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(5, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule("datetime"); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_8datetime_date = __Pyx_ImportType(__pyx_t_1, "datetime", "date", sizeof(PyDateTime_Date), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_8datetime_date) __PYX_ERR(4, 9, __pyx_L1_error) - __pyx_ptype_7cpython_8datetime_time = __Pyx_ImportType(__pyx_t_1, "datetime", "time", sizeof(PyDateTime_Time), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_8datetime_time) __PYX_ERR(4, 12, __pyx_L1_error) - __pyx_ptype_7cpython_8datetime_datetime = __Pyx_ImportType(__pyx_t_1, "datetime", "datetime", sizeof(PyDateTime_DateTime), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_8datetime_datetime) __PYX_ERR(4, 15, __pyx_L1_error) - __pyx_ptype_7cpython_8datetime_timedelta = __Pyx_ImportType(__pyx_t_1, "datetime", "timedelta", sizeof(PyDateTime_Delta), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_8datetime_timedelta) __PYX_ERR(4, 18, __pyx_L1_error) - __pyx_ptype_7cpython_8datetime_tzinfo = __Pyx_ImportType(__pyx_t_1, "datetime", "tzinfo", sizeof(PyDateTime_TZInfo), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_8datetime_tzinfo) __PYX_ERR(4, 21, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(6, 8, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); - if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(6, 8, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_modinit_variable_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); - /*--- Variable import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - -static int __Pyx_modinit_function_import_code(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); - /*--- Function import code ---*/ - __Pyx_RefNannyFinishContext(); - return 0; -} - - -#ifndef CYTHON_NO_PYINIT_EXPORT -#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC -#elif PY_MAJOR_VERSION < 3 -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" void -#else -#define __Pyx_PyMODINIT_FUNC void -#endif -#else -#ifdef __cplusplus -#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * -#else -#define __Pyx_PyMODINIT_FUNC PyObject * -#endif -#endif - - -#if PY_MAJOR_VERSION < 3 -__Pyx_PyMODINIT_FUNC initingress(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC initingress(void) -#else -__Pyx_PyMODINIT_FUNC PyInit_ingress(void) CYTHON_SMALL_CODE; /*proto*/ -__Pyx_PyMODINIT_FUNC PyInit_ingress(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { - #if PY_VERSION_HEX >= 0x030700A1 - static PY_INT64_T main_interpreter_id = -1; - PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); - if (main_interpreter_id == -1) { - main_interpreter_id = current_id; - return (unlikely(current_id == -1)) ? -1 : 0; - } else if (unlikely(main_interpreter_id != current_id)) - #else - static PyInterpreterState *main_interpreter = NULL; - PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; - if (!main_interpreter) { - main_interpreter = current_interpreter; - } else if (unlikely(main_interpreter != current_interpreter)) - #endif - { - PyErr_SetString( - PyExc_ImportError, - "Interpreter change detected - this module can only be loaded into one interpreter per process."); - return -1; - } - return 0; -} -static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - if (allow_none || value != Py_None) { - result = PyDict_SetItemString(moddict, to_name, value); - } - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__Pyx_check_single_interpreter()) - return NULL; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static CYTHON_SMALL_CODE int __pyx_pymod_exec_ingress(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - int __pyx_lineno = 0; - const char *__pyx_filename = NULL; - int __pyx_clineno = 0; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m) { - if (__pyx_m == __pyx_pyinit_module) return 0; - PyErr_SetString(PyExc_RuntimeError, "Module 'ingress' has already been imported. Re-initialisation is not supported."); - return -1; - } - #elif PY_MAJOR_VERSION >= 3 - if (__pyx_m) return __Pyx_NewRef(__pyx_m); - #endif - #if CYTHON_REFNANNY -__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); -if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); -} -#endif - __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit_ingress(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pxy_PyFrame_Initialize_Offsets - __Pxy_PyFrame_Initialize_Offsets(); - #endif - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(WITH_THREAD) && PY_VERSION_HEX < 0x030700F0 && defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - PyEval_InitThreads(); - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("ingress", __pyx_methods, __pyx_k_API_for_fast_data_ingestion_int, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_b); - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_cython_runtime); - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_questdb__ingress) { - if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name_2, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "questdb.ingress")) { - if (unlikely(PyDict_SetItemString(modules, "questdb.ingress", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global type/function init code ---*/ - (void)__Pyx_modinit_global_init_code(); - (void)__Pyx_modinit_variable_export_code(); - (void)__Pyx_modinit_function_export_code(); - if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - (void)__Pyx_modinit_variable_import_code(); - (void)__Pyx_modinit_function_import_code(); - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "src/questdb/pandas_helpers.pxi":76 - * - * - * cdef object _PANDAS_NA = None # <<<<<<<<<<<<<< - * - * - */ - __Pyx_INCREF(Py_None); - __Pyx_XGOTREF(__pyx_v_7questdb_7ingress__PANDAS_NA); - __Pyx_DECREF_SET(__pyx_v_7questdb_7ingress__PANDAS_NA, Py_None); - __Pyx_GIVEREF(Py_None); - - /* "src/questdb/pandas_helpers.pxi":435 - * - * - * cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' # <<<<<<<<<<<<<< - * cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' - * - */ - __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_OBJECT = ((char)79); - - /* "src/questdb/pandas_helpers.pxi":436 - * - * cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' - * cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' # <<<<<<<<<<<<<< - * - * - */ - __pyx_v_7questdb_7ingress__PANDAS_DTYPE_KIND_DATETIME = ((char)77); - - /* "questdb/ingress.pyx":56 - * - * import cython - * from enum import Enum # <<<<<<<<<<<<<< - * from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable - * import pathlib - */ - __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(__pyx_n_s_Enum); - __Pyx_GIVEREF(__pyx_n_s_Enum); - PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_Enum); - __pyx_t_2 = __Pyx_Import(__pyx_n_s_enum, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Enum, __pyx_t_1) < 0) __PYX_ERR(0, 56, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":57 - * import cython - * from enum import Enum - * from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable # <<<<<<<<<<<<<< - * import pathlib - * - */ - __pyx_t_2 = PyList_New(8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(__pyx_n_s_List); - __Pyx_GIVEREF(__pyx_n_s_List); - PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_List); - __Pyx_INCREF(__pyx_n_s_Tuple); - __Pyx_GIVEREF(__pyx_n_s_Tuple); - PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_Tuple); - __Pyx_INCREF(__pyx_n_s_Dict); - __Pyx_GIVEREF(__pyx_n_s_Dict); - PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_Dict); - __Pyx_INCREF(__pyx_n_s_Union); - __Pyx_GIVEREF(__pyx_n_s_Union); - PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_s_Union); - __Pyx_INCREF(__pyx_n_s_Any); - __Pyx_GIVEREF(__pyx_n_s_Any); - PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_s_Any); - __Pyx_INCREF(__pyx_n_s_Optional); - __Pyx_GIVEREF(__pyx_n_s_Optional); - PyList_SET_ITEM(__pyx_t_2, 5, __pyx_n_s_Optional); - __Pyx_INCREF(__pyx_n_s_Callable); - __Pyx_GIVEREF(__pyx_n_s_Callable); - PyList_SET_ITEM(__pyx_t_2, 6, __pyx_n_s_Callable); - __Pyx_INCREF(__pyx_n_s_Iterable); - __Pyx_GIVEREF(__pyx_n_s_Iterable); - PyList_SET_ITEM(__pyx_t_2, 7, __pyx_n_s_Iterable); - __pyx_t_1 = __Pyx_Import(__pyx_n_s_typing, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_List, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Tuple, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Dict, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Union); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Union, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Any); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Any, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Optional); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Optional, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Callable); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Callable, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Iterable); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_Iterable, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":58 - * from enum import Enum - * from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable - * import pathlib # <<<<<<<<<<<<<< - * - * import sys - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_pathlib, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 58, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_pathlib, __pyx_t_1) < 0) __PYX_ERR(0, 58, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":60 - * import pathlib - * - * import sys # <<<<<<<<<<<<<< - * - * class IngressErrorCode(Enum): - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "questdb/ingress.pyx":62 - * import sys - * - * class IngressErrorCode(Enum): # <<<<<<<<<<<<<< - * """Category of Error.""" - * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_IngressErrorCode, __pyx_n_s_IngressErrorCode, (PyObject *) NULL, __pyx_n_s_questdb_ingress, __pyx_kp_s_Category_of_Error); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - - /* "questdb/ingress.pyx":64 - * class IngressErrorCode(Enum): - * """Category of Error.""" - * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr # <<<<<<<<<<<<<< - * InvalidApiCall = line_sender_error_invalid_api_call - * SocketError = line_sender_error_socket_error - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_could_not_resolve_addr); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 64, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_CouldNotResolveAddr, __pyx_t_4) < 0) __PYX_ERR(0, 64, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":65 - * """Category of Error.""" - * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr - * InvalidApiCall = line_sender_error_invalid_api_call # <<<<<<<<<<<<<< - * SocketError = line_sender_error_socket_error - * InvalidUtf8 = line_sender_error_invalid_utf8 - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_api_call); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 65, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidApiCall, __pyx_t_4) < 0) __PYX_ERR(0, 65, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":66 - * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr - * InvalidApiCall = line_sender_error_invalid_api_call - * SocketError = line_sender_error_socket_error # <<<<<<<<<<<<<< - * InvalidUtf8 = line_sender_error_invalid_utf8 - * InvalidName = line_sender_error_invalid_name - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_socket_error); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 66, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_SocketError, __pyx_t_4) < 0) __PYX_ERR(0, 66, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":67 - * InvalidApiCall = line_sender_error_invalid_api_call - * SocketError = line_sender_error_socket_error - * InvalidUtf8 = line_sender_error_invalid_utf8 # <<<<<<<<<<<<<< - * InvalidName = line_sender_error_invalid_name - * InvalidTimestamp = line_sender_error_invalid_timestamp - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_utf8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidUtf8, __pyx_t_4) < 0) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":68 - * SocketError = line_sender_error_socket_error - * InvalidUtf8 = line_sender_error_invalid_utf8 - * InvalidName = line_sender_error_invalid_name # <<<<<<<<<<<<<< - * InvalidTimestamp = line_sender_error_invalid_timestamp - * AuthError = line_sender_error_auth_error - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidName, __pyx_t_4) < 0) __PYX_ERR(0, 68, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":69 - * InvalidUtf8 = line_sender_error_invalid_utf8 - * InvalidName = line_sender_error_invalid_name - * InvalidTimestamp = line_sender_error_invalid_timestamp # <<<<<<<<<<<<<< - * AuthError = line_sender_error_auth_error - * TlsError = line_sender_error_tls_error - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_invalid_timestamp); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_InvalidTimestamp, __pyx_t_4) < 0) __PYX_ERR(0, 69, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":70 - * InvalidName = line_sender_error_invalid_name - * InvalidTimestamp = line_sender_error_invalid_timestamp - * AuthError = line_sender_error_auth_error # <<<<<<<<<<<<<< - * TlsError = line_sender_error_tls_error - * - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_auth_error); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_AuthError, __pyx_t_4) < 0) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":71 - * InvalidTimestamp = line_sender_error_invalid_timestamp - * AuthError = line_sender_error_auth_error - * TlsError = line_sender_error_tls_error # <<<<<<<<<<<<<< - * - * def __str__(self) -> str: - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__line_sender_error_code(line_sender_error_tls_error); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_TlsError, __pyx_t_4) < 0) __PYX_ERR(0, 71, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":73 - * TlsError = line_sender_error_tls_error - * - * def __str__(self) -> str: # <<<<<<<<<<<<<< - * """Return the name of the enum.""" - * return self.name - */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 73, __pyx_L1_error) - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_16IngressErrorCode_1__str__, 0, __pyx_n_s_IngressErrorCode___str, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__34)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_4); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_str_2, __pyx_t_5) < 0) __PYX_ERR(0, 73, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "questdb/ingress.pyx":62 - * import sys - * - * class IngressErrorCode(Enum): # <<<<<<<<<<<<<< - * """Category of Error.""" - * CouldNotResolveAddr = line_sender_error_could_not_resolve_addr - */ - __pyx_t_5 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_IngressErrorCode, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_IngressErrorCode, __pyx_t_5) < 0) __PYX_ERR(0, 62, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":78 - * - * - * class IngressError(Exception): # <<<<<<<<<<<<<< - * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" - * def __init__(self, code, msg): - */ - __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - __Pyx_GIVEREF(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_IngressError, __pyx_n_s_IngressError, (PyObject *) NULL, __pyx_n_s_questdb_ingress, __pyx_kp_s_An_error_whilst_using_the_Sender); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - - /* "questdb/ingress.pyx":80 - * class IngressError(Exception): - * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" - * def __init__(self, code, msg): # <<<<<<<<<<<<<< - * super().__init__(msg) - * self._code = code - */ - __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_12IngressError_1__init__, 0, __pyx_n_s_IngressError___init, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__36)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_INCREF(__pyx_t_4); - PyList_Append(__pyx_t_5, __pyx_t_4); - __Pyx_GIVEREF(__pyx_t_4); - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_init, __pyx_t_4) < 0) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":85 - * - * @property - * def code(self) -> IngressErrorCode: # <<<<<<<<<<<<<< - * """Return the error code.""" - * return self._code - */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_IngressErrorCode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_12IngressError_3code, 0, __pyx_n_s_IngressError_code, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__38)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_4); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":84 - * self._code = code - * - * @property # <<<<<<<<<<<<<< - * def code(self) -> IngressErrorCode: - * """Return the error code.""" - */ - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_property, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 84, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_code, __pyx_t_4) < 0) __PYX_ERR(0, 85, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":78 - * - * - * class IngressError(Exception): # <<<<<<<<<<<<<< - * """An error whilst using the ``Sender`` or constructing its ``Buffer``.""" - * def __init__(self, code, msg): - */ - __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_IngressError, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_CyFunction_InitClassCell(__pyx_t_5, __pyx_t_4) < 0) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (PyDict_SetItem(__pyx_d, __pyx_n_s_IngressError, __pyx_t_4) < 0) __PYX_ERR(0, 78, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":298 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampMicros`` from a ``datetime.datetime`` object. - */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 298, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dt, __pyx_n_u_datetime) < 0) __PYX_ERR(0, 298, __pyx_L1_error) - __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_15TimestampMicros_3from_datetime, __Pyx_CYFUNCTION_CLASSMETHOD | __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampMicros_from_datetime, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__40)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 298, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros->tp_dict, __pyx_n_s_from_datetime, __pyx_t_1) < 0) __PYX_ERR(0, 298, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampMicros); - - /* "questdb/ingress.pyx":297 - * self._value = value - * - * @classmethod # <<<<<<<<<<<<<< - * def from_datetime(cls, dt: datetime): - * """ - */ - __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros, __pyx_n_s_from_datetime); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 298, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 297, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros->tp_dict, __pyx_n_s_from_datetime, __pyx_t_2) < 0) __PYX_ERR(0, 298, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampMicros); - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_15TimestampMicros_5__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampMicros___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__42)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_2) < 0) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_15TimestampMicros_7__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampMicros___setstate_cytho, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__44)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_2) < 0) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":349 - * - * @classmethod - * def from_datetime(cls, dt: datetime): # <<<<<<<<<<<<<< - * """ - * Construct a ``TimestampNanos`` from a ``datetime.datetime`` object. - */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 349, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dt, __pyx_n_u_datetime) < 0) __PYX_ERR(0, 349, __pyx_L1_error) - __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_14TimestampNanos_3from_datetime, __Pyx_CYFUNCTION_CLASSMETHOD | __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampNanos_from_datetime, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos->tp_dict, __pyx_n_s_from_datetime, __pyx_t_1) < 0) __PYX_ERR(0, 349, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampNanos); - - /* "questdb/ingress.pyx":348 - * self._value = value - * - * @classmethod # <<<<<<<<<<<<<< - * def from_datetime(cls, dt: datetime): - * """ - */ - __Pyx_GetNameInClass(__pyx_t_1, (PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos, __pyx_n_s_from_datetime); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 349, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_Method_ClassMethod(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 348, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos->tp_dict, __pyx_n_s_from_datetime, __pyx_t_2) < 0) __PYX_ERR(0, 349, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_TimestampNanos); - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_14TimestampNanos_5__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampNanos___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_2) < 0) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_14TimestampNanos_7__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_TimestampNanos___setstate_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__50)); if (unlikely(!__pyx_t_2)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_2) < 0) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":493 - * return self._max_name_len - * - * def reserve(self, additional: int): # <<<<<<<<<<<<<< - * """ - * Ensure the buffer has at least `additional` bytes of future capacity. - */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 493, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_additional, __pyx_n_u_int) < 0) __PYX_ERR(0, 493, __pyx_L1_error) - __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_5reserve, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_reserve, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__52)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 493, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_reserve, __pyx_t_1) < 0) __PYX_ERR(0, 493, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); - - /* "questdb/ingress.pyx":503 - * line_sender_buffer_reserve(self._impl, additional) - * - * def capacity(self) -> int: # <<<<<<<<<<<<<< - * """The current buffer capacity.""" - * return line_sender_buffer_capacity(self._impl) - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 503, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_n_u_int) < 0) __PYX_ERR(0, 503, __pyx_L1_error) - __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_7capacity, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_capacity, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__54)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 503, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_1); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_capacity, __pyx_t_2) < 0) __PYX_ERR(0, 503, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); - - /* "questdb/ingress.pyx":507 - * return line_sender_buffer_capacity(self._impl) - * - * def clear(self): # <<<<<<<<<<<<<< - * """ - * Reset the buffer. - */ - __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_9clear, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_clear, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__56)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 507, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_clear, __pyx_t_2) < 0) __PYX_ERR(0, 507, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); - - /* "questdb/ingress.pyx":716 - * self._may_trigger_row_complete() - * - * def row( # <<<<<<<<<<<<<< - * self, - * table_name: str, - */ - __pyx_t_2 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 716, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_table_name, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 716, __pyx_L1_error) - - /* "questdb/ingress.pyx":720 - * table_name: str, - * *, - * symbols: Optional[Dict[str, Optional[str]]]=None, # <<<<<<<<<<<<<< - * columns: Optional[Dict[ - * str, - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Optional); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 720, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Dict); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 720, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Optional); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_4, ((PyObject *)(&PyUnicode_Type))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 720, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_5); - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 720, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_symbols, __pyx_t_4) < 0) __PYX_ERR(0, 716, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":721 - * *, - * symbols: Optional[Dict[str, Optional[str]]]=None, - * columns: Optional[Dict[ # <<<<<<<<<<<<<< - * str, - * Union[None, bool, int, float, str, TimestampMicros, datetime]] - */ - __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Optional); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 721, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Dict); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 721, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - - /* "questdb/ingress.pyx":723 - * columns: Optional[Dict[ - * str, - * Union[None, bool, int, float, str, TimestampMicros, datetime]] # <<<<<<<<<<<<<< - * ]=None, - * at: Union[None, TimestampNanos, datetime]=None): - */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Union); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 723, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 723, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - PyTuple_SET_ITEM(__pyx_t_3, 1, ((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - __Pyx_INCREF(((PyObject *)(&PyInt_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); - PyTuple_SET_ITEM(__pyx_t_3, 2, ((PyObject *)(&PyInt_Type))); - __Pyx_INCREF(((PyObject *)(&PyFloat_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type))); - PyTuple_SET_ITEM(__pyx_t_3, 3, ((PyObject *)(&PyFloat_Type))); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_3, 4, ((PyObject *)(&PyUnicode_Type))); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); - PyTuple_SET_ITEM(__pyx_t_3, 5, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - PyTuple_SET_ITEM(__pyx_t_3, 6, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 723, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":721 - * *, - * symbols: Optional[Dict[str, Optional[str]]]=None, - * columns: Optional[Dict[ # <<<<<<<<<<<<<< - * str, - * Union[None, bool, int, float, str, TimestampMicros, datetime]] - */ - __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 721, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 721, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 721, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_columns, __pyx_t_3) < 0) __PYX_ERR(0, 716, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":725 - * Union[None, bool, int, float, str, TimestampMicros, datetime]] - * ]=None, - * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< - * """ - * Add a single row (line) to the buffer. - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 725, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 725, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_6, 0, Py_None); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - PyTuple_SET_ITEM(__pyx_t_6, 1, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - PyTuple_SET_ITEM(__pyx_t_6, 2, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 725, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_at, __pyx_t_4) < 0) __PYX_ERR(0, 716, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - - /* "questdb/ingress.pyx":716 - * self._may_trigger_row_complete() - * - * def row( # <<<<<<<<<<<<<< - * self, - * table_name: str, - */ - __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_15row, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_row, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__58)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 716, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_2); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_row, __pyx_t_4) < 0) __PYX_ERR(0, 716, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); - - /* "questdb/ingress.pyx":1090 - * qdb_pystr_buf_clear(self._b) - * - * def pandas( # <<<<<<<<<<<<<< - * self, - * data, # : pd.DataFrame - */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - - /* "questdb/ingress.pyx":1094 - * data, # : pd.DataFrame - * *, - * table_name: Optional[str] = None, # <<<<<<<<<<<<<< - * table_name_col: Union[None, int, str] = None, - * symbols: Union[bool, List[int], List[str]] = False, - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Optional); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1094, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, ((PyObject *)(&PyUnicode_Type))); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1094, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_table_name, __pyx_t_6) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - - /* "questdb/ingress.pyx":1095 - * *, - * table_name: Optional[str] = None, - * table_name_col: Union[None, int, str] = None, # <<<<<<<<<<<<<< - * symbols: Union[bool, List[int], List[str]] = False, - * at: Union[None, int, str, TimestampNanos, datetime] = None, - */ - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Union); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1095, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1095, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_2, 0, Py_None); - __Pyx_INCREF(((PyObject *)(&PyInt_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 1, ((PyObject *)(&PyInt_Type))); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 2, ((PyObject *)(&PyUnicode_Type))); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1095, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_table_name_col, __pyx_t_3) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":1096 - * table_name: Optional[str] = None, - * table_name_col: Union[None, int, str] = None, - * symbols: Union[bool, List[int], List[str]] = False, # <<<<<<<<<<<<<< - * at: Union[None, int, str, TimestampNanos, datetime] = None, - * sort: bool = True): - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1096, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1096, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, ((PyObject *)(&PyInt_Type))); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1096, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1096, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_2, ((PyObject *)(&PyUnicode_Type))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1096, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1096, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_6); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5); - __pyx_t_6 = 0; - __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1096, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_symbols, __pyx_t_5) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "questdb/ingress.pyx":1097 - * table_name_col: Union[None, int, str] = None, - * symbols: Union[bool, List[int], List[str]] = False, - * at: Union[None, int, str, TimestampNanos, datetime] = None, # <<<<<<<<<<<<<< - * sort: bool = True): - * """ - */ - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Union); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1097, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_2 = PyTuple_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1097, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_2, 0, Py_None); - __Pyx_INCREF(((PyObject *)(&PyInt_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 1, ((PyObject *)(&PyInt_Type))); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 2, ((PyObject *)(&PyUnicode_Type))); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - PyTuple_SET_ITEM(__pyx_t_2, 3, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - PyTuple_SET_ITEM(__pyx_t_2, 4, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1097, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_at, __pyx_t_3) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_sort, __pyx_n_u_bool) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) - - /* "questdb/ingress.pyx":1090 - * qdb_pystr_buf_clear(self._b) - * - * def pandas( # <<<<<<<<<<<<<< - * self, - * data, # : pd.DataFrame - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_17pandas, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer_pandas, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__60)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_4); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Buffer->tp_dict, __pyx_n_s_pandas, __pyx_t_3) < 0) __PYX_ERR(0, 1090, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Buffer); - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_19__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__62)); if (unlikely(!__pyx_t_3)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_3) < 0) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Buffer_21__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Buffer___setstate_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__64)); if (unlikely(!__pyx_t_3)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_3) < 0) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - - /* "questdb/ingress.pyx":1122 - * - * - * _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' # <<<<<<<<<<<<<< - * 'v1.0.2' - * '/troubleshooting.html#inspecting-and-debugging-errors#flush-failed') - */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_FLUSH_FMT, __pyx_kp_u_See_https_py_questdb_client_rea) < 0) __PYX_ERR(0, 1122, __pyx_L1_error) - - /* "questdb/ingress.pyx":1383 - * qdb_pystr_buf_clear(b) - * - * def new_buffer(self): # <<<<<<<<<<<<<< - * """ - * Make a new configured buffer. - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_3new_buffer, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_new_buffer, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__66)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1383, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_new_buffer, __pyx_t_3) < 0) __PYX_ERR(0, 1383, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); - - /* "questdb/ingress.pyx":1404 - * return self._max_name_len - * - * def connect(self): # <<<<<<<<<<<<<< - * """ - * Connect to the QuestDB server. - */ - __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_5connect, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_connect, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1404, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_connect, __pyx_t_3) < 0) __PYX_ERR(0, 1404, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); - - /* "questdb/ingress.pyx":1429 - * self._buffer._row_complete_sender = PyWeakref_NewRef(self, None) - * - * def __enter__(self) -> Sender: # <<<<<<<<<<<<<< - * """Call :func:`Sender.connect` at the start of a ``with`` block.""" - * self.connect() - */ - __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_return, __pyx_n_u_Sender) < 0) __PYX_ERR(0, 1429, __pyx_L1_error) - __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_7__enter__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___enter, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1429, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_3); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_enter, __pyx_t_4) < 0) __PYX_ERR(0, 1429, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); - - /* "questdb/ingress.pyx":1452 - * return len(self._buffer) - * - * def row(self, # <<<<<<<<<<<<<< - * table_name: str, - * *, - */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1452, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_table_name, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) - - /* "questdb/ingress.pyx":1455 - * table_name: str, - * *, - * symbols: Optional[Dict[str, str]]=None, # <<<<<<<<<<<<<< - * columns: Optional[Dict[ - * str, - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Optional); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1455, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1455, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1455, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyUnicode_Type))); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)(&PyUnicode_Type))); - __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1455, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1455, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_symbols, __pyx_t_5) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "questdb/ingress.pyx":1456 - * *, - * symbols: Optional[Dict[str, str]]=None, - * columns: Optional[Dict[ # <<<<<<<<<<<<<< - * str, - * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, - */ - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Optional); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1456, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1456, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - - /* "questdb/ingress.pyx":1458 - * columns: Optional[Dict[ - * str, - * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, # <<<<<<<<<<<<<< - * at: Union[None, TimestampNanos, datetime]=None): - * """ - */ - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1458, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = PyTuple_New(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1458, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_ptype_7cpython_4bool_bool)); - __Pyx_INCREF(((PyObject *)(&PyInt_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyInt_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 1, ((PyObject *)(&PyInt_Type))); - __Pyx_INCREF(((PyObject *)(&PyFloat_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 2, ((PyObject *)(&PyFloat_Type))); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 3, ((PyObject *)(&PyUnicode_Type))); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); - PyTuple_SET_ITEM(__pyx_t_2, 4, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampMicros)); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - PyTuple_SET_ITEM(__pyx_t_2, 5, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1458, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1456 - * *, - * symbols: Optional[Dict[str, str]]=None, - * columns: Optional[Dict[ # <<<<<<<<<<<<<< - * str, - * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, - */ - __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1456, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_INCREF(((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type))); - PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)(&PyUnicode_Type))); - __Pyx_GIVEREF(__pyx_t_1); - PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1); - __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1456, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1456, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_columns, __pyx_t_2) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - - /* "questdb/ingress.pyx":1459 - * str, - * Union[bool, int, float, str, TimestampMicros, datetime]]]=None, - * at: Union[None, TimestampNanos, datetime]=None): # <<<<<<<<<<<<<< - * """ - * Write a row to the internal buffer. - */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Union); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1459, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1459, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - PyTuple_SET_ITEM(__pyx_t_1, 0, Py_None); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - PyTuple_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_ptype_7questdb_7ingress_TimestampNanos)); - __Pyx_INCREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __Pyx_GIVEREF(((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - PyTuple_SET_ITEM(__pyx_t_1, 2, ((PyObject *)__pyx_ptype_7cpython_8datetime_datetime)); - __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1459, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_at, __pyx_t_5) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "questdb/ingress.pyx":1452 - * return len(self._buffer) - * - * def row(self, # <<<<<<<<<<<<<< - * table_name: str, - * *, - */ - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_13row, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_row, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__72)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1452, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_4); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_row, __pyx_t_5) < 0) __PYX_ERR(0, 1452, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); - - /* "questdb/ingress.pyx":1470 - * self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) - * - * cpdef flush(self, Buffer buffer=None, bint clear=True): # <<<<<<<<<<<<<< - * """ - * If called with no arguments, immediately flushes the internal buffer. - */ - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_15flush, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_flush, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__74)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_flush, __pyx_t_5) < 0) __PYX_ERR(0, 1470, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); - - /* "questdb/ingress.pyx":1528 - * self._impl = NULL - * - * cpdef close(self, bint flush=True): # <<<<<<<<<<<<<< - * """ - * Disconnect. - */ - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_17close, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender_close, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__76)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1528, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_close, __pyx_t_5) < 0) __PYX_ERR(0, 1528, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); - - /* "questdb/ingress.pyx":1545 - * self._close() - * - * def __exit__(self, exc_type, _exc_val, _exc_tb): # <<<<<<<<<<<<<< - * """ - * Flush pending and disconnect at the end of a ``with`` block. - */ - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_19__exit__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___exit, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__78)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1545, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem((PyObject *)__pyx_ptype_7questdb_7ingress_Sender->tp_dict, __pyx_n_s_exit, __pyx_t_5) < 0) __PYX_ERR(0, 1545, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - PyType_Modified(__pyx_ptype_7questdb_7ingress_Sender); - - /* "(tree fragment)":1 - * def __reduce_cython__(self): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): - */ - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_23__reduce_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___reduce_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__80)); if (unlikely(!__pyx_t_5)) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_reduce_cython, __pyx_t_5) < 0) __PYX_ERR(3, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "(tree fragment)":3 - * def __reduce_cython__(self): - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< - * raise TypeError("no default __reduce__ due to non-trivial __cinit__") - */ - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_7questdb_7ingress_6Sender_25__setstate_cython__, __Pyx_CYFUNCTION_CCLASS, __pyx_n_s_Sender___setstate_cython, NULL, __pyx_n_s_questdb_ingress, __pyx_d, ((PyObject *)__pyx_codeobj__82)); if (unlikely(!__pyx_t_5)) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_setstate_cython, __pyx_t_5) < 0) __PYX_ERR(3, 3, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "questdb/ingress.pyx":1 - * ################################################################################ # <<<<<<<<<<<<<< - * ## ___ _ ____ ____ - * ## / _ \ _ _ ___ ___| |_| _ \| __ ) - */ - __pyx_t_5 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_5) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "cpython/datetime.pxd":211 - * - * # Get microseconds of timedelta - * cdef inline int timedelta_microseconds(object o): # <<<<<<<<<<<<<< - * return (o).microseconds - */ - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_2); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init questdb.ingress", __pyx_clineno, __pyx_lineno, __pyx_filename); - } - Py_CLEAR(__pyx_m); - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init questdb.ingress"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule(modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, "RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* PyObjectGetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* PyCFunctionFastCall */ -#if CYTHON_FAST_PYCCALL -static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { - PyCFunctionObject *func = (PyCFunctionObject*)func_obj; - PyCFunction meth = PyCFunction_GET_FUNCTION(func); - PyObject *self = PyCFunction_GET_SELF(func); - int flags = PyCFunction_GET_FLAGS(func); - assert(PyCFunction_Check(func)); - assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - /* _PyCFunction_FastCallDict() must not be called with an exception set, - because it may clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); - if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { - return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); - } else { - return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); - } -} -#endif - -/* PyFunctionFastCall */ -#if CYTHON_FAST_PYCALL -static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, - PyObject *globals) { - PyFrameObject *f; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; - assert(globals != NULL); - /* XXX Perhaps we should create a specialized - PyFrame_New() that doesn't take locals, but does - take builtins without sanity checking them. - */ - assert(tstate != NULL); - f = PyFrame_New(tstate, co, globals, NULL); - if (f == NULL) { - return NULL; - } - fastlocals = __Pyx_PyFrame_GetLocalsplus(f); - for (i = 0; i < na; i++) { - Py_INCREF(*args); - fastlocals[i] = *args++; - } - result = PyEval_EvalFrameEx(f,0); - ++tstate->recursion_depth; - Py_DECREF(f); - --tstate->recursion_depth; - return result; -} -#if 1 || PY_VERSION_HEX < 0x030600B1 -static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *closure; -#if PY_MAJOR_VERSION >= 3 - PyObject *kwdefs; -#endif - PyObject *kwtuple, **k; - PyObject **d; - Py_ssize_t nd; - Py_ssize_t nk; - PyObject *result; - assert(kwargs == NULL || PyDict_Check(kwargs)); - nk = kwargs ? PyDict_Size(kwargs) : 0; - if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { - return NULL; - } - if ( -#if PY_MAJOR_VERSION >= 3 - co->co_kwonlyargcount == 0 && -#endif - likely(kwargs == NULL || nk == 0) && - co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { - result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); - goto done; - } - else if (nargs == 0 && argdefs != NULL - && co->co_argcount == Py_SIZE(argdefs)) { - /* function called with no arguments, but all parameters have - a default value: use default values as arguments .*/ - args = &PyTuple_GET_ITEM(argdefs, 0); - result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); - goto done; - } - } - if (kwargs != NULL) { - Py_ssize_t pos, i; - kwtuple = PyTuple_New(2 * nk); - if (kwtuple == NULL) { - result = NULL; - goto done; - } - k = &PyTuple_GET_ITEM(kwtuple, 0); - pos = i = 0; - while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { - Py_INCREF(k[i]); - Py_INCREF(k[i+1]); - i += 2; - } - nk = i / 2; - } - else { - kwtuple = NULL; - k = NULL; - } - closure = PyFunction_GET_CLOSURE(func); -#if PY_MAJOR_VERSION >= 3 - kwdefs = PyFunction_GET_KW_DEFAULTS(func); -#endif - if (argdefs != NULL) { - d = &PyTuple_GET_ITEM(argdefs, 0); - nd = Py_SIZE(argdefs); - } - else { - d = NULL; - nd = 0; - } -#if PY_MAJOR_VERSION >= 3 - result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, kwdefs, closure); -#else - result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, - args, (int)nargs, - k, (int)nk, - d, (int)nd, closure); -#endif - Py_XDECREF(kwtuple); -done: - Py_LeaveRecursiveCall(); - return result; -} -#endif -#endif - -/* PyObjectCall */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = Py_TYPE(func)->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallMethO */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { - PyObject *self, *result; - PyCFunction cfunc; - cfunc = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = cfunc(self, arg); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* PyObjectCallOneArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_New(1); - if (unlikely(!args)) return NULL; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, &arg, 1); - } -#endif - if (likely(PyCFunction_Check(func))) { - if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { - return __Pyx_PyObject_CallMethO(func, arg); -#if CYTHON_FAST_PYCCALL - } else if (__Pyx_PyFastCFunction_Check(func)) { - return __Pyx_PyCFunction_FastCall(func, &arg, 1); -#endif - } - } - return __Pyx__PyObject_CallOneArg(func, arg); -} -#else -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { - PyObject *result; - PyObject *args = PyTuple_Pack(1, arg); - if (unlikely(!args)) return NULL; - result = __Pyx_PyObject_Call(func, args, NULL); - Py_DECREF(args); - return result; -} -#endif - -/* Import */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* PyErrFetchRestore */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* RaiseException */ -#if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* GetTopmostException */ -#if CYTHON_USE_EXC_INFO_STACK -static _PyErr_StackItem * -__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) -{ - _PyErr_StackItem *exc_info = tstate->exc_info; - while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && - exc_info->previous_item != NULL) - { - exc_info = exc_info->previous_item; - } - return exc_info; -} -#endif - -/* SaveResetException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); - *type = exc_info->exc_type; - *value = exc_info->exc_value; - *tb = exc_info->exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = type; - exc_info->exc_value = value; - exc_info->exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -#endif - -/* FastTypeChecks */ -#if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - assert(PyExceptionClass_Check(exc_type)); - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; itp_dict; - return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; -} -static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { - PyObject **dictptr = NULL; - Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; - if (offset) { -#if CYTHON_COMPILING_IN_CPYTHON - dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); -#else - dictptr = _PyObject_GetDictPtr(obj); -#endif - } - return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; -} -static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { - PyObject *dict = Py_TYPE(obj)->tp_dict; - if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) - return 0; - return obj_dict_version == __Pyx_get_object_dict_version(obj); -} -#endif - -/* GetModuleGlobalName */ -#if CYTHON_USE_DICT_VERSIONS -static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) -#else -static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) -#endif -{ - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 - result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } else if (unlikely(PyErr_Occurred())) { - return NULL; - } -#else - result = PyDict_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } -#endif -#else - result = PyObject_GetItem(__pyx_d, name); - __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) - if (likely(result)) { - return __Pyx_NewRef(result); - } - PyErr_Clear(); -#endif - return __Pyx_GetBuiltinName(name); -} - -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* SwapException */ -#if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if CYTHON_USE_EXC_INFO_STACK - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = *type; - exc_info->exc_value = *value; - exc_info->exc_traceback = *tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = *type; - tstate->exc_value = *value; - tstate->exc_traceback = *tb; - #endif - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#else -static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); - PyErr_SetExcInfo(*type, *value, *tb); - *type = tmp_type; - *value = tmp_value; - *tb = tmp_tb; -} -#endif - -/* GetItemInt */ -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* PyUnicode_Unicode */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj) { - if (unlikely(obj == Py_None)) - obj = __pyx_kp_u_None; - return __Pyx_NewRef(obj); -} - -/* CIntToDigits */ -static const char DIGIT_PAIRS_10[2*10*10+1] = { - "00010203040506070809" - "10111213141516171819" - "20212223242526272829" - "30313233343536373839" - "40414243444546474849" - "50515253545556575859" - "60616263646566676869" - "70717273747576777879" - "80818283848586878889" - "90919293949596979899" -}; -static const char DIGIT_PAIRS_8[2*8*8+1] = { - "0001020304050607" - "1011121314151617" - "2021222324252627" - "3031323334353637" - "4041424344454647" - "5051525354555657" - "6061626364656667" - "7071727374757677" -}; -static const char DIGITS_HEX[2*16+1] = { - "0123456789abcdef" - "0123456789ABCDEF" -}; - -/* BuildPyUnicode */ -static PyObject* __Pyx_PyUnicode_BuildFromAscii(Py_ssize_t ulength, char* chars, int clength, - int prepend_sign, char padding_char) { - PyObject *uval; - Py_ssize_t uoffset = ulength - clength; -#if CYTHON_USE_UNICODE_INTERNALS - Py_ssize_t i; -#if CYTHON_PEP393_ENABLED - void *udata; - uval = PyUnicode_New(ulength, 127); - if (unlikely(!uval)) return NULL; - udata = PyUnicode_DATA(uval); -#else - Py_UNICODE *udata; - uval = PyUnicode_FromUnicode(NULL, ulength); - if (unlikely(!uval)) return NULL; - udata = PyUnicode_AS_UNICODE(uval); -#endif - if (uoffset > 0) { - i = 0; - if (prepend_sign) { - __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, 0, '-'); - i++; - } - for (; i < uoffset; i++) { - __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, i, padding_char); - } - } - for (i=0; i < clength; i++) { - __Pyx_PyUnicode_WRITE(PyUnicode_1BYTE_KIND, udata, uoffset+i, chars[i]); - } -#else - { - PyObject *sign = NULL, *padding = NULL; - uval = NULL; - if (uoffset > 0) { - prepend_sign = !!prepend_sign; - if (uoffset > prepend_sign) { - padding = PyUnicode_FromOrdinal(padding_char); - if (likely(padding) && uoffset > prepend_sign + 1) { - PyObject *tmp; - PyObject *repeat = PyInt_FromSize_t(uoffset - prepend_sign); - if (unlikely(!repeat)) goto done_or_error; - tmp = PyNumber_Multiply(padding, repeat); - Py_DECREF(repeat); - Py_DECREF(padding); - padding = tmp; - } - if (unlikely(!padding)) goto done_or_error; - } - if (prepend_sign) { - sign = PyUnicode_FromOrdinal('-'); - if (unlikely(!sign)) goto done_or_error; - } - } - uval = PyUnicode_DecodeASCII(chars, clength, NULL); - if (likely(uval) && padding) { - PyObject *tmp = PyNumber_Add(padding, uval); - Py_DECREF(uval); - uval = tmp; - } - if (likely(uval) && sign) { - PyObject *tmp = PyNumber_Add(sign, uval); - Py_DECREF(uval); - uval = tmp; - } -done_or_error: - Py_XDECREF(padding); - Py_XDECREF(sign); - } -#endif - return uval; -} - -/* CIntToPyUnicode */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_int(int value, Py_ssize_t width, char padding_char, char format_char) { - char digits[sizeof(int)*3+2]; - char *dpos, *end = digits + sizeof(int)*3+2; - const char *hex_digits = DIGITS_HEX; - Py_ssize_t length, ulength; - int prepend_sign, last_one_off; - int remaining; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (format_char == 'X') { - hex_digits += 16; - format_char = 'x'; - } - remaining = value; - last_one_off = 0; - dpos = end; - do { - int digit_pos; - switch (format_char) { - case 'o': - digit_pos = abs((int)(remaining % (8*8))); - remaining = (int) (remaining / (8*8)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); - last_one_off = (digit_pos < 8); - break; - case 'd': - digit_pos = abs((int)(remaining % (10*10))); - remaining = (int) (remaining / (10*10)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); - last_one_off = (digit_pos < 10); - break; - case 'x': - *(--dpos) = hex_digits[abs((int)(remaining % 16))]; - remaining = (int) (remaining / 16); - break; - default: - assert(0); - break; - } - } while (unlikely(remaining != 0)); - if (last_one_off) { - assert(*dpos == '0'); - dpos++; - } - length = end - dpos; - ulength = length; - prepend_sign = 0; - if (!is_unsigned && value <= neg_one) { - if (padding_char == ' ' || width <= length + 1) { - *(--dpos) = '-'; - ++length; - } else { - prepend_sign = 1; - } - ++ulength; - } - if (width > ulength) { - ulength = width; - } - if (ulength == 1) { - return PyUnicode_FromOrdinal(*dpos); - } - return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); -} - -/* JoinPyUnicode */ -static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength, - CYTHON_UNUSED Py_UCS4 max_char) { -#if CYTHON_USE_UNICODE_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - PyObject *result_uval; - int result_ukind; - Py_ssize_t i, char_pos; - void *result_udata; -#if CYTHON_PEP393_ENABLED - result_uval = PyUnicode_New(result_ulength, max_char); - if (unlikely(!result_uval)) return NULL; - result_ukind = (max_char <= 255) ? PyUnicode_1BYTE_KIND : (max_char <= 65535) ? PyUnicode_2BYTE_KIND : PyUnicode_4BYTE_KIND; - result_udata = PyUnicode_DATA(result_uval); -#else - result_uval = PyUnicode_FromUnicode(NULL, result_ulength); - if (unlikely(!result_uval)) return NULL; - result_ukind = sizeof(Py_UNICODE); - result_udata = PyUnicode_AS_UNICODE(result_uval); -#endif - char_pos = 0; - for (i=0; i < value_count; i++) { - int ukind; - Py_ssize_t ulength; - void *udata; - PyObject *uval = PyTuple_GET_ITEM(value_tuple, i); - if (unlikely(__Pyx_PyUnicode_READY(uval))) - goto bad; - ulength = __Pyx_PyUnicode_GET_LENGTH(uval); - if (unlikely(!ulength)) - continue; - if (unlikely(char_pos + ulength < 0)) - goto overflow; - ukind = __Pyx_PyUnicode_KIND(uval); - udata = __Pyx_PyUnicode_DATA(uval); - if (!CYTHON_PEP393_ENABLED || ukind == result_ukind) { - memcpy((char *)result_udata + char_pos * result_ukind, udata, (size_t) (ulength * result_ukind)); - } else { - #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030300F0 || defined(_PyUnicode_FastCopyCharacters) - _PyUnicode_FastCopyCharacters(result_uval, char_pos, uval, 0, ulength); - #else - Py_ssize_t j; - for (j=0; j < ulength; j++) { - Py_UCS4 uchar = __Pyx_PyUnicode_READ(ukind, udata, j); - __Pyx_PyUnicode_WRITE(result_ukind, result_udata, char_pos+j, uchar); - } - #endif - } - char_pos += ulength; - } - return result_uval; -overflow: - PyErr_SetString(PyExc_OverflowError, "join() result is too long for a Python string"); -bad: - Py_DECREF(result_uval); - return NULL; -#else - result_ulength++; - value_count++; - return PyUnicode_Join(__pyx_empty_unicode, value_tuple); -#endif -} - -/* BytesEquals */ -static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else - if (s1 == s2) { - return (equals == Py_EQ); - } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { - const char *ps1, *ps2; - Py_ssize_t length = PyBytes_GET_SIZE(s1); - if (length != PyBytes_GET_SIZE(s2)) - return (equals == Py_NE); - ps1 = PyBytes_AS_STRING(s1); - ps2 = PyBytes_AS_STRING(s2); - if (ps1[0] != ps2[0]) { - return (equals == Py_NE); - } else if (length == 1) { - return (equals == Py_EQ); - } else { - int result; -#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) - Py_hash_t hash1, hash2; - hash1 = ((PyBytesObject*)s1)->ob_shash; - hash2 = ((PyBytesObject*)s2)->ob_shash; - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - return (equals == Py_NE); - } -#endif - result = memcmp(ps1, ps2, (size_t)length); - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { - return (equals == Py_NE); - } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { - return (equals == Py_NE); - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -#endif -} - -/* UnicodeEquals */ -static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { -#if CYTHON_COMPILING_IN_PYPY - return PyObject_RichCompareBool(s1, s2, equals); -#else -#if PY_MAJOR_VERSION < 3 - PyObject* owned_ref = NULL; -#endif - int s1_is_unicode, s2_is_unicode; - if (s1 == s2) { - goto return_eq; - } - s1_is_unicode = PyUnicode_CheckExact(s1); - s2_is_unicode = PyUnicode_CheckExact(s2); -#if PY_MAJOR_VERSION < 3 - if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { - owned_ref = PyUnicode_FromObject(s2); - if (unlikely(!owned_ref)) - return -1; - s2 = owned_ref; - s2_is_unicode = 1; - } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { - owned_ref = PyUnicode_FromObject(s1); - if (unlikely(!owned_ref)) - return -1; - s1 = owned_ref; - s1_is_unicode = 1; - } else if (((!s2_is_unicode) & (!s1_is_unicode))) { - return __Pyx_PyBytes_Equals(s1, s2, equals); - } -#endif - if (s1_is_unicode & s2_is_unicode) { - Py_ssize_t length; - int kind; - void *data1, *data2; - if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) - return -1; - length = __Pyx_PyUnicode_GET_LENGTH(s1); - if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { - goto return_ne; - } -#if CYTHON_USE_UNICODE_INTERNALS - { - Py_hash_t hash1, hash2; - #if CYTHON_PEP393_ENABLED - hash1 = ((PyASCIIObject*)s1)->hash; - hash2 = ((PyASCIIObject*)s2)->hash; - #else - hash1 = ((PyUnicodeObject*)s1)->hash; - hash2 = ((PyUnicodeObject*)s2)->hash; - #endif - if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { - goto return_ne; - } - } -#endif - kind = __Pyx_PyUnicode_KIND(s1); - if (kind != __Pyx_PyUnicode_KIND(s2)) { - goto return_ne; - } - data1 = __Pyx_PyUnicode_DATA(s1); - data2 = __Pyx_PyUnicode_DATA(s2); - if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { - goto return_ne; - } else if (length == 1) { - goto return_eq; - } else { - int result = memcmp(data1, data2, (size_t)(length * kind)); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ) ? (result == 0) : (result != 0); - } - } else if ((s1 == Py_None) & s2_is_unicode) { - goto return_ne; - } else if ((s2 == Py_None) & s1_is_unicode) { - goto return_ne; - } else { - int result; - PyObject* py_result = PyObject_RichCompare(s1, s2, equals); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - if (!py_result) - return -1; - result = __Pyx_PyObject_IsTrue(py_result); - Py_DECREF(py_result); - return result; - } -return_eq: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_EQ); -return_ne: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(owned_ref); - #endif - return (equals == Py_NE); -#endif -} - -/* ObjectGetItem */ -#if CYTHON_USE_TYPE_SLOTS -static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { - PyObject *runerr; - Py_ssize_t key_value; - PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; - if (unlikely(!(m && m->sq_item))) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); - return NULL; - } - key_value = __Pyx_PyIndex_AsSsize_t(index); - if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { - return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); - } - if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { - PyErr_Clear(); - PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); - } - return NULL; -} -static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { - PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; - if (likely(m && m->mp_subscript)) { - return m->mp_subscript(obj, key); - } - return __Pyx_PyObject_GetIndex(obj, key); -} -#endif - -/* PyObjectFormatAndDecref */ -static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatSimpleAndDecref(PyObject* s, PyObject* f) { - if (unlikely(!s)) return NULL; - if (likely(PyUnicode_CheckExact(s))) return s; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_CheckExact(s))) { - PyObject *result = PyUnicode_FromEncodedObject(s, NULL, "strict"); - Py_DECREF(s); - return result; - } - #endif - return __Pyx_PyObject_FormatAndDecref(s, f); -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_FormatAndDecref(PyObject* s, PyObject* f) { - PyObject *result = PyObject_Format(s, f); - Py_DECREF(s); - return result; -} - -/* PyObjectCall2Args */ -static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { - PyObject *args, *result = NULL; - #if CYTHON_FAST_PYCALL - if (PyFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyFunction_FastCall(function, args, 2); - } - #endif - #if CYTHON_FAST_PYCCALL - if (__Pyx_PyFastCFunction_Check(function)) { - PyObject *args[2] = {arg1, arg2}; - return __Pyx_PyCFunction_FastCall(function, args, 2); - } - #endif - args = PyTuple_New(2); - if (unlikely(!args)) goto done; - Py_INCREF(arg1); - PyTuple_SET_ITEM(args, 0, arg1); - Py_INCREF(arg2); - PyTuple_SET_ITEM(args, 1, arg2); - Py_INCREF(function); - result = __Pyx_PyObject_Call(function, args, NULL); - Py_DECREF(args); - Py_DECREF(function); -done: - return result; -} - -/* PyErrExceptionMatches */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; icurexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); -} -#endif - -/* ExtTypeTest */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - if (likely(__Pyx_TypeCheck(obj, type))) - return 1; - PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", - Py_TYPE(obj)->tp_name, type->tp_name); - return 0; -} - -/* PyIntCompare */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED long inplace) { - if (op1 == op2) { - Py_RETURN_TRUE; - } - #if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(op1))) { - const long b = intval; - long a = PyInt_AS_LONG(op1); - if (a == b) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } - #endif - #if CYTHON_USE_PYLONG_INTERNALS - if (likely(PyLong_CheckExact(op1))) { - int unequal; - unsigned long uintval; - Py_ssize_t size = Py_SIZE(op1); - const digit* digits = ((PyLongObject*)op1)->ob_digit; - if (intval == 0) { - if (size == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } else if (intval < 0) { - if (size >= 0) - Py_RETURN_FALSE; - intval = -intval; - size = -size; - } else { - if (size <= 0) - Py_RETURN_FALSE; - } - uintval = (unsigned long) intval; -#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 4)) { - unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif -#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 3)) { - unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif -#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 2)) { - unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif -#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 - if (uintval >> (PyLong_SHIFT * 1)) { - unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) - | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); - } else -#endif - unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); - if (unequal == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } - #endif - if (PyFloat_CheckExact(op1)) { - const long b = intval; - double a = PyFloat_AS_DOUBLE(op1); - if ((double)a == (double)b) Py_RETURN_TRUE; else Py_RETURN_FALSE; - } - return ( - PyObject_RichCompare(op1, op2, Py_EQ)); -} - -/* UnicodeAsUCS4 */ -static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject* x) { - Py_ssize_t length; - #if CYTHON_PEP393_ENABLED - length = PyUnicode_GET_LENGTH(x); - if (likely(length == 1)) { - return PyUnicode_READ_CHAR(x, 0); - } - #else - length = PyUnicode_GET_SIZE(x); - if (likely(length == 1)) { - return PyUnicode_AS_UNICODE(x)[0]; - } - #if Py_UNICODE_SIZE == 2 - else if (PyUnicode_GET_SIZE(x) == 2) { - Py_UCS4 high_val = PyUnicode_AS_UNICODE(x)[0]; - if (high_val >= 0xD800 && high_val <= 0xDBFF) { - Py_UCS4 low_val = PyUnicode_AS_UNICODE(x)[1]; - if (low_val >= 0xDC00 && low_val <= 0xDFFF) { - return 0x10000 + (((high_val & ((1<<10)-1)) << 10) | (low_val & ((1<<10)-1))); - } - } - } - #endif - #endif - PyErr_Format(PyExc_ValueError, - "only single character unicode strings can be converted to Py_UCS4, " - "got length %" CYTHON_FORMAT_SSIZE_T "d", length); - return (Py_UCS4)-1; -} - -/* object_ord */ -static long __Pyx__PyObject_Ord(PyObject* c) { - Py_ssize_t size; - if (PyBytes_Check(c)) { - size = PyBytes_GET_SIZE(c); - if (likely(size == 1)) { - return (unsigned char) PyBytes_AS_STRING(c)[0]; - } -#if PY_MAJOR_VERSION < 3 - } else if (PyUnicode_Check(c)) { - return (long)__Pyx_PyUnicode_AsPy_UCS4(c); -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - } else if (PyByteArray_Check(c)) { - size = PyByteArray_GET_SIZE(c); - if (likely(size == 1)) { - return (unsigned char) PyByteArray_AS_STRING(c)[0]; - } -#endif - } else { - PyErr_Format(PyExc_TypeError, - "ord() expected string of length 1, but %.200s found", Py_TYPE(c)->tp_name); - return (long)(Py_UCS4)-1; - } - PyErr_Format(PyExc_TypeError, - "ord() expected a character, but string of length %zd found", size); - return (long)(Py_UCS4)-1; -} - -/* GetAttr */ -static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { -#if CYTHON_USE_TYPE_SLOTS -#if PY_MAJOR_VERSION >= 3 - if (likely(PyUnicode_Check(n))) -#else - if (likely(PyString_Check(n))) -#endif - return __Pyx_PyObject_GetAttrStr(o, n); -#endif - return PyObject_GetAttr(o, n); -} - -/* GetAttr3 */ -static PyObject *__Pyx_GetAttr3Default(PyObject *d) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - Py_INCREF(d); - return d; -} -static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { - PyObject *r = __Pyx_GetAttr(o, n); - return (likely(r)) ? r : __Pyx_GetAttr3Default(d); -} - -/* PyObjectCallNoArg */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { -#if CYTHON_FAST_PYCALL - if (PyFunction_Check(func)) { - return __Pyx_PyFunction_FastCall(func, NULL, 0); - } -#endif -#ifdef __Pyx_CyFunction_USED - if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) -#else - if (likely(PyCFunction_Check(func))) -#endif - { - if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { - return __Pyx_PyObject_CallMethO(func, NULL); - } - } - return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); -} -#endif - -/* CIntToPyUnicode */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_char(char value, Py_ssize_t width, char padding_char, char format_char) { - char digits[sizeof(char)*3+2]; - char *dpos, *end = digits + sizeof(char)*3+2; - const char *hex_digits = DIGITS_HEX; - Py_ssize_t length, ulength; - int prepend_sign, last_one_off; - char remaining; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const char neg_one = (char) -1, const_zero = (char) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (format_char == 'X') { - hex_digits += 16; - format_char = 'x'; - } - remaining = value; - last_one_off = 0; - dpos = end; - do { - int digit_pos; - switch (format_char) { - case 'o': - digit_pos = abs((int)(remaining % (8*8))); - remaining = (char) (remaining / (8*8)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); - last_one_off = (digit_pos < 8); - break; - case 'd': - digit_pos = abs((int)(remaining % (10*10))); - remaining = (char) (remaining / (10*10)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); - last_one_off = (digit_pos < 10); - break; - case 'x': - *(--dpos) = hex_digits[abs((int)(remaining % 16))]; - remaining = (char) (remaining / 16); - break; - default: - assert(0); - break; - } - } while (unlikely(remaining != 0)); - if (last_one_off) { - assert(*dpos == '0'); - dpos++; - } - length = end - dpos; - ulength = length; - prepend_sign = 0; - if (!is_unsigned && value <= neg_one) { - if (padding_char == ' ' || width <= length + 1) { - *(--dpos) = '-'; - ++length; - } else { - prepend_sign = 1; - } - ++ulength; - } - if (width > ulength) { - ulength = width; - } - if (ulength == 1) { - return PyUnicode_FromOrdinal(*dpos); - } - return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); -} - -/* CIntToPyUnicode */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_size_t(size_t value, Py_ssize_t width, char padding_char, char format_char) { - char digits[sizeof(size_t)*3+2]; - char *dpos, *end = digits + sizeof(size_t)*3+2; - const char *hex_digits = DIGITS_HEX; - Py_ssize_t length, ulength; - int prepend_sign, last_one_off; - size_t remaining; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const size_t neg_one = (size_t) -1, const_zero = (size_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (format_char == 'X') { - hex_digits += 16; - format_char = 'x'; - } - remaining = value; - last_one_off = 0; - dpos = end; - do { - int digit_pos; - switch (format_char) { - case 'o': - digit_pos = abs((int)(remaining % (8*8))); - remaining = (size_t) (remaining / (8*8)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); - last_one_off = (digit_pos < 8); - break; - case 'd': - digit_pos = abs((int)(remaining % (10*10))); - remaining = (size_t) (remaining / (10*10)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); - last_one_off = (digit_pos < 10); - break; - case 'x': - *(--dpos) = hex_digits[abs((int)(remaining % 16))]; - remaining = (size_t) (remaining / 16); - break; - default: - assert(0); - break; - } - } while (unlikely(remaining != 0)); - if (last_one_off) { - assert(*dpos == '0'); - dpos++; - } - length = end - dpos; - ulength = length; - prepend_sign = 0; - if (!is_unsigned && value <= neg_one) { - if (padding_char == ' ' || width <= length + 1) { - *(--dpos) = '-'; - ++length; - } else { - prepend_sign = 1; - } - ++ulength; - } - if (width > ulength) { - ulength = width; - } - if (ulength == 1) { - return PyUnicode_FromOrdinal(*dpos); - } - return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* PyObjectSetAttrStr */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_setattro)) - return tp->tp_setattro(obj, attr_name, value); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_setattr)) - return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value); -#endif - return PyObject_SetAttr(obj, attr_name, value); -} -#endif - -/* UnpackUnboundCMethod */ -static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { - PyObject *method; - method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); - if (unlikely(!method)) - return -1; - target->method = method; -#if CYTHON_COMPILING_IN_CPYTHON - #if PY_MAJOR_VERSION >= 3 - if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) - #endif - { - PyMethodDescrObject *descr = (PyMethodDescrObject*) method; - target->func = descr->d_method->ml_meth; - target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); - } -#endif - return 0; -} - -/* CallUnboundCMethod1 */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg) { - if (likely(cfunc->func)) { - int flag = cfunc->flag; - if (flag == METH_O) { - return (*(cfunc->func))(self, arg); - } else if (PY_VERSION_HEX >= 0x030600B1 && flag == METH_FASTCALL) { - if (PY_VERSION_HEX >= 0x030700A0) { - return (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)cfunc->func)(self, &arg, 1); - } else { - return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); - } - } else if (PY_VERSION_HEX >= 0x030700A0 && flag == (METH_FASTCALL | METH_KEYWORDS)) { - return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); - } - } - return __Pyx__CallUnboundCMethod1(cfunc, self, arg); -} -#endif -static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg){ - PyObject *args, *result = NULL; - if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; -#if CYTHON_COMPILING_IN_CPYTHON - if (cfunc->func && (cfunc->flag & METH_VARARGS)) { - args = PyTuple_New(1); - if (unlikely(!args)) goto bad; - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 0, arg); - if (cfunc->flag & METH_KEYWORDS) - result = (*(PyCFunctionWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, NULL); - else - result = (*cfunc->func)(self, args); - } else { - args = PyTuple_New(2); - if (unlikely(!args)) goto bad; - Py_INCREF(self); - PyTuple_SET_ITEM(args, 0, self); - Py_INCREF(arg); - PyTuple_SET_ITEM(args, 1, arg); - result = __Pyx_PyObject_Call(cfunc->method, args, NULL); - } -#else - args = PyTuple_Pack(2, self, arg); - if (unlikely(!args)) goto bad; - result = __Pyx_PyObject_Call(cfunc->method, args, NULL); -#endif -bad: - Py_XDECREF(args); - return result; -} - -/* PyObjectFormat */ -#if CYTHON_USE_UNICODE_WRITER -static PyObject* __Pyx_PyObject_Format(PyObject* obj, PyObject* format_spec) { - int ret; - _PyUnicodeWriter writer; - if (likely(PyFloat_CheckExact(obj))) { -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x03040000 - _PyUnicodeWriter_Init(&writer, 0); -#else - _PyUnicodeWriter_Init(&writer); -#endif - ret = _PyFloat_FormatAdvancedWriter( - &writer, - obj, - format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); - } else if (likely(PyLong_CheckExact(obj))) { -#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x03040000 - _PyUnicodeWriter_Init(&writer, 0); -#else - _PyUnicodeWriter_Init(&writer); -#endif - ret = _PyLong_FormatAdvancedWriter( - &writer, - obj, - format_spec, 0, PyUnicode_GET_LENGTH(format_spec)); - } else { - return PyObject_Format(obj, format_spec); - } - if (unlikely(ret == -1)) { - _PyUnicodeWriter_Dealloc(&writer); - return NULL; - } - return _PyUnicodeWriter_Finish(&writer); -} -#endif - -/* WriteUnraisableException */ -static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, - CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, - int full_traceback, CYTHON_UNUSED int nogil) { - PyObject *old_exc, *old_val, *old_tb; - PyObject *ctx; - __Pyx_PyThreadState_declare -#ifdef WITH_THREAD - PyGILState_STATE state; - if (nogil) - state = PyGILState_Ensure(); -#ifdef _MSC_VER - else state = (PyGILState_STATE)-1; -#endif -#endif - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); - if (full_traceback) { - Py_XINCREF(old_exc); - Py_XINCREF(old_val); - Py_XINCREF(old_tb); - __Pyx_ErrRestore(old_exc, old_val, old_tb); - PyErr_PrintEx(1); - } - #if PY_MAJOR_VERSION < 3 - ctx = PyString_FromString(name); - #else - ctx = PyUnicode_FromString(name); - #endif - __Pyx_ErrRestore(old_exc, old_val, old_tb); - if (!ctx) { - PyErr_WriteUnraisable(Py_None); - } else { - PyErr_WriteUnraisable(ctx); - Py_DECREF(ctx); - } -#ifdef WITH_THREAD - if (nogil) - PyGILState_Release(state); -#endif -} - -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) -{ - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif - } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; - } - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", - name, type->tp_name, Py_TYPE(obj)->tp_name); - return 0; -} - -/* IterFinish */ -static CYTHON_INLINE int __Pyx_IterFinish(void) { -#if CYTHON_FAST_THREAD_STATE - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* exc_type = tstate->curexc_type; - if (unlikely(exc_type)) { - if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) { - PyObject *exc_value, *exc_tb; - exc_value = tstate->curexc_value; - exc_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; - Py_DECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - return 0; - } else { - return -1; - } - } - return 0; -#else - if (unlikely(PyErr_Occurred())) { - if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { - PyErr_Clear(); - return 0; - } else { - return -1; - } - } - return 0; -#endif -} - -/* PyObjectGetMethod */ -static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { - PyObject *attr; -#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP - PyTypeObject *tp = Py_TYPE(obj); - PyObject *descr; - descrgetfunc f = NULL; - PyObject **dictptr, *dict; - int meth_found = 0; - assert (*method == NULL); - if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; - } - if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { - return 0; - } - descr = _PyType_Lookup(tp, name); - if (likely(descr != NULL)) { - Py_INCREF(descr); -#if PY_MAJOR_VERSION >= 3 - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) - #endif -#else - #ifdef __Pyx_CyFunction_USED - if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) - #else - if (likely(PyFunction_Check(descr))) - #endif -#endif - { - meth_found = 1; - } else { - f = Py_TYPE(descr)->tp_descr_get; - if (f != NULL && PyDescr_IsData(descr)) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - } - } - dictptr = _PyObject_GetDictPtr(obj); - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - attr = __Pyx_PyDict_GetItemStr(dict, name); - if (attr != NULL) { - Py_INCREF(attr); - Py_DECREF(dict); - Py_XDECREF(descr); - goto try_unpack; - } - Py_DECREF(dict); - } - if (meth_found) { - *method = descr; - return 1; - } - if (f != NULL) { - attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); - Py_DECREF(descr); - goto try_unpack; - } - if (descr != NULL) { - *method = descr; - return 0; - } - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(name)); -#endif - return 0; -#else - attr = __Pyx_PyObject_GetAttrStr(obj, name); - goto try_unpack; -#endif -try_unpack: -#if CYTHON_UNPACK_METHODS - if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { - PyObject *function = PyMethod_GET_FUNCTION(attr); - Py_INCREF(function); - Py_DECREF(attr); - *method = function; - return 1; - } -#endif - *method = attr; - return 0; -} - -/* PyObjectCallMethod0 */ -static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { - PyObject *method = NULL, *result = NULL; - int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); - if (likely(is_method)) { - result = __Pyx_PyObject_CallOneArg(method, obj); - Py_DECREF(method); - return result; - } - if (unlikely(!method)) goto bad; - result = __Pyx_PyObject_CallNoArg(method); - Py_DECREF(method); -bad: - return result; -} - -/* RaiseNeedMoreValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* RaiseTooManyValuesToUnpack */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* UnpackItemEndCheck */ -static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { - if (unlikely(retval)) { - Py_DECREF(retval); - __Pyx_RaiseTooManyValuesError(expected); - return -1; - } else { - return __Pyx_IterFinish(); - } - return 0; -} - -/* RaiseNoneIterError */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); -} - -/* UnpackTupleError */ -static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { - if (t == Py_None) { - __Pyx_RaiseNoneNotIterableError(); - } else if (PyTuple_GET_SIZE(t) < index) { - __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t)); - } else { - __Pyx_RaiseTooManyValuesError(index); - } -} - -/* UnpackTuple2 */ -static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( - PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int decref_tuple) { - PyObject *value1 = NULL, *value2 = NULL; -#if CYTHON_COMPILING_IN_PYPY - value1 = PySequence_ITEM(tuple, 0); if (unlikely(!value1)) goto bad; - value2 = PySequence_ITEM(tuple, 1); if (unlikely(!value2)) goto bad; -#else - value1 = PyTuple_GET_ITEM(tuple, 0); Py_INCREF(value1); - value2 = PyTuple_GET_ITEM(tuple, 1); Py_INCREF(value2); -#endif - if (decref_tuple) { - Py_DECREF(tuple); - } - *pvalue1 = value1; - *pvalue2 = value2; - return 0; -#if CYTHON_COMPILING_IN_PYPY -bad: - Py_XDECREF(value1); - Py_XDECREF(value2); - if (decref_tuple) { Py_XDECREF(tuple); } - return -1; -#endif -} -static int __Pyx_unpack_tuple2_generic(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, - int has_known_size, int decref_tuple) { - Py_ssize_t index; - PyObject *value1 = NULL, *value2 = NULL, *iter = NULL; - iternextfunc iternext; - iter = PyObject_GetIter(tuple); - if (unlikely(!iter)) goto bad; - if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; } - iternext = Py_TYPE(iter)->tp_iternext; - value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; } - value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; } - if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad; - Py_DECREF(iter); - *pvalue1 = value1; - *pvalue2 = value2; - return 0; -unpacking_failed: - if (!has_known_size && __Pyx_IterFinish() == 0) - __Pyx_RaiseNeedMoreValuesError(index); -bad: - Py_XDECREF(iter); - Py_XDECREF(value1); - Py_XDECREF(value2); - if (decref_tuple) { Py_XDECREF(tuple); } - return -1; -} - -/* dict_iter */ -static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name, - Py_ssize_t* p_orig_length, int* p_source_is_dict) { - is_dict = is_dict || likely(PyDict_CheckExact(iterable)); - *p_source_is_dict = is_dict; - if (is_dict) { -#if !CYTHON_COMPILING_IN_PYPY - *p_orig_length = PyDict_Size(iterable); - Py_INCREF(iterable); - return iterable; -#elif PY_MAJOR_VERSION >= 3 - static PyObject *py_items = NULL, *py_keys = NULL, *py_values = NULL; - PyObject **pp = NULL; - if (method_name) { - const char *name = PyUnicode_AsUTF8(method_name); - if (strcmp(name, "iteritems") == 0) pp = &py_items; - else if (strcmp(name, "iterkeys") == 0) pp = &py_keys; - else if (strcmp(name, "itervalues") == 0) pp = &py_values; - if (pp) { - if (!*pp) { - *pp = PyUnicode_FromString(name + 4); - if (!*pp) - return NULL; - } - method_name = *pp; - } - } -#endif - } - *p_orig_length = 0; - if (method_name) { - PyObject* iter; - iterable = __Pyx_PyObject_CallMethod0(iterable, method_name); - if (!iterable) - return NULL; -#if !CYTHON_COMPILING_IN_PYPY - if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable)) - return iterable; -#endif - iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - return iter; - } - return PyObject_GetIter(iterable); -} -static CYTHON_INLINE int __Pyx_dict_iter_next( - PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos, - PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) { - PyObject* next_item; -#if !CYTHON_COMPILING_IN_PYPY - if (source_is_dict) { - PyObject *key, *value; - if (unlikely(orig_length != PyDict_Size(iter_obj))) { - PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); - return -1; - } - if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) { - return 0; - } - if (pitem) { - PyObject* tuple = PyTuple_New(2); - if (unlikely(!tuple)) { - return -1; - } - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(tuple, 0, key); - PyTuple_SET_ITEM(tuple, 1, value); - *pitem = tuple; - } else { - if (pkey) { - Py_INCREF(key); - *pkey = key; - } - if (pvalue) { - Py_INCREF(value); - *pvalue = value; - } - } - return 1; - } else if (PyTuple_CheckExact(iter_obj)) { - Py_ssize_t pos = *ppos; - if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0; - *ppos = pos + 1; - next_item = PyTuple_GET_ITEM(iter_obj, pos); - Py_INCREF(next_item); - } else if (PyList_CheckExact(iter_obj)) { - Py_ssize_t pos = *ppos; - if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0; - *ppos = pos + 1; - next_item = PyList_GET_ITEM(iter_obj, pos); - Py_INCREF(next_item); - } else -#endif - { - next_item = PyIter_Next(iter_obj); - if (unlikely(!next_item)) { - return __Pyx_IterFinish(); - } - } - if (pitem) { - *pitem = next_item; - } else if (pkey && pvalue) { - if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1)) - return -1; - } else if (pkey) { - *pkey = next_item; - } else { - *pvalue = next_item; - } - return 1; -} - -/* CIntToPyUnicode */ -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_From_Py_ssize_t(Py_ssize_t value, Py_ssize_t width, char padding_char, char format_char) { - char digits[sizeof(Py_ssize_t)*3+2]; - char *dpos, *end = digits + sizeof(Py_ssize_t)*3+2; - const char *hex_digits = DIGITS_HEX; - Py_ssize_t length, ulength; - int prepend_sign, last_one_off; - Py_ssize_t remaining; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const Py_ssize_t neg_one = (Py_ssize_t) -1, const_zero = (Py_ssize_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (format_char == 'X') { - hex_digits += 16; - format_char = 'x'; - } - remaining = value; - last_one_off = 0; - dpos = end; - do { - int digit_pos; - switch (format_char) { - case 'o': - digit_pos = abs((int)(remaining % (8*8))); - remaining = (Py_ssize_t) (remaining / (8*8)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); - last_one_off = (digit_pos < 8); - break; - case 'd': - digit_pos = abs((int)(remaining % (10*10))); - remaining = (Py_ssize_t) (remaining / (10*10)); - dpos -= 2; - memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); - last_one_off = (digit_pos < 10); - break; - case 'x': - *(--dpos) = hex_digits[abs((int)(remaining % 16))]; - remaining = (Py_ssize_t) (remaining / 16); - break; - default: - assert(0); - break; - } - } while (unlikely(remaining != 0)); - if (last_one_off) { - assert(*dpos == '0'); - dpos++; - } - length = end - dpos; - ulength = length; - prepend_sign = 0; - if (!is_unsigned && value <= neg_one) { - if (padding_char == ' ' || width <= length + 1) { - *(--dpos) = '-'; - ++length; - } else { - prepend_sign = 1; - } - ++ulength; - } - if (width > ulength) { - ulength = width; - } - if (ulength == 1) { - return PyUnicode_FromOrdinal(*dpos); - } - return __Pyx_PyUnicode_BuildFromAscii(ulength, dpos, (int) length, prepend_sign, padding_char); -} - -/* PyObject_GenericGetAttrNoDict */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { - PyErr_Format(PyExc_AttributeError, -#if PY_MAJOR_VERSION >= 3 - "'%.50s' object has no attribute '%U'", - tp->tp_name, attr_name); -#else - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(attr_name)); -#endif - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { - PyObject *descr; - PyTypeObject *tp = Py_TYPE(obj); - if (unlikely(!PyString_Check(attr_name))) { - return PyObject_GenericGetAttr(obj, attr_name); - } - assert(!tp->tp_dictoffset); - descr = _PyType_Lookup(tp, attr_name); - if (unlikely(!descr)) { - return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); - } - Py_INCREF(descr); - #if PY_MAJOR_VERSION < 3 - if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) - #endif - { - descrgetfunc f = Py_TYPE(descr)->tp_descr_get; - if (unlikely(f)) { - PyObject *res = f(descr, obj, (PyObject *)tp); - Py_DECREF(descr); - return res; - } - } - return descr; -} -#endif - -/* PyObject_GenericGetAttr */ -#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 -static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { - if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { - return PyObject_GenericGetAttr(obj, attr_name); - } - return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); -} -#endif - -/* PyObjectGetAttrStrNoError */ -static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - __Pyx_PyErr_Clear(); -} -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { - PyObject *result; -#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { - return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); - } -#endif - result = __Pyx_PyObject_GetAttrStr(obj, attr_name); - if (unlikely(!result)) { - __Pyx_PyObject_GetAttrStr_ClearAttributeError(); - } - return result; -} - -/* SetupReduce */ -static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { - int ret; - PyObject *name_attr; - name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name_2); - if (likely(name_attr)) { - ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); - } else { - ret = -1; - } - if (unlikely(ret < 0)) { - PyErr_Clear(); - ret = 0; - } - Py_XDECREF(name_attr); - return ret; -} -static int __Pyx_setup_reduce(PyObject* type_obj) { - int ret = 0; - PyObject *object_reduce = NULL; - PyObject *object_getstate = NULL; - PyObject *object_reduce_ex = NULL; - PyObject *reduce = NULL; - PyObject *reduce_ex = NULL; - PyObject *reduce_cython = NULL; - PyObject *setstate = NULL; - PyObject *setstate_cython = NULL; - PyObject *getstate = NULL; -#if CYTHON_USE_PYTYPE_LOOKUP - getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); -#else - getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); - if (!getstate && PyErr_Occurred()) { - goto __PYX_BAD; - } -#endif - if (getstate) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); -#else - object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); - if (!object_getstate && PyErr_Occurred()) { - goto __PYX_BAD; - } -#endif - if (object_getstate != getstate) { - goto __PYX_GOOD; - } - } -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#else - object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; -#endif - reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; - if (reduce_ex == object_reduce_ex) { -#if CYTHON_USE_PYTYPE_LOOKUP - object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#else - object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; -#endif - reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; - if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { - reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); - if (likely(reduce_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (reduce == object_reduce || PyErr_Occurred()) { - goto __PYX_BAD; - } - setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); - if (!setstate) PyErr_Clear(); - if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { - setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); - if (likely(setstate_cython)) { - ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; - } else if (!setstate || PyErr_Occurred()) { - goto __PYX_BAD; - } - } - PyType_Modified((PyTypeObject*)type_obj); - } - } - goto __PYX_GOOD; -__PYX_BAD: - if (!PyErr_Occurred()) - PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); - ret = -1; -__PYX_GOOD: -#if !CYTHON_USE_PYTYPE_LOOKUP - Py_XDECREF(object_reduce); - Py_XDECREF(object_reduce_ex); - Py_XDECREF(object_getstate); - Py_XDECREF(getstate); -#endif - Py_XDECREF(reduce); - Py_XDECREF(reduce_ex); - Py_XDECREF(reduce_cython); - Py_XDECREF(setstate); - Py_XDECREF(setstate_cython); - return ret; -} - -/* SetVTable */ -static int __Pyx_SetVtable(PyObject *dict, void *vtable) { -#if PY_VERSION_HEX >= 0x02070000 - PyObject *ob = PyCapsule_New(vtable, 0, 0); -#else - PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); -#endif - if (!ob) - goto bad; - if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) - goto bad; - Py_DECREF(ob); - return 0; -bad: - Py_XDECREF(ob); - return -1; -} - -/* TypeImport */ -#ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, - size_t size, enum __Pyx_ImportType_CheckSize check_size) -{ - PyObject *result = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - result = PyObject_GetAttrString(module, class_name); - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if ((size_t)basicsize < size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - goto bad; - } - else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. " - "Expected %zd from C header, got %zd from PyObject", - module_name, class_name, size, basicsize); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(result); - return NULL; -} -#endif - -/* ImportFrom */ -static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { - PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); - if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, - #if PY_MAJOR_VERSION < 3 - "cannot import name %.230s", PyString_AS_STRING(name)); - #else - "cannot import name %S", name); - #endif - } - return value; -} - -/* CalculateMetaclass */ -static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) { - Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases); - for (i=0; i < nbases; i++) { - PyTypeObject *tmptype; - PyObject *tmp = PyTuple_GET_ITEM(bases, i); - tmptype = Py_TYPE(tmp); -#if PY_MAJOR_VERSION < 3 - if (tmptype == &PyClass_Type) - continue; -#endif - if (!metaclass) { - metaclass = tmptype; - continue; - } - if (PyType_IsSubtype(metaclass, tmptype)) - continue; - if (PyType_IsSubtype(tmptype, metaclass)) { - metaclass = tmptype; - continue; - } - PyErr_SetString(PyExc_TypeError, - "metaclass conflict: " - "the metaclass of a derived class " - "must be a (non-strict) subclass " - "of the metaclasses of all its bases"); - return NULL; - } - if (!metaclass) { -#if PY_MAJOR_VERSION < 3 - metaclass = &PyClass_Type; -#else - metaclass = &PyType_Type; -#endif - } - Py_INCREF((PyObject*) metaclass); - return (PyObject*) metaclass; -} - -/* FetchCommonType */ -static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { - PyObject* fake_module; - PyTypeObject* cached_type = NULL; - fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI); - if (!fake_module) return NULL; - Py_INCREF(fake_module); - cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name); - if (cached_type) { - if (!PyType_Check((PyObject*)cached_type)) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s is not a type object", - type->tp_name); - goto bad; - } - if (cached_type->tp_basicsize != type->tp_basicsize) { - PyErr_Format(PyExc_TypeError, - "Shared Cython type %.200s has the wrong size, try recompiling", - type->tp_name); - goto bad; - } - } else { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; - PyErr_Clear(); - if (PyType_Ready(type) < 0) goto bad; - if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0) - goto bad; - Py_INCREF(type); - cached_type = type; - } -done: - Py_DECREF(fake_module); - return cached_type; -bad: - Py_XDECREF(cached_type); - cached_type = NULL; - goto done; -} - -/* CythonFunctionShared */ -#include -static PyObject * -__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure) -{ - if (unlikely(op->func_doc == NULL)) { - if (op->func.m_ml->ml_doc) { -#if PY_MAJOR_VERSION >= 3 - op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc); -#else - op->func_doc = PyString_FromString(op->func.m_ml->ml_doc); -#endif - if (unlikely(op->func_doc == NULL)) - return NULL; - } else { - Py_INCREF(Py_None); - return Py_None; - } - } - Py_INCREF(op->func_doc); - return op->func_doc; -} -static int -__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) -{ - PyObject *tmp = op->func_doc; - if (value == NULL) { - value = Py_None; - } - Py_INCREF(value); - op->func_doc = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) -{ - if (unlikely(op->func_name == NULL)) { -#if PY_MAJOR_VERSION >= 3 - op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name); -#else - op->func_name = PyString_InternFromString(op->func.m_ml->ml_name); -#endif - if (unlikely(op->func_name == NULL)) - return NULL; - } - Py_INCREF(op->func_name); - return op->func_name; -} -static int -__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) -{ - PyObject *tmp; -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__name__ must be set to a string object"); - return -1; - } - tmp = op->func_name; - Py_INCREF(value); - op->func_name = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) -{ - Py_INCREF(op->func_qualname); - return op->func_qualname; -} -static int -__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) -{ - PyObject *tmp; -#if PY_MAJOR_VERSION >= 3 - if (unlikely(value == NULL || !PyUnicode_Check(value))) -#else - if (unlikely(value == NULL || !PyString_Check(value))) -#endif - { - PyErr_SetString(PyExc_TypeError, - "__qualname__ must be set to a string object"); - return -1; - } - tmp = op->func_qualname; - Py_INCREF(value); - op->func_qualname = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure) -{ - PyObject *self; - self = m->func_closure; - if (self == NULL) - self = Py_None; - Py_INCREF(self); - return self; -} -static PyObject * -__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) -{ - if (unlikely(op->func_dict == NULL)) { - op->func_dict = PyDict_New(); - if (unlikely(op->func_dict == NULL)) - return NULL; - } - Py_INCREF(op->func_dict); - return op->func_dict; -} -static int -__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value, CYTHON_UNUSED void *context) -{ - PyObject *tmp; - if (unlikely(value == NULL)) { - PyErr_SetString(PyExc_TypeError, - "function's dictionary may not be deleted"); - return -1; - } - if (unlikely(!PyDict_Check(value))) { - PyErr_SetString(PyExc_TypeError, - "setting function's dictionary to a non-dict"); - return -1; - } - tmp = op->func_dict; - Py_INCREF(value); - op->func_dict = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) -{ - Py_INCREF(op->func_globals); - return op->func_globals; -} -static PyObject * -__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) -{ - Py_INCREF(Py_None); - return Py_None; -} -static PyObject * -__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) -{ - PyObject* result = (op->func_code) ? op->func_code : Py_None; - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { - int result = 0; - PyObject *res = op->defaults_getter((PyObject *) op); - if (unlikely(!res)) - return -1; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - op->defaults_tuple = PyTuple_GET_ITEM(res, 0); - Py_INCREF(op->defaults_tuple); - op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); - Py_INCREF(op->defaults_kwdict); - #else - op->defaults_tuple = PySequence_ITEM(res, 0); - if (unlikely(!op->defaults_tuple)) result = -1; - else { - op->defaults_kwdict = PySequence_ITEM(res, 1); - if (unlikely(!op->defaults_kwdict)) result = -1; - } - #endif - Py_DECREF(res); - return result; -} -static int -__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) { - PyObject* tmp; - if (!value) { - value = Py_None; - } else if (value != Py_None && !PyTuple_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__defaults__ must be set to a tuple object"); - return -1; - } - Py_INCREF(value); - tmp = op->defaults_tuple; - op->defaults_tuple = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) { - PyObject* result = op->defaults_tuple; - if (unlikely(!result)) { - if (op->defaults_getter) { - if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; - result = op->defaults_tuple; - } else { - result = Py_None; - } - } - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) { - PyObject* tmp; - if (!value) { - value = Py_None; - } else if (value != Py_None && !PyDict_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__kwdefaults__ must be set to a dict object"); - return -1; - } - Py_INCREF(value); - tmp = op->defaults_kwdict; - op->defaults_kwdict = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) { - PyObject* result = op->defaults_kwdict; - if (unlikely(!result)) { - if (op->defaults_getter) { - if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; - result = op->defaults_kwdict; - } else { - result = Py_None; - } - } - Py_INCREF(result); - return result; -} -static int -__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, CYTHON_UNUSED void *context) { - PyObject* tmp; - if (!value || value == Py_None) { - value = NULL; - } else if (!PyDict_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__annotations__ must be set to a dict object"); - return -1; - } - Py_XINCREF(value); - tmp = op->func_annotations; - op->func_annotations = value; - Py_XDECREF(tmp); - return 0; -} -static PyObject * -__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *context) { - PyObject* result = op->func_annotations; - if (unlikely(!result)) { - result = PyDict_New(); - if (unlikely(!result)) return NULL; - op->func_annotations = result; - } - Py_INCREF(result); - return result; -} -static PyGetSetDef __pyx_CyFunction_getsets[] = { - {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, - {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, - {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, - {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, - {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, - {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0}, - {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, - {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, - {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, - {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, - {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, - {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, - {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, - {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, - {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, - {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, - {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, - {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, - {0, 0, 0, 0, 0} -}; -static PyMemberDef __pyx_CyFunction_members[] = { - {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), PY_WRITE_RESTRICTED, 0}, - {0, 0, 0, 0, 0} -}; -static PyObject * -__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args) -{ -#if PY_MAJOR_VERSION >= 3 - Py_INCREF(m->func_qualname); - return m->func_qualname; -#else - return PyString_FromString(m->func.m_ml->ml_name); -#endif -} -static PyMethodDef __pyx_CyFunction_methods[] = { - {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, - {0, 0, 0, 0} -}; -#if PY_VERSION_HEX < 0x030500A0 -#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) -#else -#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist) -#endif -static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { - if (unlikely(op == NULL)) - return NULL; - op->flags = flags; - __Pyx_CyFunction_weakreflist(op) = NULL; - op->func.m_ml = ml; - op->func.m_self = (PyObject *) op; - Py_XINCREF(closure); - op->func_closure = closure; - Py_XINCREF(module); - op->func.m_module = module; - op->func_dict = NULL; - op->func_name = NULL; - Py_INCREF(qualname); - op->func_qualname = qualname; - op->func_doc = NULL; - op->func_classobj = NULL; - op->func_globals = globals; - Py_INCREF(op->func_globals); - Py_XINCREF(code); - op->func_code = code; - op->defaults_pyobjects = 0; - op->defaults_size = 0; - op->defaults = NULL; - op->defaults_tuple = NULL; - op->defaults_kwdict = NULL; - op->defaults_getter = NULL; - op->func_annotations = NULL; - return (PyObject *) op; -} -static int -__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) -{ - Py_CLEAR(m->func_closure); - Py_CLEAR(m->func.m_module); - Py_CLEAR(m->func_dict); - Py_CLEAR(m->func_name); - Py_CLEAR(m->func_qualname); - Py_CLEAR(m->func_doc); - Py_CLEAR(m->func_globals); - Py_CLEAR(m->func_code); - Py_CLEAR(m->func_classobj); - Py_CLEAR(m->defaults_tuple); - Py_CLEAR(m->defaults_kwdict); - Py_CLEAR(m->func_annotations); - if (m->defaults) { - PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); - int i; - for (i = 0; i < m->defaults_pyobjects; i++) - Py_XDECREF(pydefaults[i]); - PyObject_Free(m->defaults); - m->defaults = NULL; - } - return 0; -} -static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) -{ - if (__Pyx_CyFunction_weakreflist(m) != NULL) - PyObject_ClearWeakRefs((PyObject *) m); - __Pyx_CyFunction_clear(m); - PyObject_GC_Del(m); -} -static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) -{ - PyObject_GC_UnTrack(m); - __Pyx__CyFunction_dealloc(m); -} -static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) -{ - Py_VISIT(m->func_closure); - Py_VISIT(m->func.m_module); - Py_VISIT(m->func_dict); - Py_VISIT(m->func_name); - Py_VISIT(m->func_qualname); - Py_VISIT(m->func_doc); - Py_VISIT(m->func_globals); - Py_VISIT(m->func_code); - Py_VISIT(m->func_classobj); - Py_VISIT(m->defaults_tuple); - Py_VISIT(m->defaults_kwdict); - if (m->defaults) { - PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); - int i; - for (i = 0; i < m->defaults_pyobjects; i++) - Py_VISIT(pydefaults[i]); - } - return 0; -} -static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type) -{ -#if PY_MAJOR_VERSION < 3 - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) { - Py_INCREF(func); - return func; - } - if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) { - if (type == NULL) - type = (PyObject *)(Py_TYPE(obj)); - return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type))); - } - if (obj == Py_None) - obj = NULL; -#endif - return __Pyx_PyMethod_New(func, obj, type); -} -static PyObject* -__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) -{ -#if PY_MAJOR_VERSION >= 3 - return PyUnicode_FromFormat("", - op->func_qualname, (void *)op); -#else - return PyString_FromFormat("", - PyString_AsString(op->func_qualname), (void *)op); -#endif -} -static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { - PyCFunctionObject* f = (PyCFunctionObject*)func; - PyCFunction meth = f->m_ml->ml_meth; - Py_ssize_t size; - switch (f->m_ml->ml_flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { - case METH_VARARGS: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) - return (*meth)(self, arg); - break; - case METH_VARARGS | METH_KEYWORDS: - return (*(PyCFunctionWithKeywords)(void*)meth)(self, arg, kw); - case METH_NOARGS: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) { - size = PyTuple_GET_SIZE(arg); - if (likely(size == 0)) - return (*meth)(self, NULL); - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", - f->m_ml->ml_name, size); - return NULL; - } - break; - case METH_O: - if (likely(kw == NULL || PyDict_Size(kw) == 0)) { - size = PyTuple_GET_SIZE(arg); - if (likely(size == 1)) { - PyObject *result, *arg0; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - arg0 = PyTuple_GET_ITEM(arg, 0); - #else - arg0 = PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; - #endif - result = (*meth)(self, arg0); - #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) - Py_DECREF(arg0); - #endif - return result; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", - f->m_ml->ml_name, size); - return NULL; - } - break; - default: - PyErr_SetString(PyExc_SystemError, "Bad call flags in " - "__Pyx_CyFunction_Call. METH_OLDARGS is no " - "longer supported!"); - return NULL; - } - PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - f->m_ml->ml_name); - return NULL; -} -static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { - return __Pyx_CyFunction_CallMethod(func, ((PyCFunctionObject*)func)->m_self, arg, kw); -} -static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { - PyObject *result; - __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; - if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { - Py_ssize_t argc; - PyObject *new_args; - PyObject *self; - argc = PyTuple_GET_SIZE(args); - new_args = PyTuple_GetSlice(args, 1, argc); - if (unlikely(!new_args)) - return NULL; - self = PyTuple_GetItem(args, 0); - if (unlikely(!self)) { - Py_DECREF(new_args); - PyErr_Format(PyExc_TypeError, - "unbound method %.200S() needs an argument", - cyfunc->func_qualname); - return NULL; - } - result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); - Py_DECREF(new_args); - } else { - result = __Pyx_CyFunction_Call(func, args, kw); - } - return result; -} -static PyTypeObject __pyx_CyFunctionType_type = { - PyVarObject_HEAD_INIT(0, 0) - "cython_function_or_method", - sizeof(__pyx_CyFunctionObject), - 0, - (destructor) __Pyx_CyFunction_dealloc, - 0, - 0, - 0, -#if PY_MAJOR_VERSION < 3 - 0, -#else - 0, -#endif - (reprfunc) __Pyx_CyFunction_repr, - 0, - 0, - 0, - 0, - __Pyx_CyFunction_CallAsMethod, - 0, - 0, - 0, - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - 0, - (traverseproc) __Pyx_CyFunction_traverse, - (inquiry) __Pyx_CyFunction_clear, - 0, -#if PY_VERSION_HEX < 0x030500A0 - offsetof(__pyx_CyFunctionObject, func_weakreflist), -#else - offsetof(PyCFunctionObject, m_weakreflist), -#endif - 0, - 0, - __pyx_CyFunction_methods, - __pyx_CyFunction_members, - __pyx_CyFunction_getsets, - 0, - 0, - __Pyx_CyFunction_descr_get, - 0, - offsetof(__pyx_CyFunctionObject, func_dict), - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -#if PY_VERSION_HEX >= 0x030400a1 - 0, -#endif -#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800) - 0, -#endif -#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 - 0, -#endif -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 - 0, -#endif -}; -static int __pyx_CyFunction_init(void) { - __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); - if (unlikely(__pyx_CyFunctionType == NULL)) { - return -1; - } - return 0; -} -static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults = PyObject_Malloc(size); - if (unlikely(!m->defaults)) - return PyErr_NoMemory(); - memset(m->defaults, 0, size); - m->defaults_pyobjects = pyobjects; - m->defaults_size = size; - return m->defaults; -} -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults_tuple = tuple; - Py_INCREF(tuple); -} -static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->defaults_kwdict = dict; - Py_INCREF(dict); -} -static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; - m->func_annotations = dict; - Py_INCREF(dict); -} - -/* CythonFunction */ -static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, - PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { - PyObject *op = __Pyx_CyFunction_Init( - PyObject_GC_New(__pyx_CyFunctionObject, __pyx_CyFunctionType), - ml, flags, qualname, closure, module, globals, code - ); - if (likely(op)) { - PyObject_GC_Track(op); - } - return op; -} - -/* Py3ClassCreate */ -static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, - PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) { - PyObject *ns; - if (metaclass) { - PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, __pyx_n_s_prepare); - if (prep) { - PyObject *pargs = PyTuple_Pack(2, name, bases); - if (unlikely(!pargs)) { - Py_DECREF(prep); - return NULL; - } - ns = PyObject_Call(prep, pargs, mkw); - Py_DECREF(prep); - Py_DECREF(pargs); - } else { - if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - PyErr_Clear(); - ns = PyDict_New(); - } - } else { - ns = PyDict_New(); - } - if (unlikely(!ns)) - return NULL; - if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad; - if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad; - if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad; - return ns; -bad: - Py_DECREF(ns); - return NULL; -} -static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, - PyObject *dict, PyObject *mkw, - int calculate_metaclass, int allow_py2_metaclass) { - PyObject *result, *margs; - PyObject *owned_metaclass = NULL; - if (allow_py2_metaclass) { - owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass); - if (owned_metaclass) { - metaclass = owned_metaclass; - } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { - PyErr_Clear(); - } else { - return NULL; - } - } - if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) { - metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); - Py_XDECREF(owned_metaclass); - if (unlikely(!metaclass)) - return NULL; - owned_metaclass = metaclass; - } - margs = PyTuple_Pack(3, name, bases, dict); - if (unlikely(!margs)) { - result = NULL; - } else { - result = PyObject_Call(metaclass, margs, mkw); - Py_DECREF(margs); - } - Py_XDECREF(owned_metaclass); - return result; -} - -/* CyFunctionClassCell */ -static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj) { - Py_ssize_t i, count = PyList_GET_SIZE(cyfunctions); - for (i = 0; i < count; i++) { - __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - PyList_GET_ITEM(cyfunctions, i); -#else - PySequence_ITEM(cyfunctions, i); - if (unlikely(!m)) - return -1; -#endif - Py_INCREF(classobj); - m->func_classobj = classobj; -#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) - Py_DECREF((PyObject*)m); -#endif - } - return 0; -} - -/* ClassMethod */ -static PyObject* __Pyx_Method_ClassMethod(PyObject *method) { -#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM <= 0x05080000 - if (PyObject_TypeCheck(method, &PyWrapperDescr_Type)) { - return PyClassMethod_New(method); - } -#else -#if CYTHON_COMPILING_IN_PYSTON || CYTHON_COMPILING_IN_PYPY - if (PyMethodDescr_Check(method)) -#else - #if PY_MAJOR_VERSION == 2 - static PyTypeObject *methoddescr_type = NULL; - if (methoddescr_type == NULL) { - PyObject *meth = PyObject_GetAttrString((PyObject*)&PyList_Type, "append"); - if (!meth) return NULL; - methoddescr_type = Py_TYPE(meth); - Py_DECREF(meth); - } - #else - PyTypeObject *methoddescr_type = &PyMethodDescr_Type; - #endif - if (__Pyx_TypeCheck(method, methoddescr_type)) -#endif - { - PyMethodDescrObject *descr = (PyMethodDescrObject *)method; - #if PY_VERSION_HEX < 0x03020000 - PyTypeObject *d_type = descr->d_type; - #else - PyTypeObject *d_type = descr->d_common.d_type; - #endif - return PyDescr_NewClassMethod(d_type, descr->d_method); - } -#endif - else if (PyMethod_Check(method)) { - return PyClassMethod_New(PyMethod_GET_FUNCTION(method)); - } - else { - return PyClassMethod_New(method); - } -} - -/* GetNameInClass */ -static PyObject *__Pyx_GetGlobalNameAfterAttributeLookup(PyObject *name) { - PyObject *result; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) - return NULL; - __Pyx_PyErr_Clear(); - __Pyx_GetModuleGlobalNameUncached(result, name); - return result; -} -static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) { - PyObject *result; - result = __Pyx_PyObject_GetAttrStr(nmspace, name); - if (!result) { - result = __Pyx_GetGlobalNameAfterAttributeLookup(name); - } - return result; -} - -/* CLineInTraceback */ -#ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - if (unlikely(!__pyx_cython_runtime)) { - return c_line; - } - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - __PYX_PY_DICT_LOOKUP_IF_MODIFIED( - use_cline, *cython_runtime_dict, - __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - (void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" -#if PY_VERSION_HEX >= 0x030b00a6 - #ifndef Py_BUILD_CORE - #define Py_BUILD_CORE 1 - #endif - #include "internal/pycore_frame.h" -#endif -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = NULL; - PyObject *py_funcname = NULL; - #if PY_MAJOR_VERSION < 3 - PyObject *py_srcfile = NULL; - py_srcfile = PyString_FromString(filename); - if (!py_srcfile) goto bad; - #endif - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - if (!py_funcname) goto bad; - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - if (!py_funcname) goto bad; - funcname = PyUnicode_AsUTF8(py_funcname); - if (!funcname) goto bad; - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - if (!py_funcname) goto bad; - #endif - } - #if PY_MAJOR_VERSION < 3 - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - #else - py_code = PyCode_NewEmpty(filename, funcname, py_line); - #endif - Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline - return py_code; -bad: - Py_XDECREF(py_funcname); - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_srcfile); - #endif - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject *ptype, *pvalue, *ptraceback; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) { - /* If the code object creation fails, then we should clear the - fetched exception references and propagate the new exception */ - Py_XDECREF(ptype); - Py_XDECREF(pvalue); - Py_XDECREF(ptraceback); - goto bad; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -/* CIntFromPyVerify */ -#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__line_sender_error_code(enum line_sender_error_code value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const enum line_sender_error_code neg_one = (enum line_sender_error_code) -1, const_zero = (enum line_sender_error_code) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(enum line_sender_error_code) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(enum line_sender_error_code) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum line_sender_error_code) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(enum line_sender_error_code) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum line_sender_error_code) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(enum line_sender_error_code), - little, !is_unsigned); - } -} - -/* CIntFromPy */ -static CYTHON_INLINE uint64_t __Pyx_PyInt_As_uint64_t(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const uint64_t neg_one = (uint64_t) -1, const_zero = (uint64_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(uint64_t) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(uint64_t, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (uint64_t) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (uint64_t) 0; - case 1: __PYX_VERIFY_RETURN_INT(uint64_t, digit, digits[0]) - case 2: - if (8 * sizeof(uint64_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) >= 2 * PyLong_SHIFT) { - return (uint64_t) (((((uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(uint64_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) >= 3 * PyLong_SHIFT) { - return (uint64_t) (((((((uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(uint64_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) >= 4 * PyLong_SHIFT) { - return (uint64_t) (((((((((uint64_t)digits[3]) << PyLong_SHIFT) | (uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (uint64_t) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(uint64_t) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(uint64_t, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint64_t) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(uint64_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (uint64_t) 0; - case -1: __PYX_VERIFY_RETURN_INT(uint64_t, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(uint64_t, digit, +digits[0]) - case -2: - if (8 * sizeof(uint64_t) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) - 1 > 2 * PyLong_SHIFT) { - return (uint64_t) (((uint64_t)-1)*(((((uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(uint64_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) - 1 > 2 * PyLong_SHIFT) { - return (uint64_t) ((((((uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(uint64_t) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) - 1 > 3 * PyLong_SHIFT) { - return (uint64_t) (((uint64_t)-1)*(((((((uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(uint64_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) - 1 > 3 * PyLong_SHIFT) { - return (uint64_t) ((((((((uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(uint64_t) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) - 1 > 4 * PyLong_SHIFT) { - return (uint64_t) (((uint64_t)-1)*(((((((((uint64_t)digits[3]) << PyLong_SHIFT) | (uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(uint64_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(uint64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(uint64_t) - 1 > 4 * PyLong_SHIFT) { - return (uint64_t) ((((((((((uint64_t)digits[3]) << PyLong_SHIFT) | (uint64_t)digits[2]) << PyLong_SHIFT) | (uint64_t)digits[1]) << PyLong_SHIFT) | (uint64_t)digits[0]))); - } - } - break; - } -#endif - if (sizeof(uint64_t) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(uint64_t, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint64_t) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(uint64_t, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - uint64_t val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (uint64_t) -1; - } - } else { - uint64_t val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (uint64_t) -1; - val = __Pyx_PyInt_As_uint64_t(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to uint64_t"); - return (uint64_t) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to uint64_t"); - return (uint64_t) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const size_t neg_one = (size_t) -1, const_zero = (size_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(size_t) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (size_t) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (size_t) 0; - case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, digits[0]) - case 2: - if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) >= 2 * PyLong_SHIFT) { - return (size_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) >= 3 * PyLong_SHIFT) { - return (size_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) >= 4 * PyLong_SHIFT) { - return (size_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (size_t) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(size_t) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(size_t) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (size_t) 0; - case -1: __PYX_VERIFY_RETURN_INT(size_t, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, +digits[0]) - case -2: - if (8 * sizeof(size_t) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { - return (size_t) (((size_t)-1)*(((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { - return (size_t) ((((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { - return (size_t) (((size_t)-1)*(((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { - return (size_t) ((((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { - return (size_t) (((size_t)-1)*(((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { - return (size_t) ((((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); - } - } - break; - } -#endif - if (sizeof(size_t) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(size_t) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(size_t, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - size_t val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (size_t) -1; - } - } else { - size_t val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (size_t) -1; - val = __Pyx_PyInt_As_size_t(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to size_t"); - return (size_t) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to size_t"); - return (size_t) -1; -} - -/* CIntFromPy */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int neg_one = (int) -1, const_zero = (int) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); - } -} - -/* CIntFromPy */ -static CYTHON_INLINE int64_t __Pyx_PyInt_As_int64_t(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int64_t) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int64_t, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int64_t) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int64_t) 0; - case 1: __PYX_VERIFY_RETURN_INT(int64_t, digit, digits[0]) - case 2: - if (8 * sizeof(int64_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) >= 2 * PyLong_SHIFT) { - return (int64_t) (((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int64_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) >= 3 * PyLong_SHIFT) { - return (int64_t) (((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int64_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) >= 4 * PyLong_SHIFT) { - return (int64_t) (((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int64_t) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int64_t) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int64_t, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int64_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int64_t) 0; - case -1: __PYX_VERIFY_RETURN_INT(int64_t, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int64_t, digit, +digits[0]) - case -2: - if (8 * sizeof(int64_t) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) { - return (int64_t) (((int64_t)-1)*(((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int64_t) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) { - return (int64_t) ((((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) { - return (int64_t) (((int64_t)-1)*(((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int64_t) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) { - return (int64_t) ((((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) - 1 > 4 * PyLong_SHIFT) { - return (int64_t) (((int64_t)-1)*(((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int64_t) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int64_t) - 1 > 4 * PyLong_SHIFT) { - return (int64_t) ((((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int64_t) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int64_t, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int64_t, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int64_t val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int64_t) -1; - } - } else { - int64_t val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int64_t) -1; - val = __Pyx_PyInt_As_int64_t(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int64_t"); - return (int64_t) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int64_t"); - return (int64_t) -1; -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int64_t) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int64_t) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int64_t) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(int64_t), - little, !is_unsigned); - } -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const long neg_one = (long) -1, const_zero = (long) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const uint32_t neg_one = (uint32_t) -1, const_zero = (uint32_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(uint32_t) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(uint32_t) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint32_t) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(uint32_t) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(uint32_t), - little, !is_unsigned); - } -} - -/* CIntToPy */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint64_t(uint64_t value) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const uint64_t neg_one = (uint64_t) -1, const_zero = (uint64_t) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(uint64_t) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(uint64_t) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint64_t) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(uint64_t) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(uint64_t) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(uint64_t), - little, !is_unsigned); - } -} - -/* CIntFromPy */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - const long neg_one = (long) -1, const_zero = (long) 0; -#ifdef __Pyx_HAS_GCC_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* CheckBinaryVersion */ -static int __Pyx_check_binary_version(void) { - char ctversion[5]; - int same=1, i, found_dot; - const char* rt_from_call = Py_GetVersion(); - PyOS_snprintf(ctversion, 5, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); - found_dot = 0; - for (i = 0; i < 4; i++) { - if (!ctversion[i]) { - same = (rt_from_call[i] < '0' || rt_from_call[i] > '9'); - break; - } - if (rt_from_call[i] != ctversion[i]) { - same = 0; - break; - } - } - if (!same) { - char rtversion[5] = {'\0'}; - char message[200]; - for (i=0; i<4; ++i) { - if (rt_from_call[i] == '.') { - if (found_dot) break; - found_dot = 1; - } else if (rt_from_call[i] < '0' || rt_from_call[i] > '9') { - break; - } - rtversion[i] = rt_from_call[i]; - } - PyOS_snprintf(message, sizeof(message), - "compiletime version %s of module '%.100s' " - "does not match runtime version %s", - ctversion, __Pyx_MODULE_NAME, rtversion); - return PyErr_WarnEx(NULL, message, 1); - } - return 0; -} - -/* InitStrings */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { - while (t->p) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - return -1; - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { - int retval; - if (unlikely(!x)) return -1; - retval = __Pyx_PyObject_IsTrue(x); - Py_DECREF(x); - return retval; -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(b); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { - if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { - return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); -#if PY_MAJOR_VERSION < 3 - } else if (likely(PyInt_CheckExact(o))) { - return PyInt_AS_LONG(o); -#endif - } else { - Py_ssize_t ival; - PyObject *x; - x = PyNumber_Index(o); - if (!x) return -1; - ival = PyInt_AsLong(x); - Py_DECREF(x); - return ival; - } -} -static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { - return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ From 939c50d70e9ef14b4d01cd5e489a9b9ac76913c0 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 15 Nov 2022 17:57:27 +0000 Subject: [PATCH 041/147] More writeup with final types. --- src/questdb/extra_cpython.pxd | 4 +- src/questdb/pandas_helpers.md | 370 +++++++++++++++++++++++++++++++++- 2 files changed, 369 insertions(+), 5 deletions(-) diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd index 7dde79d9..c6569db4 100644 --- a/src/questdb/extra_cpython.pxd +++ b/src/questdb/extra_cpython.pxd @@ -1,3 +1,5 @@ +# Custom definitions that aren't provided in the standard `cpython` module. + from libc.stdint cimport uint8_t, uint16_t, uint32_t cdef extern from "Python.h": @@ -38,4 +40,4 @@ cdef extern from "Python.h": Py_ssize_t PyBytes_GET_SIZE(object o) - char* PyBytes_AsString(object o) \ No newline at end of file + char* PyBytes_AsString(object o) diff --git a/src/questdb/pandas_helpers.md b/src/questdb/pandas_helpers.md index 73efa5d3..04884444 100644 --- a/src/questdb/pandas_helpers.md +++ b/src/questdb/pandas_helpers.md @@ -69,8 +69,8 @@ _Multiple of these `ArrowArray` structs per column. Chunked._ * `int64_t length`: We need it for the length of the chunk. **`[NEEDED]`** * `int64_t null_count`: Needed as if == 0, null col may be NULL. **`[NEEDED]`** * `int64_t offset`: Needed to determine number of skipped rows. **`[NEEDED]`** -* `int64_t n_buffers`: A function of the type, not needed. **`[NEEDED]`** -* `int64_t n_children`: +* `int64_t n_buffers`: A function of the type, not needed. **`[IGNORED]`** +* `int64_t n_children`: A function of the type, not needed. **`[IGNORED]`** * `const void** buffers`: Data, e.g. buffers[0] is validity bitvec. **`[NEEDED]`** * `ArrowArray** children`: Needed only for strings where: **`[NEEDED]`** * `buffers[0]` is nulls bitvec @@ -95,10 +95,372 @@ We need to extract: * UTF-8 string buffers * Nanosecond-precision UTC unix epoch 64-bit signed int timestamps +```python +import pandas as pd +import pyarrow as pa +``` + ### Booleans -**Numpy** +```python +>>> df = pd.DataFrame({ +... 'bool_col': [True, False, False, True], +... 'obj_bool_col': [True, False, None, False], +... 'nullable_bool_col': pd.array( +... [True, False, None, False], dtype="boolean")}) +``` + +#### Numpy-native representation. +```python +>>> df.dtypes['bool_col'] +dtype('bool') +>>> type(df.dtypes['bool_col']).mro() +[, , ] +>>> df.bool_col.to_numpy().dtype +dtype('bool') +``` + +#### Bools as Python objects +```python +>>> df.obj_bool_col +0 True +1 False +2 None +3 False +Name: obj_bool_col, dtype: object +``` + +It's unclear if this should be supported or not. We might want to and error out +as soon as we encounter either a `None` or a `pandas.NA` object. + +```python +>>> df.obj_bool_col.astype('bool') +0 True +1 False +2 False +3 False +Name: obj_bool_col, dtype: bool +``` + +Lastly, we have what appears to be an Arrow-backed representation. +```python +>>> df.dtypes['nullable_bool_col'] +BooleanDtype +>>> type(df.dtypes['nullable_bool_col']).mro() +[, , , ] +``` + +We can convert it and then access its contents: +``` +>>> arr1 = pa.Array.from_pandas(df.nullable_bool_col) +>>> arr1 + +[ + true, + false, + null, + false +] +>>> arr1._export_to_c(.... pointer_refs to ArrowArray and ArrowSchema) +``` + +This last type is represented as two bitmaps. +See: https://docs.rs/arrow-array/26.0.0/src/arrow_array/array/boolean_array.rs.html#107 + +We want to support this representation, but skip out on nulls. +We want to error out as soon as we see a `null`. + +### 64-bit signed integers + +From Numpy's side, we've got a fair few to deal with: +https://numpy.org/doc/stable/user/basics.types.html + +This is all your usual signed/unsigned integers with 8, 16, 32 and 64 bit width. + +The good news is that the default _is_ `int64`: + +```python +>>> df = pd.DataFrame({'n': [1, 2, 3, 4, 5]}) +>>> df.n +0 1 +1 2 +2 3 +3 4 +4 5 +Name: n, dtype: int64 + +>>> df.dtypes['n'] +dtype('int64') + +>>> type(df.dtypes['n']).mro() +[, , ] +``` + +Some of these are going to be in bounds, others out of bounds of 64-bit signed: +Validation needed. + +Pandas also provides its own (arrow-based) nullable integers. + +```python +>>> df2 = pd.DataFrame({'nullable_n': pd.array([1, 2, None], dtype=pd.Int64Dtype())}) +>>> df2.nullable_n +0 1 +1 2 +2 +Name: nullable_n, dtype: Int64 +>>> type(df2.dtypes['nullable_n']).mro() +[, , , , , ] +``` + +We also need to validate against potential byte-order issues as we're not going +to support this until someone asks: +https://pandas.pydata.org/pandas-docs/version/0.19.1/gotchas.html#byte-ordering-issues + +```python +>>> df3 = pd.DataFrame({'big_e': np.array([1, 2, 3, 4]).astype('>u4')}) +>>> df3.big_e +0 1 +1 2 +2 3 +3 4 +Name: big_e, dtype: uint32 +>>> type(df3.dtypes['big_e']).mro() +[, , ] +>>> df3.dtypes['big_e'].byteorder +'>' +``` + + +### 64-bit floats + +32-bit and 64-bit floats. They all support nullability. + +64-bit is default. + +```python +>>> df = pd.DataFrame({'a': [None, 1.0, 1.5, 2.0], 'b': pd.Series([None, 1.0, 1.5, 2.0], dtype='float32'), 'c': pd.Series([None, 1.0, 1.5, 2.0], dtype='float64')}) +>>> df + a b c +0 NaN NaN NaN +1 1.0 1.0 1.0 +2 1.5 1.5 1.5 +3 2.0 2.0 2.0 +>>> df.a +0 NaN +1 1.0 +2 1.5 +3 2.0 +Name: a, dtype: float64 +>>> df.b +0 NaN +1 1.0 +2 1.5 +3 2.0 +Name: b, dtype: float32 +>>> df.c +0 NaN +1 1.0 +2 1.5 +3 2.0 +Name: c, dtype: float64 +``` + + +### UTF-8 string buffers + +Strings are.. hard. Strings in dataframes are harder. + +#### Python Strings + +Numpy usually holds strings as Python objects. + +```python +>>> df = pd.DataFrame({'a': ['Strings', 'in', 'Pandas', 'are', 'objects', 'by', 'default']}) +>>> df.dtypes['a'] +dtype('O') +>>> type(df.dtypes['a']).mro() +[, , ] +``` + +Ouch. + +Python string objects internally hold buffers that, depending on need are +encoded as one of UCS-1, UCS-2 or UCS-4. These are variable-length arrays of +codepoints. One codepoint per array element. + +In UCS-1 that's 1-byte elements - effectively `uint8_t`, so the highest code +point is `2 ** 8 - 1 == 255`, or in other words: + +```python +>>> chr(255) +'ÿ' +``` + +If a string contains a codepoint with a numeric value higher than this, it would +need UCS-2 or UCS-4. Such representations are backed by `uint16_t` or `uint32_t` +arrays. + +For example, the codepoint for a lobster is 129438. + +```python +>>> ord('🦞') +129438 +``` + +We _could_ ask Python to convert strings to UTF-8 for us, + +```python +>>> '🦞'.encode('utf-8') +b'\xf0\x9f\xa6\x9e' +``` + +but this would require invoking the Python interpreter and the creation of a +gargantuan amount of little temporary objects. + +This is such a common use case that we do the encoding in a supporting Rust +library. See `pystr-to-utf8` in the source tree. + +It accumulates strings in a address-stable buffer (internally a `Vec`) +and allows us to borrow its memory. + +As a side-note, we should also be ready to handle nulls here: + +```python +>>> df = pd.DataFrame({'a': ['interspersed', None, 'in', None, 'data']}) +>>> type(df.a[1]) + +``` + +#### Fixed-length strings + +Numpy also has some fixed-length strings via two datatypes: +* `S`: Bytes +* `U`: Unicode + +```python +>>> df = pd.DataFrame({ +... 'a': np.array(['fixed', 'len', 'strings'], dtype='S'), +... 'b': np.array(['example', 'with', 'unicode 🦞'], dtype='U')}) +>>> df + a b +0 b'fixed' example +1 b'len' with +2 b'strings' unicode 🦞 +``` + +It doesn't really matter much though. Their Pandas datatype is actually just +`'O'` (object). + +```python +>>> df.dtypes['a'] +dtype('O') +>>> df.dtypes['b'] +dtype('O') +``` + +We should: +* reject the first one (because in Python3 bytes aren't strings) - We lack the powers to guess which text encoding was used. It's usually `latin-1`, but was it? + ```python + >>> type(df.a[0]) + + ``` +* Accept the second one without further optimisations: + ```python + >>> type(df.b[0]) + + ``` + +#### Pandas `string[object]` dtype + +Since the `'O'` dtype could hold anything (not just strings), Pandas introduced a new column type that ensures the column only holds strings. + +```python +>>> df = pd.DataFrame({'a': pd.Series(['another', None, 'str', 'example'], dtype='string')}) +>>> df + a +0 another +1 +2 str +3 example +>>> df.dtypes['a'] +string[python] +>>> type(df.dtypes['a']).mro() +[, , , ] +``` + +Note that by default the storage is still Python objects (sigh), +so our Rust-based conversion will will come handy here as well. + +Note however that we need to handle nulls not as `None` objects, +but as `pandas.NA` objects. + +```python +>>> df.a[1] + +``` + +#### Arrow-backed Strings + +Finally - as we would expect when obtaining a frame from something like Parquet - there's string columns in UTF-8-native format backed by Arrow. + +_note the different `dtype`:_ + +```python +df = pd.DataFrame({'a': pd.Series(['arrow', None, 'str', 'example'], dtype='string[pyarrow]')}) +``` + +``` +>>> df = pd.DataFrame({'a': pd.Series(['arrow', None, 'str', 'example'], dtype='string[pyarrow]')}) +>>> df + a +0 arrow +1 +2 str +3 example +>>> df.dtypes['a'] +string[pyarrow] +>>> type(df.dtypes['a']).mro() +[, , , ] +``` + +### Nanosecond-precision UTC unix epoch 64-bit signed int timestamps + +This one's easy: + +```python +>>> n1 = pd.Timestamp(dt.datetime.utcnow()) +>>> n2 = pd.Timestamp(dt.datetime.utcnow()) +>>> df = pd.DataFrame({'a': [n1, n2]}) +>>> df + a +0 2022-11-15 17:47:23.131445 +1 2022-11-15 17:47:26.943899 +``` + +The data is held as nanos since unix epoch as a 64-bit int. +```python +>>> df.dtypes['a'] +dtype('>> type(df.dtypes['a']).mro() +[, , ] +``` + +This matches our own designated timestamp representation and we just need to convert to micros for the rest of the columns. + +Null values _are_ supported. + +```python +>>> df = pd.DataFrame({'a': [n1, n2, None]}) +>>> df + a +0 2022-11-15 17:47:23.131445 +1 2022-11-15 17:47:26.943899 +2 NaT +``` +Unclear what the sentinel value for `NaT` is yet, but we want to map it internally to 0 for the designated timestamp and to recognise it +and skip the column otherwise. +## Unified Cursor -TO BE CONTINUED .... \ No newline at end of file +TO BE CONTINUED From 2355b3d920f3370ca65af73c68bfecb53e342373 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 15 Nov 2022 21:36:25 +0000 Subject: [PATCH 042/147] Categories added to write-up. --- src/questdb/pandas_helpers.md | 63 ++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/src/questdb/pandas_helpers.md b/src/questdb/pandas_helpers.md index 04884444..ab87903f 100644 --- a/src/questdb/pandas_helpers.md +++ b/src/questdb/pandas_helpers.md @@ -77,10 +77,9 @@ _Multiple of these `ArrowArray` structs per column. Chunked._ * `buffers[1]` is int32 offsets buffer * `children[0]` is ArrowArray of int8 * See: https://arrow.apache.org/docs/format/Columnar.html#variable-size-list-layout -* `ArrowArray* dictionary`: Needed to support Pandas categories. **`[INITIALLY OUT OF SCOPE]`** - * Given the complexity of supporting this feature - (and it being less common in use) we instead validate that it's not set. - See: https://pandas.pydata.org/docs/reference/api/pandas.CategoricalDtype.html +* `ArrowArray* dictionary`: Needed to support Pandas categories. + * This ends up being an array of strings, whilst the index is kept in the + parent `buffers[1]` with `buffers[0]` (possibly) as the validity bitmap. ## Mapping Datatypes @@ -423,6 +422,62 @@ string[pyarrow] [, , , ] ``` +#### Symbol-like Categorical Data + +Pandas supports categories. These are backed by Arrow. + +```python +>>> df = pd.DataFrame({'a': pd.Series( +... ['symbol', 'like', 'type', 'symbol', 'like', 'like', 'like', None], +... dtype='category')}) +>>> df + a +0 symbol +1 like +2 type +3 symbol +4 like +5 like +6 like +7 NaN +>>> df.dtypes['a'] +CategoricalDtype(categories=['like', 'symbol', 'type'], ordered=False) +>>> type(df.dtypes['a']).mro() +[, , , ] +``` + +This is how it's represented: + +```python +>>> pa.Array.from_pandas(df.a) + + +-- dictionary: + [ + "like", + "symbol", + "type" + ] +-- indices: + [ + 1, + 0, + 2, + 1, + 0, + 0, + 0, + null + ] +``` + +For this, we need the `dictionary` field in the `ArrowArray` struct. + +What's also neat is that we know the categories in advance _before_ running the +encoding. This means we can build up our `line_sender_utf8` objects in advance, +though they are all UTF-8 buffers already so.. little gain. + + ### Nanosecond-precision UTC unix epoch 64-bit signed int timestamps This one's easy: From 1c14cb73901b3de2dc0c8e4fe680703eabadf6cf Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 15 Nov 2022 21:58:48 +0000 Subject: [PATCH 043/147] Consolidated Pandas logic into single .pxi file. --- src/questdb/ingress.pyx | 124 +--------------------------- src/questdb/pandas_helpers.pxi | 143 +++++++++++++++++++++++++++++++-- 2 files changed, 139 insertions(+), 128 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 45662f18..c7415001 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -360,16 +360,6 @@ cdef class TimestampNanos: return self._value -cdef _check_is_pandas_dataframe(data): - exp_mod = 'pandas.core.frame' - exp_name = 'DataFrame' - t = type(data) - if (t.__module__ != exp_mod) or (t.__qualname__ != exp_name): - raise TypeError( - f'Bad argument `data`: Expected {exp_mod}.{exp_name}, ' + - f'not {t.__module__}.{t.__qualname__}.') - - cdef class Sender cdef class Buffer @@ -975,118 +965,6 @@ cdef class Buffer: # """ # raise ValueError('nyi') - cdef bint _pandas( - self, - object data, - object table_name, - object table_name_col, - object symbols, - object at, - bint sort) except False: - # First, we need to make sure that `data` is a dataframe. - # We specifically avoid using `isinstance` here because we don't want - # to add a library dependency on pandas itself. We simply rely on its API. - # The only reason to validate here is to avoid obscure "AttributeError" - # exceptions later. - cdef size_t col_count - cdef ssize_t name_col - cdef line_sender_table_name c_table_name - cdef size_t_vec symbol_indices = size_t_vec_new() - cdef size_t_vec field_indices = size_t_vec_new() - cdef ssize_t at_col - cdef int64_t at_value = 0 - cdef column_name_vec symbol_names = column_name_vec_new() - cdef column_name_vec field_names = column_name_vec_new() - cdef dtype_t* dtypes = NULL - cdef size_t set_buf_count = 0 - cdef Py_buffer* col_buffers = NULL - cdef size_t col_index - cdef qdb_pystr_pos str_buf_marker - cdef size_t row_count - cdef Py_buffer* cur_col - _pandas_may_set_na_type() - try: - _check_is_pandas_dataframe(data) - col_count = len(data.columns) - qdb_pystr_buf_clear(self._b) - name_col = _pandas_resolve_table_name( - self._b, - data, table_name, table_name_col, col_count, &c_table_name) - at_col = _pandas_resolve_at(data, at, col_count, &at_value) - _pandas_resolve_symbols( - data, name_col, at_col, symbols, col_count, &symbol_indices) - _pandas_resolve_fields( - name_col, &symbol_indices, at_col, col_count, &field_indices) - _pandas_resolve_col_names( - self._b, - data, &symbol_indices, &field_indices, - &symbol_names, &field_names) - dtypes = calloc(col_count, sizeof(dtype_t)) - _pandas_resolve_dtypes(data, col_count, dtypes) - col_buffers = calloc(col_count, sizeof(Py_buffer)) - _pandas_resolve_col_buffers( - data, col_count, dtypes, col_buffers, &set_buf_count) - - # We've used the str buffer up to a point for the headers. - # Instead of clearing it (which would clear the headers' memory) - # we will truncate (rewind) back to this position. - str_buf_marker = qdb_pystr_buf_tell(self._b) - - import sys - sys.stderr.write('_pandas :: (A) ' + - f'name_col: {name_col}, ' + - f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - f'at_col: {at_col}, ' + - f'at_value: {at_value}, ' + - f'field_indices: {size_t_vec_str(&field_indices)}' + - '\n') - row_count = len(data) - self._clear_marker() - for row_index in range(row_count): - qdb_pystr_buf_truncate(self._b, str_buf_marker) - try: - self._set_marker() - _pandas_row_table_name( - self._impl, - self._b, - dtypes, - col_buffers, - name_col, - row_index, - c_table_name) - _pandas_row_symbols( - self._impl, - self._b, - dtypes, - col_buffers, - row_index, - &symbol_names, - &symbol_indices) - # _pandas_row_fields(...) # TODO [amunra]: implement - _pandas_row_at( - self._impl, - dtypes, - col_buffers, - row_index, - at_col, - at_value) - except: - self._rewind_to_marker() - raise - return True - finally: - self._clear_marker() - if col_buffers != NULL: - for col_index in range(set_buf_count): - PyBuffer_Release(&col_buffers[col_index]) - free(col_buffers) - free(dtypes) - column_name_vec_free(&field_names) - column_name_vec_free(&symbol_names) - size_t_vec_free(&field_indices) - size_t_vec_free(&symbol_indices) - qdb_pystr_buf_clear(self._b) - def pandas( self, data, # : pd.DataFrame @@ -1109,7 +987,7 @@ cdef class Buffer: f'at: {at}, ' + f'sort: {sort}' + '\n') - self._pandas(data, table_name, table_name_col, symbols, at, sort) + _pandas(self._impl, self._b, data, table_name, table_name_col, symbols, at, sort) sys.stderr.write('pandas :: (B) ' + f'table_name: {table_name}, ' + f'table_name_col: {table_name_col}, ' + diff --git a/src/questdb/pandas_helpers.pxi b/src/questdb/pandas_helpers.pxi index 65b84f3a..38aa04f1 100644 --- a/src/questdb/pandas_helpers.pxi +++ b/src/questdb/pandas_helpers.pxi @@ -73,14 +73,30 @@ cdef struct col_handle_t: col_line_sender_target_t target +cdef object _PANDAS = None +cdef object _PYARROW = None cdef object _PANDAS_NA = None -cdef object _pandas_may_set_na_type(): - global _PANDAS_NA - if _PANDAS_NA is None: - import pandas as pd - _PANDAS_NA = pd.NA +cdef object _pandas_may_import_deps(): + global _PANDAS, _PYARROW, _PANDAS_NA + if _PANDAS_NA is not None: + return + import pandas + _PANDAS = pandas + _PANDAS_NA = pandas.NA + try: + import pyarrow as pa + _PYARROW = pa + except ImportError: + _PYARROW = None + + +cdef object _check_is_pandas_dataframe(object data): + if not isinstance(data, _PANDAS.DataFrame): + raise TypeError( + f'Bad argument `data`: Expected {_PANDAS.DataFrame}, ' + + f'not an object of type {type(data)}.') cdef ssize_t _pandas_resolve_table_name( @@ -565,3 +581,120 @@ cdef bint _pandas_row_at( if not line_sender_buffer_at_now(impl, &err): raise c_err_to_py(err) return True + + +cdef bint _pandas( + line_sender_buffer* impl, + qdb_pystr_buf* b, + object data, + object table_name, + object table_name_col, + object symbols, + object at, + bint sort) except False: + # First, we need to make sure that `data` is a dataframe. + # We specifically avoid using `isinstance` here because we don't want + # to add a library dependency on pandas itself. We simply rely on its API. + # The only reason to validate here is to avoid obscure "AttributeError" + # exceptions later. + cdef size_t col_count + cdef ssize_t name_col + cdef line_sender_table_name c_table_name + cdef size_t_vec symbol_indices = size_t_vec_new() + cdef size_t_vec field_indices = size_t_vec_new() + cdef ssize_t at_col + cdef int64_t at_value = 0 + cdef column_name_vec symbol_names = column_name_vec_new() + cdef column_name_vec field_names = column_name_vec_new() + cdef dtype_t* dtypes = NULL + cdef size_t set_buf_count = 0 + cdef Py_buffer* col_buffers = NULL + cdef size_t col_index + cdef qdb_pystr_pos str_buf_marker + cdef line_sender_error* err = NULL + cdef size_t row_count + cdef Py_buffer* cur_col + _pandas_may_import_deps() + try: + _check_is_pandas_dataframe(data) + col_count = len(data.columns) + qdb_pystr_buf_clear(b) + name_col = _pandas_resolve_table_name( + b, + data, table_name, table_name_col, col_count, &c_table_name) + at_col = _pandas_resolve_at(data, at, col_count, &at_value) + _pandas_resolve_symbols( + data, name_col, at_col, symbols, col_count, &symbol_indices) + _pandas_resolve_fields( + name_col, &symbol_indices, at_col, col_count, &field_indices) + _pandas_resolve_col_names( + b, + data, &symbol_indices, &field_indices, + &symbol_names, &field_names) + dtypes = calloc(col_count, sizeof(dtype_t)) + _pandas_resolve_dtypes(data, col_count, dtypes) + col_buffers = calloc(col_count, sizeof(Py_buffer)) + _pandas_resolve_col_buffers( + data, col_count, dtypes, col_buffers, &set_buf_count) + + # We've used the str buffer up to a point for the headers. + # Instead of clearing it (which would clear the headers' memory) + # we will truncate (rewind) back to this position. + str_buf_marker = qdb_pystr_buf_tell(b) + + import sys + sys.stderr.write('_pandas :: (A) ' + + f'name_col: {name_col}, ' + + f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + f'at_col: {at_col}, ' + + f'at_value: {at_value}, ' + + f'field_indices: {size_t_vec_str(&field_indices)}' + + '\n') + row_count = len(data) + line_sender_buffer_clear_marker(impl) + for row_index in range(row_count): + qdb_pystr_buf_truncate(b, str_buf_marker) + try: + if not line_sender_buffer_set_marker(impl, &err): + raise c_err_to_py(err) + _pandas_row_table_name( + impl, + b, + dtypes, + col_buffers, + name_col, + row_index, + c_table_name) + _pandas_row_symbols( + impl, + b, + dtypes, + col_buffers, + row_index, + &symbol_names, + &symbol_indices) + # _pandas_row_fields(...) # TODO [amunra]: implement + _pandas_row_at( + impl, + dtypes, + col_buffers, + row_index, + at_col, + at_value) + except: + if not line_sender_buffer_rewind_to_marker(impl, &err): + raise c_err_to_py(err) + raise + return True + finally: + line_sender_buffer_clear_marker(impl) + if col_buffers != NULL: + for col_index in range(set_buf_count): + PyBuffer_Release(&col_buffers[col_index]) + free(col_buffers) + free(dtypes) + column_name_vec_free(&field_names) + column_name_vec_free(&symbol_names) + size_t_vec_free(&field_indices) + size_t_vec_free(&symbol_indices) + qdb_pystr_buf_clear(b) From 4f7ef81f8b8e146729c665118c24b0d74d129fee Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 15 Nov 2022 22:01:16 +0000 Subject: [PATCH 044/147] File renaming. --- src/questdb/ingress.pyx | 2 +- src/questdb/{pandas_helpers.md => pandas_integration.md} | 0 src/questdb/{pandas_helpers.pxi => pandas_integration.pxi} | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/questdb/{pandas_helpers.md => pandas_integration.md} (100%) rename src/questdb/{pandas_helpers.pxi => pandas_integration.pxi} (99%) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index c7415001..d434633b 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -49,7 +49,7 @@ from .pystr_to_utf8 cimport * from .arrow_c_data_interface cimport * from .extra_cpython cimport * -include "pandas_helpers.pxi" +include "pandas_integration.pxi" import cython diff --git a/src/questdb/pandas_helpers.md b/src/questdb/pandas_integration.md similarity index 100% rename from src/questdb/pandas_helpers.md rename to src/questdb/pandas_integration.md diff --git a/src/questdb/pandas_helpers.pxi b/src/questdb/pandas_integration.pxi similarity index 99% rename from src/questdb/pandas_helpers.pxi rename to src/questdb/pandas_integration.pxi index 38aa04f1..1608c769 100644 --- a/src/questdb/pandas_helpers.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1,7 +1,7 @@ include "size_t_vec.pxi" include "column_name_vec.pxi" -# See: pandas_helpers.md for technical overview. +# See: pandas_integration.md for technical overview. cdef struct dtype_t: # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html From de4b4717b91fa970d80f769aa95bfc3fee83269e Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 16 Nov 2022 16:28:45 +0000 Subject: [PATCH 045/147] Reorganised existing logic into a sorted array of col_t types. Some progress with the cursor type. --- src/questdb/ingress.pyx | 2 +- src/questdb/pandas_integration.pxi | 367 ++++++++++++++++++----------- 2 files changed, 224 insertions(+), 145 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index d434633b..c6264c62 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -49,10 +49,10 @@ from .pystr_to_utf8 cimport * from .arrow_c_data_interface cimport * from .extra_cpython cimport * +import cython include "pandas_integration.pxi" -import cython from enum import Enum from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable import pathlib diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 1608c769..ae51084d 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -21,9 +21,8 @@ cdef struct col_numpy_data_t: cdef struct col_arrow_data_t: - ArrowSchema schema + ArrowSchema schema # Schema of first chunk. size_t n_chunks - ArrowArray chunks cdef enum col_access_tag_t: @@ -36,23 +35,15 @@ cdef union col_access_t: col_arrow_data_t arrow -cdef struct col_cursor_t: - size_t chunk_index +cdef struct col_chunks_t: size_t n_chunks - size_t offset # i.e. the element index (not byte offset) - size_t length # number of elements in current chunk - - # Expanded pointers to Numpy or Arrow buffers - - # https://arrow.apache.org/docs/format/Columnar.html#validity-bitmaps - # Always NULL for Numpy, optionally null for Arrow. - uint8_t* validity + ArrowArray* chunks # We calloc `n_chunks + 1` of these. - # Must cast to correct datatype - void* data - # NULL for Numpy, may be set for Arrow strings. - uint8_t* utf8_buf +cdef struct col_cursor_t: + ArrowArray* chunk # Current chunk. + size_t chunk_index + size_t offset # i.e. the element index (not byte offset) cdef enum col_line_sender_target_t: @@ -66,16 +57,55 @@ cdef enum col_line_sender_target_t: at -cdef struct col_handle_t: +cdef struct col_t: + line_sender_utf8 col_name col_access_tag_t access_tag col_access_t access + col_chunks_t chunks col_cursor_t cursor col_line_sender_target_t target -cdef object _PANDAS = None -cdef object _PYARROW = None -cdef object _PANDAS_NA = None +cdef void col_t_release(col_t* col): + # TODO: Implement cleanup, PyBuffer_Release, etc. + pass + + +cdef struct col_t_arr: + size_t capacity + size_t size # Number of elements we've populated. Needed for cleanup. + col_t* d + + +cdef col_t_arr col_t_arr_blank(): + cdef col_t_arr arr + arr.capacity = 0 + arr.size = 0 + arr.d = NULL + return arr + + +cdef col_t_arr col_t_arr_new(size_t capacity): + cdef col_t_arr arr + arr.capacity = capacity + arr.size = 0 + arr.d = calloc(capacity, sizeof(col_t)) + return arr + + +cdef void col_t_arr_release(col_t_arr* arr): + if arr.d: + for i in range(arr.size): + col_t_release(&arr.d[i]) + free(arr.d) + arr.size = 0 + arr.capacity = 0 + arr.d = NULL + + +cdef object _PANDAS = None # module object +cdef object _PANDAS_NA = None # pandas.NA +cdef object _PYARROW = None # module object, if available or None cdef object _pandas_may_import_deps(): @@ -102,6 +132,7 @@ cdef object _check_is_pandas_dataframe(object data): cdef ssize_t _pandas_resolve_table_name( qdb_pystr_buf* b, object data, + list tagged_cols, object table_name, object table_name_col, size_t col_count, @@ -148,45 +179,15 @@ cdef ssize_t _pandas_resolve_table_name( col_index, 'Bad argument `table_name_col`: ', table_name_col) + tagged_cols[col_index][3] = -2 # Sort column to front as table name. + name_out.len = 0 + name_out.buf = NULL return col_index else: raise ValueError( 'Must specify at least one of `table_name` or `table_name_col`.') -cdef int _pandas_resolve_fields( - int name_col, - const size_t_vec* symbol_indices, - int at_col, - size_t col_count, - size_t_vec* field_indices_out) except -1: - """ - Populate vec of field column indices via `field_indices_out`. - Returns the length of the list. - The vec will contain all columns which are not the table name column, - symbols or the at timestamp column. - """ - # We rely on `symbol_indices` being sorted. - cdef size_t col_index = 0 - cdef size_t sym_index = 0 - cdef size_t sym_len = symbol_indices.size - while col_index < col_count: - if (name_col >= 0) and (col_index == name_col): - col_index += 1 - continue - if (at_col >= 0) and (col_index == at_col): - col_index += 1 - continue - while sym_index < sym_len and symbol_indices.d[sym_index] < col_index: - sym_index += 1 - if sym_index < sym_len and symbol_indices.d[sym_index] == col_index: - col_index += 1 - continue - size_t_vec_push(field_indices_out, col_index) - col_index += 1 - return 0 - - cdef bint _pandas_resolve_col_names( qdb_pystr_buf* b, object data, @@ -269,17 +270,35 @@ cdef object _pandas_check_column_is_str( f'{col_name!r} column: Must be a strings column.') -cdef int _pandas_resolve_symbols( +@cython.internal +cdef class TaggedEntry: + """Python object representing a column whilst parsing .pandas arguments.""" + + cdef size_t index + cdef str name + cdef object series + cdef int sort_key + + def __init__(self, size_t index, str name, object series, int sort_key): + self.index = index + self.name = name + self.series = series + self.sort_key = sort_key + + +cdef int _SORT_AS_FIELD = 0 +cdef int _SORT_AS_TABLE_NAME = -2 +cdef int _SORT_AS_SYMBOL = -1 +cdef int _SORT_AS_AT = 1 + + +cdef bint _pandas_resolve_symbols( object data, + list tagged_cols, ssize_t table_name_col, ssize_t at_col, object symbols, - size_t col_count, - size_t_vec* symbol_indices_out) except -1: - """ - Populate vec of symbol column indices via `symbol_indices_out`. - Returns the length of the vec. - """ + size_t col_count) except False: cdef size_t col_index = 0 cdef object symbol if symbols is False: @@ -287,8 +306,8 @@ cdef int _pandas_resolve_symbols( elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): - size_t_vec_push(symbol_indices_out, col_index) - return 0 + tagged_cols[col_index].sort_key = -1 # Sort col as as symbol. + return True else: if not isinstance(symbols, (tuple, list)): raise TypeError( @@ -316,8 +335,8 @@ cdef int _pandas_resolve_symbols( col_index, 'Bad element in argument `symbols`: ', symbol) - size_t_vec_push(symbol_indices_out, col_index) - return 0 + tagged_cols[col_index].sort_key = -1 # Sort col as as symbol. + return True cdef bint _pandas_get_loc( @@ -335,8 +354,14 @@ cdef bint _pandas_get_loc( f'Column {col_name!r} not found in the dataframe.') +# The -1 value is safe to use as a sentinel because the TimestampNanos type +# already validates that the value is >= 0. +cdef int64_t _AT_SET_BY_COLUMN = -1 + + cdef ssize_t _pandas_resolve_at( object data, + list tagged_cols, object at, size_t col_count, int64_t* at_value_out) except -2: @@ -362,7 +387,8 @@ cdef ssize_t _pandas_resolve_at( 'int (column index), str (colum name)') dtype = data.dtypes[col_index] if _pandas_is_supported_datetime(dtype): - at_value_out[0] = 0 + at_value_out[0] = _AT_SET_BY_COLUMN + tagged_cols[col_index].sort_key = 1 # Ordering key for "at" column. return col_index else: raise TypeError( @@ -380,9 +406,6 @@ cdef object _pandas_is_supported_datetime(object dtype): (not dtype.hasobject)) - - - cdef char _str_to_char(str field, str s) except 0: cdef int res if len(s) != 1: @@ -583,6 +606,91 @@ cdef bint _pandas_row_at( return True +cdef bint _pandas_resolve_args( + object data, + object table_name, + object table_name_col, + object symbols, + object at, + qdb_pystr_buf* b, + size_t col_count, + line_sender_table_name* c_table_name_out, + int64_t* at_value_out, + col_t_arr* cols_out) except False: + cdef ssize_t name_col + cdef ssize_t at_col + + # List of Lists with col index, col name, series object, sorting key. + cdef list tagged_cols = [ + TaggedEntry( + index, + name, + series, + _SORT_AS_FIELD) + for index, (name, series) in data.items()] + name_col = _pandas_resolve_table_name( + b, + data, tagged_cols, table_name, table_name_col, col_count, c_table_name_out) + at_col = _pandas_resolve_at(data, tagged_cols, at, col_count, at_value_out) + _pandas_resolve_symbols( + data, tagged_cols, name_col, at_col, symbols, col_count) + + # Sort with table name is first, then the symbols, then fields, then at. + # Note: Python 3.6+ guarantees stable sort. + tagged_cols.sort(key=lambda x: x.sort_key) + + return True + + + # _pandas_resolve_col_names( + # b, + # data, &symbol_indices, &field_indices, + # &symbol_names, &field_names) + # cdef dtype_t* dtypes = NULL + # cdef size_t set_buf_count = 0 + # cdef Py_buffer* col_buffers = NULL + # dtypes = calloc(col_count, sizeof(dtype_t)) + # _pandas_resolve_dtypes(data, col_count, dtypes) + # col_buffers = calloc(col_count, sizeof(Py_buffer)) + # _pandas_resolve_col_buffers( + # data, col_count, dtypes, col_buffers, &set_buf_count) + + +cdef bint _pandas_serialize_cell( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + pass + + +cdef void _pandas_col_advance(col_t* col): + # Branchless version of: + # cdef bint new_chunk = cursor.offset == cursor.chunk.length + # if new_chunk == 0: + # cursor.chunk_index += 1 + # cursor.chunk += 1 # pointer advance + # + # if new_chunk: + # cursor.offset = cursor.chunk.offset + # else: + # cursor.offset += 1 + # + # + # (Checked with Godbolt, GCC -O3 code was rather "jumpy") + cdef col_cursor_t* cursor = &col.cursor + cdef size_t new_chunk # disguised bint. Either 0 or 1. + cursor.offset += 1 + new_chunk = cursor.offset == cursor.chunk.length + cursor.chunk_index += new_chunk + cursor.chunk += new_chunk + # Note: We get away with this because we've allocated one extra blank chunk. + # This ensures that `cursor.chunk.offset` is always valid. + cursor.offset = ( + (new_chunk * cursor.chunk.offset) + + ((not new_chunk) * cursor.offset)) + + cdef bint _pandas( line_sender_buffer* impl, qdb_pystr_buf* b, @@ -592,64 +700,47 @@ cdef bint _pandas( object symbols, object at, bint sort) except False: - # First, we need to make sure that `data` is a dataframe. - # We specifically avoid using `isinstance` here because we don't want - # to add a library dependency on pandas itself. We simply rely on its API. - # The only reason to validate here is to avoid obscure "AttributeError" - # exceptions later. cdef size_t col_count - cdef ssize_t name_col cdef line_sender_table_name c_table_name - cdef size_t_vec symbol_indices = size_t_vec_new() - cdef size_t_vec field_indices = size_t_vec_new() - cdef ssize_t at_col - cdef int64_t at_value = 0 - cdef column_name_vec symbol_names = column_name_vec_new() - cdef column_name_vec field_names = column_name_vec_new() - cdef dtype_t* dtypes = NULL - cdef size_t set_buf_count = 0 - cdef Py_buffer* col_buffers = NULL - cdef size_t col_index + cdef int64_t at_value = _AT_SET_BY_COLUMN + cdef col_t_arr cols = col_t_arr_blank() cdef qdb_pystr_pos str_buf_marker - cdef line_sender_error* err = NULL cdef size_t row_count - cdef Py_buffer* cur_col + cdef line_sender_error* err = NULL + cdef size_t col_index + cdef col_t* col + _pandas_may_import_deps() try: + qdb_pystr_buf_clear(b) _check_is_pandas_dataframe(data) col_count = len(data.columns) - qdb_pystr_buf_clear(b) - name_col = _pandas_resolve_table_name( - b, - data, table_name, table_name_col, col_count, &c_table_name) - at_col = _pandas_resolve_at(data, at, col_count, &at_value) - _pandas_resolve_symbols( - data, name_col, at_col, symbols, col_count, &symbol_indices) - _pandas_resolve_fields( - name_col, &symbol_indices, at_col, col_count, &field_indices) - _pandas_resolve_col_names( + cols = col_t_arr_new(col_count) + _pandas_resolve_args( + data, + table_name, + table_name_col, + symbols, + at, b, - data, &symbol_indices, &field_indices, - &symbol_names, &field_names) - dtypes = calloc(col_count, sizeof(dtype_t)) - _pandas_resolve_dtypes(data, col_count, dtypes) - col_buffers = calloc(col_count, sizeof(Py_buffer)) - _pandas_resolve_col_buffers( - data, col_count, dtypes, col_buffers, &set_buf_count) + col_count, + &c_table_name, + &at_value, + &cols) # We've used the str buffer up to a point for the headers. # Instead of clearing it (which would clear the headers' memory) # we will truncate (rewind) back to this position. str_buf_marker = qdb_pystr_buf_tell(b) - import sys - sys.stderr.write('_pandas :: (A) ' + - f'name_col: {name_col}, ' + - f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - f'at_col: {at_col}, ' + - f'at_value: {at_value}, ' + - f'field_indices: {size_t_vec_str(&field_indices)}' + - '\n') + # import sys + # sys.stderr.write('_pandas :: (A) ' + + # f'name_col: {name_col}, ' + + # f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + + # f'at_col: {at_col}, ' + + # f'at_value: {at_value}, ' + + # f'field_indices: {size_t_vec_str(&field_indices)}' + + # '\n') row_count = len(data) line_sender_buffer_clear_marker(impl) for row_index in range(row_count): @@ -657,30 +748,26 @@ cdef bint _pandas( try: if not line_sender_buffer_set_marker(impl, &err): raise c_err_to_py(err) - _pandas_row_table_name( - impl, - b, - dtypes, - col_buffers, - name_col, - row_index, - c_table_name) - _pandas_row_symbols( - impl, - b, - dtypes, - col_buffers, - row_index, - &symbol_names, - &symbol_indices) - # _pandas_row_fields(...) # TODO [amunra]: implement - _pandas_row_at( - impl, - dtypes, - col_buffers, - row_index, - at_col, - at_value) + + # Fixed table-name. + if c_table_name.buf != NULL: + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + + # Serialize columns cells. + # Note: Columns are sorted: table name, symbols, fields, at. + for col_index in range(col_count): + col = &cols.d[col_index] + _pandas_serialize_cell(impl, b, col, row_index) + _pandas_col_advance(col) + + # Fixed "at" value (not from a column). + if at_value == 0: + if not line_sender_buffer_at_now(impl, &err): + raise c_err_to_py(err) + elif at_value > 0: + if not line_sender_buffer_at(impl, at_value, &err): + raise c_err_to_py(err) except: if not line_sender_buffer_rewind_to_marker(impl, &err): raise c_err_to_py(err) @@ -688,13 +775,5 @@ cdef bint _pandas( return True finally: line_sender_buffer_clear_marker(impl) - if col_buffers != NULL: - for col_index in range(set_buf_count): - PyBuffer_Release(&col_buffers[col_index]) - free(col_buffers) - free(dtypes) - column_name_vec_free(&field_names) - column_name_vec_free(&symbol_names) - size_t_vec_free(&field_indices) - size_t_vec_free(&symbol_indices) + col_t_arr_release(&cols) qdb_pystr_buf_clear(b) From ef2424dc649947f0c39e010e174e34eb076280fe Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 16 Nov 2022 18:11:19 +0000 Subject: [PATCH 046/147] Documented float16, added col_source_t. --- src/questdb/pandas_integration.md | 26 +++++++++++++++++++-- src/questdb/pandas_integration.pxi | 37 +++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/questdb/pandas_integration.md b/src/questdb/pandas_integration.md index ab87903f..aea27f97 100644 --- a/src/questdb/pandas_integration.md +++ b/src/questdb/pandas_integration.md @@ -232,7 +232,8 @@ Name: big_e, dtype: uint32 ### 64-bit floats -32-bit and 64-bit floats. They all support nullability. +32-bit and 64-bit floats. They all support nullability. We will disallow 16-bit +floats. 64-bit is default. @@ -264,6 +265,21 @@ Name: b, dtype: float32 Name: c, dtype: float64 ``` +16-bit floats _are_ allowed, but we will disallow them: + +```python +>>> df = pd.DataFrame({'a': pd.Series([1.0, 1.5, 2.0], dtype='float16')}) +>>> df + a +0 1.0 +1 1.5 +2 2.0 +>>> df.a +0 1.0 +1 1.5 +2 2.0 +Name: a, dtype: float16 +``` ### UTF-8 string buffers @@ -274,7 +290,8 @@ Strings are.. hard. Strings in dataframes are harder. Numpy usually holds strings as Python objects. ```python ->>> df = pd.DataFrame({'a': ['Strings', 'in', 'Pandas', 'are', 'objects', 'by', 'default']}) +>>> df = pd.DataFrame({'a': [ +... 'Strings', 'in', 'Pandas', 'are', 'objects', 'by', 'default']}) >>> df.dtypes['a'] dtype('O') >>> type(df.dtypes['a']).mro() @@ -355,6 +372,8 @@ It doesn't really matter much though. Their Pandas datatype is actually just dtype('O') >>> df.dtypes['b'] dtype('O') +>>> type(df.dtypes['b']) + ``` We should: @@ -398,6 +417,9 @@ but as `pandas.NA` objects. ``` +At other times, we end up with `nan` python float objects to represent nulls. +_Yay!_. + #### Arrow-backed Strings Finally - as we would expect when obtaining a frame from something like Parquet - there's string columns in UTF-8-native format backed by Arrow. diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index ae51084d..feeca46d 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -47,14 +47,35 @@ cdef struct col_cursor_t: cdef enum col_line_sender_target_t: - table - symbol - column_bool - column_i64 - column_f64 - column_str - column_ts - at + table = 1 + symbol = 2 + column_bool = 3 + column_i64 = 4 + column_f64 = 5 + column_str = 6 + column_ts = 7 + at = 8 + + +cdef enum col_source_t: + bool_pyobj = 11000 + bool_numpy = 12000 + bool_arrow = 13000 + int_pyobj = 21000 + u8_num = 22000 + i8_num = 23000 + u16_num = 24000 + i16_num = 25000 + u32_num = 26000 + i32_num = 27000 + u64_num = 28000 + i64_num = 29000 + f32_num = 31000 + f64_num = 32000 + str_pyobj = 41000 + str_arrow = 42000 + str_categ = 43000 + dt64 = 51000 cdef struct col_t: From 993dd5ff7bcf0a498d1d6e5af58120d33e37c965 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 17 Nov 2022 12:14:14 +0000 Subject: [PATCH 047/147] Beginning to resolve columns. --- src/questdb/pandas_integration.md | 5 + src/questdb/pandas_integration.pxi | 199 ++++++++++++++++++++--------- 2 files changed, 145 insertions(+), 59 deletions(-) diff --git a/src/questdb/pandas_integration.md b/src/questdb/pandas_integration.md index aea27f97..792f4bad 100644 --- a/src/questdb/pandas_integration.md +++ b/src/questdb/pandas_integration.md @@ -444,6 +444,11 @@ string[pyarrow] [, , , ] ``` +Note that these strings will always have indicies based on `int32_t`. + +Arrow also has a `pyarrow.large_string()` type, but +pandas doesn't support it. + #### Symbol-like Categorical Data Pandas supports categories. These are backed by Arrow. diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index feeca46d..ad6f67e3 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -46,7 +46,7 @@ cdef struct col_cursor_t: size_t offset # i.e. the element index (not byte offset) -cdef enum col_line_sender_target_t: +cdef enum col_target_t: table = 1 symbol = 2 column_bool = 3 @@ -58,33 +58,97 @@ cdef enum col_line_sender_target_t: cdef enum col_source_t: - bool_pyobj = 11000 - bool_numpy = 12000 - bool_arrow = 13000 - int_pyobj = 21000 - u8_num = 22000 - i8_num = 23000 - u16_num = 24000 - i16_num = 25000 - u32_num = 26000 - i32_num = 27000 - u64_num = 28000 - i64_num = 29000 - f32_num = 31000 - f64_num = 32000 - str_pyobj = 41000 - str_arrow = 42000 - str_categ = 43000 - dt64 = 51000 + bool_pyobj = 11000 + bool_numpy = 12000 + bool_arrow = 13000 + int_pyobj = 21000 + u8_num = 22000 + i8_num = 23000 + u16_num = 24000 + i16_num = 25000 + u32_num = 26000 + i32_num = 27000 + u64_num = 28000 + i64_num = 29000 + f32_num = 31000 + f64_num = 32000 + str_pyobj = 41000 + str_arrow = 42000 + str_i8_cat = 43000 + str_i16_cat = 44000 + str_i32_cat = 45000 + str_i64_cat = 46000 + dt64_numpy = 51000 + + +cdef dict _TARGET_TO_SOURCE = { + col_target_t.table: { + col_source_t.str_pyobj, + col_source_t.str_arrow, + }, + col_target_t.symbol: { + col_source_t.str_pyobj, + col_source_t.str_arrow, + }, + col_target_t.column_bool: { + col_source_t.bool_pyobj, + col_source_t.bool_numpy, + col_source_t.bool_arrow, + }, + col_target_t.column_i64: { + col_source_t.int_pyobj, + col_source_t.u8_num, + col_source_t.i8_num, + col_source_t.u16_num, + col_source_t.i16_num, + col_source_t.u32_num, + col_source_t.i32_num, + col_source_t.u64_num, + col_source_t.i64_num, + }, + col_target_t.column_f64: { + col_source_t.f32_num, + col_source_t.f64_num, + }, + col_target_t.column_str: { + col_source_t.str_pyobj, + col_source_t.str_arrow, + }, + col_target_t.column_ts: { + col_source_t.dt64_numpy, + }, + col_target_t.at: { + col_source_t.dt64_numpy + }, +} + + +cdef dict _invert_dict(dict d): + cdef dict res = {} + cdef object key + cdef set value_set + cdef object value + for key, value_set in d.items(): + for value in value_set: + if value not in res: + res[value] = set() + res[value].add(key) + return res + + +cdef dict _SOURCE_TO_TARGET = _invert_dict(_TARGET_TO_SOURCE) cdef struct col_t: - line_sender_utf8 col_name + size_t orig_index + line_sender_column_name name col_access_tag_t access_tag col_access_t access col_chunks_t chunks col_cursor_t cursor - col_line_sender_target_t target + col_source_t source + col_target_t target + int dispatch_code # source + target. Determines cell encoder function. cdef void col_t_release(col_t* col): @@ -209,26 +273,6 @@ cdef ssize_t _pandas_resolve_table_name( 'Must specify at least one of `table_name` or `table_name_col`.') -cdef bint _pandas_resolve_col_names( - qdb_pystr_buf* b, - object data, - const size_t_vec* symbol_indices, - const size_t_vec* field_indices, - column_name_vec* symbol_names_out, - column_name_vec* field_names_out) except False: - cdef line_sender_column_name c_name - cdef size_t col_index - for col_index in range(symbol_indices.size): - col_index = symbol_indices.d[col_index] - str_to_column_name(b, data.columns[col_index], &c_name) - column_name_vec_push(symbol_names_out, c_name) - for col_index in range(field_indices.size): - col_index = field_indices.d[col_index] - str_to_column_name(b, data.columns[col_index], &c_name) - column_name_vec_push(field_names_out, c_name) - return True - - cdef bint _bind_col_index( str arg_name, int col_num, size_t col_count, size_t* col_index) except False: @@ -295,22 +339,23 @@ cdef object _pandas_check_column_is_str( cdef class TaggedEntry: """Python object representing a column whilst parsing .pandas arguments.""" - cdef size_t index + cdef size_t orig_index cdef str name cdef object series - cdef int sort_key + cdef int meta_target - def __init__(self, size_t index, str name, object series, int sort_key): - self.index = index + def __init__( + self, size_t orig_index, str name, object series, int meta_target): + self.orig_index = orig_index self.name = name self.series = series - self.sort_key = sort_key + self.meta_target = meta_target -cdef int _SORT_AS_FIELD = 0 -cdef int _SORT_AS_TABLE_NAME = -2 -cdef int _SORT_AS_SYMBOL = -1 -cdef int _SORT_AS_AT = 1 +cdef int _META_TARGET_FIELD = 0 +cdef int _META_TARGET_TABLE_NAME = -2 +cdef int _META_TARGET_SYMBOL = -1 +cdef int _META_TARGET_AT = 1 cdef bint _pandas_resolve_symbols( @@ -327,7 +372,7 @@ cdef bint _pandas_resolve_symbols( elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): - tagged_cols[col_index].sort_key = -1 # Sort col as as symbol. + tagged_cols[col_index].meta_target = _META_TARGET_SYMBOL return True else: if not isinstance(symbols, (tuple, list)): @@ -356,7 +401,7 @@ cdef bint _pandas_resolve_symbols( col_index, 'Bad element in argument `symbols`: ', symbol) - tagged_cols[col_index].sort_key = -1 # Sort col as as symbol. + tagged_cols[col_index].meta_target = _META_TARGET_SYMBOL return True @@ -409,7 +454,7 @@ cdef ssize_t _pandas_resolve_at( dtype = data.dtypes[col_index] if _pandas_is_supported_datetime(dtype): at_value_out[0] = _AT_SET_BY_COLUMN - tagged_cols[col_index].sort_key = 1 # Ordering key for "at" column. + tagged_cols[col_index].meta_target = _META_TARGET_AT return col_index else: raise TypeError( @@ -627,6 +672,45 @@ cdef bint _pandas_row_at( return True +cdef int _pandas_resolve_source(TaggedEntry entry) except -1: + raise ValueError('nyi') + + +cdef int _pandas_resolve_target( + TaggedEntry entry, col_source_t source) except -1: + raise ValueError('nyi') + + +cdef bint _pandas_resolve_col( + qdb_pystr_buf* b, + size_t index, + TaggedEntry entry, + col_t* col_out) except False: + col_out.orig_index = entry.orig_index + + # Since we don't need to send the column names for 'table' and 'at' columns, + # we don't need to validate and encode them as column names. + if ((entry.meta_target != _META_TARGET_TABLE_NAME) and + (entry.meta_target != _META_TARGET_AT)): + str_to_column_name(b, entry.name, &col_out.name) + + col_out.source = _pandas_resolve_source(entry) + col_out.target = _pandas_resolve_target(entry, col_out.source) + + col_out.dispatch_code = col_out.source + col_out.target + + + + +cdef bint _pandas_resolve_cols( + qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except False: + cdef size_t index + for index in range(len(tagged_cols)): + _pandas_resolve_col(b, index, tagged_cols[index], &cols_out.d[index]) + cols_out.size += 1 + return True + + cdef bint _pandas_resolve_args( object data, object table_name, @@ -647,7 +731,7 @@ cdef bint _pandas_resolve_args( index, name, series, - _SORT_AS_FIELD) + _META_TARGET_FIELD) # FIELD is a `bool`, `f64`, `string` or `ts`. for index, (name, series) in data.items()] name_col = _pandas_resolve_table_name( b, @@ -658,15 +742,12 @@ cdef bint _pandas_resolve_args( # Sort with table name is first, then the symbols, then fields, then at. # Note: Python 3.6+ guarantees stable sort. - tagged_cols.sort(key=lambda x: x.sort_key) + tagged_cols.sort(key=lambda x: x.meta_target) + _pandas_resolve_cols(b, tagged_cols, cols_out) return True - # _pandas_resolve_col_names( - # b, - # data, &symbol_indices, &field_indices, - # &symbol_names, &field_names) # cdef dtype_t* dtypes = NULL # cdef size_t set_buf_count = 0 # cdef Py_buffer* col_buffers = NULL From 8387209d3c3d65e00d31c1c15cbfee42738930d5 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 18 Nov 2022 21:21:47 +0000 Subject: [PATCH 048/147] More array extraction logic. --- src/questdb/pandas_integration.md | 11 +- src/questdb/pandas_integration.pxi | 346 ++++++++++++++++++++++------- 2 files changed, 272 insertions(+), 85 deletions(-) diff --git a/src/questdb/pandas_integration.md b/src/questdb/pandas_integration.md index 792f4bad..1505ce49 100644 --- a/src/questdb/pandas_integration.md +++ b/src/questdb/pandas_integration.md @@ -265,7 +265,16 @@ Name: b, dtype: float32 Name: c, dtype: float64 ``` -16-bit floats _are_ allowed, but we will disallow them: +#### Arrow floats + +Pandas also has arrow-compatible floats. +These have an additiona bitvector to represent nulls. + + + +#### 16-bit floats + +16-bit floats _do exist_ in Pandas, but we will disallow them: ```python >>> df = pd.DataFrame({'a': pd.Series([1.0, 1.5, 2.0], dtype='float16')}) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index ad6f67e3..38b63376 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -3,26 +3,16 @@ include "column_name_vec.pxi" # See: pandas_integration.md for technical overview. -cdef struct dtype_t: - # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html - # ?highlight=dtype#numpy.dtype - # See: https://numpy.org/doc/stable/reference/c-api - # /types-and-structures.html#c.PyArray_Descr - int alignment - char kind - int itemsize - char byteorder - bint hasobject - - -cdef struct col_numpy_data_t: - dtype_t dtype - Py_buffer pybuf - - -cdef struct col_arrow_data_t: - ArrowSchema schema # Schema of first chunk. - size_t n_chunks +# cdef struct dtype_t: +# # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html +# # ?highlight=dtype#numpy.dtype +# # See: https://numpy.org/doc/stable/reference/c-api +# # /types-and-structures.html#c.PyArray_Descr +# int alignment +# char kind +# int itemsize +# char byteorder +# bint hasobject cdef enum col_access_tag_t: @@ -30,11 +20,6 @@ cdef enum col_access_tag_t: arrow -cdef union col_access_t: - col_numpy_data_t numpy - col_arrow_data_t arrow - - cdef struct col_chunks_t: size_t n_chunks ArrowArray* chunks # We calloc `n_chunks + 1` of these. @@ -57,28 +42,51 @@ cdef enum col_target_t: at = 8 +cdef dict _TARGET_NAMES = { + col_target_t.table: "table name", + col_target_t.symbol: "symbol", + col_target_t.column_bool: "boolean", + col_target_t.column_i64: "integer", + col_target_t.column_f64: "float", + col_target_t.column_str: "string", + col_target_t.column_ts: "timestamp", + col_target_t.at: "designated timestamp", +} + + cdef enum col_source_t: - bool_pyobj = 11000 - bool_numpy = 12000 - bool_arrow = 13000 - int_pyobj = 21000 - u8_num = 22000 - i8_num = 23000 - u16_num = 24000 - i16_num = 25000 - u32_num = 26000 - i32_num = 27000 - u64_num = 28000 - i64_num = 29000 - f32_num = 31000 - f64_num = 32000 - str_pyobj = 41000 - str_arrow = 42000 - str_i8_cat = 43000 - str_i16_cat = 44000 - str_i32_cat = 45000 - str_i64_cat = 46000 - dt64_numpy = 51000 + bool_pyobj = 101000 + bool_numpy = 102000 + bool_arrow = 103000 + int_pyobj = 201000 + u8_numpy = 202000 + i8_numpy = 203000 + u16_numpy = 204000 + i16_numpy = 205000 + u32_numpy = 206000 + i32_numpy = 207000 + u64_numpy = 208000 + i64_numpy = 209000 + u8_arrow = 210000 + i8_arrow = 211000 + u16_arrow = 212000 + i16_arrow = 213000 + u32_arrow = 214000 + i32_arrow = 215000 + u64_arrow = 216000 + i64_arrow = 217000 + float_pyobj = 301000 + f32_numpy = 302000 + f64_numpy = 303000 + f32_arrow = 304000 + f64_arrow = 305000 + str_pyobj = 401000 + str_arrow = 402000 + str_i8_cat = 403000 + str_i16_cat = 404000 + str_i32_cat = 405000 + str_i64_cat = 406000 + dt64_numpy = 501000 cdef dict _TARGET_TO_SOURCE = { @@ -97,14 +105,14 @@ cdef dict _TARGET_TO_SOURCE = { }, col_target_t.column_i64: { col_source_t.int_pyobj, - col_source_t.u8_num, - col_source_t.i8_num, - col_source_t.u16_num, - col_source_t.i16_num, - col_source_t.u32_num, - col_source_t.i32_num, - col_source_t.u64_num, - col_source_t.i64_num, + col_source_t.u8_numpy, + col_source_t.i8_numpy, + col_source_t.u16_numpy, + col_source_t.i16_numpy, + col_source_t.u32_numpy, + col_source_t.i32_numpy, + col_source_t.u64_numpy, + col_source_t.i64_numpy, }, col_target_t.column_f64: { col_source_t.f32_num, @@ -123,27 +131,12 @@ cdef dict _TARGET_TO_SOURCE = { } -cdef dict _invert_dict(dict d): - cdef dict res = {} - cdef object key - cdef set value_set - cdef object value - for key, value_set in d.items(): - for value in value_set: - if value not in res: - res[value] = set() - res[value].add(key) - return res - - -cdef dict _SOURCE_TO_TARGET = _invert_dict(_TARGET_TO_SOURCE) - - cdef struct col_t: size_t orig_index line_sender_column_name name - col_access_tag_t access_tag - col_access_t access + col_access_tag_t tag + Py_buffer pybuf + ArrowSchema arrow_schema # Schema of first chunk. col_chunks_t chunks col_cursor_t cursor col_source_t source @@ -152,7 +145,10 @@ cdef struct col_t: cdef void col_t_release(col_t* col): + # We can use `col.tag` to determine what to release. + # Arrow chunks might be "synthetic" borrowing from `col.pybuf`. # TODO: Implement cleanup, PyBuffer_Release, etc. + # TODO: Do we need to call Arrow's cleanup functions when done? pass @@ -188,21 +184,35 @@ cdef void col_t_arr_release(col_t_arr* arr): arr.d = NULL +cdef object _NUMPY = None # module object cdef object _PANDAS = None # module object cdef object _PANDAS_NA = None # pandas.NA cdef object _PYARROW = None # module object, if available or None cdef object _pandas_may_import_deps(): - global _PANDAS, _PYARROW, _PANDAS_NA - if _PANDAS_NA is not None: + """" + Lazily import module dependencies on first use to avoid startup overhead. + + $ cat imp_test.py + import numpy + import pandas + import pyarrow + + $ time python3 ./imp_test.py + python3 ./imp_test.py 0.56s user 1.60s system 852% cpu 0.254 total + """ + global _NUMPY, _PANDAS, _PYARROW, _PANDAS_NA + if _NUMPY is not None: return + import numpy + _NUMPY = numpy import pandas _PANDAS = pandas _PANDAS_NA = pandas.NA try: - import pyarrow as pa - _PYARROW = pa + import pyarrow + _PYARROW = pyarrow except ImportError: _PYARROW = None @@ -341,13 +351,20 @@ cdef class TaggedEntry: cdef size_t orig_index cdef str name + cdef object dtype cdef object series cdef int meta_target def __init__( - self, size_t orig_index, str name, object series, int meta_target): + self, + size_t orig_index, + str name, + object dtype, + object series, + int meta_target): self.orig_index = orig_index self.name = name + self.dtype = dtype self.series = series self.meta_target = meta_target @@ -672,8 +689,167 @@ cdef bint _pandas_row_at( return True -cdef int _pandas_resolve_source(TaggedEntry entry) except -1: - raise ValueError('nyi') +cdef int _pandas_series_as_pybuf( + TaggedEntry entry, col_t* col_out) except -1: + cdef object nparr = entry.series.to_numpy() + if not PyObject_CheckBuffer(nparr): + raise TypeError( + f'Bad column {entry.name!r}: Expected a buffer, got ' + + f'{entry.series!r} ({type(entry.series)!r})') + col_out.tag = col_access_tag_t.numpy + return PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_STRIDES) + # TODO: Wrap exception from `PyObject_GetBuffer` informatively. + # Then change to `except False` and `bint` return type. + # Then manually map the `pybuf` to the arrow `col.chunks` even if we're + # not using arrow. This allows is to give us a single consistent iterating + # device. + # TODO: Set stride. + + +cdef bint _pandas_series_as_arrow( + TaggedEntry entry, + col_t* col_out, + col_source_t np_fallback) except False: + cdef object array + cdef list chunks + cdef size_t chunk_index + if _PYARROW is None: + col_out.source = np_fallback + _pandas_series_as_pybuf(entry, col_out) + return True + + col_out.tag = col_access_tag_t.arrow + array = _PYARROW.Array.from_pandas(entry.series) + if isinstance(array, _PYARROW.ChunkedArray): + chunks = array.chunks + else: + chunks = [array] + + col_out.chunks.n_chunks = len(chunks) + col_out.chunks.chunks = calloc( + col_out.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. + sizeof(ArrowArray)) + + for chunk_index in range(len(chunks)): + array = chunks[chunk_index] + if chunk_index == 0: + chunks[chunk_index]._export_to_c( + &col_out.chunks.chunks[chunk_index], + &col_out.arrow_schema) + else: + chunks[chunk_index]._export_to_c( + &col_out.chunks.chunks[chunk_index]) + return True + + +cdef bint _pandas_category_series_as_arrow( + TaggedEntry entry, col_t* col_out) except False: + col_out.source = 0 # place holder value + _pandas_series_as_arrow(entry, col_out, col_source_t.str_pyobj) + if col_out.source == col_source_t.str_pyobj: + return True + + + +cdef bint _pandas_resolve_source_and_buffers( + TaggedEntry entry, col_t* col_out) except False: + cdef object dtype = entry.dtype + if isinstance(dtype, _PANDAS.dtype('bool')): + col_out.source = col_source_t.bool_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _PANDAS.BooleanDtype): + col_out.source = col_source_t.bool_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.bool_pyobj) + elif isinstance(dtype, _NUMPY.dtype('uint8')): + col_out.source = col_source_t.u8_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('int8')): + col_out.source = col_source_t.i8_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('uint16')): + col_out.source = col_source_t.u16_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('int16')): + col_out.source = col_source_t.i16_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('uint32')): + col_out.source = col_source_t.u32_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('int32')): + col_out.source = col_source_t.i32_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('uint64')): + col_out.source = col_source_t.u64_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('int64')): + col_out.source = col_source_t.i64_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _PANDAS.UInt8Dtype): + col_out.source = col_source_t.u8_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _PANDAS.Int8Dtype): + col_out.source = col_source_t.i8_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _PANDAS.UInt16Dtype): + col_out.source = col_source_t.u16_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _PANDAS.Int16Dtype): + col_out.source = col_source_t.i16_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _PANDAS.UInt32Dtype): + col_out.source = col_source_t.u32_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _PANDAS.Int32Dtype): + col_out.source = col_source_t.i32_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _PANDAS.UInt64Dtype): + col_out.source = col_source_t.u64_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _PANDAS.Int64Dtype): + col_out.source = col_source_t.i64_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + elif isinstance(dtype, _NUMPY.dtype('float32')): + col_out.source = col_source_t.f32_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('float64')): + col_out.source = col_source_t.f64_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _PANDAS.Float32Dtype): + col_out.source = col_source_t.f32_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.float_pyobj) + elif isinstance(dtype, _PANDAS.Float64Dtype): + col_out.source = col_source_t.f64_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.float_pyobj) + elif isinstance(dtype, _PANDAS.StringDtype): + if dtype.storage == 'pyarrow': + col_out.source = col_source_t.str_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.str_pyobj) + elif dtype.storage == 'python': + col_out.source = col_source_t.str_pyobj + _pandas_series_as_pybuf(entry, col_out) + else: + raise ValueError( + f'Unknown string dtype storage: f{dtype.storage} ' + + f'for column {entry.name} of dtype {dtype}.') + elif isinstance(dtype, _PANDAS.CategoricalDtype): + _pandas_category_series_as_arrow(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('object')): + # We need to sniff the objects + # TODO: bool_pyobj, int_pyobj, str_pyobj + + # TODO + + # f32_num = 31000 + # f64_num = 32000 + # str_pyobj = 41000 + # str_arrow = 42000 + # str_i8_cat = 43000 + # str_i16_cat = 44000 + # str_i32_cat = 45000 + # str_i64_cat = 46000 + # dt64_numpy = 51000 + + raise ValueError('nyi') # TODO [amunra]: Implement and test. cdef int _pandas_resolve_target( @@ -694,14 +870,16 @@ cdef bint _pandas_resolve_col( (entry.meta_target != _META_TARGET_AT)): str_to_column_name(b, entry.name, &col_out.name) - col_out.source = _pandas_resolve_source(entry) + _pandas_resolve_source_and_buffers(entry, col_out) col_out.target = _pandas_resolve_target(entry, col_out.source) - + if col_out.source not in _TARGET_TO_SOURCE[col_out.target]: + raise ValueError( + f'Bad value: Column {entry.name!r} ({entry.dtype}) is not ' + + f'supported as a {_TARGET_NAMES[col_out.target]} column.') col_out.dispatch_code = col_out.source + col_out.target - cdef bint _pandas_resolve_cols( qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except False: cdef size_t index @@ -730,6 +908,7 @@ cdef bint _pandas_resolve_args( TaggedEntry( index, name, + data.dtypes[index] series, _META_TARGET_FIELD) # FIELD is a `bool`, `f64`, `string` or `ts`. for index, (name, series) in data.items()] @@ -778,7 +957,6 @@ cdef void _pandas_col_advance(col_t* col): # else: # cursor.offset += 1 # - # # (Checked with Godbolt, GCC -O3 code was rather "jumpy") cdef col_cursor_t* cursor = &col.cursor cdef size_t new_chunk # disguised bint. Either 0 or 1. @@ -787,7 +965,7 @@ cdef void _pandas_col_advance(col_t* col): cursor.chunk_index += new_chunk cursor.chunk += new_chunk # Note: We get away with this because we've allocated one extra blank chunk. - # This ensures that `cursor.chunk.offset` is always valid. + # This ensures that accessing `cursor.chunk.offset` doesn't segfault. cursor.offset = ( (new_chunk * cursor.chunk.offset) + ((not new_chunk) * cursor.offset)) From 5e5158fbe7b51d3462b8af9d704915487a91f1c4 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 21 Nov 2022 11:00:14 +0000 Subject: [PATCH 049/147] Updating of types, updating tech doc for timezone timestamps. --- src/questdb/pandas_integration.md | 31 ++++++++++- src/questdb/pandas_integration.pxi | 84 +++++++++++++++--------------- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/src/questdb/pandas_integration.md b/src/questdb/pandas_integration.md index 1505ce49..fa985f7b 100644 --- a/src/questdb/pandas_integration.md +++ b/src/questdb/pandas_integration.md @@ -516,7 +516,7 @@ though they are all UTF-8 buffers already so.. little gain. ### Nanosecond-precision UTC unix epoch 64-bit signed int timestamps -This one's easy: +#### Timezone-free timestamp ```python >>> n1 = pd.Timestamp(dt.datetime.utcnow()) @@ -552,6 +552,35 @@ Null values _are_ supported. Unclear what the sentinel value for `NaT` is yet, but we want to map it internally to 0 for the designated timestamp and to recognise it and skip the column otherwise. +#### Additionally, we can also have datetimes with a timezone + +```python +>>> ts = pd.Timestamp( +... year=2020, month=1, day=1, hour=12, minute=0, second=0, +... tz=zoneinfo.ZoneInfo('America/Los_Angeles')) +>>> df = pd.DataFrame({'a': [ts]}) +>>> df.dtypes['a'] +datetime64[ns, America/Los_Angeles] +>>> type(_) + +>>> df.dtypes['a'].tz +zoneinfo.ZoneInfo(key='America/Los_Angeles') +``` + +The good news here is that the timestamp is still held as UTC (regardless of +timezone), so no timezone conversion logic is required here. + +```python +>>> pa.Array.from_pandas(df.a) + +[ + 2020-01-01 20:00:00.000000000 +] +``` + +**Note**: We don't need PyArrow to access the buffer as +it's only used here to show raw data. + ## Unified Cursor TO BE CONTINUED diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 38b63376..d524ef81 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -55,38 +55,39 @@ cdef dict _TARGET_NAMES = { cdef enum col_source_t: - bool_pyobj = 101000 - bool_numpy = 102000 - bool_arrow = 103000 - int_pyobj = 201000 - u8_numpy = 202000 - i8_numpy = 203000 - u16_numpy = 204000 - i16_numpy = 205000 - u32_numpy = 206000 - i32_numpy = 207000 - u64_numpy = 208000 - i64_numpy = 209000 - u8_arrow = 210000 - i8_arrow = 211000 - u16_arrow = 212000 - i16_arrow = 213000 - u32_arrow = 214000 - i32_arrow = 215000 - u64_arrow = 216000 - i64_arrow = 217000 - float_pyobj = 301000 - f32_numpy = 302000 - f64_numpy = 303000 - f32_arrow = 304000 - f64_arrow = 305000 - str_pyobj = 401000 - str_arrow = 402000 - str_i8_cat = 403000 - str_i16_cat = 404000 - str_i32_cat = 405000 - str_i64_cat = 406000 - dt64_numpy = 501000 + bool_pyobj = 101000 + bool_numpy = 102000 + bool_arrow = 103000 + int_pyobj = 201000 + u8_numpy = 202000 + i8_numpy = 203000 + u16_numpy = 204000 + i16_numpy = 205000 + u32_numpy = 206000 + i32_numpy = 207000 + u64_numpy = 208000 + i64_numpy = 209000 + u8_arrow = 210000 + i8_arrow = 211000 + u16_arrow = 212000 + i16_arrow = 213000 + u32_arrow = 214000 + i32_arrow = 215000 + u64_arrow = 216000 + i64_arrow = 217000 + float_pyobj = 301000 + f32_numpy = 302000 + f64_numpy = 303000 + f32_arrow = 304000 + f64_arrow = 305000 + str_pyobj = 401000 + str_arrow = 402000 + str_i8_cat = 403000 + str_i16_cat = 404000 + str_i32_cat = 405000 + str_i64_cat = 406000 + dt64ns_numpy = 501000 + dt64ns_tz_numpy = 502000 cdef dict _TARGET_TO_SOURCE = { @@ -833,21 +834,18 @@ cdef bint _pandas_resolve_source_and_buffers( f'for column {entry.name} of dtype {dtype}.') elif isinstance(dtype, _PANDAS.CategoricalDtype): _pandas_category_series_as_arrow(entry, col_out) + elif isinstance(dtype, _NUMPY.dtype('datetime64[ns]')): + col_out.source = col_source_t.dt64ns_numpy + _pandas_series_as_pybuf(entry, col_out) + elif isinstance(dtype, _PANDAS.DatetimeTZDtype): + col_out.source = col_source_t.dt64ns_tz_numpy + col_out.tz_offset_ns = _pandas_get_tz_offset_ns(dtype.tz) + _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('object')): # We need to sniff the objects # TODO: bool_pyobj, int_pyobj, str_pyobj - # TODO - - # f32_num = 31000 - # f64_num = 32000 - # str_pyobj = 41000 - # str_arrow = 42000 - # str_i8_cat = 43000 - # str_i16_cat = 44000 - # str_i32_cat = 45000 - # str_i64_cat = 46000 - # dt64_numpy = 51000 + raise ValueError('nyi') # TODO [amunra]: Implement and test. From 2a26d8f9474fe50039c2da87ef1a3b9a8f000bc3 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 21 Nov 2022 14:02:30 +0000 Subject: [PATCH 050/147] Fixed up most cython build issues. Mostly enum usage issues. --- src/questdb/ingress.pyx | 3 +- src/questdb/pandas_integration.pxi | 838 +++++++++++++++++------------ 2 files changed, 492 insertions(+), 349 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index c6264c62..38a56821 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -31,8 +31,9 @@ API for fast data ingestion into QuestDB. """ # For prototypes: https://github.com/cython/cython/tree/master/Cython/Includes -from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t +from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t from libc.stdlib cimport malloc, calloc, realloc, free, abort +from libc.string import strncmp from cpython.datetime cimport datetime from cpython.bool cimport bool, PyBool_Check from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index d524ef81..2707a907 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -32,103 +32,152 @@ cdef struct col_cursor_t: cdef enum col_target_t: - table = 1 - symbol = 2 - column_bool = 3 - column_i64 = 4 - column_f64 = 5 - column_str = 6 - column_ts = 7 - at = 8 + col_target_skip = 0 + col_target_table = 1 + col_target_symbol = 2 + col_target_column_bool = 3 + col_target_column_i64 = 4 + col_target_column_f64 = 5 + col_target_column_str = 6 + col_target_column_ts = 7 + col_target_at = 8 cdef dict _TARGET_NAMES = { - col_target_t.table: "table name", - col_target_t.symbol: "symbol", - col_target_t.column_bool: "boolean", - col_target_t.column_i64: "integer", - col_target_t.column_f64: "float", - col_target_t.column_str: "string", - col_target_t.column_ts: "timestamp", - col_target_t.at: "designated timestamp", + col_target_t.col_target_skip: "skipped", + col_target_t.col_target_table: "table name", + col_target_t.col_target_symbol: "symbol", + col_target_t.col_target_column_bool: "boolean", + col_target_t.col_target_column_i64: "integer", + col_target_t.col_target_column_f64: "float", + col_target_t.col_target_column_str: "string", + col_target_t.col_target_column_ts: "timestamp", + col_target_t.col_target_at: "designated timestamp", } cdef enum col_source_t: - bool_pyobj = 101000 - bool_numpy = 102000 - bool_arrow = 103000 - int_pyobj = 201000 - u8_numpy = 202000 - i8_numpy = 203000 - u16_numpy = 204000 - i16_numpy = 205000 - u32_numpy = 206000 - i32_numpy = 207000 - u64_numpy = 208000 - i64_numpy = 209000 - u8_arrow = 210000 - i8_arrow = 211000 - u16_arrow = 212000 - i16_arrow = 213000 - u32_arrow = 214000 - i32_arrow = 215000 - u64_arrow = 216000 - i64_arrow = 217000 - float_pyobj = 301000 - f32_numpy = 302000 - f64_numpy = 303000 - f32_arrow = 304000 - f64_arrow = 305000 - str_pyobj = 401000 - str_arrow = 402000 - str_i8_cat = 403000 - str_i16_cat = 404000 - str_i32_cat = 405000 - str_i64_cat = 406000 - dt64ns_numpy = 501000 - dt64ns_tz_numpy = 502000 + col_source_nulls = 0 + col_source_bool_pyobj = 101000 + col_source_bool_numpy = 102000 + col_source_bool_arrow = 103000 + col_source_int_pyobj = 201000 + col_source_u8_numpy = 202000 + col_source_i8_numpy = 203000 + col_source_u16_numpy = 204000 + col_source_i16_numpy = 205000 + col_source_u32_numpy = 206000 + col_source_i32_numpy = 207000 + col_source_u64_numpy = 208000 + col_source_i64_numpy = 209000 + col_source_u8_arrow = 210000 + col_source_i8_arrow = 211000 + col_source_u16_arrow = 212000 + col_source_i16_arrow = 213000 + col_source_u32_arrow = 214000 + col_source_i32_arrow = 215000 + col_source_u64_arrow = 216000 + col_source_i64_arrow = 217000 + col_source_float_pyobj = 301000 + col_source_f32_numpy = 302000 + col_source_f64_numpy = 303000 + col_source_f32_arrow = 304000 + col_source_f64_arrow = 305000 + col_source_str_pyobj = 401000 + col_source_str_arrow = 402000 + col_source_str_i8_cat = 403000 + col_source_str_i16_cat = 404000 + col_source_str_i32_cat = 405000 + col_source_str_i64_cat = 406000 + col_source_dt64ns_numpy = 501000 + col_source_dt64ns_tz_numpy = 502000 cdef dict _TARGET_TO_SOURCE = { - col_target_t.table: { - col_source_t.str_pyobj, - col_source_t.str_arrow, + col_target_t.col_target_skip: { + col_source_t.col_source_nulls, }, - col_target_t.symbol: { - col_source_t.str_pyobj, - col_source_t.str_arrow, + col_target_t.col_target_table: { + col_source_t.col_source_str_pyobj, + col_source_t.col_source_str_arrow, + col_source_t.col_source_str_i8_cat, + col_source_t.col_source_str_i16_cat, + col_source_t.col_source_str_i32_cat, + col_source_t.col_source_str_i64_cat, }, - col_target_t.column_bool: { - col_source_t.bool_pyobj, - col_source_t.bool_numpy, - col_source_t.bool_arrow, + col_target_t.col_target_symbol: { + col_source_t.col_source_str_pyobj, + col_source_t.col_source_str_arrow, + col_source_t.col_source_str_i8_cat, + col_source_t.col_source_str_i16_cat, + col_source_t.col_source_str_i32_cat, + col_source_t.col_source_str_i64_cat, }, - col_target_t.column_i64: { - col_source_t.int_pyobj, - col_source_t.u8_numpy, - col_source_t.i8_numpy, - col_source_t.u16_numpy, - col_source_t.i16_numpy, - col_source_t.u32_numpy, - col_source_t.i32_numpy, - col_source_t.u64_numpy, - col_source_t.i64_numpy, + col_target_t.col_target_column_bool: { + col_source_t.col_source_bool_pyobj, + col_source_t.col_source_bool_numpy, + col_source_t.col_source_bool_arrow, }, - col_target_t.column_f64: { - col_source_t.f32_num, - col_source_t.f64_num, + col_target_t.col_target_column_i64: { + col_source_t.col_source_int_pyobj, + col_source_t.col_source_u8_numpy, + col_source_t.col_source_i8_numpy, + col_source_t.col_source_u16_numpy, + col_source_t.col_source_i16_numpy, + col_source_t.col_source_u32_numpy, + col_source_t.col_source_i32_numpy, + col_source_t.col_source_u64_numpy, + col_source_t.col_source_i64_numpy, + col_source_t.col_source_u8_arrow, + col_source_t.col_source_i8_arrow, + col_source_t.col_source_u16_arrow, + col_source_t.col_source_i16_arrow, + col_source_t.col_source_u32_arrow, + col_source_t.col_source_i32_arrow, + col_source_t.col_source_u64_arrow, + col_source_t.col_source_i64_arrow, }, - col_target_t.column_str: { - col_source_t.str_pyobj, - col_source_t.str_arrow, + col_target_t.col_target_column_f64: { + col_source_t.col_source_float_pyobj, + col_source_t.col_source_f32_numpy, + col_source_t.col_source_f64_numpy, + col_source_t.col_source_f32_arrow, + col_source_t.col_source_f64_arrow, }, - col_target_t.column_ts: { - col_source_t.dt64_numpy, + col_target_t.col_target_column_str: { + col_source_t.col_source_str_pyobj, + col_source_t.col_source_str_arrow, + col_source_t.col_source_str_i8_cat, + col_source_t.col_source_str_i16_cat, + col_source_t.col_source_str_i32_cat, + col_source_t.col_source_str_i64_cat, }, - col_target_t.at: { - col_source_t.dt64_numpy + col_target_t.col_target_column_ts: { + col_source_t.col_source_dt64ns_numpy, + col_source_t.col_source_dt64ns_tz_numpy, }, + col_target_t.col_target_at: { + col_source_t.col_source_dt64ns_numpy, + col_source_t.col_source_dt64ns_tz_numpy, + }, +} + + +# Targets associated with col_meta_target.field. +cdef tuple _FIELD_TARGETS = ( + col_target_t.col_target_skip, + col_target_t.col_target_column_bool, + col_target_t.col_target_column_i64, + col_target_t.col_target_column_f64, + col_target_t.col_target_column_str, + col_target_t.col_target_column_ts) + + +# Targets that map directly from a meta target. +cdef set _DIRECT_META_TARGETS = { + col_target_t.col_target_table, + col_target_t.col_target_symbol, + col_target_t.col_target_at, } @@ -346,6 +395,14 @@ cdef object _pandas_check_column_is_str( f'{col_name!r} column: Must be a strings column.') +# Int values in order for sorting (as needed for API's sequential coupling). +cdef enum meta_target_t: + meta_target_table = col_target_t.col_target_table + meta_target_symbol = col_target_t.col_target_symbol + meta_target_field = col_target_t.col_target_column_bool + meta_target_at = col_target_t.col_target_at + + @cython.internal cdef class TaggedEntry: """Python object representing a column whilst parsing .pandas arguments.""" @@ -354,7 +411,7 @@ cdef class TaggedEntry: cdef str name cdef object dtype cdef object series - cdef int meta_target + cdef meta_target_t meta_target def __init__( self, @@ -362,7 +419,7 @@ cdef class TaggedEntry: str name, object dtype, object series, - int meta_target): + meta_target_t meta_target): self.orig_index = orig_index self.name = name self.dtype = dtype @@ -370,12 +427,6 @@ cdef class TaggedEntry: self.meta_target = meta_target -cdef int _META_TARGET_FIELD = 0 -cdef int _META_TARGET_TABLE_NAME = -2 -cdef int _META_TARGET_SYMBOL = -1 -cdef int _META_TARGET_AT = 1 - - cdef bint _pandas_resolve_symbols( object data, list tagged_cols, @@ -390,7 +441,7 @@ cdef bint _pandas_resolve_symbols( elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): - tagged_cols[col_index].meta_target = _META_TARGET_SYMBOL + tagged_cols[col_index].meta_target = meta_target_t.meta_target_symbol return True else: if not isinstance(symbols, (tuple, list)): @@ -419,7 +470,7 @@ cdef bint _pandas_resolve_symbols( col_index, 'Bad element in argument `symbols`: ', symbol) - tagged_cols[col_index].meta_target = _META_TARGET_SYMBOL + tagged_cols[col_index].meta_target = meta_target_t.meta_target_symbol return True @@ -472,7 +523,7 @@ cdef ssize_t _pandas_resolve_at( dtype = data.dtypes[col_index] if _pandas_is_supported_datetime(dtype): at_value_out[0] = _AT_SET_BY_COLUMN - tagged_cols[col_index].meta_target = _META_TARGET_AT + tagged_cols[col_index].meta_target = meta_target_t.meta_target_at return col_index else: raise TypeError( @@ -490,204 +541,204 @@ cdef object _pandas_is_supported_datetime(object dtype): (not dtype.hasobject)) -cdef char _str_to_char(str field, str s) except 0: - cdef int res - if len(s) != 1: - raise ValueError( - f'dtype.{field}: Expected a single character, got {s!r}') - res = ord(s) - if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. - raise ValueError( - f'dtype.{field}: Character out of ASCII range, got {s!r}') - return res - - -cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: - """ - Parse a numpy dtype and return a dtype_t. - """ - dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) - dtype_out.kind = _str_to_char('kind', np_dtype.kind) - dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) - dtype_out.byteorder = _str_to_char( - 'byteorder', getattr(np_dtype, 'byteorder', '=')) - dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) - return True - - -cdef bint _pandas_resolve_dtypes( - object data, size_t col_count, dtype_t* dtypes_out) except False: - cdef size_t col_index - for col_index in range(col_count): - _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) - return True - - -cdef bint _pandas_resolve_col_buffers( - object data, size_t col_count, const dtype_t* dtypes, - Py_buffer* col_buffers, size_t* set_buf_count) except False: - """ - Map pandas columns to array of col_buffers. - """ - # Note: By calling "to_numpy" we are throwing away what might be an Arrow. - # This is particularly expensive for string columns. - # If you want to use Arrow (i.e. your data comes from Parquet) please ask - # for the feature in our issue tracker. - cdef size_t col_index - cdef object nparr - cdef Py_buffer* view - cdef const dtype_t* dtype - for col_index in range(col_count): - nparr = data.iloc[:, col_index].to_numpy() - view = &col_buffers[col_index] - dtype = &dtypes[col_index] - if not PyObject_CheckBuffer(nparr): - raise TypeError( - f'Bad column: Expected a numpy array, got {nparr!r}') - PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) - # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. - set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. - return True - - -cdef inline const void* _pandas_get_cell( - Py_buffer* col_buffer, size_t row_index): - return col_buffer.buf + (row_index * col_buffer.strides[0]) - - -cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' -cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' - - -cdef bint _pandas_get_str_cell( - qdb_pystr_buf* b, - dtype_t* dtype, - Py_buffer* col_buffer, - size_t row_index, - bint* is_null_out, - line_sender_utf8* utf8_out) except False: - cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - cdef object obj - if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: - # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. - # TODO: Improve error messaging. Error message should include the column name. - obj = ((cell)[0]) - if (obj is None) or (obj is _PANDAS_NA): - is_null_out[0] = True - else: - is_null_out[0] = False - try: - str_to_utf8(b, obj, utf8_out) - except TypeError as e: - raise TypeError( - 'Bad column: Expected a string, ' + - f'got {obj!r} ({type(obj)!r})') from e - else: - raise TypeError( - f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. - return True - - -cdef int64_t _pandas_get_timestamp_cell( - dtype_t* dtype, - Py_buffer* col_buffer, - size_t row_index) except -1: - # Note: Type is pre-validated by `_pandas_is_supported_datetime`. - cdef const void* cell = _pandas_get_cell(col_buffer, row_index) - cdef int64_t res = (cell)[0] - if res < 0: - # TODO [amunra]: Improve error messaging. Add column name. - raise ValueError( - f'Bad value: Negative timestamp, got {res}') - return res - - -cdef bint _pandas_row_table_name( - line_sender_buffer* impl, - qdb_pystr_buf* b, - dtype_t* dtypes, - Py_buffer* col_buffers, - ssize_t name_col, - size_t row_index, - line_sender_table_name c_table_name) except False: - cdef line_sender_error* err = NULL - cdef bint is_null = False - cdef line_sender_utf8 utf8 - if name_col >= 0: - _pandas_get_str_cell( - b, - &dtypes[name_col], - &col_buffers[name_col], - row_index, - &is_null, - &utf8) - if is_null: - # TODO [amunra]: Improve error messaging. Add column name. - raise ValueError( - f'Bad value: `None` table name value at row {row_index}.') - if not line_sender_table_name_init( - &c_table_name, utf8.len, utf8.buf, &err): - raise c_err_to_py(err) - if not line_sender_buffer_table(impl, c_table_name, &err): - raise c_err_to_py(err) - return True +# cdef char _str_to_char(str field, str s) except 0: +# cdef int res +# if len(s) != 1: +# raise ValueError( +# f'dtype.{field}: Expected a single character, got {s!r}') +# res = ord(s) +# if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. +# raise ValueError( +# f'dtype.{field}: Character out of ASCII range, got {s!r}') +# return res + + +# cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: +# """ +# Parse a numpy dtype and return a dtype_t. +# """ +# dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) +# dtype_out.kind = _str_to_char('kind', np_dtype.kind) +# dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) +# dtype_out.byteorder = _str_to_char( +# 'byteorder', getattr(np_dtype, 'byteorder', '=')) +# dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) +# return True + + +# cdef bint _pandas_resolve_dtypes( +# object data, size_t col_count, dtype_t* dtypes_out) except False: +# cdef size_t col_index +# for col_index in range(col_count): +# _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) +# return True + + +# cdef bint _pandas_resolve_col_buffers( +# object data, size_t col_count, const dtype_t* dtypes, +# Py_buffer* col_buffers, size_t* set_buf_count) except False: +# """ +# Map pandas columns to array of col_buffers. +# """ +# # Note: By calling "to_numpy" we are throwing away what might be an Arrow. +# # This is particularly expensive for string columns. +# # If you want to use Arrow (i.e. your data comes from Parquet) please ask +# # for the feature in our issue tracker. +# cdef size_t col_index +# cdef object nparr +# cdef Py_buffer* view +# cdef const dtype_t* dtype +# for col_index in range(col_count): +# nparr = data.iloc[:, col_index].to_numpy() +# view = &col_buffers[col_index] +# dtype = &dtypes[col_index] +# if not PyObject_CheckBuffer(nparr): +# raise TypeError( +# f'Bad column: Expected a numpy array, got {nparr!r}') +# PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) +# # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. +# set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. +# return True + + +# cdef inline const void* _pandas_get_cell( +# Py_buffer* col_buffer, size_t row_index): +# return col_buffer.buf + (row_index * col_buffer.strides[0]) + + +# cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' +# cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' + + +# cdef bint _pandas_get_str_cell( +# qdb_pystr_buf* b, +# dtype_t* dtype, +# Py_buffer* col_buffer, +# size_t row_index, +# bint* is_null_out, +# line_sender_utf8* utf8_out) except False: +# cdef const void* cell = _pandas_get_cell(col_buffer, row_index) +# cdef object obj +# if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: +# # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. +# # TODO: Improve error messaging. Error message should include the column name. +# obj = ((cell)[0]) +# if (obj is None) or (obj is _PANDAS_NA): +# is_null_out[0] = True +# else: +# is_null_out[0] = False +# try: +# str_to_utf8(b, obj, utf8_out) +# except TypeError as e: +# raise TypeError( +# 'Bad column: Expected a string, ' + +# f'got {obj!r} ({type(obj)!r})') from e +# else: +# raise TypeError( +# f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. +# return True + + +# cdef int64_t _pandas_get_timestamp_cell( +# dtype_t* dtype, +# Py_buffer* col_buffer, +# size_t row_index) except -1: +# # Note: Type is pre-validated by `_pandas_is_supported_datetime`. +# cdef const void* cell = _pandas_get_cell(col_buffer, row_index) +# cdef int64_t res = (cell)[0] +# if res < 0: +# # TODO [amunra]: Improve error messaging. Add column name. +# raise ValueError( +# f'Bad value: Negative timestamp, got {res}') +# return res + + +# cdef bint _pandas_row_table_name( +# line_sender_buffer* impl, +# qdb_pystr_buf* b, +# dtype_t* dtypes, +# Py_buffer* col_buffers, +# ssize_t name_col, +# size_t row_index, +# line_sender_table_name c_table_name) except False: +# cdef line_sender_error* err = NULL +# cdef bint is_null = False +# cdef line_sender_utf8 utf8 +# if name_col >= 0: +# _pandas_get_str_cell( +# b, +# &dtypes[name_col], +# &col_buffers[name_col], +# row_index, +# &is_null, +# &utf8) +# if is_null: +# # TODO [amunra]: Improve error messaging. Add column name. +# raise ValueError( +# f'Bad value: `None` table name value at row {row_index}.') +# if not line_sender_table_name_init( +# &c_table_name, utf8.len, utf8.buf, &err): +# raise c_err_to_py(err) +# if not line_sender_buffer_table(impl, c_table_name, &err): +# raise c_err_to_py(err) +# return True -cdef bint _pandas_row_symbols( - line_sender_buffer* impl, - qdb_pystr_buf* b, - dtype_t* dtypes, - Py_buffer* col_buffers, - size_t row_index, - const column_name_vec* symbol_names, - const size_t_vec* symbol_indices) except False: - cdef line_sender_error* err = NULL - cdef size_t sym_index - cdef size_t col_index - cdef dtype_t* dtype - cdef Py_buffer* col_buffer - cdef line_sender_column_name col_name - cdef line_sender_utf8 symbol - cdef bint is_null = False - for sym_index in range(symbol_indices.size): - col_name = symbol_names.d[sym_index] - col_index = symbol_indices.d[sym_index] - col_buffer = &col_buffers[col_index] - dtype = &dtypes[col_index] - _pandas_get_str_cell( - b, - dtype, - col_buffer, - row_index, - &is_null, - &symbol) - if not is_null: - if not line_sender_buffer_symbol(impl, col_name, symbol, &err): - raise c_err_to_py(err) - return True - - -cdef bint _pandas_row_at( - line_sender_buffer* impl, - dtype_t* dtypes, - Py_buffer* col_buffers, - size_t row_index, - ssize_t at_col, - int64_t at_value) except False: - cdef line_sender_error* err = NULL - cdef Py_buffer* col_buffer - cdef dtype_t* dtype - if at_col >= 0: - col_buffer = &col_buffers[at_col] - dtype = &dtypes[at_col] - at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) - if at_value > 0: - if not line_sender_buffer_at(impl, at_value, &err): - raise c_err_to_py(err) - else: - if not line_sender_buffer_at_now(impl, &err): - raise c_err_to_py(err) - return True +# cdef bint _pandas_row_symbols( +# line_sender_buffer* impl, +# qdb_pystr_buf* b, +# dtype_t* dtypes, +# Py_buffer* col_buffers, +# size_t row_index, +# const column_name_vec* symbol_names, +# const size_t_vec* symbol_indices) except False: +# cdef line_sender_error* err = NULL +# cdef size_t sym_index +# cdef size_t col_index +# cdef dtype_t* dtype +# cdef Py_buffer* col_buffer +# cdef line_sender_column_name col_name +# cdef line_sender_utf8 symbol +# cdef bint is_null = False +# for sym_index in range(symbol_indices.size): +# col_name = symbol_names.d[sym_index] +# col_index = symbol_indices.d[sym_index] +# col_buffer = &col_buffers[col_index] +# dtype = &dtypes[col_index] +# _pandas_get_str_cell( +# b, +# dtype, +# col_buffer, +# row_index, +# &is_null, +# &symbol) +# if not is_null: +# if not line_sender_buffer_symbol(impl, col_name, symbol, &err): +# raise c_err_to_py(err) +# return True + + +# cdef bint _pandas_row_at( +# line_sender_buffer* impl, +# dtype_t* dtypes, +# Py_buffer* col_buffers, +# size_t row_index, +# ssize_t at_col, +# int64_t at_value) except False: +# cdef line_sender_error* err = NULL +# cdef Py_buffer* col_buffer +# cdef dtype_t* dtype +# if at_col >= 0: +# col_buffer = &col_buffers[at_col] +# dtype = &dtypes[at_col] +# at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) +# if at_value > 0: +# if not line_sender_buffer_at(impl, at_value, &err): +# raise c_err_to_py(err) +# else: +# if not line_sender_buffer_at_now(impl, &err): +# raise c_err_to_py(err) +# return True cdef int _pandas_series_as_pybuf( @@ -735,98 +786,172 @@ cdef bint _pandas_series_as_arrow( array = chunks[chunk_index] if chunk_index == 0: chunks[chunk_index]._export_to_c( - &col_out.chunks.chunks[chunk_index], - &col_out.arrow_schema) + &col_out.chunks.chunks[chunk_index], + &col_out.arrow_schema) else: chunks[chunk_index]._export_to_c( - &col_out.chunks.chunks[chunk_index]) + &col_out.chunks.chunks[chunk_index]) return True +cdef const char* _ARROW_INT8_FMT = "c" +cdef const char* _ARROW_INT16_FMT = "s" +cdef const char* _ARROW_INT32_FMT = "i" +cdef const char* _ARROW_INT64_FMT = "l" + + cdef bint _pandas_category_series_as_arrow( TaggedEntry entry, col_t* col_out) except False: - col_out.source = 0 # place holder value - _pandas_series_as_arrow(entry, col_out, col_source_t.str_pyobj) - if col_out.source == col_source_t.str_pyobj: - return True - + cdef const char* format + col_out.source = col_source_t.col_source_nulls # placeholder, maybe overwritten below. + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_str_pyobj) + if col_out.source == col_source_t.col_source_str_pyobj: + return True # PyArrow not imported. + format = col_out.arrow_schema.format + if strncmp(format, _ARROW_INT8_FMT, 1) == 0: + col_out.source = col_source_t.col_source_str_i8_cat + elif strncmp(format, _ARROW_INT16_FMT, 1) == 0: + col_out.source = col_source_t.col_source_str_i16_cat + elif strncmp(format, _ARROW_INT32_FMT, 1) == 0: + col_out.source = col_source_t.col_source_str_i32_cat + elif strncmp(format, _ARROW_INT64_FMT, 1) == 0: + col_out.source = col_source_t.col_source_str_i64_cat + else: + raise TypeError( + f'Bad column {entry.name!r}: Expected an arrow category index ' + + f'format, got {(format).decode("utf-8")!r}') + return True + + +cdef inline bint _pandas_is_null_pyobj(object obj): + return (obj is None) or (obj is _PANDAS_NA) + + +cdef bint _pandas_series_sniff_pyobj( + TaggedEntry entry, col_t* col_out) except False: + """ + Deduct the type of the object column. + Object columns can contain pretty much anything, but they usually don't. + We make an educated guess by finding the first non-null value in the column. + """ + cdef object obj + cdef size_t el_index + cdef size_t n_elements = len(entry.series) + _pandas_series_as_pybuf(entry, col_out) + # cdef int _pandas_series_as_pybuf( + # TaggedEntry entry, col_t* col_out) except -1: + # cdef object nparr = entry.series.to_numpy() + # if not PyObject_CheckBuffer(nparr): + # raise TypeError( + # f'Bad column {entry.name!r}: Expected a buffer, got ' + + # f'{entry.series!r} ({type(entry.series)!r})') + # col_out.tag = col_access_tag_t.numpy + # return PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_STRIDES) + for el_index in range(n_elements): + # TODO: Check there's no pointless INCREF/DECREF going on here. + obj = _pandas_col_get_el(col_out, el_index) + if _pandas_is_null_pyobj(obj): + continue + elif isinstance(obj, bool): + col_out.source = col_source_t.col_source_bool_pyobj + elif isinstance(obj, int): + col_out.source = col_source_t.col_source_int_pyobj + elif isinstance(obj, float): + col_out.source = col_source_t.col_source_float_pyobj + elif isinstance(obj, str): + col_out.source = col_source_t.col_source_str_pyobj + elif isinstance(obj, bytes): + raise ValueError( + f'Bad column {entry.name!r}: ' + + 'Unsupported object column containing bytes.' + + 'If this is a string column, decode it first. ' + + 'See: https://stackoverflow.com/questions/40389764/') + else: + raise TypeError( + f'Bad column {entry.name!r}: ' + + f'Unsupported object column containing an {type(obj)!r}') + # We've hit an object column that exclusively has null values. + # We will just skip this column. + col_out.source = col_source_t.col_source_nulls + + cdef bint _pandas_resolve_source_and_buffers( TaggedEntry entry, col_t* col_out) except False: cdef object dtype = entry.dtype if isinstance(dtype, _PANDAS.dtype('bool')): - col_out.source = col_source_t.bool_numpy + col_out.source = col_source_t.col_source_bool_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.BooleanDtype): - col_out.source = col_source_t.bool_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.bool_pyobj) + col_out.source = col_source_t.col_source_bool_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_bool_pyobj) elif isinstance(dtype, _NUMPY.dtype('uint8')): - col_out.source = col_source_t.u8_numpy + col_out.source = col_source_t.col_source_u8_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('int8')): - col_out.source = col_source_t.i8_numpy + col_out.source = col_source_t.col_source_i8_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('uint16')): - col_out.source = col_source_t.u16_numpy + col_out.source = col_source_t.col_source_u16_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('int16')): - col_out.source = col_source_t.i16_numpy + col_out.source = col_source_t.col_source_i16_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('uint32')): - col_out.source = col_source_t.u32_numpy + col_out.source = col_source_t.col_source_u32_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('int32')): - col_out.source = col_source_t.i32_numpy + col_out.source = col_source_t.col_source_i32_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('uint64')): - col_out.source = col_source_t.u64_numpy + col_out.source = col_source_t.col_source_u64_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('int64')): - col_out.source = col_source_t.i64_numpy + col_out.source = col_source_t.col_source_i64_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.UInt8Dtype): - col_out.source = col_source_t.u8_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_u8_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int8Dtype): - col_out.source = col_source_t.i8_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_i8_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt16Dtype): - col_out.source = col_source_t.u16_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_u16_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int16Dtype): - col_out.source = col_source_t.i16_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_i16_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt32Dtype): - col_out.source = col_source_t.u32_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_u32_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int32Dtype): - col_out.source = col_source_t.i32_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_i32_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt64Dtype): - col_out.source = col_source_t.u64_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_u64_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int64Dtype): - col_out.source = col_source_t.i64_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.int_pyobj) + col_out.source = col_source_t.col_source_i64_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _NUMPY.dtype('float32')): - col_out.source = col_source_t.f32_numpy + col_out.source = col_source_t.col_source_f32_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('float64')): - col_out.source = col_source_t.f64_numpy + col_out.source = col_source_t.col_source_f64_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.Float32Dtype): - col_out.source = col_source_t.f32_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.float_pyobj) + col_out.source = col_source_t.col_source_f32_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_float_pyobj) elif isinstance(dtype, _PANDAS.Float64Dtype): - col_out.source = col_source_t.f64_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.float_pyobj) + col_out.source = col_source_t.col_source_f64_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_float_pyobj) elif isinstance(dtype, _PANDAS.StringDtype): if dtype.storage == 'pyarrow': - col_out.source = col_source_t.str_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.str_pyobj) + col_out.source = col_source_t.col_source_str_arrow + _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_str_pyobj) elif dtype.storage == 'python': - col_out.source = col_source_t.str_pyobj + col_out.source = col_source_t.col_source_str_pyobj _pandas_series_as_pybuf(entry, col_out) else: raise ValueError( @@ -835,24 +960,36 @@ cdef bint _pandas_resolve_source_and_buffers( elif isinstance(dtype, _PANDAS.CategoricalDtype): _pandas_category_series_as_arrow(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('datetime64[ns]')): - col_out.source = col_source_t.dt64ns_numpy + col_out.source = col_source_t.col_source_dt64ns_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.DatetimeTZDtype): - col_out.source = col_source_t.dt64ns_tz_numpy - col_out.tz_offset_ns = _pandas_get_tz_offset_ns(dtype.tz) + col_out.source = col_source_t.col_source_dt64ns_tz_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY.dtype('object')): - # We need to sniff the objects - # TODO: bool_pyobj, int_pyobj, str_pyobj - - - - raise ValueError('nyi') # TODO [amunra]: Implement and test. + _pandas_series_sniff_pyobj(entry, col_out) + else: + raise ValueError( + f'Unsupported dtype {dtype} for column {entry.name}. ' + + 'Raise an issue if you think it should be supported: ' + + 'https://github.com/questdb/py-questdb-client/issues.') + return True -cdef int _pandas_resolve_target( - TaggedEntry entry, col_source_t source) except -1: - raise ValueError('nyi') +cdef bint _pandas_resolve_target( + TaggedEntry entry, col_t* col_out) except False: + cdef col_target_t target + cdef set target_sources + if entry.meta_target in _DIRECT_META_TARGETS: + col_out.target = entry.meta_target + return True + for target in _FIELD_TARGETS: + target_sources = _FIELD_TARGETS[target] + if col_out.source in target_sources: + col_out.target = target + return True + raise ValueError( + f'Could not map column source type (code {col_out.source} for ' + + f'{entry.dtype!r}) {entry.name}.') cdef bint _pandas_resolve_col( @@ -864,12 +1001,12 @@ cdef bint _pandas_resolve_col( # Since we don't need to send the column names for 'table' and 'at' columns, # we don't need to validate and encode them as column names. - if ((entry.meta_target != _META_TARGET_TABLE_NAME) and - (entry.meta_target != _META_TARGET_AT)): + if ((entry.meta_target != meta_target_t.meta_target_table) and + (entry.meta_target != meta_target_t.meta_target_at)): str_to_column_name(b, entry.name, &col_out.name) _pandas_resolve_source_and_buffers(entry, col_out) - col_out.target = _pandas_resolve_target(entry, col_out.source) + _pandas_resolve_target(entry, col_out) if col_out.source not in _TARGET_TO_SOURCE[col_out.target]: raise ValueError( f'Bad value: Column {entry.name!r} ({entry.dtype}) is not ' + @@ -906,13 +1043,18 @@ cdef bint _pandas_resolve_args( TaggedEntry( index, name, - data.dtypes[index] + data.dtypes[index], series, - _META_TARGET_FIELD) # FIELD is a `bool`, `f64`, `string` or `ts`. + meta_target_t.meta_target_field) # Later resolved to one of column_* targets. for index, (name, series) in data.items()] name_col = _pandas_resolve_table_name( b, - data, tagged_cols, table_name, table_name_col, col_count, c_table_name_out) + data, + tagged_cols, + table_name, + table_name_col, + col_count, + c_table_name_out) at_col = _pandas_resolve_at(data, tagged_cols, at, col_count, at_value_out) _pandas_resolve_symbols( data, tagged_cols, name_col, at_col, symbols, col_count) From e9890a63fe7c672fe6cc999f2af5c6bfd2b0155c Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 21 Nov 2022 16:54:45 +0000 Subject: [PATCH 051/147] Code builds again finally. --- src/questdb/column_name_vec.pxi | 36 ---------- src/questdb/ingress.pyx | 2 +- src/questdb/pandas_integration.md | 75 +++++++++++++++++++++ src/questdb/pandas_integration.pxi | 101 ++++++++++++++++++----------- src/questdb/size_t_vec.pxi | 35 ---------- 5 files changed, 139 insertions(+), 110 deletions(-) delete mode 100644 src/questdb/column_name_vec.pxi delete mode 100644 src/questdb/size_t_vec.pxi diff --git a/src/questdb/column_name_vec.pxi b/src/questdb/column_name_vec.pxi deleted file mode 100644 index 8ea920a6..00000000 --- a/src/questdb/column_name_vec.pxi +++ /dev/null @@ -1,36 +0,0 @@ -cdef struct c_column_name_vec: - size_t capacity - size_t size - line_sender_column_name* d - -ctypedef c_column_name_vec column_name_vec - -cdef column_name_vec column_name_vec_new(): - cdef column_name_vec vec - vec.capacity = 0 - vec.size = 0 - vec.d = NULL - return vec - -cdef void column_name_vec_free(column_name_vec* vec): - if vec.d: - free(vec.d) - vec.d = NULL - -cdef void column_name_vec_push( - column_name_vec* vec, line_sender_column_name value): - if vec.capacity == 0: - vec.capacity = 8 - vec.d = malloc( - vec.capacity * sizeof(line_sender_column_name)) - if vec.d == NULL: - abort() - elif vec.size == vec.capacity: - vec.capacity = vec.capacity * 2 - vec.d = realloc( - vec.d, - vec.capacity * sizeof(line_sender_column_name)) - if not vec.d: - abort() - vec.d[vec.size] = value - vec.size += 1 diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 38a56821..b5ccbb2a 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -42,7 +42,7 @@ from cpython.float cimport PyFloat_Check from cpython.int cimport PyInt_Check from cpython.unicode cimport PyUnicode_Check from cpython.buffer cimport Py_buffer, PyObject_CheckBuffer, \ - PyObject_GetBuffer, PyBuffer_Release, PyBUF_READ, PyBUF_STRIDES + PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE from cpython.memoryview cimport PyMemoryView_FromMemory from .line_sender cimport * diff --git a/src/questdb/pandas_integration.md b/src/questdb/pandas_integration.md index fa985f7b..e2cc2b16 100644 --- a/src/questdb/pandas_integration.md +++ b/src/questdb/pandas_integration.md @@ -581,6 +581,81 @@ timezone), so no timezone conversion logic is required here. **Note**: We don't need PyArrow to access the buffer as it's only used here to show raw data. + +## Strided Numpy Arrays + +Numpy arrays need not be contiguous. In Pandas, however, we +need not worry about this. + +If we construct a `(4, 3)`-shaped 2D numpy array + +```python +>>> import numpy as np +>>> a1 = np.array([[1, 10, 100], [2, 20, 200], [3, 30, 300], [4, 40, 400]]) +>>> a1 +array([[ 1, 10, 100], + [ 2, 20, 200], + [ 3, 30, 300], + [ 4, 40, 400]]) +>>> a1.dtype +dtype('int64') +``` + +and then select it's second column + +```python +>>> a2 = a1[:, 1] +>>> a2 +array([10, 20, 30, 40]) +``` + +We encounter a non-contiguous array. + +```python +>>> a2.data + +>>> a2.data.contiguous +False +>>> a2.data.strides +(24,) +``` + +If we then wrap up the array in a dataframe and convert the series back to numpy + +```python +>>> df = pd.DataFrame({'a': a2}) +>>> df + a +0 10 +1 20 +2 30 +3 40 +>>> df.a +0 10 +1 20 +2 30 +3 40 +Name: a, dtype: int64 +>>> a3 = df.a.to_numpy() +``` + +We see that we get a new object back, and that the new object actually _is_ +contiguous. + +```python +>>> id(a2) +140389455034672 +>>> id(a3) +140388032511696 +>>> a3.data + +>>> a3.data.contiguous +True +``` + +For this reason, supporting strides is not necessary. + + ## Unified Cursor TO BE CONTINUED diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 2707a907..6709bbc3 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1,6 +1,3 @@ -include "size_t_vec.pxi" -include "column_name_vec.pxi" - # See: pandas_integration.md for technical overview. # cdef struct dtype_t: @@ -741,21 +738,59 @@ cdef object _pandas_is_supported_datetime(object dtype): # return True -cdef int _pandas_series_as_pybuf( - TaggedEntry entry, col_t* col_out) except -1: +cdef bint _pandas_alloc_chunks(size_t n_chunks, col_t* col_out) except False: + col_out.chunks.n_chunks = n_chunks + col_out.chunks.chunks = calloc( + col_out.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. + sizeof(ArrowArray)) + + +cdef void _pandas_free_mapped_arrow(ArrowArray* arr): + free(arr.buffers) + arr.buffers = NULL + arr.release = NULL + + +cdef bint _pandas_series_as_pybuf( + TaggedEntry entry, col_t* col_out) except False: cdef object nparr = entry.series.to_numpy() + cdef ArrowArray* mapped if not PyObject_CheckBuffer(nparr): raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + f'{entry.series!r} ({type(entry.series)!r})') col_out.tag = col_access_tag_t.numpy - return PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_STRIDES) - # TODO: Wrap exception from `PyObject_GetBuffer` informatively. - # Then change to `except False` and `bint` return type. - # Then manually map the `pybuf` to the arrow `col.chunks` even if we're - # not using arrow. This allows is to give us a single consistent iterating - # device. - # TODO: Set stride. + + try: + # Note! We don't need to support numpy strides since Pandas doesn't. + PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_SIMPLE) + except BufferError as be: + raise TypeError( + f'Bad column {entry.name!r}: Expected a buffer, got ' + + f'{entry.series!r} ({type(entry.series)!r})') from be + + if col_out.pybuf.ndim != 1: + raise ValueError( + f'Bad column {entry.name!r}: Expected a 1D column, ' + + f'got a {col_out.pybuf.ndim}D column.') + + _pandas_alloc_chunks(1, col_out) + mapped = &col_out.chunks.chunks[0] + + # Total number of elements. + mapped.length = ( + col_out.pybuf.len // col_out.pybuf.itemsize) + mapped.null_count = 0 + mapped.offset = 0 + mapped.n_buffers = 2 + mapped.n_children = 0 + mapped.buffers = calloc(2, sizeof(const void*)) + mapped.buffers[0] = NULL + mapped.buffers[1] = col_out.pybuf.buf + mapped.children = NULL + mapped.dictionary = NULL + mapped.release = _pandas_free_mapped_arrow # to cleanup allocated array. + return True cdef bint _pandas_series_as_arrow( @@ -764,6 +799,7 @@ cdef bint _pandas_series_as_arrow( col_source_t np_fallback) except False: cdef object array cdef list chunks + cdef size_t n_chunks cdef size_t chunk_index if _PYARROW is None: col_out.source = np_fallback @@ -777,12 +813,10 @@ cdef bint _pandas_series_as_arrow( else: chunks = [array] - col_out.chunks.n_chunks = len(chunks) - col_out.chunks.chunks = calloc( - col_out.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. - sizeof(ArrowArray)) + n_chunks = len(chunks) + _pandas_alloc_chunks(n_chunks, col_out) - for chunk_index in range(len(chunks)): + for chunk_index in range(n_chunks): array = chunks[chunk_index] if chunk_index == 0: chunks[chunk_index]._export_to_c( @@ -794,10 +828,10 @@ cdef bint _pandas_series_as_arrow( return True -cdef const char* _ARROW_INT8_FMT = "c" -cdef const char* _ARROW_INT16_FMT = "s" -cdef const char* _ARROW_INT32_FMT = "i" -cdef const char* _ARROW_INT64_FMT = "l" +cdef const char* _ARROW_FMT_INT8 = "c" +cdef const char* _ARROW_FMT_INT16 = "s" +cdef const char* _ARROW_FMT_INT32 = "i" +cdef const char* _ARROW_FMT_INT64 = "l" cdef bint _pandas_category_series_as_arrow( @@ -808,13 +842,13 @@ cdef bint _pandas_category_series_as_arrow( if col_out.source == col_source_t.col_source_str_pyobj: return True # PyArrow not imported. format = col_out.arrow_schema.format - if strncmp(format, _ARROW_INT8_FMT, 1) == 0: + if strncmp(format, _ARROW_FMT_INT8, 1) == 0: col_out.source = col_source_t.col_source_str_i8_cat - elif strncmp(format, _ARROW_INT16_FMT, 1) == 0: + elif strncmp(format, _ARROW_FMT_INT16, 1) == 0: col_out.source = col_source_t.col_source_str_i16_cat - elif strncmp(format, _ARROW_INT32_FMT, 1) == 0: + elif strncmp(format, _ARROW_FMT_INT32, 1) == 0: col_out.source = col_source_t.col_source_str_i32_cat - elif strncmp(format, _ARROW_INT64_FMT, 1) == 0: + elif strncmp(format, _ARROW_FMT_INT64, 1) == 0: col_out.source = col_source_t.col_source_str_i64_cat else: raise TypeError( @@ -838,18 +872,9 @@ cdef bint _pandas_series_sniff_pyobj( cdef size_t el_index cdef size_t n_elements = len(entry.series) _pandas_series_as_pybuf(entry, col_out) - # cdef int _pandas_series_as_pybuf( - # TaggedEntry entry, col_t* col_out) except -1: - # cdef object nparr = entry.series.to_numpy() - # if not PyObject_CheckBuffer(nparr): - # raise TypeError( - # f'Bad column {entry.name!r}: Expected a buffer, got ' + - # f'{entry.series!r} ({type(entry.series)!r})') - # col_out.tag = col_access_tag_t.numpy - # return PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_STRIDES) for el_index in range(n_elements): # TODO: Check there's no pointless INCREF/DECREF going on here. - obj = _pandas_col_get_el(col_out, el_index) + obj = &((col_out.pybuf.buf))[el_index] if _pandas_is_null_pyobj(obj): continue elif isinstance(obj, bool): @@ -1016,11 +1041,11 @@ cdef bint _pandas_resolve_col( cdef bint _pandas_resolve_cols( - qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except False: + qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except False: # TODO: Remove `col_t_arr*` type. cdef size_t index - for index in range(len(tagged_cols)): + cdef size_t len_tagged_cols = len(tagged_cols) + for index in range(len_tagged_cols): _pandas_resolve_col(b, index, tagged_cols[index], &cols_out.d[index]) - cols_out.size += 1 return True diff --git a/src/questdb/size_t_vec.pxi b/src/questdb/size_t_vec.pxi deleted file mode 100644 index 6a53a646..00000000 --- a/src/questdb/size_t_vec.pxi +++ /dev/null @@ -1,35 +0,0 @@ -cdef struct c_size_t_vec: - size_t capacity - size_t size - size_t* d - -ctypedef c_size_t_vec size_t_vec - -cdef size_t_vec size_t_vec_new(): - cdef size_t_vec vec - vec.capacity = 0 - vec.size = 0 - vec.d = NULL - return vec - -cdef void size_t_vec_free(size_t_vec* vec): - if vec.d: - free(vec.d) - vec.d = NULL - -cdef str size_t_vec_str(size_t_vec* vec): - return 'size_t_vec' + str([vec.d[i] for i in range(vec.size)]) - -cdef void size_t_vec_push(size_t_vec* vec, size_t value): - if vec.capacity == 0: - vec.capacity = 8 - vec.d = malloc(vec.capacity * sizeof(size_t)) - if vec.d == NULL: - abort() - elif vec.size == vec.capacity: - vec.capacity = vec.capacity * 2 - vec.d = realloc(vec.d, vec.capacity * sizeof(size_t)) - if not vec.d: - abort() - vec.d[vec.size] = value - vec.size += 1 From 7e752608c81c66725bbcaf555eff9441f2cbbb62 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 21 Nov 2022 17:13:37 +0000 Subject: [PATCH 052/147] Dead code removal. --- src/questdb/ingress.pyx | 3 +- src/questdb/pandas_integration.pxi | 124 ++++------------------------- 2 files changed, 16 insertions(+), 111 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index b5ccbb2a..55d4d0bf 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -34,11 +34,12 @@ API for fast data ingestion into QuestDB. from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t from libc.stdlib cimport malloc, calloc, realloc, free, abort from libc.string import strncmp +from libc.math cimport isnan from cpython.datetime cimport datetime from cpython.bool cimport bool, PyBool_Check from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject from cpython.object cimport PyObject -from cpython.float cimport PyFloat_Check +from cpython.float cimport PyFloat_Check, PyFloat_CheckExact, PyFloat_AS_DOUBLE from cpython.int cimport PyInt_Check from cpython.unicode cimport PyUnicode_Check from cpython.buffer cimport Py_buffer, PyObject_CheckBuffer, \ diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 6709bbc3..dcfa14de 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -199,35 +199,33 @@ cdef void col_t_release(col_t* col): pass +# Calloc'd array of col_t. cdef struct col_t_arr: - size_t capacity - size_t size # Number of elements we've populated. Needed for cleanup. + size_t size col_t* d cdef col_t_arr col_t_arr_blank(): cdef col_t_arr arr - arr.capacity = 0 arr.size = 0 arr.d = NULL return arr -cdef col_t_arr col_t_arr_new(size_t capacity): +cdef col_t_arr col_t_arr_new(size_t size): cdef col_t_arr arr - arr.capacity = capacity - arr.size = 0 - arr.d = calloc(capacity, sizeof(col_t)) + arr.size = size + arr.d = calloc(size, sizeof(col_t)) return arr cdef void col_t_arr_release(col_t_arr* arr): + cdef size_t index if arr.d: - for i in range(arr.size): - col_t_release(&arr.d[i]) + for index in range(arr.size): + col_t_release(&arr.d[index]) free(arr.d) arr.size = 0 - arr.capacity = 0 arr.d = NULL @@ -538,104 +536,6 @@ cdef object _pandas_is_supported_datetime(object dtype): (not dtype.hasobject)) -# cdef char _str_to_char(str field, str s) except 0: -# cdef int res -# if len(s) != 1: -# raise ValueError( -# f'dtype.{field}: Expected a single character, got {s!r}') -# res = ord(s) -# if res <= 0 or res > 127: # Check if ASCII, excluding the nul-termintor. -# raise ValueError( -# f'dtype.{field}: Character out of ASCII range, got {s!r}') -# return res - - -# cdef bint _pandas_parse_dtype(object np_dtype, dtype_t* dtype_out) except False: -# """ -# Parse a numpy dtype and return a dtype_t. -# """ -# dtype_out.alignment = getattr(np_dtype, 'alignment' , 0) -# dtype_out.kind = _str_to_char('kind', np_dtype.kind) -# dtype_out.itemsize = getattr(np_dtype, 'itemsize', 0) -# dtype_out.byteorder = _str_to_char( -# 'byteorder', getattr(np_dtype, 'byteorder', '=')) -# dtype_out.hasobject = getattr(np_dtype, 'hasobject', False) -# return True - - -# cdef bint _pandas_resolve_dtypes( -# object data, size_t col_count, dtype_t* dtypes_out) except False: -# cdef size_t col_index -# for col_index in range(col_count): -# _pandas_parse_dtype(data.dtypes[col_index], &dtypes_out[col_index]) -# return True - - -# cdef bint _pandas_resolve_col_buffers( -# object data, size_t col_count, const dtype_t* dtypes, -# Py_buffer* col_buffers, size_t* set_buf_count) except False: -# """ -# Map pandas columns to array of col_buffers. -# """ -# # Note: By calling "to_numpy" we are throwing away what might be an Arrow. -# # This is particularly expensive for string columns. -# # If you want to use Arrow (i.e. your data comes from Parquet) please ask -# # for the feature in our issue tracker. -# cdef size_t col_index -# cdef object nparr -# cdef Py_buffer* view -# cdef const dtype_t* dtype -# for col_index in range(col_count): -# nparr = data.iloc[:, col_index].to_numpy() -# view = &col_buffers[col_index] -# dtype = &dtypes[col_index] -# if not PyObject_CheckBuffer(nparr): -# raise TypeError( -# f'Bad column: Expected a numpy array, got {nparr!r}') -# PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) -# # TODO [amunra]: We should check that the buffer metadata and the dtype match. We currently risk a segfault. -# set_buf_count[0] += 1 # Set to avoid wrongly calling PyBuffer_Release. -# return True - - -# cdef inline const void* _pandas_get_cell( -# Py_buffer* col_buffer, size_t row_index): -# return col_buffer.buf + (row_index * col_buffer.strides[0]) - - -# cdef char _PANDAS_DTYPE_KIND_OBJECT = 79 # 'O' -# cdef char _PANDAS_DTYPE_KIND_DATETIME = 77 # 'M' - - -# cdef bint _pandas_get_str_cell( -# qdb_pystr_buf* b, -# dtype_t* dtype, -# Py_buffer* col_buffer, -# size_t row_index, -# bint* is_null_out, -# line_sender_utf8* utf8_out) except False: -# cdef const void* cell = _pandas_get_cell(col_buffer, row_index) -# cdef object obj -# if dtype.kind == _PANDAS_DTYPE_KIND_OBJECT: -# # TODO [amunra]: Check in the generated .C code that it doesn't produce an INCREF. -# # TODO: Improve error messaging. Error message should include the column name. -# obj = ((cell)[0]) -# if (obj is None) or (obj is _PANDAS_NA): -# is_null_out[0] = True -# else: -# is_null_out[0] = False -# try: -# str_to_utf8(b, obj, utf8_out) -# except TypeError as e: -# raise TypeError( -# 'Bad column: Expected a string, ' + -# f'got {obj!r} ({type(obj)!r})') from e -# else: -# raise TypeError( -# f'NOT YET IMPLEMENTED. Kind: {dtype.kind}') # TODO [amunra]: Implement and test. -# return True - - # cdef int64_t _pandas_get_timestamp_cell( # dtype_t* dtype, # Py_buffer* col_buffer, @@ -857,8 +757,12 @@ cdef bint _pandas_category_series_as_arrow( return True +cdef inline bint _pandas_is_float_nan(obj): + return PyFloat_CheckExact(obj) and isnan(PyFloat_AS_DOUBLE(obj)) + + cdef inline bint _pandas_is_null_pyobj(object obj): - return (obj is None) or (obj is _PANDAS_NA) + return (obj is None) or (obj is _PANDAS_NA) or _pandas_is_float_nan(obj) cdef bint _pandas_series_sniff_pyobj( @@ -1041,7 +945,7 @@ cdef bint _pandas_resolve_col( cdef bint _pandas_resolve_cols( - qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except False: # TODO: Remove `col_t_arr*` type. + qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except False: cdef size_t index cdef size_t len_tagged_cols = len(tagged_cols) for index in range(len_tagged_cols): From 0e6748067a346e0090b60fffb4056062bb3a9509 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 21 Nov 2022 18:11:03 +0000 Subject: [PATCH 053/147] Types to dispatch codes to functions. --- src/questdb/pandas_integration.pxi | 637 +++++++++++++++++++++++++++-- 1 file changed, 606 insertions(+), 31 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index dcfa14de..1d094024 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -178,6 +178,113 @@ cdef set _DIRECT_META_TARGETS = { } +# This is verbose, but.. +# * Enums give us constants. +# * Constants allow unfolding `if` statements into `switch` +# * Switch statements can be more heavily optimized by the C compiler. +cdef enum col_dispatch_code_t: + col_dispatch_code_skip_nulls = \ + col_target_t.col_target_skip + col_source_t.col_source_nulls + + col_dispatch_code_table__str_pyobj = \ + col_target_t.col_target_table + col_source_t.col_source_str_pyobj + col_dispatch_code_table__str_arrow = \ + col_target_t.col_target_table + col_source_t.col_source_str_arrow + col_dispatch_code_table__str_i8_cat = \ + col_target_t.col_target_table + col_source_t.col_source_str_i8_cat + col_dispatch_code_table__str_i16_cat = \ + col_target_t.col_target_table + col_source_t.col_source_str_i16_cat + col_dispatch_code_table__str_i32_cat = \ + col_target_t.col_target_table + col_source_t.col_source_str_i32_cat + col_dispatch_code_table__str_i64_cat = \ + col_target_t.col_target_table + col_source_t.col_source_str_i64_cat + + col_dispatch_code_symbol__str_pyobj = \ + col_target_t.col_target_symbol + col_source_t.col_source_str_pyobj + col_dispatch_code_symbol__str_arrow = \ + col_target_t.col_target_symbol + col_source_t.col_source_str_arrow + col_dispatch_code_symbol__str_i8_cat = \ + col_target_t.col_target_symbol + col_source_t.col_source_str_i8_cat + col_dispatch_code_symbol__str_i16_cat = \ + col_target_t.col_target_symbol + col_source_t.col_source_str_i16_cat + col_dispatch_code_symbol__str_i32_cat = \ + col_target_t.col_target_symbol + col_source_t.col_source_str_i32_cat + col_dispatch_code_symbol__str_i64_cat = \ + col_target_t.col_target_symbol + col_source_t.col_source_str_i64_cat + + col_dispatch_code_column_bool__bool_pyobj = \ + col_target_t.col_target_column_bool + col_source_t.col_source_bool_pyobj + col_dispatch_code_column_bool__bool_numpy = \ + col_target_t.col_target_column_bool + col_source_t.col_source_bool_numpy + col_dispatch_code_column_bool__bool_arrow = \ + col_target_t.col_target_column_bool + col_source_t.col_source_bool_arrow + + col_dispatch_code_column_i64__int_pyobj = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_int_pyobj + col_dispatch_code_column_i64__u8_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u8_numpy + col_dispatch_code_column_i64__i8_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i8_numpy + col_dispatch_code_column_i64__u16_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u16_numpy + col_dispatch_code_column_i64__i16_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i16_numpy + col_dispatch_code_column_i64__u32_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u32_numpy + col_dispatch_code_column_i64__i32_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i32_numpy + col_dispatch_code_column_i64__u64_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u64_numpy + col_dispatch_code_column_i64__i64_numpy = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i64_numpy + col_dispatch_code_column_i64__u8_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u8_arrow + col_dispatch_code_column_i64__i8_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i8_arrow + col_dispatch_code_column_i64__u16_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u16_arrow + col_dispatch_code_column_i64__i16_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i16_arrow + col_dispatch_code_column_i64__u32_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u32_arrow + col_dispatch_code_column_i64__i32_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i32_arrow + col_dispatch_code_column_i64__u64_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_u64_arrow + col_dispatch_code_column_i64__i64_arrow = \ + col_target_t.col_target_column_i64 + col_source_t.col_source_i64_arrow + + col_dispatch_code_column_f64__float_pyobj = \ + col_target_t.col_target_column_f64 + col_source_t.col_source_float_pyobj + col_dispatch_code_column_f64__f32_numpy = \ + col_target_t.col_target_column_f64 + col_source_t.col_source_f32_numpy + col_dispatch_code_column_f64__f64_numpy = \ + col_target_t.col_target_column_f64 + col_source_t.col_source_f64_numpy + col_dispatch_code_column_f64__f32_arrow = \ + col_target_t.col_target_column_f64 + col_source_t.col_source_f32_arrow + col_dispatch_code_column_f64__f64_arrow = \ + col_target_t.col_target_column_f64 + col_source_t.col_source_f64_arrow + + col_dispatch_code_column_str__str_pyobj = \ + col_target_t.col_target_column_str + col_source_t.col_source_str_pyobj + col_dispatch_code_column_str__str_arrow = \ + col_target_t.col_target_column_str + col_source_t.col_source_str_arrow + col_dispatch_code_column_str__str_i8_cat = \ + col_target_t.col_target_column_str + col_source_t.col_source_str_i8_cat + col_dispatch_code_column_str__str_i16_cat = \ + col_target_t.col_target_column_str + col_source_t.col_source_str_i16_cat + col_dispatch_code_column_str__str_i32_cat = \ + col_target_t.col_target_column_str + col_source_t.col_source_str_i32_cat + col_dispatch_code_column_str__str_i64_cat = \ + col_target_t.col_target_column_str + col_source_t.col_source_str_i64_cat + + col_dispatch_code_column_ts__dt64ns_numpy = \ + col_target_t.col_target_column_ts + col_source_t.col_source_dt64ns_numpy + col_dispatch_code_column_ts__dt64ns_tz_numpy = \ + col_target_t.col_target_column_ts + \ + col_source_t.col_source_dt64ns_tz_numpy + + cdef struct col_t: size_t orig_index line_sender_column_name name @@ -188,7 +295,7 @@ cdef struct col_t: col_cursor_t cursor col_source_t source col_target_t target - int dispatch_code # source + target. Determines cell encoder function. + col_dispatch_code_t dispatch_code # source + target. Determines serializer. cdef void col_t_release(col_t* col): @@ -436,7 +543,8 @@ cdef bint _pandas_resolve_symbols( elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): - tagged_cols[col_index].meta_target = meta_target_t.meta_target_symbol + tagged_cols[col_index].meta_target = \ + meta_target_t.meta_target_symbol return True else: if not isinstance(symbols, (tuple, list)): @@ -465,7 +573,8 @@ cdef bint _pandas_resolve_symbols( col_index, 'Bad element in argument `symbols`: ', symbol) - tagged_cols[col_index].meta_target = meta_target_t.meta_target_symbol + tagged_cols[col_index].meta_target = \ + meta_target_t.meta_target_symbol return True @@ -737,10 +846,10 @@ cdef const char* _ARROW_FMT_INT64 = "l" cdef bint _pandas_category_series_as_arrow( TaggedEntry entry, col_t* col_out) except False: cdef const char* format - col_out.source = col_source_t.col_source_nulls # placeholder, maybe overwritten below. + col_out.source = col_source_t.col_source_nulls # placeholder value. _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_str_pyobj) if col_out.source == col_source_t.col_source_str_pyobj: - return True # PyArrow not imported. + return True # PyArrow wasn't imported. format = col_out.arrow_schema.format if strncmp(format, _ARROW_FMT_INT8, 1) == 0: col_out.source = col_source_t.col_source_str_i8_cat @@ -814,7 +923,8 @@ cdef bint _pandas_resolve_source_and_buffers( _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.BooleanDtype): col_out.source = col_source_t.col_source_bool_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_bool_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_bool_pyobj) elif isinstance(dtype, _NUMPY.dtype('uint8')): col_out.source = col_source_t.col_source_u8_numpy _pandas_series_as_pybuf(entry, col_out) @@ -841,44 +951,57 @@ cdef bint _pandas_resolve_source_and_buffers( _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.UInt8Dtype): col_out.source = col_source_t.col_source_u8_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int8Dtype): col_out.source = col_source_t.col_source_i8_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt16Dtype): col_out.source = col_source_t.col_source_u16_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int16Dtype): col_out.source = col_source_t.col_source_i16_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt32Dtype): col_out.source = col_source_t.col_source_u32_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int32Dtype): col_out.source = col_source_t.col_source_i32_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt64Dtype): col_out.source = col_source_t.col_source_u64_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int64Dtype): col_out.source = col_source_t.col_source_i64_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _NUMPY.dtype('float32')): col_out.source = col_source_t.col_source_f32_numpy - _pandas_series_as_pybuf(entry, col_out) + _pandas_series_as_pybuf( + entry, col_out) elif isinstance(dtype, _NUMPY.dtype('float64')): col_out.source = col_source_t.col_source_f64_numpy - _pandas_series_as_pybuf(entry, col_out) + _pandas_series_as_pybuf( + entry, col_out) elif isinstance(dtype, _PANDAS.Float32Dtype): col_out.source = col_source_t.col_source_f32_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_float_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_float_pyobj) elif isinstance(dtype, _PANDAS.Float64Dtype): col_out.source = col_source_t.col_source_f64_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_float_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_float_pyobj) elif isinstance(dtype, _PANDAS.StringDtype): if dtype.storage == 'pyarrow': col_out.source = col_source_t.col_source_str_arrow - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_str_pyobj) + _pandas_series_as_arrow( + entry, col_out, col_source_t.col_source_str_pyobj) elif dtype.storage == 'python': col_out.source = col_source_t.col_source_str_pyobj _pandas_series_as_pybuf(entry, col_out) @@ -921,6 +1044,12 @@ cdef bint _pandas_resolve_target( f'{entry.dtype!r}) {entry.name}.') +cdef void _pandas_init_cursor(col_t* col_out): + col_out.cursor.chunk = col_out.chunks.chunks + col_out.cursor.chunk_index = 0 + col_out.cursor.offset = col_out.cursor.chunk.offset + + cdef bint _pandas_resolve_col( qdb_pystr_buf* b, size_t index, @@ -940,7 +1069,10 @@ cdef bint _pandas_resolve_col( raise ValueError( f'Bad value: Column {entry.name!r} ({entry.dtype}) is not ' + f'supported as a {_TARGET_NAMES[col_out.target]} column.') - col_out.dispatch_code = col_out.source + col_out.target + col_out.dispatch_code = ( + col_out.source + col_out.target) + _pandas_init_cursor(col_out) + return True @@ -974,7 +1106,7 @@ cdef bint _pandas_resolve_args( name, data.dtypes[index], series, - meta_target_t.meta_target_field) # Later resolved to one of column_* targets. + meta_target_t.meta_target_field) # Later resolved to a target. for index, (name, series) in data.items()] name_col = _pandas_resolve_table_name( b, @@ -992,18 +1124,367 @@ cdef bint _pandas_resolve_args( # Note: Python 3.6+ guarantees stable sort. tagged_cols.sort(key=lambda x: x.meta_target) _pandas_resolve_cols(b, tagged_cols, cols_out) - return True - # cdef dtype_t* dtypes = NULL - # cdef size_t set_buf_count = 0 - # cdef Py_buffer* col_buffers = NULL - # dtypes = calloc(col_count, sizeof(dtype_t)) - # _pandas_resolve_dtypes(data, col_count, dtypes) - # col_buffers = calloc(col_count, sizeof(Py_buffer)) - # _pandas_resolve_col_buffers( - # data, col_count, dtypes, col_buffers, &set_buf_count) +cdef bint _pandas_serialize_cell_table__str_pyobj( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_table__str_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_table__str_i8_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_table__str_i16_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_table__str_i32_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_table__str_i64_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_symbol__str_pyobj( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_symbol__str_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_symbol__str_i8_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_symbol__str_i16_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_symbol__str_i32_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_symbol__str_i64_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_bool__bool_pyobj( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_bool__bool_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_bool__bool_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__int_pyobj( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u8_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i8_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u16_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i16_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u32_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i32_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u64_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i64_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u8_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i8_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u16_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i16_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u32_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i32_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__u64_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_i64__i64_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_f64__float_pyobj( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_f64__f32_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_f64__f64_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_f64__f32_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_f64__f64_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_str__str_pyobj( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_str__str_arrow( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_str__str_i8_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_str__str_i16_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_str__str_i32_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_str__str_i64_cat( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_ts__dt64ns_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') + + +cdef bint _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + raise ValueError('nyi') cdef bint _pandas_serialize_cell( @@ -1011,7 +1492,101 @@ cdef bint _pandas_serialize_cell( qdb_pystr_buf* b, col_t* col, size_t row_index) except False: - pass + cdef col_dispatch_code_t dc = col.dispatch_code + # TODO: Check that this `if/elif` gets compiled into a C switch statement. + if dc == col_dispatch_code_t.col_dispatch_code_skip_nulls: + pass # We skip a null column. Nothing to do. + elif dc == col_dispatch_code_t.col_dispatch_code_table__str_pyobj: + _pandas_serialize_cell_table__str_pyobj(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_table__str_arrow: + _pandas_serialize_cell_table__str_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i8_cat: + _pandas_serialize_cell_table__str_i8_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i16_cat: + _pandas_serialize_cell_table__str_i16_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i32_cat: + _pandas_serialize_cell_table__str_i32_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i64_cat: + _pandas_serialize_cell_table__str_i64_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_pyobj: + _pandas_serialize_cell_symbol__str_pyobj(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_arrow: + _pandas_serialize_cell_symbol__str_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i8_cat: + _pandas_serialize_cell_symbol__str_i8_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i16_cat: + _pandas_serialize_cell_symbol__str_i16_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i32_cat: + _pandas_serialize_cell_symbol__str_i32_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i64_cat: + _pandas_serialize_cell_symbol__str_i64_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_pyobj: + _pandas_serialize_cell_column_bool__bool_pyobj(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_numpy: + _pandas_serialize_cell_column_bool__bool_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_arrow: + _pandas_serialize_cell_column_bool__bool_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__int_pyobj: + _pandas_serialize_cell_column_i64__int_pyobj(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_numpy: + _pandas_serialize_cell_column_i64__u8_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_numpy: + _pandas_serialize_cell_column_i64__i8_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_numpy: + _pandas_serialize_cell_column_i64__u16_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_numpy: + _pandas_serialize_cell_column_i64__i16_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_numpy: + _pandas_serialize_cell_column_i64__u32_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_numpy: + _pandas_serialize_cell_column_i64__i32_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_numpy: + _pandas_serialize_cell_column_i64__u64_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_numpy: + _pandas_serialize_cell_column_i64__i64_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_arrow: + _pandas_serialize_cell_column_i64__u8_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_arrow: + _pandas_serialize_cell_column_i64__i8_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_arrow: + _pandas_serialize_cell_column_i64__u16_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_arrow: + _pandas_serialize_cell_column_i64__i16_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_arrow: + _pandas_serialize_cell_column_i64__u32_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_arrow: + _pandas_serialize_cell_column_i64__i32_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_arrow: + _pandas_serialize_cell_column_i64__u64_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_arrow: + _pandas_serialize_cell_column_i64__i64_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__float_pyobj: + _pandas_serialize_cell_column_f64__float_pyobj(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_numpy: + _pandas_serialize_cell_column_f64__f32_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_numpy: + _pandas_serialize_cell_column_f64__f64_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_arrow: + _pandas_serialize_cell_column_f64__f32_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_arrow: + _pandas_serialize_cell_column_f64__f64_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_pyobj: + _pandas_serialize_cell_column_str__str_pyobj(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_arrow: + _pandas_serialize_cell_column_str__str_arrow(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i8_cat: + _pandas_serialize_cell_column_str__str_i8_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i16_cat: + _pandas_serialize_cell_column_str__str_i16_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i32_cat: + _pandas_serialize_cell_column_str__str_i32_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i64_cat: + _pandas_serialize_cell_column_str__str_i64_cat(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_numpy: + _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_numpy: + _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( + impl, b, col, row_index) cdef void _pandas_col_advance(col_t* col): From 41d3e6b7e2bac7471b11d7ce62ea34b731626c9c Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 22 Nov 2022 12:22:27 +0000 Subject: [PATCH 054/147] Some test fixup --- src/questdb/ingress.pyx | 2 +- src/questdb/pandas_integration.pxi | 35 +++++++++++++++++++----------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 55d4d0bf..c44afa0e 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -33,7 +33,7 @@ API for fast data ingestion into QuestDB. # For prototypes: https://github.com/cython/cython/tree/master/Cython/Includes from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t from libc.stdlib cimport malloc, calloc, realloc, free, abort -from libc.string import strncmp +from libc.string cimport strncmp from libc.math cimport isnan from cpython.datetime cimport datetime from cpython.bool cimport bool, PyBool_Check diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 1d094024..edf8c952 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -369,11 +369,15 @@ cdef object _pandas_may_import_deps(): _PYARROW = None +cdef str _fqn(type obj): + return obj.__module__ + '.' + obj.__qualname__ + + cdef object _check_is_pandas_dataframe(object data): if not isinstance(data, _PANDAS.DataFrame): raise TypeError( - f'Bad argument `data`: Expected {_PANDAS.DataFrame}, ' + - f'not an object of type {type(data)}.') + f'Bad argument `data`: Expected {_fqn(_PANDAS.DataFrame)}, ' + + f'not an object of type {_fqn(type(data))}.') cdef ssize_t _pandas_resolve_table_name( @@ -399,6 +403,7 @@ cdef ssize_t _pandas_resolve_table_name( This method validates input and may raise. """ cdef size_t col_index = 0 + cdef TaggedEntry entry if table_name is not None: if table_name_col is not None: raise ValueError( @@ -426,7 +431,8 @@ cdef ssize_t _pandas_resolve_table_name( col_index, 'Bad argument `table_name_col`: ', table_name_col) - tagged_cols[col_index][3] = -2 # Sort column to front as table name. + entry = tagged_cols[col_index] + entry.meta_target = meta_target_t.meta_target_table name_out.len = 0 name_out.buf = NULL return col_index @@ -538,6 +544,7 @@ cdef bint _pandas_resolve_symbols( size_t col_count) except False: cdef size_t col_index = 0 cdef object symbol + cdef TaggedEntry entry if symbols is False: return 0 elif symbols is True: @@ -573,8 +580,8 @@ cdef bint _pandas_resolve_symbols( col_index, 'Bad element in argument `symbols`: ', symbol) - tagged_cols[col_index].meta_target = \ - meta_target_t.meta_target_symbol + entry = tagged_cols[col_index] + entry.meta_target = meta_target_t.meta_target_symbol return True @@ -606,6 +613,7 @@ cdef ssize_t _pandas_resolve_at( int64_t* at_value_out) except -2: cdef size_t col_index cdef object dtype + cdef TaggedEntry entry if at is None: at_value_out[0] = 0 # Special value for `at_now`. return -1 @@ -621,13 +629,14 @@ cdef ssize_t _pandas_resolve_at( _bind_col_index('at', at, col_count, &col_index) else: raise TypeError( - f'Bad argument `at`: Unsupported type {type(at)}. ' + + f'Bad argument `at`: Unsupported type {_fqn(type(at))}. ' + 'Must be one of: None, TimestampNanos, datetime, ' + 'int (column index), str (colum name)') dtype = data.dtypes[col_index] if _pandas_is_supported_datetime(dtype): at_value_out[0] = _AT_SET_BY_COLUMN - tagged_cols[col_index].meta_target = meta_target_t.meta_target_at + entry = tagged_cols[col_index] + entry.meta_target = meta_target_t.meta_target_at return col_index else: raise TypeError( @@ -767,7 +776,7 @@ cdef bint _pandas_series_as_pybuf( if not PyObject_CheckBuffer(nparr): raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + - f'{entry.series!r} ({type(entry.series)!r})') + f'{entry.series!r} ({_fqn(type(entry.series))})') col_out.tag = col_access_tag_t.numpy try: @@ -776,7 +785,7 @@ cdef bint _pandas_series_as_pybuf( except BufferError as be: raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + - f'{entry.series!r} ({type(entry.series)!r})') from be + f'{entry.series!r} ({_fqn(type(entry.series))})') from be if col_out.pybuf.ndim != 1: raise ValueError( @@ -907,7 +916,7 @@ cdef bint _pandas_series_sniff_pyobj( else: raise TypeError( f'Bad column {entry.name!r}: ' + - f'Unsupported object column containing an {type(obj)!r}') + f'Unsupported object column containing an {_fqn(type(obj))}') # We've hit an object column that exclusively has null values. # We will just skip this column. @@ -918,7 +927,7 @@ cdef bint _pandas_series_sniff_pyobj( cdef bint _pandas_resolve_source_and_buffers( TaggedEntry entry, col_t* col_out) except False: cdef object dtype = entry.dtype - if isinstance(dtype, _PANDAS.dtype('bool')): + if isinstance(dtype, _NUMPY.dtype('bool')): col_out.source = col_source_t.col_source_bool_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.BooleanDtype): @@ -1107,7 +1116,7 @@ cdef bint _pandas_resolve_args( data.dtypes[index], series, meta_target_t.meta_target_field) # Later resolved to a target. - for index, (name, series) in data.items()] + for index, (name, series) in enumerate(data.items())] name_col = _pandas_resolve_table_name( b, data, @@ -1122,7 +1131,7 @@ cdef bint _pandas_resolve_args( # Sort with table name is first, then the symbols, then fields, then at. # Note: Python 3.6+ guarantees stable sort. - tagged_cols.sort(key=lambda x: x.meta_target) + tagged_cols.sort(key=lambda x: (x).meta_target) _pandas_resolve_cols(b, tagged_cols, cols_out) return True From 7a1c0b0329970983ffa0857bbaad905fa34e3e91 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 22 Nov 2022 13:26:29 +0000 Subject: [PATCH 055/147] Yay, segfault! --- src/questdb/pandas_integration.pxi | 71 ++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index edf8c952..62e54c9e 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -337,6 +337,19 @@ cdef void col_t_arr_release(col_t_arr* arr): cdef object _NUMPY = None # module object +cdef object _NUMPY_BOOL = None +cdef object _NUMPY_UINT8 = None +cdef object _NUMPY_INT8 = None +cdef object _NUMPY_UINT16 = None +cdef object _NUMPY_INT16 = None +cdef object _NUMPY_UINT32 = None +cdef object _NUMPY_INT32 = None +cdef object _NUMPY_UINT64 = None +cdef object _NUMPY_INT64 = None +cdef object _NUMPY_FLOAT32 = None +cdef object _NUMPY_FLOAT64 = None +cdef object _NUMPY_DATETIME64_NS = None +cdef object _NUMPY_OBJECT = None cdef object _PANDAS = None # module object cdef object _PANDAS_NA = None # pandas.NA cdef object _PYARROW = None # module object, if available or None @@ -355,10 +368,36 @@ cdef object _pandas_may_import_deps(): python3 ./imp_test.py 0.56s user 1.60s system 852% cpu 0.254 total """ global _NUMPY, _PANDAS, _PYARROW, _PANDAS_NA + global _NUMPY_BOOL + global _NUMPY_UINT8 + global _NUMPY_INT8 + global _NUMPY_UINT16 + global _NUMPY_INT16 + global _NUMPY_UINT32 + global _NUMPY_INT32 + global _NUMPY_UINT64 + global _NUMPY_INT64 + global _NUMPY_FLOAT32 + global _NUMPY_FLOAT64 + global _NUMPY_DATETIME64_NS + global _NUMPY_OBJECT if _NUMPY is not None: return import numpy _NUMPY = numpy + _NUMPY_BOOL = type(_NUMPY.dtype('bool')) + _NUMPY_UINT8 = type(_NUMPY.dtype('uint8')) + _NUMPY_INT8 = type(_NUMPY.dtype('int8')) + _NUMPY_UINT16 = type(_NUMPY.dtype('uint16')) + _NUMPY_INT16 = type(_NUMPY.dtype('int16')) + _NUMPY_UINT32 = type(_NUMPY.dtype('uint32')) + _NUMPY_INT32 = type(_NUMPY.dtype('int32')) + _NUMPY_UINT64 = type(_NUMPY.dtype('uint64')) + _NUMPY_INT64 = type(_NUMPY.dtype('int64')) + _NUMPY_FLOAT32 = type(_NUMPY.dtype('float32')) + _NUMPY_FLOAT64 = type(_NUMPY.dtype('float64')) + _NUMPY_DATETIME64_NS = type(_NUMPY.dtype('datetime64[ns]')) + _NUMPY_OBJECT = type(_NUMPY.dtype('object')) import pandas _PANDAS = pandas _PANDAS_NA = pandas.NA @@ -781,16 +820,12 @@ cdef bint _pandas_series_as_pybuf( try: # Note! We don't need to support numpy strides since Pandas doesn't. + # Also note that this guarantees a 1D buffer. PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_SIMPLE) except BufferError as be: raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + f'{entry.series!r} ({_fqn(type(entry.series))})') from be - - if col_out.pybuf.ndim != 1: - raise ValueError( - f'Bad column {entry.name!r}: Expected a 1D column, ' + - f'got a {col_out.pybuf.ndim}D column.') _pandas_alloc_chunks(1, col_out) mapped = &col_out.chunks.chunks[0] @@ -927,35 +962,35 @@ cdef bint _pandas_series_sniff_pyobj( cdef bint _pandas_resolve_source_and_buffers( TaggedEntry entry, col_t* col_out) except False: cdef object dtype = entry.dtype - if isinstance(dtype, _NUMPY.dtype('bool')): + if isinstance(dtype, _NUMPY_BOOL): col_out.source = col_source_t.col_source_bool_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.BooleanDtype): col_out.source = col_source_t.col_source_bool_arrow _pandas_series_as_arrow( entry, col_out, col_source_t.col_source_bool_pyobj) - elif isinstance(dtype, _NUMPY.dtype('uint8')): + elif isinstance(dtype, _NUMPY_UINT8): col_out.source = col_source_t.col_source_u8_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('int8')): + elif isinstance(dtype, _NUMPY_INT8): col_out.source = col_source_t.col_source_i8_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('uint16')): + elif isinstance(dtype, _NUMPY_UINT16): col_out.source = col_source_t.col_source_u16_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('int16')): + elif isinstance(dtype, _NUMPY_INT16): col_out.source = col_source_t.col_source_i16_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('uint32')): + elif isinstance(dtype, _NUMPY_UINT32): col_out.source = col_source_t.col_source_u32_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('int32')): + elif isinstance(dtype, _NUMPY_INT32): col_out.source = col_source_t.col_source_i32_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('uint64')): + elif isinstance(dtype, _NUMPY_UINT64): col_out.source = col_source_t.col_source_u64_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('int64')): + elif isinstance(dtype, _NUMPY_INT64): col_out.source = col_source_t.col_source_i64_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.UInt8Dtype): @@ -990,11 +1025,11 @@ cdef bint _pandas_resolve_source_and_buffers( col_out.source = col_source_t.col_source_i64_arrow _pandas_series_as_arrow( entry, col_out, col_source_t.col_source_int_pyobj) - elif isinstance(dtype, _NUMPY.dtype('float32')): + elif isinstance(dtype, _NUMPY_FLOAT32): col_out.source = col_source_t.col_source_f32_numpy _pandas_series_as_pybuf( entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('float64')): + elif isinstance(dtype, _NUMPY_FLOAT64): col_out.source = col_source_t.col_source_f64_numpy _pandas_series_as_pybuf( entry, col_out) @@ -1020,13 +1055,13 @@ cdef bint _pandas_resolve_source_and_buffers( f'for column {entry.name} of dtype {dtype}.') elif isinstance(dtype, _PANDAS.CategoricalDtype): _pandas_category_series_as_arrow(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('datetime64[ns]')): + elif isinstance(dtype, _NUMPY_DATETIME64_NS): col_out.source = col_source_t.col_source_dt64ns_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.DatetimeTZDtype): col_out.source = col_source_t.col_source_dt64ns_tz_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _NUMPY.dtype('object')): + elif isinstance(dtype, _NUMPY_OBJECT): _pandas_series_sniff_pyobj(entry, col_out) else: raise ValueError( From 3af4899dace033df91eaa4c241be62cd58727619 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 22 Nov 2022 17:38:20 +0000 Subject: [PATCH 056/147] Fixed a few segfaults, got some more. --- proj.py | 7 ++++ src/questdb/ingress.pyx | 6 +-- src/questdb/pandas_integration.pxi | 65 +++++++++++++++++++++++++----- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/proj.py b/proj.py index 5ee7a8e4..ba7d0066 100755 --- a/proj.py +++ b/proj.py @@ -76,6 +76,13 @@ def test(all=False, patch_path='1', *args): env=env) +@command +def gdb_test(*args): + env = {'TEST_QUESTDB_PATCH_PATH': '1'} + _run('gdb', '-ex', 'r', '--args', 'python3', 'test/test.py', '-v', *args, + env=env) + + @command def doc(http_serve=False, port=None): _run('python3', '-m', 'sphinx.cmd.build', diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index c44afa0e..cd6d5646 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -40,7 +40,7 @@ from cpython.bool cimport bool, PyBool_Check from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject from cpython.object cimport PyObject from cpython.float cimport PyFloat_Check, PyFloat_CheckExact, PyFloat_AS_DOUBLE -from cpython.int cimport PyInt_Check +from cpython.long cimport PyLong_Check from cpython.unicode cimport PyUnicode_Check from cpython.buffer cimport Py_buffer, PyObject_CheckBuffer, \ PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE @@ -611,7 +611,7 @@ cdef class Buffer: str_to_column_name(self._cleared_b(), name, &c_name) if PyBool_Check(value): return self._column_bool(c_name, value) - elif PyInt_Check(value): + elif PyLong_Check(value): return self._column_i64(c_name, value) elif PyFloat_Check(value): return self._column_f64(c_name, value) @@ -1197,7 +1197,7 @@ cdef class Sender: b = self._buffer._b - if PyInt_Check(port): + if PyLong_Check(port): port_str = str(port) elif PyUnicode_Check(port): port_str = port diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 62e54c9e..b907178e 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -800,6 +800,9 @@ cdef bint _pandas_alloc_chunks(size_t n_chunks, col_t* col_out) except False: col_out.chunks.chunks = calloc( col_out.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. sizeof(ArrowArray)) + if col_out.chunks.chunks == NULL: + raise MemoryError() + return True cdef void _pandas_free_mapped_arrow(ArrowArray* arr): @@ -810,23 +813,30 @@ cdef void _pandas_free_mapped_arrow(ArrowArray* arr): cdef bint _pandas_series_as_pybuf( TaggedEntry entry, col_t* col_out) except False: + import sys; sys.stderr.write('_pandas_series_as_pybuf :: (A)\n') cdef object nparr = entry.series.to_numpy() cdef ArrowArray* mapped + sys.stderr.write('_pandas_series_as_pybuf :: (C)\n') if not PyObject_CheckBuffer(nparr): + sys.stderr.write('_pandas_series_as_pybuf :: (D)\n') raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + f'{entry.series!r} ({_fqn(type(entry.series))})') + sys.stderr.write('_pandas_series_as_pybuf :: (E)\n') col_out.tag = col_access_tag_t.numpy - + sys.stderr.write('_pandas_series_as_pybuf :: (F)\n') try: + sys.stderr.write('_pandas_series_as_pybuf :: (G)\n') # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_SIMPLE) + sys.stderr.write('_pandas_series_as_pybuf :: (H)\n') except BufferError as be: + sys.stderr.write('_pandas_series_as_pybuf :: (I)\n') raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + f'{entry.series!r} ({_fqn(type(entry.series))})') from be - + sys.stderr.write('_pandas_series_as_pybuf :: (J)\n') _pandas_alloc_chunks(1, col_out) mapped = &col_out.chunks.chunks[0] @@ -928,19 +938,23 @@ cdef bint _pandas_series_sniff_pyobj( cdef object obj cdef size_t el_index cdef size_t n_elements = len(entry.series) + cdef PyObject* obj_arr = (col_out.pybuf.buf) + import sys; sys.stderr.write('_pandas_series_sniff_pyobj :: (A)\n') _pandas_series_as_pybuf(entry, col_out) + sys.stderr.write('_pandas_series_sniff_pyobj :: (B)\n') for el_index in range(n_elements): # TODO: Check there's no pointless INCREF/DECREF going on here. - obj = &((col_out.pybuf.buf))[el_index] + obj = &(obj_arr[el_index]) + sys.stderr.write(f'_pandas_series_sniff_pyobj :: (C) obj: {obj!r}\n') if _pandas_is_null_pyobj(obj): continue - elif isinstance(obj, bool): + elif PyBool_Check(obj): col_out.source = col_source_t.col_source_bool_pyobj - elif isinstance(obj, int): + elif PyLong_Check(obj): col_out.source = col_source_t.col_source_int_pyobj - elif isinstance(obj, float): + elif PyFloat_Check(obj): col_out.source = col_source_t.col_source_float_pyobj - elif isinstance(obj, str): + elif PyUnicode_Check(obj): col_out.source = col_source_t.col_source_str_pyobj elif isinstance(obj, bytes): raise ValueError( @@ -952,11 +966,15 @@ cdef bint _pandas_series_sniff_pyobj( raise TypeError( f'Bad column {entry.name!r}: ' + f'Unsupported object column containing an {_fqn(type(obj))}') + sys.stderr.write('_pandas_series_sniff_pyobj :: (D)\n') + return True + sys.stderr.write('_pandas_series_sniff_pyobj :: (E)\n') # We've hit an object column that exclusively has null values. # We will just skip this column. col_out.source = col_source_t.col_source_nulls - + sys.stderr.write('_pandas_series_sniff_pyobj :: (F)\n') + return True cdef bint _pandas_resolve_source_and_buffers( @@ -1062,7 +1080,9 @@ cdef bint _pandas_resolve_source_and_buffers( col_out.source = col_source_t.col_source_dt64ns_tz_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY_OBJECT): + import sys; sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (A)\n') _pandas_series_sniff_pyobj(entry, col_out) + import sys; sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (B)\n') else: raise ValueError( f'Unsupported dtype {dtype} for column {entry.name}. ' + @@ -1103,19 +1123,29 @@ cdef bint _pandas_resolve_col( # Since we don't need to send the column names for 'table' and 'at' columns, # we don't need to validate and encode them as column names. + import sys; sys.stderr.write(f'_pandas_resolve_col :: (A) name: {entry.name}, dtype: {entry.dtype}\n') if ((entry.meta_target != meta_target_t.meta_target_table) and (entry.meta_target != meta_target_t.meta_target_at)): + sys.stderr.write('_pandas_resolve_col :: (B)\n') str_to_column_name(b, entry.name, &col_out.name) + sys.stderr.write('_pandas_resolve_col :: (C)\n') + sys.stderr.write('_pandas_resolve_col :: (D)\n') _pandas_resolve_source_and_buffers(entry, col_out) + sys.stderr.write('_pandas_resolve_col :: (E)\n') _pandas_resolve_target(entry, col_out) + sys.stderr.write('_pandas_resolve_col :: (F)\n') if col_out.source not in _TARGET_TO_SOURCE[col_out.target]: + sys.stderr.write('_pandas_resolve_col :: (G)\n') raise ValueError( f'Bad value: Column {entry.name!r} ({entry.dtype}) is not ' + f'supported as a {_TARGET_NAMES[col_out.target]} column.') + sys.stderr.write('_pandas_resolve_col :: (H)\n') col_out.dispatch_code = ( col_out.source + col_out.target) + sys.stderr.write('_pandas_resolve_col :: (I)\n') _pandas_init_cursor(col_out) + sys.stderr.write('_pandas_resolve_col :: (J)\n') return True @@ -1143,6 +1173,7 @@ cdef bint _pandas_resolve_args( cdef ssize_t name_col cdef ssize_t at_col + import sys; sys.stderr.write('_pandas_resolve_args :: (A)\n') # List of Lists with col index, col name, series object, sorting key. cdef list tagged_cols = [ TaggedEntry( @@ -1152,6 +1183,7 @@ cdef bint _pandas_resolve_args( series, meta_target_t.meta_target_field) # Later resolved to a target. for index, (name, series) in enumerate(data.items())] + sys.stderr.write('_pandas_resolve_args :: (A)\n') name_col = _pandas_resolve_table_name( b, data, @@ -1160,14 +1192,19 @@ cdef bint _pandas_resolve_args( table_name_col, col_count, c_table_name_out) + sys.stderr.write('_pandas_resolve_args :: (B)\n') at_col = _pandas_resolve_at(data, tagged_cols, at, col_count, at_value_out) + sys.stderr.write('_pandas_resolve_args :: (C)\n') _pandas_resolve_symbols( data, tagged_cols, name_col, at_col, symbols, col_count) + sys.stderr.write('_pandas_resolve_args :: (D)\n') # Sort with table name is first, then the symbols, then fields, then at. # Note: Python 3.6+ guarantees stable sort. tagged_cols.sort(key=lambda x: (x).meta_target) + sys.stderr.write('_pandas_resolve_args :: (E)\n') _pandas_resolve_cols(b, tagged_cols, cols_out) + sys.stderr.write('_pandas_resolve_args :: (F)\n') return True @@ -1631,6 +1668,9 @@ cdef bint _pandas_serialize_cell( elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_numpy: _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( impl, b, col, row_index) + else: + raise RuntimeError(f"Unknown column dispatch code: {dc}") + return True cdef void _pandas_col_advance(col_t* col): @@ -1680,10 +1720,15 @@ cdef bint _pandas( _pandas_may_import_deps() try: + import sys; sys.stderr.write(' :: :: (A)\n') qdb_pystr_buf_clear(b) + sys.stderr.write(' :: :: (B)\n') _check_is_pandas_dataframe(data) + sys.stderr.write(' :: :: (C)\n') col_count = len(data.columns) + sys.stderr.write(' :: :: (D)\n') cols = col_t_arr_new(col_count) + sys.stderr.write(' :: :: (E)\n') _pandas_resolve_args( data, table_name, @@ -1695,11 +1740,13 @@ cdef bint _pandas( &c_table_name, &at_value, &cols) + sys.stderr.write(' :: :: (F)\n') # We've used the str buffer up to a point for the headers. # Instead of clearing it (which would clear the headers' memory) # we will truncate (rewind) back to this position. str_buf_marker = qdb_pystr_buf_tell(b) + sys.stderr.write(' :: :: (G)\n') # import sys # sys.stderr.write('_pandas :: (A) ' + @@ -1740,8 +1787,8 @@ cdef bint _pandas( if not line_sender_buffer_rewind_to_marker(impl, &err): raise c_err_to_py(err) raise - return True finally: line_sender_buffer_clear_marker(impl) col_t_arr_release(&cols) qdb_pystr_buf_clear(b) + return True From 9dc17a3956be39aeb285aca20d14bd00ee596c45 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 22 Nov 2022 20:32:21 +0000 Subject: [PATCH 057/147] Fixed segfaults. --- src/questdb/ingress.pyx | 2 +- src/questdb/pandas_integration.pxi | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index cd6d5646..970ffea1 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -43,7 +43,7 @@ from cpython.float cimport PyFloat_Check, PyFloat_CheckExact, PyFloat_AS_DOUBLE from cpython.long cimport PyLong_Check from cpython.unicode cimport PyUnicode_Check from cpython.buffer cimport Py_buffer, PyObject_CheckBuffer, \ - PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE + PyObject_GetBuffer, PyBuffer_Release, PyBUF_STRIDES from cpython.memoryview cimport PyMemoryView_FromMemory from .line_sender cimport * diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index b907178e..8e7689fc 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -90,7 +90,7 @@ cdef enum col_source_t: col_source_dt64ns_tz_numpy = 502000 -cdef dict _TARGET_TO_SOURCE = { +cdef dict _TARGET_TO_SOURCES = { col_target_t.col_target_skip: { col_source_t.col_source_nulls, }, @@ -813,9 +813,12 @@ cdef void _pandas_free_mapped_arrow(ArrowArray* arr): cdef bint _pandas_series_as_pybuf( TaggedEntry entry, col_t* col_out) except False: - import sys; sys.stderr.write('_pandas_series_as_pybuf :: (A)\n') cdef object nparr = entry.series.to_numpy() cdef ArrowArray* mapped + cdef int get_buf_ret + cdef bytes format + cdef Py_buffer* view + import sys; sys.stderr.write(f'_pandas_series_as_pybuf :: (A) entry.name: {entry.name}\n') sys.stderr.write('_pandas_series_as_pybuf :: (C)\n') if not PyObject_CheckBuffer(nparr): sys.stderr.write('_pandas_series_as_pybuf :: (D)\n') @@ -826,11 +829,13 @@ cdef bint _pandas_series_as_pybuf( col_out.tag = col_access_tag_t.numpy sys.stderr.write('_pandas_series_as_pybuf :: (F)\n') try: - sys.stderr.write('_pandas_series_as_pybuf :: (G)\n') + sys.stderr.write(f'_pandas_series_as_pybuf :: (G) {col_out.pybuf.buf}, nparr: {nparr!r}\n') # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. - PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_SIMPLE) - sys.stderr.write('_pandas_series_as_pybuf :: (H)\n') + view = &col_out.pybuf + get_buf_ret = PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) + sys.stderr.write(f'_pandas_series_as_pybuf :: (H1) {col_out.pybuf.buf}, ret: {get_buf_ret}, ndim: {col_out.pybuf.ndim}, strides[0]: {col_out.pybuf.strides[0]}, itemsize: {col_out.pybuf.itemsize}, len: {col_out.pybuf.len}, count: {col_out.pybuf.len // col_out.pybuf.itemsize}\n') + except BufferError as be: sys.stderr.write('_pandas_series_as_pybuf :: (I)\n') raise TypeError( @@ -938,14 +943,16 @@ cdef bint _pandas_series_sniff_pyobj( cdef object obj cdef size_t el_index cdef size_t n_elements = len(entry.series) - cdef PyObject* obj_arr = (col_out.pybuf.buf) - import sys; sys.stderr.write('_pandas_series_sniff_pyobj :: (A)\n') + cdef PyObject** obj_arr + import sys; sys.stderr.write(f'_pandas_series_sniff_pyobj :: (A) buf: {col_out.pybuf.buf}, n_elements: {n_elements}, series:\n{entry.series}\n') _pandas_series_as_pybuf(entry, col_out) + obj_arr = (col_out.pybuf.buf) sys.stderr.write('_pandas_series_sniff_pyobj :: (B)\n') for el_index in range(n_elements): + sys.stderr.write(f'_pandas_series_sniff_pyobj :: (C1) {el_index}, ptr: {&obj_arr[el_index]}\n') # TODO: Check there's no pointless INCREF/DECREF going on here. - obj = &(obj_arr[el_index]) - sys.stderr.write(f'_pandas_series_sniff_pyobj :: (C) obj: {obj!r}\n') + obj = obj_arr[el_index] + sys.stderr.write(f'_pandas_series_sniff_pyobj :: (C2) obj: {obj!r}\n') if _pandas_is_null_pyobj(obj): continue elif PyBool_Check(obj): @@ -1099,7 +1106,7 @@ cdef bint _pandas_resolve_target( col_out.target = entry.meta_target return True for target in _FIELD_TARGETS: - target_sources = _FIELD_TARGETS[target] + target_sources = _TARGET_TO_SOURCES[target] if col_out.source in target_sources: col_out.target = target return True @@ -1135,7 +1142,7 @@ cdef bint _pandas_resolve_col( sys.stderr.write('_pandas_resolve_col :: (E)\n') _pandas_resolve_target(entry, col_out) sys.stderr.write('_pandas_resolve_col :: (F)\n') - if col_out.source not in _TARGET_TO_SOURCE[col_out.target]: + if col_out.source not in _TARGET_TO_SOURCES[col_out.target]: sys.stderr.write('_pandas_resolve_col :: (G)\n') raise ValueError( f'Bad value: Column {entry.name!r} ({entry.dtype}) is not ' + From 9665d9fdf812c6407c1148792dcd36f062b8f2bc Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 22 Nov 2022 21:29:18 +0000 Subject: [PATCH 058/147] Added missing dispatch codes and lots of TODOs. --- src/questdb/pandas_integration.pxi | 76 ++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 8e7689fc..e070b10e 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -284,6 +284,11 @@ cdef enum col_dispatch_code_t: col_target_t.col_target_column_ts + \ col_source_t.col_source_dt64ns_tz_numpy + col_dispatch_code_at__dt64ns_numpy = \ + col_target_t.col_target_at + col_source_t.col_source_dt64ns_numpy + col_dispatch_code_at__dt64ns_tz_numpy = \ + col_target_t.col_target_at + col_source_t.col_source_dt64ns_tz_numpy + cdef struct col_t: size_t orig_index @@ -929,6 +934,7 @@ cdef inline bint _pandas_is_float_nan(obj): return PyFloat_CheckExact(obj) and isnan(PyFloat_AS_DOUBLE(obj)) +# TODO: Check for pointless incref at callsite or here. cdef inline bint _pandas_is_null_pyobj(object obj): return (obj is None) or (obj is _PANDAS_NA) or _pandas_is_float_nan(obj) @@ -1220,7 +1226,15 @@ cdef bint _pandas_serialize_cell_table__str_pyobj( qdb_pystr_buf* b, col_t* col, size_t row_index) except False: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef PyObject** access = col.cursor.chunk.buffers[1] + cdef object cell = access[row_index] + cdef line_sender_table_name c_table_name + # TODO: Check if object is not none and check if string. Then see if there's silly increfs. + str_to_table_name(b, cell, &c_table_name) + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + return True cdef bint _pandas_serialize_cell_table__str_arrow( @@ -1268,7 +1282,15 @@ cdef bint _pandas_serialize_cell_symbol__str_pyobj( qdb_pystr_buf* b, col_t* col, size_t row_index) except False: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef PyObject** access = col.cursor.chunk.buffers[1] + cdef object cell = access[row_index] + cdef line_sender_utf8 utf8 + # TODO: Null checks, string checks, no incref verifications. + str_to_utf8(b, cell, &utf8) + if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + raise c_err_to_py(err) + return True cdef bint _pandas_serialize_cell_symbol__str_arrow( @@ -1404,7 +1426,12 @@ cdef bint _pandas_serialize_cell_column_i64__i64_numpy( qdb_pystr_buf* b, col_t* col, size_t row_index) except False: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef int64_t* access = col.cursor.chunk.buffers[1] + cdef int64_t cell = access[row_index] + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) + return True cdef bint _pandas_serialize_cell_column_i64__u8_arrow( @@ -1492,7 +1519,16 @@ cdef bint _pandas_serialize_cell_column_f64__f64_numpy( qdb_pystr_buf* b, col_t* col, size_t row_index) except False: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef double* access = col.cursor.chunk.buffers[1] + cdef double cell = access[row_index] + # TODO: Skip if NaN, then test degenerate case where all cells are NaN for a row. + if isnan(cell): + return True + if not line_sender_buffer_column_f64(impl, col.name, cell, &err): + raise c_err_to_py(err) + return True + cdef bint _pandas_serialize_cell_column_f64__f32_arrow( @@ -1575,6 +1611,32 @@ cdef bint _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( raise ValueError('nyi') +cdef bint _pandas_serialize_cell_at_dt64ns_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + cdef line_sender_error* err = NULL + cdef int64_t* access = col.cursor.chunk.buffers[1] + cdef int64_t cell = access[row_index] + if cell == 0: + if not line_sender_buffer_at_now(impl, &err): + raise c_err_to_py(err) + else: + # Note: impl will validate against negative numbers. + if not line_sender_buffer_at(impl, cell, &err): + raise c_err_to_py(err) + return True + + +cdef bint _pandas_serialize_cell_at_dt64ns_tz_numpy( + line_sender_buffer* impl, + qdb_pystr_buf* b, + col_t* col, + size_t row_index) except False: + _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col, row_index) + + cdef bint _pandas_serialize_cell( line_sender_buffer* impl, qdb_pystr_buf* b, @@ -1675,6 +1737,10 @@ cdef bint _pandas_serialize_cell( elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_numpy: _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_numpy: + _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col, row_index) + elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_tz_numpy: + _pandas_serialize_cell_at_dt64ns_tz_numpy(impl, b, col, row_index) else: raise RuntimeError(f"Unknown column dispatch code: {dc}") return True @@ -1780,6 +1846,8 @@ cdef bint _pandas( # Note: Columns are sorted: table name, symbols, fields, at. for col_index in range(col_count): col = &cols.d[col_index] + # TODO: Wrap error exceptions messaging with column name + # and row index. Ideally, extract value in python too. _pandas_serialize_cell(impl, b, col, row_index) _pandas_col_advance(col) From 194ad25689d214ab371509cc8d7853b17591ec1e Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 23 Nov 2022 11:59:56 +0000 Subject: [PATCH 059/147] Got rid of a lot of INCREF/DECREF silliness. --- src/questdb/extra_cpython.pxd | 29 ++++++++--- src/questdb/ingress.pyx | 66 ++++++++++++----------- src/questdb/pandas_integration.pxi | 84 +++++++++++++++++++----------- 3 files changed, 113 insertions(+), 66 deletions(-) diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd index c6569db4..f7548310 100644 --- a/src/questdb/extra_cpython.pxd +++ b/src/questdb/extra_cpython.pxd @@ -1,8 +1,11 @@ # Custom definitions that aren't provided in the standard `cpython` module. from libc.stdint cimport uint8_t, uint16_t, uint32_t +from cpython.object cimport PyObject cdef extern from "Python.h": + cdef PyObject* Py_None + ctypedef uint8_t Py_UCS1 # unicodeobject.h ctypedef uint16_t Py_UCS2 ctypedef uint32_t Py_UCS4 @@ -24,20 +27,32 @@ cdef extern from "Python.h": const char* u, Py_ssize_t size) # Must be called before accessing data or is compact check. - int PyUnicode_READY(object o) except -1 + int PyUnicode_READY(PyObject* o) except -1 # Is UCS1 and ascii (and therefore valid UTF-8). - bint PyUnicode_IS_COMPACT_ASCII(object o) + bint PyUnicode_IS_COMPACT_ASCII(PyObject* o) # Get length. - Py_ssize_t PyUnicode_GET_LENGTH(object o) + Py_ssize_t PyUnicode_GET_LENGTH(PyObject* o) # Zero-copy access to string buffer. - int PyUnicode_KIND(object o) - Py_UCS1* PyUnicode_1BYTE_DATA(object o) - Py_UCS2* PyUnicode_2BYTE_DATA(object o) - Py_UCS4* PyUnicode_4BYTE_DATA(object o) + int PyUnicode_KIND(PyObject* o) + Py_UCS1* PyUnicode_1BYTE_DATA(PyObject* o) + Py_UCS2* PyUnicode_2BYTE_DATA(PyObject* o) + Py_UCS4* PyUnicode_4BYTE_DATA(PyObject* o) Py_ssize_t PyBytes_GET_SIZE(object o) + bint PyBytes_CheckExact(PyObject* o) + char* PyBytes_AsString(object o) + + bint PyUnicode_CheckExact(PyObject* o) + + bint PyBool_Check(PyObject* o) + + bint PyLong_CheckExact(PyObject* o) + + bint PyFloat_CheckExact(PyObject* o) + + double PyFloat_AS_DOUBLE(PyObject* o) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 970ffea1..09ac6184 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -36,14 +36,11 @@ from libc.stdlib cimport malloc, calloc, realloc, free, abort from libc.string cimport strncmp from libc.math cimport isnan from cpython.datetime cimport datetime -from cpython.bool cimport bool, PyBool_Check +from cpython.bool cimport bool from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject from cpython.object cimport PyObject -from cpython.float cimport PyFloat_Check, PyFloat_CheckExact, PyFloat_AS_DOUBLE -from cpython.long cimport PyLong_Check -from cpython.unicode cimport PyUnicode_Check from cpython.buffer cimport Py_buffer, PyObject_CheckBuffer, \ - PyObject_GetBuffer, PyBuffer_Release, PyBUF_STRIDES + PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE from cpython.memoryview cimport PyMemoryView_FromMemory from .line_sender cimport * @@ -138,16 +135,21 @@ cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): return IngressError(tup[0], fmt.format(tup[1])) -cdef object _utf8_decode_error(str string, uint32_t bad_codepoint): +cdef object _utf8_decode_error(PyObject* string, uint32_t bad_codepoint): + cdef str s = string return IngressError( IngressErrorCode.InvalidUtf8, - f'Invalid codepoint 0x{bad_codepoint:x} in string {string!r}: ' + + f'Invalid codepoint 0x{bad_codepoint:x} in string {s!r}: ' + 'Cannot be encoded as UTF-8.') +cdef str _fqn(type obj): + return obj.__module__ + '.' + obj.__qualname__ + + cdef bint str_to_utf8( qdb_pystr_buf* b, - str string, + PyObject* string, line_sender_utf8* utf8_out) except False: """ Convert a Python string to a UTF-8 borrowed buffer. @@ -160,8 +162,11 @@ cdef bint str_to_utf8( cdef size_t count cdef int kind cdef uint32_t bad_codepoint = 0 + if not PyUnicode_CheckExact(string): + raise TypeError( + f'Expected a str object, not a {_fqn(type(string))}') PyUnicode_READY(string) - count = (PyUnicode_GET_LENGTH(string)) + count = (PyUnicode_GET_LENGTH(string)) # We optimize the common case of ASCII strings. # This avoid memory allocations and copies altogether. @@ -210,7 +215,7 @@ cdef bint str_to_utf8( cdef bint str_to_table_name( qdb_pystr_buf* b, - str string, + PyObject* string, line_sender_table_name* name_out) except False: """ Python string to borrowed C table name. @@ -234,7 +239,7 @@ cdef bint str_to_column_name( """ cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - str_to_utf8(b, string, &utf8) + str_to_utf8(b, string, &utf8) if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): raise c_err_to_py(err) return True @@ -542,7 +547,8 @@ cdef class Buffer: cdef inline int _table(self, str table_name) except -1: cdef line_sender_error* err = NULL cdef line_sender_table_name c_table_name - str_to_table_name(self._cleared_b(), table_name, &c_table_name) + str_to_table_name( + self._cleared_b(), table_name, &c_table_name) if not line_sender_buffer_table(self._impl, c_table_name, &err): raise c_err_to_py(err) return 0 @@ -556,7 +562,7 @@ cdef class Buffer: cdef line_sender_column_name c_name cdef line_sender_utf8 c_value str_to_column_name(self._cleared_b(), name, &c_name) - str_to_utf8(self._b, value, &c_value) + str_to_utf8(self._b, value, &c_value) if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): raise c_err_to_py(err) return 0 @@ -586,7 +592,7 @@ cdef class Buffer: self, line_sender_column_name c_name, str value) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 c_value - str_to_utf8(self._b, value, &c_value) + str_to_utf8(self._b, value, &c_value) if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): raise c_err_to_py(err) return 0 @@ -609,13 +615,13 @@ cdef class Buffer: cdef inline int _column(self, str name, object value) except -1: cdef line_sender_column_name c_name str_to_column_name(self._cleared_b(), name, &c_name) - if PyBool_Check(value): + if PyBool_Check(value): return self._column_bool(c_name, value) - elif PyLong_Check(value): + elif PyLong_CheckExact(value): return self._column_i64(c_name, value) - elif PyFloat_Check(value): + elif PyFloat_CheckExact(value): return self._column_f64(c_name, value) - elif PyUnicode_Check(value): + elif PyUnicode_CheckExact(value): return self._column_str(c_name, value) elif isinstance(value, TimestampMicros): return self._column_ts(c_name, value) @@ -1197,20 +1203,20 @@ cdef class Sender: b = self._buffer._b - if PyLong_Check(port): + if PyLong_CheckExact(port): port_str = str(port) - elif PyUnicode_Check(port): + elif PyUnicode_CheckExact(port): port_str = port else: raise TypeError( - f'port must be an integer or a string, not {type(port)}') + f'port must be an int or a str, not {_fqn(type(port))}') - str_to_utf8(b, host, &host_utf8) - str_to_utf8(b, port_str, &port_utf8) + str_to_utf8(b, host, &host_utf8) + str_to_utf8(b, port_str, &port_utf8) self._opts = line_sender_opts_new_service(host_utf8, port_utf8) if interface is not None: - str_to_utf8(b, interface, &interface_utf8) + str_to_utf8(b, interface, &interface_utf8) line_sender_opts_net_interface(self._opts, interface_utf8) if auth is not None: @@ -1218,10 +1224,10 @@ cdef class Sender: a_priv_key, a_pub_key_x, a_pub_key_y) = auth - str_to_utf8(b, a_key_id, &a_key_id_utf8) - str_to_utf8(b, a_priv_key, &a_priv_key_utf8) - str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) - str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) + str_to_utf8(b, a_key_id, &a_key_id_utf8) + str_to_utf8(b, a_priv_key, &a_priv_key_utf8) + str_to_utf8(b, a_pub_key_x, &a_pub_key_x_utf8) + str_to_utf8(b, a_pub_key_y, &a_pub_key_y_utf8) line_sender_opts_auth( self._opts, a_key_id_utf8, @@ -1236,11 +1242,11 @@ cdef class Sender: if tls == 'insecure_skip_verify': line_sender_opts_tls_insecure_skip_verify(self._opts) else: - str_to_utf8(b, tls, &ca_utf8) + str_to_utf8(b, tls, &ca_utf8) line_sender_opts_tls_ca(self._opts, ca_utf8) elif isinstance(tls, pathlib.Path): tls = str(tls) - str_to_utf8(b, tls, &ca_utf8) + str_to_utf8(b, tls, &ca_utf8) line_sender_opts_tls_ca(self._opts, ca_utf8) else: raise TypeError( diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index e070b10e..3c6587c3 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -413,10 +413,6 @@ cdef object _pandas_may_import_deps(): _PYARROW = None -cdef str _fqn(type obj): - return obj.__module__ + '.' + obj.__qualname__ - - cdef object _check_is_pandas_dataframe(object data): if not isinstance(data, _PANDAS.DataFrame): raise TypeError( @@ -454,7 +450,7 @@ cdef ssize_t _pandas_resolve_table_name( 'Can specify only one of `table_name` or `table_name_col`.') if isinstance(table_name, str): try: - str_to_table_name(b, table_name, name_out) + str_to_table_name(b, table_name, name_out) return -1 # Magic value for "no column index". except IngressError as ie: raise ValueError(f'Bad argument `table_name`: {ie}') @@ -838,8 +834,8 @@ cdef bint _pandas_series_as_pybuf( # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. view = &col_out.pybuf - get_buf_ret = PyObject_GetBuffer(nparr, view, PyBUF_STRIDES) - sys.stderr.write(f'_pandas_series_as_pybuf :: (H1) {col_out.pybuf.buf}, ret: {get_buf_ret}, ndim: {col_out.pybuf.ndim}, strides[0]: {col_out.pybuf.strides[0]}, itemsize: {col_out.pybuf.itemsize}, len: {col_out.pybuf.len}, count: {col_out.pybuf.len // col_out.pybuf.itemsize}\n') + get_buf_ret = PyObject_GetBuffer(nparr, view, PyBUF_SIMPLE) + sys.stderr.write(f'_pandas_series_as_pybuf :: (H1) {col_out.pybuf.buf}, ret: {get_buf_ret}, ndim: {col_out.pybuf.ndim}, itemsize: {col_out.pybuf.itemsize}, len: {col_out.pybuf.len}, count: {col_out.pybuf.len // col_out.pybuf.itemsize}\n') except BufferError as be: sys.stderr.write('_pandas_series_as_pybuf :: (I)\n') @@ -930,13 +926,16 @@ cdef bint _pandas_category_series_as_arrow( return True -cdef inline bint _pandas_is_float_nan(obj): +cdef inline bint _pandas_is_float_nan(PyObject* obj): return PyFloat_CheckExact(obj) and isnan(PyFloat_AS_DOUBLE(obj)) # TODO: Check for pointless incref at callsite or here. -cdef inline bint _pandas_is_null_pyobj(object obj): - return (obj is None) or (obj is _PANDAS_NA) or _pandas_is_float_nan(obj) +cdef inline bint _pandas_is_null_pyobj(PyObject* obj): + return ( + (obj == Py_None) or + (obj == _PANDAS_NA) or + _pandas_is_float_nan(obj)) cdef bint _pandas_series_sniff_pyobj( @@ -946,30 +945,27 @@ cdef bint _pandas_series_sniff_pyobj( Object columns can contain pretty much anything, but they usually don't. We make an educated guess by finding the first non-null value in the column. """ - cdef object obj cdef size_t el_index cdef size_t n_elements = len(entry.series) cdef PyObject** obj_arr + cdef PyObject* obj import sys; sys.stderr.write(f'_pandas_series_sniff_pyobj :: (A) buf: {col_out.pybuf.buf}, n_elements: {n_elements}, series:\n{entry.series}\n') _pandas_series_as_pybuf(entry, col_out) obj_arr = (col_out.pybuf.buf) sys.stderr.write('_pandas_series_sniff_pyobj :: (B)\n') for el_index in range(n_elements): - sys.stderr.write(f'_pandas_series_sniff_pyobj :: (C1) {el_index}, ptr: {&obj_arr[el_index]}\n') - # TODO: Check there's no pointless INCREF/DECREF going on here. - obj = obj_arr[el_index] - sys.stderr.write(f'_pandas_series_sniff_pyobj :: (C2) obj: {obj!r}\n') + obj = obj_arr[el_index] if _pandas_is_null_pyobj(obj): continue elif PyBool_Check(obj): col_out.source = col_source_t.col_source_bool_pyobj - elif PyLong_Check(obj): + elif PyLong_CheckExact(obj): col_out.source = col_source_t.col_source_int_pyobj - elif PyFloat_Check(obj): + elif PyFloat_CheckExact(obj): col_out.source = col_source_t.col_source_float_pyobj - elif PyUnicode_Check(obj): + elif PyUnicode_CheckExact(obj): col_out.source = col_source_t.col_source_str_pyobj - elif isinstance(obj, bytes): + elif PyBytes_CheckExact(obj): raise ValueError( f'Bad column {entry.name!r}: ' + 'Unsupported object column containing bytes.' + @@ -978,7 +974,7 @@ cdef bint _pandas_series_sniff_pyobj( else: raise TypeError( f'Bad column {entry.name!r}: ' + - f'Unsupported object column containing an {_fqn(type(obj))}') + f'Unsupported object column containing an {_fqn(type(obj))}') sys.stderr.write('_pandas_series_sniff_pyobj :: (D)\n') return True sys.stderr.write('_pandas_series_sniff_pyobj :: (E)\n') @@ -1221,6 +1217,26 @@ cdef bint _pandas_resolve_args( return True +cdef inline bint _pandas_cell_str_pyobj_to_utf8( + qdb_pystr_buf* b, + col_t* col, + size_t row_index, + bint* valid_out, + line_sender_utf8* utf8_out) except False: + cdef PyObject** access = col.cursor.chunk.buffers[1] + cdef PyObject* cell = access[row_index] + if _pandas_is_null_pyobj(cell): + valid_out[0] = False + return True + elif PyUnicode_CheckExact(cell): + str_to_utf8(b, cell, utf8_out) + valid_out[0] = True + return True + else: + raise ValueError( + f'Expected an object of type str, got a {_fqn(type(cell))}') + + cdef bint _pandas_serialize_cell_table__str_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, @@ -1228,9 +1244,11 @@ cdef bint _pandas_serialize_cell_table__str_pyobj( size_t row_index) except False: cdef line_sender_error* err = NULL cdef PyObject** access = col.cursor.chunk.buffers[1] - cdef object cell = access[row_index] + cdef PyObject* cell = access[row_index] cdef line_sender_table_name c_table_name - # TODO: Check if object is not none and check if string. Then see if there's silly increfs. + if _pandas_is_null_pyobj(cell) or not PyUnicode_CheckExact(cell): + raise ValueError(f'Expected an object of type str, got a {_fqn(type(cell))}') + # TODO: See if there's silly increfs. str_to_table_name(b, cell, &c_table_name) if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) @@ -1283,12 +1301,10 @@ cdef bint _pandas_serialize_cell_symbol__str_pyobj( col_t* col, size_t row_index) except False: cdef line_sender_error* err = NULL - cdef PyObject** access = col.cursor.chunk.buffers[1] - cdef object cell = access[row_index] + cdef bint valid = False cdef line_sender_utf8 utf8 - # TODO: Null checks, string checks, no incref verifications. - str_to_utf8(b, cell, &utf8) - if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + _pandas_cell_str_pyobj_to_utf8(b, col, row_index, &valid, &utf8) + if valid and not line_sender_buffer_symbol(impl, col.name, utf8, &err): raise c_err_to_py(err) return True @@ -1552,7 +1568,13 @@ cdef bint _pandas_serialize_cell_column_str__str_pyobj( qdb_pystr_buf* b, col_t* col, size_t row_index) except False: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = False + cdef line_sender_utf8 utf8 + _pandas_cell_str_pyobj_to_utf8(b, col, row_index, &valid, &utf8) + if valid and not line_sender_buffer_column_str(impl, col.name, utf8, &err): + raise c_err_to_py(err) + return True cdef bint _pandas_serialize_cell_column_str__str_arrow( @@ -1643,7 +1665,8 @@ cdef bint _pandas_serialize_cell( col_t* col, size_t row_index) except False: cdef col_dispatch_code_t dc = col.dispatch_code - # TODO: Check that this `if/elif` gets compiled into a C switch statement. + # Note!: Code below will generate a `switch` statement. + # Ensure this happens! Don't break the `dc == ...` pattern. if dc == col_dispatch_code_t.col_dispatch_code_skip_nulls: pass # We skip a null column. Nothing to do. elif dc == col_dispatch_code_t.col_dispatch_code_table__str_pyobj: @@ -1743,6 +1766,9 @@ cdef bint _pandas_serialize_cell( _pandas_serialize_cell_at_dt64ns_tz_numpy(impl, b, col, row_index) else: raise RuntimeError(f"Unknown column dispatch code: {dc}") + # See earlier note about switch statement generation. + # Don't add complex conditions above! + return True From 9ea4a0e9923e49f8a11804f4f1aa537faf468cd3 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 23 Nov 2022 16:58:28 +0000 Subject: [PATCH 060/147] Ohh look. Tests pass again. --- src/questdb/pandas_integration.pxi | 267 ++++++++++++----------------- test/test.py | 6 +- 2 files changed, 114 insertions(+), 159 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 3c6587c3..5157cbc1 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1220,11 +1220,10 @@ cdef bint _pandas_resolve_args( cdef inline bint _pandas_cell_str_pyobj_to_utf8( qdb_pystr_buf* b, col_t* col, - size_t row_index, bint* valid_out, line_sender_utf8* utf8_out) except False: cdef PyObject** access = col.cursor.chunk.buffers[1] - cdef PyObject* cell = access[row_index] + cdef PyObject* cell = access[col.cursor.offset] if _pandas_is_null_pyobj(cell): valid_out[0] = False return True @@ -1240,11 +1239,10 @@ cdef inline bint _pandas_cell_str_pyobj_to_utf8( cdef bint _pandas_serialize_cell_table__str_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: cdef line_sender_error* err = NULL cdef PyObject** access = col.cursor.chunk.buffers[1] - cdef PyObject* cell = access[row_index] + cdef PyObject* cell = access[col.cursor.offset] cdef line_sender_table_name c_table_name if _pandas_is_null_pyobj(cell) or not PyUnicode_CheckExact(cell): raise ValueError(f'Expected an object of type str, got a {_fqn(type(cell))}') @@ -1258,52 +1256,50 @@ cdef bint _pandas_serialize_cell_table__str_pyobj( cdef bint _pandas_serialize_cell_table__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: - raise ValueError('nyi') + col_t* col) except False: + cdef line_sender_error* err = NULL + cdef line_sender_table_name c_table_name + cdef uint8_t* validity_access = col.cursor.chunk.buffers[0] + cdef int32_t* index_access = col.cursor.chunk.buffers[1] + raise ValueError('Not implemented') cdef bint _pandas_serialize_cell_table__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_table__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_table__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_table__str_i64_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_symbol__str_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 - _pandas_cell_str_pyobj_to_utf8(b, col, row_index, &valid, &utf8) + _pandas_cell_str_pyobj_to_utf8(b, col, &valid, &utf8) if valid and not line_sender_buffer_symbol(impl, col.name, utf8, &err): raise c_err_to_py(err) return True @@ -1312,139 +1308,122 @@ cdef bint _pandas_serialize_cell_symbol__str_pyobj( cdef bint _pandas_serialize_cell_symbol__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_symbol__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_symbol__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_symbol__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_symbol__str_i64_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_bool__bool_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_bool__bool_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_bool__bool_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__int_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__u8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__u16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__u32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__u64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] - cdef int64_t cell = access[row_index] + cdef int64_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): raise c_err_to_py(err) return True @@ -1453,91 +1432,80 @@ cdef bint _pandas_serialize_cell_column_i64__i64_numpy( cdef bint _pandas_serialize_cell_column_i64__u8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__u16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__u32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__u64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_i64__i64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_f64__float_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_f64__f32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_f64__f64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: cdef line_sender_error* err = NULL cdef double* access = col.cursor.chunk.buffers[1] - cdef double cell = access[row_index] + cdef double cell = access[col.cursor.offset] # TODO: Skip if NaN, then test degenerate case where all cells are NaN for a row. if isnan(cell): return True @@ -1550,28 +1518,25 @@ cdef bint _pandas_serialize_cell_column_f64__f64_numpy( cdef bint _pandas_serialize_cell_column_f64__f32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_f64__f64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_str__str_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 - _pandas_cell_str_pyobj_to_utf8(b, col, row_index, &valid, &utf8) + _pandas_cell_str_pyobj_to_utf8(b, col, &valid, &utf8) if valid and not line_sender_buffer_column_str(impl, col.name, utf8, &err): raise c_err_to_py(err) return True @@ -1580,67 +1545,59 @@ cdef bint _pandas_serialize_cell_column_str__str_pyobj( cdef bint _pandas_serialize_cell_column_str__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_str__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_str__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_str__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_str__str_i64_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_ts__dt64ns_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: raise ValueError('nyi') cdef bint _pandas_serialize_cell_at_dt64ns_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] - cdef int64_t cell = access[row_index] + cdef int64_t cell = access[col.cursor.offset] if cell == 0: if not line_sender_buffer_at_now(impl, &err): raise c_err_to_py(err) @@ -1654,116 +1611,113 @@ cdef bint _pandas_serialize_cell_at_dt64ns_numpy( cdef bint _pandas_serialize_cell_at_dt64ns_tz_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: - _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col, row_index) + col_t* col) except False: + _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col) cdef bint _pandas_serialize_cell( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col, - size_t row_index) except False: + col_t* col) except False: cdef col_dispatch_code_t dc = col.dispatch_code # Note!: Code below will generate a `switch` statement. # Ensure this happens! Don't break the `dc == ...` pattern. if dc == col_dispatch_code_t.col_dispatch_code_skip_nulls: pass # We skip a null column. Nothing to do. elif dc == col_dispatch_code_t.col_dispatch_code_table__str_pyobj: - _pandas_serialize_cell_table__str_pyobj(impl, b, col, row_index) + _pandas_serialize_cell_table__str_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_arrow: - _pandas_serialize_cell_table__str_arrow(impl, b, col, row_index) + _pandas_serialize_cell_table__str_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i8_cat: - _pandas_serialize_cell_table__str_i8_cat(impl, b, col, row_index) + _pandas_serialize_cell_table__str_i8_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i16_cat: - _pandas_serialize_cell_table__str_i16_cat(impl, b, col, row_index) + _pandas_serialize_cell_table__str_i16_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i32_cat: - _pandas_serialize_cell_table__str_i32_cat(impl, b, col, row_index) + _pandas_serialize_cell_table__str_i32_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i64_cat: - _pandas_serialize_cell_table__str_i64_cat(impl, b, col, row_index) + _pandas_serialize_cell_table__str_i64_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_pyobj: - _pandas_serialize_cell_symbol__str_pyobj(impl, b, col, row_index) + _pandas_serialize_cell_symbol__str_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_arrow: - _pandas_serialize_cell_symbol__str_arrow(impl, b, col, row_index) + _pandas_serialize_cell_symbol__str_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i8_cat: - _pandas_serialize_cell_symbol__str_i8_cat(impl, b, col, row_index) + _pandas_serialize_cell_symbol__str_i8_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i16_cat: - _pandas_serialize_cell_symbol__str_i16_cat(impl, b, col, row_index) + _pandas_serialize_cell_symbol__str_i16_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i32_cat: - _pandas_serialize_cell_symbol__str_i32_cat(impl, b, col, row_index) + _pandas_serialize_cell_symbol__str_i32_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i64_cat: - _pandas_serialize_cell_symbol__str_i64_cat(impl, b, col, row_index) + _pandas_serialize_cell_symbol__str_i64_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_pyobj: - _pandas_serialize_cell_column_bool__bool_pyobj(impl, b, col, row_index) + _pandas_serialize_cell_column_bool__bool_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_numpy: - _pandas_serialize_cell_column_bool__bool_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_bool__bool_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_arrow: - _pandas_serialize_cell_column_bool__bool_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_bool__bool_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__int_pyobj: - _pandas_serialize_cell_column_i64__int_pyobj(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__int_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_numpy: - _pandas_serialize_cell_column_i64__u8_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u8_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_numpy: - _pandas_serialize_cell_column_i64__i8_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i8_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_numpy: - _pandas_serialize_cell_column_i64__u16_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u16_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_numpy: - _pandas_serialize_cell_column_i64__i16_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i16_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_numpy: - _pandas_serialize_cell_column_i64__u32_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u32_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_numpy: - _pandas_serialize_cell_column_i64__i32_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i32_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_numpy: - _pandas_serialize_cell_column_i64__u64_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u64_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_numpy: - _pandas_serialize_cell_column_i64__i64_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i64_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_arrow: - _pandas_serialize_cell_column_i64__u8_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u8_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_arrow: - _pandas_serialize_cell_column_i64__i8_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i8_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_arrow: - _pandas_serialize_cell_column_i64__u16_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u16_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_arrow: - _pandas_serialize_cell_column_i64__i16_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i16_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_arrow: - _pandas_serialize_cell_column_i64__u32_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u32_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_arrow: - _pandas_serialize_cell_column_i64__i32_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i32_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_arrow: - _pandas_serialize_cell_column_i64__u64_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__u64_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_arrow: - _pandas_serialize_cell_column_i64__i64_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_i64__i64_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__float_pyobj: - _pandas_serialize_cell_column_f64__float_pyobj(impl, b, col, row_index) + _pandas_serialize_cell_column_f64__float_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_numpy: - _pandas_serialize_cell_column_f64__f32_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_f64__f32_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_numpy: - _pandas_serialize_cell_column_f64__f64_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_f64__f64_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_arrow: - _pandas_serialize_cell_column_f64__f32_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_f64__f32_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_arrow: - _pandas_serialize_cell_column_f64__f64_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_f64__f64_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_pyobj: - _pandas_serialize_cell_column_str__str_pyobj(impl, b, col, row_index) + _pandas_serialize_cell_column_str__str_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_arrow: - _pandas_serialize_cell_column_str__str_arrow(impl, b, col, row_index) + _pandas_serialize_cell_column_str__str_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i8_cat: - _pandas_serialize_cell_column_str__str_i8_cat(impl, b, col, row_index) + _pandas_serialize_cell_column_str__str_i8_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i16_cat: - _pandas_serialize_cell_column_str__str_i16_cat(impl, b, col, row_index) + _pandas_serialize_cell_column_str__str_i16_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i32_cat: - _pandas_serialize_cell_column_str__str_i32_cat(impl, b, col, row_index) + _pandas_serialize_cell_column_str__str_i32_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i64_cat: - _pandas_serialize_cell_column_str__str_i64_cat(impl, b, col, row_index) + _pandas_serialize_cell_column_str__str_i64_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_numpy: - _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col, row_index) + _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_numpy: - _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( - impl, b, col, row_index) + _pandas_serialize_cell_column_ts__dt64ns_tz_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_numpy: - _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col, row_index) + _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_tz_numpy: - _pandas_serialize_cell_at_dt64ns_tz_numpy(impl, b, col, row_index) + _pandas_serialize_cell_at_dt64ns_tz_numpy(impl, b, col) else: raise RuntimeError(f"Unknown column dispatch code: {dc}") # See earlier note about switch statement generation. @@ -1814,6 +1768,7 @@ cdef bint _pandas( cdef qdb_pystr_pos str_buf_marker cdef size_t row_count cdef line_sender_error* err = NULL + cdef size_t _row_index cdef size_t col_index cdef col_t* col @@ -1857,7 +1812,7 @@ cdef bint _pandas( # '\n') row_count = len(data) line_sender_buffer_clear_marker(impl) - for row_index in range(row_count): + for _row_index in range(row_count): qdb_pystr_buf_truncate(b, str_buf_marker) try: if not line_sender_buffer_set_marker(impl, &err): @@ -1874,7 +1829,7 @@ cdef bint _pandas( col = &cols.d[col_index] # TODO: Wrap error exceptions messaging with column name # and row index. Ideally, extract value in python too. - _pandas_serialize_cell(impl, b, col, row_index) + _pandas_serialize_cell(impl, b, col) _pandas_col_advance(col) # Fixed "at" value (not from a column). diff --git a/test/test.py b/test/test.py index eea4a267..e51dbf46 100755 --- a/test/test.py +++ b/test/test.py @@ -525,9 +525,9 @@ def test_basic(self): at=-1) self.assertEqual( buf, - 't1,A=a1,B=b1 1520640000000000000\n' + - 't2,A=a2,B=b2 1520726400000000000\n' + - 't1,A=a3,B=b3 1520812800000000000\n') + 't1,A=a1,B=b1,C=b1,D=a1 E=1.0,F=1i 1520640000000000000\n' + + 't2,A=a2,D=a2 E=2.0,F=2i 1520726400000000000\n' + + 't1,A=a3,B=b3,C=b3,D=a3 E=3.0,F=3i 1520812800000000000\n') if __name__ == '__main__': unittest.main() From 7c03446785679f59f223741a074bcb4ad15921f0 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 23 Nov 2022 18:46:56 +0000 Subject: [PATCH 061/147] Fixed another segfault. --- proj.py | 31 ++++++++++++++++++ src/questdb/pandas_integration.pxi | 52 +++++++++++++++++++----------- test/test.py | 15 +++++++++ 3 files changed, 79 insertions(+), 19 deletions(-) diff --git a/proj.py b/proj.py index ba7d0066..7a773a98 100755 --- a/proj.py +++ b/proj.py @@ -83,6 +83,37 @@ def gdb_test(*args): env=env) +@command +def rr_test(*args): + """ + Linux-only reverse debugger. + https://github.com/rr-debugger/rr + https://www.youtube.com/watch?v=61kD3x4Pu8I + + Install rr: + $ sudo apt install rr + $ sudo vim /proc/sys/kernel/perf_event_paranoid # set to -1 + """ + env = {'TEST_QUESTDB_PATCH_PATH': '1'} + try: + _run('rr', 'record', 'python3', 'test/test.py', '-v', *args, + env=env) + finally: + sys.stdout.flush() + sys.stderr.flush() + red = '\033[01;31m' + reset = '\033[0m' + sys.stderr.write(f'''\n{red} + Now first re-run marking stdout/stderr events with a unique ID: + $ rr -M replay -a + + Then re-run inside GDB, running up to a specific event: + $ rr replay -g $EVENT_ID + (rr) break ingress.c:9999 + (rr) continue # or step, next, etc.{reset}\n\n''') + + + @command def doc(http_serve=False, port=None): _run('python3', '-m', 'sphinx.cmd.build', diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 5157cbc1..09fc2fc5 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1,16 +1,6 @@ # See: pandas_integration.md for technical overview. -# cdef struct dtype_t: -# # See: https://numpy.org/doc/stable/reference/generated/numpy.dtype.html -# # ?highlight=dtype#numpy.dtype -# # See: https://numpy.org/doc/stable/reference/c-api -# # /types-and-structures.html#c.PyArray_Descr -# int alignment -# char kind -# int itemsize -# char byteorder -# bint hasobject - +import sys # TODO, remove me. cdef enum col_access_tag_t: numpy @@ -586,12 +576,13 @@ cdef bint _pandas_resolve_symbols( cdef object symbol cdef TaggedEntry entry if symbols is False: - return 0 + return True elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): tagged_cols[col_index].meta_target = \ meta_target_t.meta_target_symbol + return True else: if not isinstance(symbols, (tuple, list)): @@ -819,7 +810,7 @@ cdef bint _pandas_series_as_pybuf( cdef int get_buf_ret cdef bytes format cdef Py_buffer* view - import sys; sys.stderr.write(f'_pandas_series_as_pybuf :: (A) entry.name: {entry.name}\n') + sys.stderr.write(f'_pandas_series_as_pybuf :: (A) entry.name: {entry.name}\n') sys.stderr.write('_pandas_series_as_pybuf :: (C)\n') if not PyObject_CheckBuffer(nparr): sys.stderr.write('_pandas_series_as_pybuf :: (D)\n') @@ -949,7 +940,7 @@ cdef bint _pandas_series_sniff_pyobj( cdef size_t n_elements = len(entry.series) cdef PyObject** obj_arr cdef PyObject* obj - import sys; sys.stderr.write(f'_pandas_series_sniff_pyobj :: (A) buf: {col_out.pybuf.buf}, n_elements: {n_elements}, series:\n{entry.series}\n') + sys.stderr.write(f'_pandas_series_sniff_pyobj :: (A) buf: {col_out.pybuf.buf}, n_elements: {n_elements}, series:\n{entry.series}\n') _pandas_series_as_pybuf(entry, col_out) obj_arr = (col_out.pybuf.buf) sys.stderr.write('_pandas_series_sniff_pyobj :: (B)\n') @@ -1089,9 +1080,9 @@ cdef bint _pandas_resolve_source_and_buffers( col_out.source = col_source_t.col_source_dt64ns_tz_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY_OBJECT): - import sys; sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (A)\n') + sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (A)\n') _pandas_series_sniff_pyobj(entry, col_out) - import sys; sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (B)\n') + sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (B)\n') else: raise ValueError( f'Unsupported dtype {dtype} for column {entry.name}. ' + @@ -1132,7 +1123,7 @@ cdef bint _pandas_resolve_col( # Since we don't need to send the column names for 'table' and 'at' columns, # we don't need to validate and encode them as column names. - import sys; sys.stderr.write(f'_pandas_resolve_col :: (A) name: {entry.name}, dtype: {entry.dtype}\n') + sys.stderr.write(f'_pandas_resolve_col :: (A) name: {entry.name}, dtype: {entry.dtype}\n') if ((entry.meta_target != meta_target_t.meta_target_table) and (entry.meta_target != meta_target_t.meta_target_at)): sys.stderr.write('_pandas_resolve_col :: (B)\n') @@ -1182,7 +1173,7 @@ cdef bint _pandas_resolve_args( cdef ssize_t name_col cdef ssize_t at_col - import sys; sys.stderr.write('_pandas_resolve_args :: (A)\n') + sys.stderr.write('_pandas_resolve_args :: (A)\n') # List of Lists with col index, col name, series object, sorting key. cdef list tagged_cols = [ TaggedEntry( @@ -1774,7 +1765,7 @@ cdef bint _pandas( _pandas_may_import_deps() try: - import sys; sys.stderr.write(' :: :: (A)\n') + sys.stderr.write(' :: :: (A)\n') qdb_pystr_buf_clear(b) sys.stderr.write(' :: :: (B)\n') _check_is_pandas_dataframe(data) @@ -1811,40 +1802,63 @@ cdef bint _pandas( # f'field_indices: {size_t_vec_str(&field_indices)}' + # '\n') row_count = len(data) + sys.stderr.write(' :: :: (H)\n') line_sender_buffer_clear_marker(impl) + sys.stderr.write(' :: :: (I)\n') for _row_index in range(row_count): + sys.stderr.write(' :: :: (J)\n') qdb_pystr_buf_truncate(b, str_buf_marker) + sys.stderr.write(' :: :: (K)\n') try: + sys.stderr.write(' :: :: (L)\n') if not line_sender_buffer_set_marker(impl, &err): raise c_err_to_py(err) + sys.stderr.write(' :: :: (M)\n') # Fixed table-name. if c_table_name.buf != NULL: if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) + sys.stderr.write(' :: :: (N)\n') # Serialize columns cells. # Note: Columns are sorted: table name, symbols, fields, at. for col_index in range(col_count): + sys.stderr.write(' :: :: (O)\n') col = &cols.d[col_index] # TODO: Wrap error exceptions messaging with column name # and row index. Ideally, extract value in python too. _pandas_serialize_cell(impl, b, col) + sys.stderr.write(' :: :: (P)\n') _pandas_col_advance(col) + sys.stderr.write(' :: :: (Q)\n') + sys.stderr.write(' :: :: (R)\n') # Fixed "at" value (not from a column). if at_value == 0: + sys.stderr.write(' :: :: (S)\n') if not line_sender_buffer_at_now(impl, &err): raise c_err_to_py(err) + sys.stderr.write(' :: :: (T)\n') elif at_value > 0: + sys.stderr.write(' :: :: (U)\n') if not line_sender_buffer_at(impl, at_value, &err): raise c_err_to_py(err) + sys.stderr.write(' :: :: (V)\n') except: + sys.stderr.write(' :: :: (W)\n') if not line_sender_buffer_rewind_to_marker(impl, &err): raise c_err_to_py(err) + sys.stderr.write(' :: :: (X)\n') raise + sys.stderr.write(' :: :: (Y)\n') finally: + sys.stderr.write(' :: :: (Z)\n') line_sender_buffer_clear_marker(impl) + sys.stderr.write(' :: :: (a)\n') col_t_arr_release(&cols) + sys.stderr.write(' :: :: (b)\n') qdb_pystr_buf_clear(b) + sys.stderr.write(' :: :: (c)\n') + sys.stderr.write(' :: :: (d)\n') return True diff --git a/test/test.py b/test/test.py index e51dbf46..50871694 100755 --- a/test/test.py +++ b/test/test.py @@ -528,6 +528,21 @@ def test_basic(self): 't1,A=a1,B=b1,C=b1,D=a1 E=1.0,F=1i 1520640000000000000\n' + 't2,A=a2,D=a2 E=2.0,F=2i 1520726400000000000\n' + 't1,A=a3,B=b3,C=b3,D=a3 E=3.0,F=3i 1520812800000000000\n') + + def test_i32_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -2147483648, # i32 min + 0, + 2147483647], # i32 max + dtype='int32')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1,a=1i 0\n' + + 'tbl1,a=2i 0\n' + + 'tbl1,a=3i 0\n') + if __name__ == '__main__': unittest.main() From 80748ad7e11f7450136cd7878a16cd076691431a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 23 Nov 2022 18:49:45 +0000 Subject: [PATCH 062/147] Another bug bites the dust. --- src/questdb/pandas_integration.pxi | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 09fc2fc5..0f4b5c8d 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -580,9 +580,8 @@ cdef bint _pandas_resolve_symbols( elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): - tagged_cols[col_index].meta_target = \ - meta_target_t.meta_target_symbol - + entry = tagged_cols[col_index] + entry.meta_target = meta_target_t.meta_target_symbol return True else: if not isinstance(symbols, (tuple, list)): From 01d873223da9aa214ed2f8f32014051bf43388ee Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 23 Nov 2022 19:01:10 +0000 Subject: [PATCH 063/147] Implemented symbols='auto' and i32 column support. --- src/questdb/ingress.pyx | 6 ++++-- src/questdb/pandas_integration.pxi | 19 ++++++++++++++----- test/test.py | 9 ++++++--- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 09ac6184..7184ec6e 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -53,7 +53,8 @@ include "pandas_integration.pxi" from enum import Enum -from typing import List, Tuple, Dict, Union, Any, Optional, Callable, Iterable +from typing import List, Tuple, Dict, Union, Any, Optional, Callable, \ + Iterable, Literal import pathlib import sys @@ -979,7 +980,8 @@ cdef class Buffer: *, table_name: Optional[str] = None, table_name_col: Union[None, int, str] = None, - symbols: Union[bool, List[int], List[str]] = False, + symbols: Union[ + Literal['auto'], bool, List[int], List[str]] = 'auto', at: Union[None, int, str, TimestampNanos, datetime] = None, sort: bool = True): """ diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 0f4b5c8d..d7fd833a 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -575,14 +575,18 @@ cdef bint _pandas_resolve_symbols( cdef size_t col_index = 0 cdef object symbol cdef TaggedEntry entry - if symbols is False: - return True + if symbols == 'auto': + for col_index in range(col_count): + entry = tagged_cols[col_index] + if isinstance(entry.dtype, _PANDAS.CategoricalDtype): + entry.meta_target = meta_target_t.meta_target_symbol + elif symbols is False: + pass elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): entry = tagged_cols[col_index] entry.meta_target = meta_target_t.meta_target_symbol - return True else: if not isinstance(symbols, (tuple, list)): raise TypeError( @@ -612,7 +616,7 @@ cdef bint _pandas_resolve_symbols( symbol) entry = tagged_cols[col_index] entry.meta_target = meta_target_t.meta_target_symbol - return True + return True cdef bint _pandas_get_loc( @@ -1397,7 +1401,12 @@ cdef bint _pandas_serialize_cell_column_i64__i32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except False: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef int32_t* access = col.cursor.chunk.buffers[1] + cdef int32_t cell = access[col.cursor.offset] + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) + return True cdef bint _pandas_serialize_cell_column_i64__u64_numpy( diff --git a/test/test.py b/test/test.py index 50871694..b866a009 100755 --- a/test/test.py +++ b/test/test.py @@ -539,9 +539,12 @@ def test_i32_col(self): buf = _pandas(df, table_name='tbl1') self.assertEqual( buf, - 'tbl1,a=1i 0\n' + - 'tbl1,a=2i 0\n' + - 'tbl1,a=3i 0\n') + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-2147483648i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=2147483647i\n') if __name__ == '__main__': From 579e649044c7d97c6e2d4e6e9d16cbf8b2ce44c5 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 23 Nov 2022 21:40:41 +0000 Subject: [PATCH 064/147] Swapped out error prone 'bint / except False' declarations with 'void_int / except -1' declarations across all functions. --- src/questdb/ingress.pyx | 85 +++--- src/questdb/pandas_integration.pxi | 439 ++++++++++------------------- 2 files changed, 193 insertions(+), 331 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 7184ec6e..caf7a18c 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -48,6 +48,11 @@ from .pystr_to_utf8 cimport * from .arrow_c_data_interface cimport * from .extra_cpython cimport * +# An int we use only for error reporting. +# 0 is success. +# -1 is failure. +ctypedef int void_int + import cython include "pandas_integration.pxi" @@ -148,10 +153,10 @@ cdef str _fqn(type obj): return obj.__module__ + '.' + obj.__qualname__ -cdef bint str_to_utf8( +cdef void_int str_to_utf8( qdb_pystr_buf* b, PyObject* string, - line_sender_utf8* utf8_out) except False: + line_sender_utf8* utf8_out) except -1: """ Convert a Python string to a UTF-8 borrowed buffer. This is done without allocating new Python `bytes` objects. @@ -175,7 +180,6 @@ cdef bint str_to_utf8( if PyUnicode_IS_COMPACT_ASCII(string): utf8_out.len = count utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) - return True kind = PyUnicode_KIND(string) if kind == PyUnicode_1BYTE_KIND: @@ -211,13 +215,12 @@ cdef bint str_to_utf8( raise _utf8_decode_error(string, bad_codepoint) else: raise ValueError(f'Unknown UCS kind: {kind}.') - return True -cdef bint str_to_table_name( +cdef void_int str_to_table_name( qdb_pystr_buf* b, PyObject* string, - line_sender_table_name* name_out) except False: + line_sender_table_name* name_out) except -1: """ Python string to borrowed C table name. Also see `str_to_utf8`. @@ -227,13 +230,12 @@ cdef bint str_to_table_name( str_to_utf8(b, string, &utf8) if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): raise c_err_to_py(err) - return True -cdef bint str_to_column_name( +cdef void_int str_to_column_name( qdb_pystr_buf* b, str string, - line_sender_column_name* name_out) except False: + line_sender_column_name* name_out) except -1: """ Python string to borrowed C column name. Also see `str_to_utf8`. @@ -243,7 +245,6 @@ cdef bint str_to_column_name( str_to_utf8(b, string, &utf8) if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): raise c_err_to_py(err) - return True cdef int64_t datetime_to_micros(datetime dt): @@ -372,7 +373,7 @@ cdef class Sender cdef class Buffer -cdef int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: +cdef void_int may_flush_on_row_complete(Buffer buffer, Sender sender) except -1: if sender._auto_flush_enabled: if len(buffer) >= sender._auto_flush_watermark: sender.flush(buffer) @@ -532,12 +533,12 @@ cdef class Buffer: cdef const char* utf8 = line_sender_buffer_peek(self._impl, &size) return PyUnicode_FromStringAndSize(utf8, size) - cdef inline int _set_marker(self) except -1: + cdef inline void_int _set_marker(self) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_set_marker(self._impl, &err): raise c_err_to_py(err) - cdef inline int _rewind_to_marker(self) except -1: + cdef inline void_int _rewind_to_marker(self) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_rewind_to_marker(self._impl, &err): raise c_err_to_py(err) @@ -545,20 +546,19 @@ cdef class Buffer: cdef inline _clear_marker(self): line_sender_buffer_clear_marker(self._impl) - cdef inline int _table(self, str table_name) except -1: + cdef inline void_int _table(self, str table_name) except -1: cdef line_sender_error* err = NULL cdef line_sender_table_name c_table_name str_to_table_name( self._cleared_b(), table_name, &c_table_name) if not line_sender_buffer_table(self._impl, c_table_name, &err): raise c_err_to_py(err) - return 0 cdef inline qdb_pystr_buf* _cleared_b(self): qdb_pystr_buf_clear(self._b) return self._b - cdef inline int _symbol(self, str name, str value) except -1: + cdef inline void_int _symbol(self, str name, str value) except -1: cdef line_sender_error* err = NULL cdef line_sender_column_name c_name cdef line_sender_utf8 c_value @@ -566,68 +566,62 @@ cdef class Buffer: str_to_utf8(self._b, value, &c_value) if not line_sender_buffer_symbol(self._impl, c_name, c_value, &err): raise c_err_to_py(err) - return 0 - cdef inline int _column_bool( + cdef inline void_int _column_bool( self, line_sender_column_name c_name, bint value) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_column_bool(self._impl, c_name, value, &err): raise c_err_to_py(err) - return 0 - cdef inline int _column_i64( + cdef inline void_int _column_i64( self, line_sender_column_name c_name, int64_t value) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_column_i64(self._impl, c_name, value, &err): raise c_err_to_py(err) return 0 - cdef inline int _column_f64( + cdef inline void_int _column_f64( self, line_sender_column_name c_name, double value) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_column_f64(self._impl, c_name, value, &err): raise c_err_to_py(err) - return 0 - cdef inline int _column_str( + cdef inline void_int _column_str( self, line_sender_column_name c_name, str value) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 c_value str_to_utf8(self._b, value, &c_value) if not line_sender_buffer_column_str(self._impl, c_name, c_value, &err): raise c_err_to_py(err) - return 0 - cdef inline int _column_ts( + cdef inline void_int _column_ts( self, line_sender_column_name c_name, TimestampMicros ts) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_column_ts(self._impl, c_name, ts._value, &err): raise c_err_to_py(err) - return 0 - cdef inline int _column_dt( + cdef inline void_int _column_dt( self, line_sender_column_name c_name, datetime dt) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_column_ts( self._impl, c_name, datetime_to_micros(dt), &err): raise c_err_to_py(err) - return 0 - cdef inline int _column(self, str name, object value) except -1: + cdef inline void_int _column(self, str name, object value) except -1: cdef line_sender_column_name c_name str_to_column_name(self._cleared_b(), name, &c_name) if PyBool_Check(value): - return self._column_bool(c_name, value) + self._column_bool(c_name, value) elif PyLong_CheckExact(value): - return self._column_i64(c_name, value) + self._column_i64(c_name, value) elif PyFloat_CheckExact(value): - return self._column_f64(c_name, value) + self._column_f64(c_name, value) elif PyUnicode_CheckExact(value): - return self._column_str(c_name, value) + self._column_str(c_name, value) elif isinstance(value, TimestampMicros): - return self._column_ts(c_name, value) + self._column_ts(c_name, value) elif isinstance(value, datetime): - return self._column_dt(c_name, value) + self._column_dt(c_name, value) else: valid = ', '.join(( 'bool', @@ -639,7 +633,7 @@ cdef class Buffer: raise TypeError( f'Unsupported type: {type(value)}. Must be one of: {valid}') - cdef inline int _may_trigger_row_complete(self) except -1: + cdef inline void_int _may_trigger_row_complete(self) except -1: cdef line_sender_error* err = NULL cdef PyObject* sender = NULL if self._row_complete_sender != None: @@ -647,38 +641,35 @@ cdef class Buffer: if sender != NULL: may_flush_on_row_complete(self, sender) - cdef inline int _at_ts(self, TimestampNanos ts) except -1: + cdef inline void_int _at_ts(self, TimestampNanos ts) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_at(self._impl, ts._value, &err): raise c_err_to_py(err) - return 0 - cdef inline int _at_dt(self, datetime dt) except -1: + cdef inline void_int _at_dt(self, datetime dt) except -1: cdef int64_t value = datetime_to_nanos(dt) cdef line_sender_error* err = NULL if not line_sender_buffer_at(self._impl, value, &err): raise c_err_to_py(err) - return 0 - cdef inline int _at_now(self) except -1: + cdef inline void_int _at_now(self) except -1: cdef line_sender_error* err = NULL if not line_sender_buffer_at_now(self._impl, &err): raise c_err_to_py(err) - return 0 - cdef inline int _at(self, object ts) except -1: + cdef inline void_int _at(self, object ts) except -1: if ts is None: - return self._at_now() + self._at_now() elif isinstance(ts, TimestampNanos): - return self._at_ts(ts) + self._at_ts(ts) elif isinstance(ts, datetime): - return self._at_dt(ts) + self._at_dt(ts) else: raise TypeError( f'Unsupported type: {type(ts)}. Must be one of: ' + 'TimestampNanos, datetime, None') - cdef int _row( + cdef void_int _row( self, str table_name, dict symbols=None, diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index d7fd833a..b7c585af 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -471,9 +471,9 @@ cdef ssize_t _pandas_resolve_table_name( 'Must specify at least one of `table_name` or `table_name_col`.') -cdef bint _bind_col_index( +cdef void_int _bind_col_index( str arg_name, int col_num, size_t col_count, - size_t* col_index) except False: + size_t* col_index) except -1: """ Validate that `col_index` is in bounds for `col_count`. This function also converts negative indicies (e.g. -1 for last column) to @@ -491,7 +491,6 @@ cdef bint _bind_col_index( raise IndexError( f'Bad argument `{arg_name}`: {orig_col_num} index out of range') col_index[0] = col_num - return True cdef object _pandas_column_is_str(object data, int col_index): @@ -565,13 +564,13 @@ cdef class TaggedEntry: self.meta_target = meta_target -cdef bint _pandas_resolve_symbols( +cdef void_int _pandas_resolve_symbols( object data, list tagged_cols, ssize_t table_name_col, ssize_t at_col, object symbols, - size_t col_count) except False: + size_t col_count) except -1: cdef size_t col_index = 0 cdef object symbol cdef TaggedEntry entry @@ -616,18 +615,16 @@ cdef bint _pandas_resolve_symbols( symbol) entry = tagged_cols[col_index] entry.meta_target = meta_target_t.meta_target_symbol - return True -cdef bint _pandas_get_loc( +cdef void_int _pandas_get_loc( object data, str col_name, str arg_name, - size_t* col_index_out) except False: + size_t* col_index_out) except -1: """ Return the column index for `col_name`. """ try: col_index_out[0] = data.columns.get_loc(col_name) - return True except KeyError: raise KeyError( f'Bad argument `{arg_name}`: ' + @@ -688,116 +685,14 @@ cdef object _pandas_is_supported_datetime(object dtype): (not dtype.hasobject)) -# cdef int64_t _pandas_get_timestamp_cell( -# dtype_t* dtype, -# Py_buffer* col_buffer, -# size_t row_index) except -1: -# # Note: Type is pre-validated by `_pandas_is_supported_datetime`. -# cdef const void* cell = _pandas_get_cell(col_buffer, row_index) -# cdef int64_t res = (cell)[0] -# if res < 0: -# # TODO [amunra]: Improve error messaging. Add column name. -# raise ValueError( -# f'Bad value: Negative timestamp, got {res}') -# return res - - -# cdef bint _pandas_row_table_name( -# line_sender_buffer* impl, -# qdb_pystr_buf* b, -# dtype_t* dtypes, -# Py_buffer* col_buffers, -# ssize_t name_col, -# size_t row_index, -# line_sender_table_name c_table_name) except False: -# cdef line_sender_error* err = NULL -# cdef bint is_null = False -# cdef line_sender_utf8 utf8 -# if name_col >= 0: -# _pandas_get_str_cell( -# b, -# &dtypes[name_col], -# &col_buffers[name_col], -# row_index, -# &is_null, -# &utf8) -# if is_null: -# # TODO [amunra]: Improve error messaging. Add column name. -# raise ValueError( -# f'Bad value: `None` table name value at row {row_index}.') -# if not line_sender_table_name_init( -# &c_table_name, utf8.len, utf8.buf, &err): -# raise c_err_to_py(err) -# if not line_sender_buffer_table(impl, c_table_name, &err): -# raise c_err_to_py(err) -# return True - - -# cdef bint _pandas_row_symbols( -# line_sender_buffer* impl, -# qdb_pystr_buf* b, -# dtype_t* dtypes, -# Py_buffer* col_buffers, -# size_t row_index, -# const column_name_vec* symbol_names, -# const size_t_vec* symbol_indices) except False: -# cdef line_sender_error* err = NULL -# cdef size_t sym_index -# cdef size_t col_index -# cdef dtype_t* dtype -# cdef Py_buffer* col_buffer -# cdef line_sender_column_name col_name -# cdef line_sender_utf8 symbol -# cdef bint is_null = False -# for sym_index in range(symbol_indices.size): -# col_name = symbol_names.d[sym_index] -# col_index = symbol_indices.d[sym_index] -# col_buffer = &col_buffers[col_index] -# dtype = &dtypes[col_index] -# _pandas_get_str_cell( -# b, -# dtype, -# col_buffer, -# row_index, -# &is_null, -# &symbol) -# if not is_null: -# if not line_sender_buffer_symbol(impl, col_name, symbol, &err): -# raise c_err_to_py(err) -# return True - - -# cdef bint _pandas_row_at( -# line_sender_buffer* impl, -# dtype_t* dtypes, -# Py_buffer* col_buffers, -# size_t row_index, -# ssize_t at_col, -# int64_t at_value) except False: -# cdef line_sender_error* err = NULL -# cdef Py_buffer* col_buffer -# cdef dtype_t* dtype -# if at_col >= 0: -# col_buffer = &col_buffers[at_col] -# dtype = &dtypes[at_col] -# at_value = _pandas_get_timestamp_cell(dtype, col_buffer, row_index) -# if at_value > 0: -# if not line_sender_buffer_at(impl, at_value, &err): -# raise c_err_to_py(err) -# else: -# if not line_sender_buffer_at_now(impl, &err): -# raise c_err_to_py(err) -# return True - - -cdef bint _pandas_alloc_chunks(size_t n_chunks, col_t* col_out) except False: +cdef void_int _pandas_alloc_chunks( + size_t n_chunks, col_t* col_out) except -1: col_out.chunks.n_chunks = n_chunks col_out.chunks.chunks = calloc( col_out.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. sizeof(ArrowArray)) if col_out.chunks.chunks == NULL: raise MemoryError() - return True cdef void _pandas_free_mapped_arrow(ArrowArray* arr): @@ -806,12 +701,11 @@ cdef void _pandas_free_mapped_arrow(ArrowArray* arr): arr.release = NULL -cdef bint _pandas_series_as_pybuf( - TaggedEntry entry, col_t* col_out) except False: +cdef void_int _pandas_series_as_pybuf( + TaggedEntry entry, col_t* col_out) except -1: cdef object nparr = entry.series.to_numpy() cdef ArrowArray* mapped cdef int get_buf_ret - cdef bytes format cdef Py_buffer* view sys.stderr.write(f'_pandas_series_as_pybuf :: (A) entry.name: {entry.name}\n') sys.stderr.write('_pandas_series_as_pybuf :: (C)\n') @@ -853,13 +747,12 @@ cdef bint _pandas_series_as_pybuf( mapped.children = NULL mapped.dictionary = NULL mapped.release = _pandas_free_mapped_arrow # to cleanup allocated array. - return True -cdef bint _pandas_series_as_arrow( +cdef void_int _pandas_series_as_arrow( TaggedEntry entry, col_t* col_out, - col_source_t np_fallback) except False: + col_source_t np_fallback) except -1: cdef object array cdef list chunks cdef size_t n_chunks @@ -867,7 +760,7 @@ cdef bint _pandas_series_as_arrow( if _PYARROW is None: col_out.source = np_fallback _pandas_series_as_pybuf(entry, col_out) - return True + return 0 col_out.tag = col_access_tag_t.arrow array = _PYARROW.Array.from_pandas(entry.series) @@ -888,7 +781,6 @@ cdef bint _pandas_series_as_arrow( else: chunks[chunk_index]._export_to_c( &col_out.chunks.chunks[chunk_index]) - return True cdef const char* _ARROW_FMT_INT8 = "c" @@ -897,13 +789,13 @@ cdef const char* _ARROW_FMT_INT32 = "i" cdef const char* _ARROW_FMT_INT64 = "l" -cdef bint _pandas_category_series_as_arrow( - TaggedEntry entry, col_t* col_out) except False: +cdef void_int _pandas_category_series_as_arrow( + TaggedEntry entry, col_t* col_out) except -1: cdef const char* format col_out.source = col_source_t.col_source_nulls # placeholder value. _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_str_pyobj) if col_out.source == col_source_t.col_source_str_pyobj: - return True # PyArrow wasn't imported. + return 0 # PyArrow wasn't imported. format = col_out.arrow_schema.format if strncmp(format, _ARROW_FMT_INT8, 1) == 0: col_out.source = col_source_t.col_source_str_i8_cat @@ -917,14 +809,12 @@ cdef bint _pandas_category_series_as_arrow( raise TypeError( f'Bad column {entry.name!r}: Expected an arrow category index ' + f'format, got {(format).decode("utf-8")!r}') - return True cdef inline bint _pandas_is_float_nan(PyObject* obj): return PyFloat_CheckExact(obj) and isnan(PyFloat_AS_DOUBLE(obj)) -# TODO: Check for pointless incref at callsite or here. cdef inline bint _pandas_is_null_pyobj(PyObject* obj): return ( (obj == Py_None) or @@ -932,8 +822,8 @@ cdef inline bint _pandas_is_null_pyobj(PyObject* obj): _pandas_is_float_nan(obj)) -cdef bint _pandas_series_sniff_pyobj( - TaggedEntry entry, col_t* col_out) except False: +cdef void_int _pandas_series_sniff_pyobj( + TaggedEntry entry, col_t* col_out) except -1: """ Deduct the type of the object column. Object columns can contain pretty much anything, but they usually don't. @@ -949,39 +839,38 @@ cdef bint _pandas_series_sniff_pyobj( sys.stderr.write('_pandas_series_sniff_pyobj :: (B)\n') for el_index in range(n_elements): obj = obj_arr[el_index] - if _pandas_is_null_pyobj(obj): - continue - elif PyBool_Check(obj): - col_out.source = col_source_t.col_source_bool_pyobj - elif PyLong_CheckExact(obj): - col_out.source = col_source_t.col_source_int_pyobj - elif PyFloat_CheckExact(obj): - col_out.source = col_source_t.col_source_float_pyobj - elif PyUnicode_CheckExact(obj): - col_out.source = col_source_t.col_source_str_pyobj - elif PyBytes_CheckExact(obj): - raise ValueError( - f'Bad column {entry.name!r}: ' + - 'Unsupported object column containing bytes.' + - 'If this is a string column, decode it first. ' + - 'See: https://stackoverflow.com/questions/40389764/') - else: - raise TypeError( - f'Bad column {entry.name!r}: ' + - f'Unsupported object column containing an {_fqn(type(obj))}') - sys.stderr.write('_pandas_series_sniff_pyobj :: (D)\n') - return True + if not _pandas_is_null_pyobj(obj): + if PyBool_Check(obj): + col_out.source = col_source_t.col_source_bool_pyobj + elif PyLong_CheckExact(obj): + col_out.source = col_source_t.col_source_int_pyobj + elif PyFloat_CheckExact(obj): + col_out.source = col_source_t.col_source_float_pyobj + elif PyUnicode_CheckExact(obj): + col_out.source = col_source_t.col_source_str_pyobj + elif PyBytes_CheckExact(obj): + raise ValueError( + f'Bad column {entry.name!r}: ' + + 'Unsupported object column containing bytes.' + + 'If this is a string column, decode it first. ' + + 'See: https://stackoverflow.com/questions/40389764/') + else: + raise TypeError( + f'Bad column {entry.name!r}: ' + + f'Unsupported object column containing an {_fqn(type(obj))}') + sys.stderr.write('_pandas_series_sniff_pyobj :: (D)\n') + return 0 sys.stderr.write('_pandas_series_sniff_pyobj :: (E)\n') - # We've hit an object column that exclusively has null values. - # We will just skip this column. + # TODO: Test all-null columns (this will probably break the API). + # We haven't returned yet, so we've hit an object column that + # exclusively has null values. We will just skip this column. col_out.source = col_source_t.col_source_nulls sys.stderr.write('_pandas_series_sniff_pyobj :: (F)\n') - return True -cdef bint _pandas_resolve_source_and_buffers( - TaggedEntry entry, col_t* col_out) except False: +cdef void_int _pandas_resolve_source_and_buffers( + TaggedEntry entry, col_t* col_out) except -1: cdef object dtype = entry.dtype if isinstance(dtype, _NUMPY_BOOL): col_out.source = col_source_t.col_source_bool_numpy @@ -1091,21 +980,20 @@ cdef bint _pandas_resolve_source_and_buffers( f'Unsupported dtype {dtype} for column {entry.name}. ' + 'Raise an issue if you think it should be supported: ' + 'https://github.com/questdb/py-questdb-client/issues.') - return True -cdef bint _pandas_resolve_target( - TaggedEntry entry, col_t* col_out) except False: +cdef void_int _pandas_resolve_target( + TaggedEntry entry, col_t* col_out) except -1: cdef col_target_t target cdef set target_sources if entry.meta_target in _DIRECT_META_TARGETS: col_out.target = entry.meta_target - return True + return 0 for target in _FIELD_TARGETS: target_sources = _TARGET_TO_SOURCES[target] if col_out.source in target_sources: col_out.target = target - return True + return 0 raise ValueError( f'Could not map column source type (code {col_out.source} for ' + f'{entry.dtype!r}) {entry.name}.') @@ -1117,11 +1005,11 @@ cdef void _pandas_init_cursor(col_t* col_out): col_out.cursor.offset = col_out.cursor.chunk.offset -cdef bint _pandas_resolve_col( +cdef void_int _pandas_resolve_col( qdb_pystr_buf* b, size_t index, TaggedEntry entry, - col_t* col_out) except False: + col_t* col_out) except -1: col_out.orig_index = entry.orig_index # Since we don't need to send the column names for 'table' and 'at' columns, @@ -1149,20 +1037,17 @@ cdef bint _pandas_resolve_col( sys.stderr.write('_pandas_resolve_col :: (I)\n') _pandas_init_cursor(col_out) sys.stderr.write('_pandas_resolve_col :: (J)\n') - return True - -cdef bint _pandas_resolve_cols( - qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except False: +cdef void_int _pandas_resolve_cols( + qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except -1: cdef size_t index cdef size_t len_tagged_cols = len(tagged_cols) for index in range(len_tagged_cols): _pandas_resolve_col(b, index, tagged_cols[index], &cols_out.d[index]) - return True -cdef bint _pandas_resolve_args( +cdef void_int _pandas_resolve_args( object data, object table_name, object table_name_col, @@ -1172,7 +1057,7 @@ cdef bint _pandas_resolve_args( size_t col_count, line_sender_table_name* c_table_name_out, int64_t* at_value_out, - col_t_arr* cols_out) except False: + col_t_arr* cols_out) except -1: cdef ssize_t name_col cdef ssize_t at_col @@ -1208,32 +1093,29 @@ cdef bint _pandas_resolve_args( sys.stderr.write('_pandas_resolve_args :: (E)\n') _pandas_resolve_cols(b, tagged_cols, cols_out) sys.stderr.write('_pandas_resolve_args :: (F)\n') - return True -cdef inline bint _pandas_cell_str_pyobj_to_utf8( +cdef inline void_int _pandas_cell_str_pyobj_to_utf8( qdb_pystr_buf* b, col_t* col, bint* valid_out, - line_sender_utf8* utf8_out) except False: + line_sender_utf8* utf8_out) except -1: cdef PyObject** access = col.cursor.chunk.buffers[1] cdef PyObject* cell = access[col.cursor.offset] if _pandas_is_null_pyobj(cell): valid_out[0] = False - return True elif PyUnicode_CheckExact(cell): str_to_utf8(b, cell, utf8_out) valid_out[0] = True - return True else: raise ValueError( f'Expected an object of type str, got a {_fqn(type(cell))}') -cdef bint _pandas_serialize_cell_table__str_pyobj( +cdef void_int _pandas_serialize_cell_table__str_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef PyObject** access = col.cursor.chunk.buffers[1] cdef PyObject* cell = access[col.cursor.offset] @@ -1244,13 +1126,12 @@ cdef bint _pandas_serialize_cell_table__str_pyobj( str_to_table_name(b, cell, &c_table_name) if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) - return True -cdef bint _pandas_serialize_cell_table__str_arrow( +cdef void_int _pandas_serialize_cell_table__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef line_sender_table_name c_table_name cdef uint8_t* validity_access = col.cursor.chunk.buffers[0] @@ -1258,342 +1139,336 @@ cdef bint _pandas_serialize_cell_table__str_arrow( raise ValueError('Not implemented') -cdef bint _pandas_serialize_cell_table__str_i8_cat( +cdef void_int _pandas_serialize_cell_table__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_table__str_i16_cat( +cdef void_int _pandas_serialize_cell_table__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_table__str_i32_cat( +cdef void_int _pandas_serialize_cell_table__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_table__str_i64_cat( +cdef void_int _pandas_serialize_cell_table__str_i64_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_symbol__str_pyobj( +cdef void_int _pandas_serialize_cell_symbol__str_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 _pandas_cell_str_pyobj_to_utf8(b, col, &valid, &utf8) if valid and not line_sender_buffer_symbol(impl, col.name, utf8, &err): raise c_err_to_py(err) - return True -cdef bint _pandas_serialize_cell_symbol__str_arrow( +cdef void_int _pandas_serialize_cell_symbol__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_symbol__str_i8_cat( +cdef void_int _pandas_serialize_cell_symbol__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_symbol__str_i16_cat( +cdef void_int _pandas_serialize_cell_symbol__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_symbol__str_i32_cat( +cdef void_int _pandas_serialize_cell_symbol__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_symbol__str_i64_cat( +cdef void_int _pandas_serialize_cell_symbol__str_i64_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_bool__bool_pyobj( +cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_bool__bool_numpy( +cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_bool__bool_arrow( +cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__int_pyobj( +cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__u8_numpy( +cdef void_int _pandas_serialize_cell_column_i64__u8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i8_numpy( +cdef void_int _pandas_serialize_cell_column_i64__i8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__u16_numpy( +cdef void_int _pandas_serialize_cell_column_i64__u16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i16_numpy( +cdef void_int _pandas_serialize_cell_column_i64__i16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__u32_numpy( +cdef void_int _pandas_serialize_cell_column_i64__u32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i32_numpy( +cdef void_int _pandas_serialize_cell_column_i64__i32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef int32_t* access = col.cursor.chunk.buffers[1] cdef int32_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): raise c_err_to_py(err) - return True -cdef bint _pandas_serialize_cell_column_i64__u64_numpy( +cdef void_int _pandas_serialize_cell_column_i64__u64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i64_numpy( +cdef void_int _pandas_serialize_cell_column_i64__i64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): raise c_err_to_py(err) - return True -cdef bint _pandas_serialize_cell_column_i64__u8_arrow( +cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i8_arrow( +cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__u16_arrow( +cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i16_arrow( +cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__u32_arrow( +cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i32_arrow( +cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__u64_arrow( +cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_i64__i64_arrow( +cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_f64__float_pyobj( +cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_f64__f32_numpy( +cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_f64__f64_numpy( +cdef void_int _pandas_serialize_cell_column_f64__f64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef double* access = col.cursor.chunk.buffers[1] cdef double cell = access[col.cursor.offset] # TODO: Skip if NaN, then test degenerate case where all cells are NaN for a row. if isnan(cell): - return True + return 0 if not line_sender_buffer_column_f64(impl, col.name, cell, &err): raise c_err_to_py(err) - return True - -cdef bint _pandas_serialize_cell_column_f64__f32_arrow( +cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_f64__f64_arrow( +cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_str__str_pyobj( +cdef void_int _pandas_serialize_cell_column_str__str_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 _pandas_cell_str_pyobj_to_utf8(b, col, &valid, &utf8) if valid and not line_sender_buffer_column_str(impl, col.name, utf8, &err): raise c_err_to_py(err) - return True -cdef bint _pandas_serialize_cell_column_str__str_arrow( +cdef void_int _pandas_serialize_cell_column_str__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_str__str_i8_cat( +cdef void_int _pandas_serialize_cell_column_str__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_str__str_i16_cat( +cdef void_int _pandas_serialize_cell_column_str__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_str__str_i32_cat( +cdef void_int _pandas_serialize_cell_column_str__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_str__str_i64_cat( +cdef void_int _pandas_serialize_cell_column_str__str_i64_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_ts__dt64ns_numpy( +cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( +cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: raise ValueError('nyi') -cdef bint _pandas_serialize_cell_at_dt64ns_numpy( +cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] @@ -1604,20 +1479,19 @@ cdef bint _pandas_serialize_cell_at_dt64ns_numpy( # Note: impl will validate against negative numbers. if not line_sender_buffer_at(impl, cell, &err): raise c_err_to_py(err) - return True -cdef bint _pandas_serialize_cell_at_dt64ns_tz_numpy( +cdef void_int _pandas_serialize_cell_at_dt64ns_tz_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col) -cdef bint _pandas_serialize_cell( +cdef void_int _pandas_serialize_cell( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except False: + col_t* col) except -1: cdef col_dispatch_code_t dc = col.dispatch_code # Note!: Code below will generate a `switch` statement. # Ensure this happens! Don't break the `dc == ...` pattern. @@ -1722,8 +1596,6 @@ cdef bint _pandas_serialize_cell( # See earlier note about switch statement generation. # Don't add complex conditions above! - return True - cdef void _pandas_col_advance(col_t* col): # Branchless version of: @@ -1751,7 +1623,7 @@ cdef void _pandas_col_advance(col_t* col): ((not new_chunk) * cursor.offset)) -cdef bint _pandas( +cdef void_int _pandas( line_sender_buffer* impl, qdb_pystr_buf* b, object data, @@ -1759,7 +1631,7 @@ cdef bint _pandas( object table_name_col, object symbols, object at, - bint sort) except False: + bint sort) except -1: cdef size_t col_count cdef line_sender_table_name c_table_name cdef int64_t at_value = _AT_SET_BY_COLUMN @@ -1869,4 +1741,3 @@ cdef bint _pandas( qdb_pystr_buf_clear(b) sys.stderr.write(' :: :: (c)\n') sys.stderr.write(' :: :: (d)\n') - return True From df823b7fe1fb77a552461c737bcdc5527f07aff7 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 24 Nov 2022 18:41:05 +0000 Subject: [PATCH 065/147] More string trouble. --- c-questdb-client | 2 +- src/questdb/extra_cpython.pxd | 6 +- src/questdb/ingress.pyx | 28 ++-- src/questdb/pandas_integration.pxi | 122 ++++++++++------ test/test.py | 217 ++++++++++++++++++++++++++++- 5 files changed, 320 insertions(+), 55 deletions(-) diff --git a/c-questdb-client b/c-questdb-client index 2cd4e7fb..96cc3af6 160000 --- a/c-questdb-client +++ b/c-questdb-client @@ -1 +1 @@ -Subproject commit 2cd4e7fb3ad10b20a7de28527cdf18cf240b9634 +Subproject commit 96cc3af6745a7c6aa1b8cb6cb8feef8de0a6a8eb diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd index f7548310..0b7a87d6 100644 --- a/src/questdb/extra_cpython.pxd +++ b/src/questdb/extra_cpython.pxd @@ -30,11 +30,15 @@ cdef extern from "Python.h": int PyUnicode_READY(PyObject* o) except -1 # Is UCS1 and ascii (and therefore valid UTF-8). - bint PyUnicode_IS_COMPACT_ASCII(PyObject* o) + bint PyUnicode_IS_COMPACT(PyObject* o) # Get length. Py_ssize_t PyUnicode_GET_LENGTH(PyObject* o) + # Get or compute the UTF-8 representation. + const char* PyUnicode_AsUTF8AndSize( + PyObject* o, Py_ssize_t* size) except NULL + # Zero-copy access to string buffer. int PyUnicode_KIND(PyObject* o) Py_UCS1* PyUnicode_1BYTE_DATA(PyObject* o) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index caf7a18c..fabeb550 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -31,7 +31,8 @@ API for fast data ingestion into QuestDB. """ # For prototypes: https://github.com/cython/cython/tree/master/Cython/Includes -from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t +from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t, \ + INT64_MAX from libc.stdlib cimport malloc, calloc, realloc, free, abort from libc.string cimport strncmp from libc.math cimport isnan @@ -74,6 +75,7 @@ class IngressErrorCode(Enum): InvalidTimestamp = line_sender_error_invalid_timestamp AuthError = line_sender_error_auth_error TlsError = line_sender_error_tls_error + BadDataFrame = line_sender_error_tls_error + 1 def __str__(self) -> str: """Return the name of the enum.""" @@ -141,7 +143,8 @@ cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): return IngressError(tup[0], fmt.format(tup[1])) -cdef object _utf8_decode_error(PyObject* string, uint32_t bad_codepoint): +cdef void_int _utf8_decode_error( + PyObject* string, uint32_t bad_codepoint) except -1: cdef str s = string return IngressError( IngressErrorCode.InvalidUtf8, @@ -159,11 +162,15 @@ cdef void_int str_to_utf8( line_sender_utf8* utf8_out) except -1: """ Convert a Python string to a UTF-8 borrowed buffer. - This is done without allocating new Python `bytes` objects. - In case the string is an ASCII string, it's also generally zero-copy. + This is done without asking Python to allocate any memory. + In case the string is an ASCII string (or a previously encoded UTF-8 buffer) + it's also zero-copy. The `utf8_out` param will point to (borrow from) either the ASCII buffer inside the original Python object or a part of memory allocated inside the `b` buffer. + + To make sense of it, see: https://peps.python.org/pep-0393/ + Specifically the sections on UCS-1, UCS-2 and UCS-4 and compact strings. """ cdef size_t count cdef int kind @@ -171,16 +178,15 @@ cdef void_int str_to_utf8( if not PyUnicode_CheckExact(string): raise TypeError( f'Expected a str object, not a {_fqn(type(string))}') - PyUnicode_READY(string) - count = (PyUnicode_GET_LENGTH(string)) + PyUnicode_READY(string) # TODO: Can this be moved after the "Compact" check? - # We optimize the common case of ASCII strings. + # We optimize the common case of ASCII strings and pre-encoded UTF-8. # This avoid memory allocations and copies altogether. - # We get away with this because ASCII is a subset of UTF-8. - if PyUnicode_IS_COMPACT_ASCII(string): - utf8_out.len = count - utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) + if PyUnicode_IS_COMPACT(string): + utf8_out.buf = PyUnicode_AsUTF8AndSize(string, &utf8_out.len) + return 0 + count = (PyUnicode_GET_LENGTH(string)) kind = PyUnicode_KIND(string) if kind == PyUnicode_1BYTE_KIND: # No error handling for UCS1: All code points translate into valid UTF8. diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index b7c585af..c78eb8c7 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1225,7 +1225,12 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef uint8_t* access = col.cursor.chunk.buffers[1] + cdef uint8_t cell = access[col.cursor.offset] + cdef bint value = not not cell # Force to 0 and 1. + if not line_sender_buffer_column_bool(impl, col.name, value, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( @@ -1246,35 +1251,55 @@ cdef void_int _pandas_serialize_cell_column_i64__u8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef uint8_t* access = col.cursor.chunk.buffers[1] + cdef uint8_t cell = access[col.cursor.offset] + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef int8_t* access = col.cursor.chunk.buffers[1] + cdef int8_t cell = access[col.cursor.offset] + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef uint16_t* access = col.cursor.chunk.buffers[1] + cdef uint16_t cell = access[col.cursor.offset] + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef int16_t* access = col.cursor.chunk.buffers[1] + cdef int16_t cell = access[col.cursor.offset] + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef uint32_t* access = col.cursor.chunk.buffers[1] + cdef uint32_t cell = access[col.cursor.offset] + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i32_numpy( @@ -1292,7 +1317,13 @@ cdef void_int _pandas_serialize_cell_column_i64__u64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef uint64_t* access = col.cursor.chunk.buffers[1] + cdef uint64_t cell = access[col.cursor.offset] + if cell > INT64_MAX: + raise OverflowError('uint64 value too large for int64 column type.') + if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i64_numpy( @@ -1373,7 +1404,12 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + # Note: This is the C `float` type, not the Python `float` type. + cdef float* access = col.cursor.chunk.buffers[1] + cdef float cell = access[col.cursor.offset] + if not line_sender_buffer_column_f64(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__f64_numpy( @@ -1383,9 +1419,6 @@ cdef void_int _pandas_serialize_cell_column_f64__f64_numpy( cdef line_sender_error* err = NULL cdef double* access = col.cursor.chunk.buffers[1] cdef double cell = access[col.cursor.offset] - # TODO: Skip if NaN, then test degenerate case where all cells are NaN for a row. - if isnan(cell): - return 0 if not line_sender_buffer_column_f64(impl, col.name, cell, &err): raise c_err_to_py(err) @@ -1455,14 +1488,19 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef int64_t* access = col.cursor.chunk.buffers[1] + cdef int64_t cell = access[col.cursor.offset] + cell //= 1000 # Convert from nanoseconds to microseconds. + if not line_sender_buffer_column_ts(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col) cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( @@ -1639,7 +1677,7 @@ cdef void_int _pandas( cdef qdb_pystr_pos str_buf_marker cdef size_t row_count cdef line_sender_error* err = NULL - cdef size_t _row_index + cdef size_t row_index cdef size_t col_index cdef col_t* col @@ -1673,27 +1711,24 @@ cdef void_int _pandas( str_buf_marker = qdb_pystr_buf_tell(b) sys.stderr.write(' :: :: (G)\n') - # import sys - # sys.stderr.write('_pandas :: (A) ' + - # f'name_col: {name_col}, ' + - # f'symbol_indices: {size_t_vec_str(&symbol_indices)}, ' + - # f'at_col: {at_col}, ' + - # f'at_value: {at_value}, ' + - # f'field_indices: {size_t_vec_str(&field_indices)}' + - # '\n') row_count = len(data) sys.stderr.write(' :: :: (H)\n') line_sender_buffer_clear_marker(impl) - sys.stderr.write(' :: :: (I)\n') - for _row_index in range(row_count): - sys.stderr.write(' :: :: (J)\n') - qdb_pystr_buf_truncate(b, str_buf_marker) - sys.stderr.write(' :: :: (K)\n') - try: - sys.stderr.write(' :: :: (L)\n') - if not line_sender_buffer_set_marker(impl, &err): - raise c_err_to_py(err) + # On error, undo all added lines. + if not line_sender_buffer_set_marker(impl, &err): + raise c_err_to_py(err) + + try: + sys.stderr.write(' :: :: (I)\n') + for row_index in range(row_count): + # TODO: Occasional GIL release logic (e.g. every 5000 rows or so) + # TODO: Potentially avoid the GIL altogether if we can get away with it. + # This is column-type dependent. Some basic analysis is required. + # We need a `GilController` object so that we can raise exceptions. + sys.stderr.write(' :: :: (J)\n') + qdb_pystr_buf_truncate(b, str_buf_marker) + sys.stderr.write(' :: :: (K)\n') sys.stderr.write(' :: :: (M)\n') # Fixed table-name. if c_table_name.buf != NULL: @@ -1708,7 +1743,16 @@ cdef void_int _pandas( col = &cols.d[col_index] # TODO: Wrap error exceptions messaging with column name # and row index. Ideally, extract value in python too. - _pandas_serialize_cell(impl, b, col) + try: + _pandas_serialize_cell(impl, b, col) + except Exception as e: + raise IngressError( + IngressErrorCode.BadDataFrame, + 'Failed to serialize value of column ' + + repr(data.columns[col.orig_index]) + + f' at row index {row_index} (' + + repr(data.iloc[row_index, col.orig_index]) + + f'): {e}') from e sys.stderr.write(' :: :: (P)\n') _pandas_col_advance(col) sys.stderr.write(' :: :: (Q)\n') @@ -1725,13 +1769,13 @@ cdef void_int _pandas( if not line_sender_buffer_at(impl, at_value, &err): raise c_err_to_py(err) sys.stderr.write(' :: :: (V)\n') - except: - sys.stderr.write(' :: :: (W)\n') - if not line_sender_buffer_rewind_to_marker(impl, &err): - raise c_err_to_py(err) - sys.stderr.write(' :: :: (X)\n') - raise - sys.stderr.write(' :: :: (Y)\n') + except: + sys.stderr.write(' :: :: (W)\n') + if not line_sender_buffer_rewind_to_marker(impl, &err): + raise c_err_to_py(err) + sys.stderr.write(' :: :: (X)\n') + raise + sys.stderr.write(' :: :: (Y)\n') finally: sys.stderr.write(' :: :: (Z)\n') line_sender_buffer_clear_marker(impl) diff --git a/test/test.py b/test/test.py index b866a009..3385cfe3 100755 --- a/test/test.py +++ b/test/test.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import sys -from typing import Type sys.dont_write_bytecode = True import os import unittest @@ -528,8 +527,85 @@ def test_basic(self): 't1,A=a1,B=b1,C=b1,D=a1 E=1.0,F=1i 1520640000000000000\n' + 't2,A=a2,D=a2 E=2.0,F=2i 1520726400000000000\n' + 't1,A=a3,B=b3,C=b3,D=a3 E=3.0,F=3i 1520812800000000000\n') - - def test_i32_col(self): + + def test_u8_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 255], # u8 max + dtype='uint8')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=255i\n') + + def test_i8_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -128, # i8 min + 127, # i8 max + 0], dtype='int8')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-128i\n' + + 'tbl1 a=127i\n' + + 'tbl1 a=0i\n') + + def test_u16_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 65535], # u16 max + dtype='uint16')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=65535i\n') + + def test_i16_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -32768, # i16 min + 32767, # i16 max + 0], dtype='int16')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-32768i\n' + + 'tbl1 a=32767i\n' + + 'tbl1 a=0i\n') + + def test_u32_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 4294967295], # u32 max + dtype='uint32')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=4294967295i\n') + + def test_i32_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ 1, 2, 3, -2147483648, # i32 min @@ -546,6 +622,141 @@ def test_i32_col(self): 'tbl1 a=0i\n' + 'tbl1 a=2147483647i\n') + def test_u64_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 9223372036854775807], # i64 max + dtype='uint64')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=9223372036854775807i\n') + + buf = qi.Buffer() + buf.pandas(pd.DataFrame({'b': [.5, 1.0, 1.5]}), table_name='tbl2') + exp1 = ( + 'tbl2 b=0.5\n' + + 'tbl2 b=1.0\n' + + 'tbl2 b=1.5\n') + self.assertEqual( + str(buf), + exp1) + df2 = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 9223372036854775808], # i64 max + 1 + dtype='uint64')}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): + buf.pandas(df2, table_name='tbl1') + + self.assertEqual( + str(buf), + exp1) # No partial write of `df2`. + + def test_i64_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -9223372036854775808, # i64 min + 0, + 9223372036854775807], # i64 max + dtype='int64')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-9223372036854775808i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=9223372036854775807i\n') + + def test_f32_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 3.4028234663852886e38], # f32 max + dtype='float32')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0\n' + + 'tbl1 a=2.0\n' + + 'tbl1 a=3.0\n' + + 'tbl1 a=0.0\n' + + 'tbl1 a=Infinity\n' + + 'tbl1 a=-Infinity\n' + + 'tbl1 a=NaN\n' + + 'tbl1 a=3.4028234663852886e38\n') + + def test_f64_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 1.7976931348623157e308], # f64 max + dtype='float64')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0\n' + + 'tbl1 a=2.0\n' + + 'tbl1 a=3.0\n' + + 'tbl1 a=0.0\n' + + 'tbl1 a=Infinity\n' + + 'tbl1 a=-Infinity\n' + + 'tbl1 a=NaN\n' + + 'tbl1 a=1.7976931348623157e308\n') + + def test_bool_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + True, False, False, + False, True, False], + dtype='bool')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n') + + def test_str_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='str')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a="a"\n' + + 'tbl1 a="q❤️p"\n' + + 'tbl1 a="' + ('❤️' * 1200) + '"\n' + + 'tbl1 a="Questo è un qualcosa"\n' + + 'tbl1 a="щось"\n' + + 'tbl1 a=""\n' + + 'tbl1 a="嚜꓂"\n' + + 'tbl1 a="💩🦞"\n') + if __name__ == '__main__': unittest.main() From cb97a2038db45f39b530a944f9611b2d8db51357 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 24 Nov 2022 19:13:38 +0000 Subject: [PATCH 066/147] Normality restored. --- src/questdb/extra_cpython.pxd | 6 +----- src/questdb/ingress.pyx | 24 +++++++++++------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd index 0b7a87d6..f7548310 100644 --- a/src/questdb/extra_cpython.pxd +++ b/src/questdb/extra_cpython.pxd @@ -30,15 +30,11 @@ cdef extern from "Python.h": int PyUnicode_READY(PyObject* o) except -1 # Is UCS1 and ascii (and therefore valid UTF-8). - bint PyUnicode_IS_COMPACT(PyObject* o) + bint PyUnicode_IS_COMPACT_ASCII(PyObject* o) # Get length. Py_ssize_t PyUnicode_GET_LENGTH(PyObject* o) - # Get or compute the UTF-8 representation. - const char* PyUnicode_AsUTF8AndSize( - PyObject* o, Py_ssize_t* size) except NULL - # Zero-copy access to string buffer. int PyUnicode_KIND(PyObject* o) Py_UCS1* PyUnicode_1BYTE_DATA(PyObject* o) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index fabeb550..8cadfc60 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -143,8 +143,8 @@ cdef inline object c_err_to_py_fmt(line_sender_error* err, str fmt): return IngressError(tup[0], fmt.format(tup[1])) -cdef void_int _utf8_decode_error( - PyObject* string, uint32_t bad_codepoint) except -1: +cdef object _utf8_decode_error( + PyObject* string, uint32_t bad_codepoint): cdef str s = string return IngressError( IngressErrorCode.InvalidUtf8, @@ -162,15 +162,11 @@ cdef void_int str_to_utf8( line_sender_utf8* utf8_out) except -1: """ Convert a Python string to a UTF-8 borrowed buffer. - This is done without asking Python to allocate any memory. - In case the string is an ASCII string (or a previously encoded UTF-8 buffer) - it's also zero-copy. + This is done without allocating new Python `bytes` objects. + In case the string is an ASCII string, it's also generally zero-copy. The `utf8_out` param will point to (borrow from) either the ASCII buffer inside the original Python object or a part of memory allocated inside the `b` buffer. - - To make sense of it, see: https://peps.python.org/pep-0393/ - Specifically the sections on UCS-1, UCS-2 and UCS-4 and compact strings. """ cdef size_t count cdef int kind @@ -178,15 +174,17 @@ cdef void_int str_to_utf8( if not PyUnicode_CheckExact(string): raise TypeError( f'Expected a str object, not a {_fqn(type(string))}') - PyUnicode_READY(string) # TODO: Can this be moved after the "Compact" check? + PyUnicode_READY(string) + count = (PyUnicode_GET_LENGTH(string)) - # We optimize the common case of ASCII strings and pre-encoded UTF-8. + # We optimize the common case of ASCII strings. # This avoid memory allocations and copies altogether. - if PyUnicode_IS_COMPACT(string): - utf8_out.buf = PyUnicode_AsUTF8AndSize(string, &utf8_out.len) + # We get away with this because ASCII is a subset of UTF-8. + if PyUnicode_IS_COMPACT_ASCII(string): + utf8_out.len = count + utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) return 0 - count = (PyUnicode_GET_LENGTH(string)) kind = PyUnicode_KIND(string) if kind == PyUnicode_1BYTE_KIND: # No error handling for UCS1: All code points translate into valid UTF8. From 5c1aaffb5796e26f95de246e28e2def9c2782ce2 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 24 Nov 2022 21:10:49 +0000 Subject: [PATCH 067/147] py obj to symbols. --- src/questdb/ingress.pyx | 5 ++++- test/test.py | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 8cadfc60..ca172138 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -153,7 +153,10 @@ cdef object _utf8_decode_error( cdef str _fqn(type obj): - return obj.__module__ + '.' + obj.__qualname__ + if obj.__module__ == 'builtins': + return obj.__qualname__ + else: + return f'{obj.__module__}.{obj.__qualname__}' cdef void_int str_to_utf8( diff --git a/test/test.py b/test/test.py index 3385cfe3..a329cc30 100755 --- a/test/test.py +++ b/test/test.py @@ -734,6 +734,29 @@ def test_bool_numpy_col(self): 'tbl1 a=t\n' + 'tbl1 a=f\n') + def test_str_numpy_symbol(self): + df = pd.DataFrame({'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='str')}) + buf = _pandas(df, table_name='tbl1', symbols=True) + self.assertEqual( + buf, + 'tbl1,a=a\n' + + 'tbl1,a=q❤️p\n' + + 'tbl1,a=' + ('❤️' * 1200) + '\n' + + 'tbl1,a=Questo\\ è\\ un\\ qualcosa\n' + + 'tbl1,a=щось\n' + + 'tbl1,a=\n' + + 'tbl1,a=嚜꓂\n' + + 'tbl1,a=💩🦞\n') + def test_str_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ 'a', # ASCII From dc5795f934357c9ef02e47e22b3d16d0907dea0c Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 24 Nov 2022 22:09:27 +0000 Subject: [PATCH 068/147] Done timestamp at and columns. Found out that timezone timestamps are broken. --- src/questdb/pandas_integration.md | 4 +- src/questdb/pandas_integration.pxi | 28 +++++++++++-- test/test.py | 65 ++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/questdb/pandas_integration.md b/src/questdb/pandas_integration.md index e2cc2b16..f4f16c4c 100644 --- a/src/questdb/pandas_integration.md +++ b/src/questdb/pandas_integration.md @@ -578,8 +578,8 @@ timezone), so no timezone conversion logic is required here. ] ``` -**Note**: We don't need PyArrow to access the buffer as -it's only used here to show raw data. +**Note**: We need PyArrow to access the buffer, or we need to convert to +`datetime64[ns]`. ## Strided Numpy Arrays diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index c78eb8c7..9633571c 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -702,8 +702,8 @@ cdef void _pandas_free_mapped_arrow(ArrowArray* arr): cdef void_int _pandas_series_as_pybuf( - TaggedEntry entry, col_t* col_out) except -1: - cdef object nparr = entry.series.to_numpy() + TaggedEntry entry, col_t* col_out, str fallback_dtype=None) except -1: + cdef object nparr = entry.series.to_numpy(dtype=fallback_dtype) cdef ArrowArray* mapped cdef int get_buf_ret cdef Py_buffer* view @@ -752,14 +752,15 @@ cdef void_int _pandas_series_as_pybuf( cdef void_int _pandas_series_as_arrow( TaggedEntry entry, col_t* col_out, - col_source_t np_fallback) except -1: + col_source_t np_fallback, + str fallback_dtype=None) except -1: cdef object array cdef list chunks cdef size_t n_chunks cdef size_t chunk_index if _PYARROW is None: col_out.source = np_fallback - _pandas_series_as_pybuf(entry, col_out) + _pandas_series_as_pybuf(entry, col_out, fallback_dtype) return 0 col_out.tag = col_access_tag_t.arrow @@ -969,6 +970,25 @@ cdef void_int _pandas_resolve_source_and_buffers( col_out.source = col_source_t.col_source_dt64ns_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.DatetimeTZDtype): + # TODO: This really ought to be done through Arrow. + # We currently just encode the pointer values. Yikes! + # >>> df.a.to_numpy() + # array([Timestamp('2019-01-01 00:00:00-0500', tz='America/New_York'), + # Timestamp('2019-01-01 00:00:01-0500', tz='America/New_York'), + # Timestamp('2019-01-01 00:00:02-0500', tz='America/New_York')], + # dtype=object) + # We can fallback to `datetime64[ns]`, but that will involve copying. + # >>> df.a.to_numpy(dtype='datetime64[ns]') + # array(['2019-01-01T05:00:00.000000000', '2019-01-01T05:00:01.000000000', + # '2019-01-01T05:00:02.000000000'], dtype='datetime64[ns]') + # So instead we want arrow access. + # >>> pa.Array.from_pandas(df.a) + # + # [ + # 2019-01-01 05:00:00.000000000, + # 2019-01-01 05:00:01.000000000, + # 2019-01-01 05:00:02.000000000 + # ] col_out.source = col_source_t.col_source_dt64ns_tz_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _NUMPY_OBJECT): diff --git a/test/test.py b/test/test.py index a329cc30..ad5ed93b 100755 --- a/test/test.py +++ b/test/test.py @@ -8,6 +8,7 @@ import time import numpy as np import pandas as pd +import zoneinfo import patch_path from mock_server import Server @@ -734,6 +735,68 @@ def test_bool_numpy_col(self): 'tbl1 a=t\n' + 'tbl1 a=f\n') + def test_datetime64_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + pd.Timestamp('2019-01-01 00:00:00'), + pd.Timestamp('2019-01-01 00:00:01'), + pd.Timestamp('2019-01-01 00:00:02'), + pd.Timestamp('2019-01-01 00:00:03'), + pd.Timestamp('2019-01-01 00:00:04'), + pd.Timestamp('2019-01-01 00:00:05')], + dtype='datetime64[ns]')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1546300800000000t\n' + + 'tbl1 a=1546300801000000t\n' + + 'tbl1 a=1546300802000000t\n' + + 'tbl1 a=1546300803000000t\n' + + 'tbl1 a=1546300804000000t\n' + + 'tbl1 a=1546300805000000t\n') + + def test_datetime64_tz_numpy_col(self): + # Currently broken, find `TODO: datetime[ns]+tz`. + # We're just casting `PyObject*`` to `int64_t` at the moment. + tz = zoneinfo.ZoneInfo('America/New_York') + df = pd.DataFrame({'a': [ + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=0, tz=tz), + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=1, tz=tz), + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=2, tz=tz)]}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1546282800000000t\n' + + 'tbl1 a=1546282801000000t\n' + + 'tbl1 a=1546282802000000t\n') + + def test_datetime64_numpy_at(self): + df = pd.DataFrame({ + 'a': pd.Series([ + pd.Timestamp('2019-01-01 00:00:00'), + pd.Timestamp('2019-01-01 00:00:01'), + pd.Timestamp('2019-01-01 00:00:02'), + pd.Timestamp('2019-01-01 00:00:03'), + pd.Timestamp('2019-01-01 00:00:04'), + pd.Timestamp('2019-01-01 00:00:05')], + dtype='datetime64[ns]'), + 'b': [1, 2, 3, 4, 5, 6]}) + buf = _pandas(df, table_name='tbl1', at='a') + self.assertEqual( + buf, + 'tbl1 b=1i 1546300800000000000\n' + + 'tbl1 b=2i 1546300801000000000\n' + + 'tbl1 b=3i 1546300802000000000\n' + + 'tbl1 b=4i 1546300803000000000\n' + + 'tbl1 b=5i 1546300804000000000\n' + + 'tbl1 b=6i 1546300805000000000\n') + + def test_str_numpy_symbol(self): df = pd.DataFrame({'a': pd.Series([ 'a', # ASCII @@ -781,5 +844,7 @@ def test_str_numpy_col(self): 'tbl1 a="💩🦞"\n') + + if __name__ == '__main__': unittest.main() From b7cfd506a5783e8efc6abde714379b84ec27e958 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 24 Nov 2022 22:10:24 +0000 Subject: [PATCH 069/147] Added some testing notes. --- test/test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test.py b/test/test.py index ad5ed93b..d0add79f 100755 --- a/test/test.py +++ b/test/test.py @@ -754,6 +754,8 @@ def test_datetime64_numpy_col(self): 'tbl1 a=1546300804000000t\n' + 'tbl1 a=1546300805000000t\n') + # TODO: Test 0-epoch. + def test_datetime64_tz_numpy_col(self): # Currently broken, find `TODO: datetime[ns]+tz`. # We're just casting `PyObject*`` to `int64_t` at the moment. @@ -796,6 +798,8 @@ def test_datetime64_numpy_at(self): 'tbl1 b=5i 1546300804000000000\n' + 'tbl1 b=6i 1546300805000000000\n') + # TODO: Test 0-epoch. + def test_str_numpy_symbol(self): df = pd.DataFrame({'a': pd.Series([ From 12c6eece68160eb61b8db30dc3abcd8316dfff79 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 24 Nov 2022 22:11:46 +0000 Subject: [PATCH 070/147] TODO fixup. --- src/questdb/pandas_integration.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 9633571c..2a7072be 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -970,7 +970,7 @@ cdef void_int _pandas_resolve_source_and_buffers( col_out.source = col_source_t.col_source_dt64ns_numpy _pandas_series_as_pybuf(entry, col_out) elif isinstance(dtype, _PANDAS.DatetimeTZDtype): - # TODO: This really ought to be done through Arrow. + # TODO: datetime[ns]+tz really ought to be done through Arrow. # We currently just encode the pointer values. Yikes! # >>> df.a.to_numpy() # array([Timestamp('2019-01-01 00:00:00-0500', tz='America/New_York'), From 8593b75a9413be2f3729d987dbbca6b82aeb8bcd Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 25 Nov 2022 13:01:56 +0000 Subject: [PATCH 071/147] Added support for datetimes with timezones (only nanosecond based) via Arrow. --- ci/run_tests_pipeline.yaml | 4 + src/questdb/pandas_integration.pxi | 114 +++++++++++++++++------------ test/test.py | 67 +++++++++++++++-- 3 files changed, 131 insertions(+), 54 deletions(-) diff --git a/ci/run_tests_pipeline.yaml b/ci/run_tests_pipeline.yaml index 924d238a..1d2145b8 100644 --- a/ci/run_tests_pipeline.yaml +++ b/ci/run_tests_pipeline.yaml @@ -39,3 +39,7 @@ stages: displayName: "Test" env: JAVA_HOME: $(JAVA_HOME_11_X64) + +# TODO: Add tests with and tests without installing `pyarrow` as it's +# an optional dependency (that can't always be installed). +# The tests without to test the fallback logic. diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 2a7072be..8bfd0bdd 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -77,7 +77,7 @@ cdef enum col_source_t: col_source_str_i32_cat = 405000 col_source_str_i64_cat = 406000 col_source_dt64ns_numpy = 501000 - col_source_dt64ns_tz_numpy = 502000 + col_source_dt64ns_tz_arrow = 502000 cdef dict _TARGET_TO_SOURCES = { @@ -141,11 +141,11 @@ cdef dict _TARGET_TO_SOURCES = { }, col_target_t.col_target_column_ts: { col_source_t.col_source_dt64ns_numpy, - col_source_t.col_source_dt64ns_tz_numpy, + col_source_t.col_source_dt64ns_tz_arrow, }, col_target_t.col_target_at: { col_source_t.col_source_dt64ns_numpy, - col_source_t.col_source_dt64ns_tz_numpy, + col_source_t.col_source_dt64ns_tz_arrow, }, } @@ -270,14 +270,14 @@ cdef enum col_dispatch_code_t: col_dispatch_code_column_ts__dt64ns_numpy = \ col_target_t.col_target_column_ts + col_source_t.col_source_dt64ns_numpy - col_dispatch_code_column_ts__dt64ns_tz_numpy = \ + col_dispatch_code_column_ts__dt64ns_tz_arrow = \ col_target_t.col_target_column_ts + \ - col_source_t.col_source_dt64ns_tz_numpy + col_source_t.col_source_dt64ns_tz_arrow col_dispatch_code_at__dt64ns_numpy = \ col_target_t.col_target_at + col_source_t.col_source_dt64ns_numpy - col_dispatch_code_at__dt64ns_tz_numpy = \ - col_target_t.col_target_at + col_source_t.col_source_dt64ns_tz_numpy + col_dispatch_code_at__dt64ns_tz_arrow = \ + col_target_t.col_target_at + col_source_t.col_source_dt64ns_tz_arrow cdef struct col_t: @@ -676,13 +676,12 @@ cdef ssize_t _pandas_resolve_at( cdef object _pandas_is_supported_datetime(object dtype): - # We currently only accept datetime64[ns] columns. - return ( - (dtype.kind == 'M') and - (dtype.itemsize == 8) and - (dtype.byteorder == '=') and - (dtype.alignment == 8) and - (not dtype.hasobject)) + if (isinstance(dtype, _NUMPY_DATETIME64_NS) and + (str(dtype) == 'datetime64[ns]')): + return True + if isinstance(dtype, _PANDAS.DatetimeTZDtype): + return dtype.unit == 'ns' + return False cdef void_int _pandas_alloc_chunks( @@ -966,31 +965,18 @@ cdef void_int _pandas_resolve_source_and_buffers( f'for column {entry.name} of dtype {dtype}.') elif isinstance(dtype, _PANDAS.CategoricalDtype): _pandas_category_series_as_arrow(entry, col_out) - elif isinstance(dtype, _NUMPY_DATETIME64_NS): + elif (isinstance(dtype, _NUMPY_DATETIME64_NS) and + _pandas_is_supported_datetime(dtype)): col_out.source = col_source_t.col_source_dt64ns_numpy _pandas_series_as_pybuf(entry, col_out) - elif isinstance(dtype, _PANDAS.DatetimeTZDtype): - # TODO: datetime[ns]+tz really ought to be done through Arrow. - # We currently just encode the pointer values. Yikes! - # >>> df.a.to_numpy() - # array([Timestamp('2019-01-01 00:00:00-0500', tz='America/New_York'), - # Timestamp('2019-01-01 00:00:01-0500', tz='America/New_York'), - # Timestamp('2019-01-01 00:00:02-0500', tz='America/New_York')], - # dtype=object) - # We can fallback to `datetime64[ns]`, but that will involve copying. - # >>> df.a.to_numpy(dtype='datetime64[ns]') - # array(['2019-01-01T05:00:00.000000000', '2019-01-01T05:00:01.000000000', - # '2019-01-01T05:00:02.000000000'], dtype='datetime64[ns]') - # So instead we want arrow access. - # >>> pa.Array.from_pandas(df.a) - # - # [ - # 2019-01-01 05:00:00.000000000, - # 2019-01-01 05:00:01.000000000, - # 2019-01-01 05:00:02.000000000 - # ] - col_out.source = col_source_t.col_source_dt64ns_tz_numpy - _pandas_series_as_pybuf(entry, col_out) + elif (isinstance(dtype, _PANDAS.DatetimeTZDtype) and + _pandas_is_supported_datetime(dtype)): + col_out.source = col_source_t.col_source_dt64ns_tz_arrow + _pandas_series_as_arrow( + entry, + col_out, + col_source_t.col_source_dt64ns_numpy, + 'datetime64[ns]') elif isinstance(dtype, _NUMPY_OBJECT): sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (A)\n') _pandas_series_sniff_pyobj(entry, col_out) @@ -1115,6 +1101,14 @@ cdef void_int _pandas_resolve_args( sys.stderr.write('_pandas_resolve_args :: (F)\n') +cdef inline bint _pandas_arrow_is_valid(col_cursor_t* cursor): + return ( + cursor.chunk.null_count == 0 or + ( + (cursor.chunk.buffers[0])[cursor.offset // 8] & + (1 << (cursor.offset % 8)))) + + cdef inline void_int _pandas_cell_str_pyobj_to_utf8( qdb_pystr_buf* b, col_t* col, @@ -1516,11 +1510,20 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_numpy( +cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col) + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef int64_t cell + cdef int64_t* access + if valid: + access = col.cursor.chunk.buffers[1] + cell = access[col.cursor.offset] + cell //= 1000 # Convert from nanoseconds to microseconds. + if not line_sender_buffer_column_ts(impl, col.name, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( @@ -1539,11 +1542,27 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_at_dt64ns_tz_numpy( +cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col) + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef int64_t* access + cdef int64_t cell + if valid: + access = col.cursor.chunk.buffers[1] + cell = access[col.cursor.offset] + else: + cell = 0 + + if cell == 0: + if not line_sender_buffer_at_now(impl, &err): + raise c_err_to_py(err) + else: + # Note: impl will validate against negative numbers. + if not line_sender_buffer_at(impl, cell, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell( @@ -1643,12 +1662,12 @@ cdef void_int _pandas_serialize_cell( _pandas_serialize_cell_column_str__str_i64_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_numpy: _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col) - elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_numpy: - _pandas_serialize_cell_column_ts__dt64ns_tz_numpy(impl, b, col) + elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_arrow: + _pandas_serialize_cell_column_ts__dt64ns_tz_arrow(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_numpy: _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col) - elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_tz_numpy: - _pandas_serialize_cell_at_dt64ns_tz_numpy(impl, b, col) + elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_tz_arrow: + _pandas_serialize_cell_at_dt64ns_tz_arrow(impl, b, col) else: raise RuntimeError(f"Unknown column dispatch code: {dc}") # See earlier note about switch statement generation. @@ -1742,7 +1761,8 @@ cdef void_int _pandas( try: sys.stderr.write(' :: :: (I)\n') for row_index in range(row_count): - # TODO: Occasional GIL release logic (e.g. every 5000 rows or so) + # TODO: Occasional GIL release logic. This should be twice as + # often as `sys.getswitchinterval()`. # TODO: Potentially avoid the GIL altogether if we can get away with it. # This is column-type dependent. Some basic analysis is required. # We need a `GilController` object so that we can raise exceptions. @@ -1772,7 +1792,7 @@ cdef void_int _pandas( repr(data.columns[col.orig_index]) + f' at row index {row_index} (' + repr(data.iloc[row_index, col.orig_index]) + - f'): {e}') from e + f'): {e} [dc={col.dispatch_code}]') from e sys.stderr.write(' :: :: (P)\n') _pandas_col_advance(col) sys.stderr.write(' :: :: (Q)\n') diff --git a/test/test.py b/test/test.py index d0add79f..12628464 100755 --- a/test/test.py +++ b/test/test.py @@ -756,26 +756,43 @@ def test_datetime64_numpy_col(self): # TODO: Test 0-epoch. - def test_datetime64_tz_numpy_col(self): + def test_datetime64_tz_arrow_col(self): # Currently broken, find `TODO: datetime[ns]+tz`. # We're just casting `PyObject*`` to `int64_t` at the moment. tz = zoneinfo.ZoneInfo('America/New_York') - df = pd.DataFrame({'a': [ + df = pd.DataFrame({ + 'a': [ pd.Timestamp( year=2019, month=1, day=1, hour=0, minute=0, second=0, tz=tz), pd.Timestamp( year=2019, month=1, day=1, hour=0, minute=0, second=1, tz=tz), + None, pd.Timestamp( year=2019, month=1, day=1, - hour=0, minute=0, second=2, tz=tz)]}) - buf = _pandas(df, table_name='tbl1') + hour=0, minute=0, second=3, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) + buf = _pandas(df, table_name='tbl1', symbols=['b']) self.assertEqual( buf, - 'tbl1 a=1546282800000000t\n' + - 'tbl1 a=1546282801000000t\n' + - 'tbl1 a=1546282802000000t\n') + # Note how these are 5hr offset from `test_datetime64_numpy_col`. + 'tbl1,b=sym1 a=1546318800000000t\n' + + 'tbl1,b=sym2 a=1546318801000000t\n' + + 'tbl1,b=sym3\n' + + 'tbl1,b=sym4 a=1546318803000000t\n') + + # TODO: Test 0-epoch. + + df2 = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1900, month=1, day=1, + hour=0, minute=0, second=0, tz=tz)], + 'b': ['sym1']}) + with self.assertRaisesRegex( + qi.IngressError, "Failed.*'a'.*-2208970800000000 is negative."): + _pandas(df2, table_name='tbl1', symbols=['b']) def test_datetime64_numpy_at(self): df = pd.DataFrame({ @@ -800,6 +817,42 @@ def test_datetime64_numpy_at(self): # TODO: Test 0-epoch. + def test_datetime64_tz_arrow_at(self): + # Currently broken, find `TODO: datetime[ns]+tz`. + # We're just casting `PyObject*`` to `int64_t` at the moment. + tz = zoneinfo.ZoneInfo('America/New_York') + df = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=0, tz=tz), + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=1, tz=tz), + None, + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=3, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) + buf = _pandas(df, table_name='tbl1', symbols=['b'], at='a') + self.assertEqual( + buf, + # Note how these are 5hr offset from `test_datetime64_numpy_col`. + 'tbl1,b=sym1 1546318800000000000\n' + + 'tbl1,b=sym2 1546318801000000000\n' + + 'tbl1,b=sym3\n' + + 'tbl1,b=sym4 1546318803000000000\n') + + df2 = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1900, month=1, day=1, + hour=0, minute=0, second=0, tz=tz)], + 'b': ['sym1']}) + with self.assertRaisesRegex( + qi.IngressError, "Failed.*'a'.*-2208970800000000000 is neg"): + _pandas(df2, table_name='tbl1', symbols=['b'], at='a') + def test_str_numpy_symbol(self): df = pd.DataFrame({'a': pd.Series([ From 7f6503d7478821123cad75b40f89935e9c810ebe Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 25 Nov 2022 14:53:23 +0000 Subject: [PATCH 072/147] Bool column support from Python objects. --- src/questdb/extra_cpython.pxd | 1 + src/questdb/pandas_integration.pxi | 15 +++++++++++++-- test/test.py | 31 ++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd index f7548310..6fd605f3 100644 --- a/src/questdb/extra_cpython.pxd +++ b/src/questdb/extra_cpython.pxd @@ -5,6 +5,7 @@ from cpython.object cimport PyObject cdef extern from "Python.h": cdef PyObject* Py_None + cdef PyObject* Py_True ctypedef uint8_t Py_UCS1 # unicodeobject.h ctypedef uint16_t Py_UCS2 diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 8bfd0bdd..20b09ffd 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1136,7 +1136,6 @@ cdef void_int _pandas_serialize_cell_table__str_pyobj( cdef line_sender_table_name c_table_name if _pandas_is_null_pyobj(cell) or not PyUnicode_CheckExact(cell): raise ValueError(f'Expected an object of type str, got a {_fqn(type(cell))}') - # TODO: See if there's silly increfs. str_to_table_name(b, cell, &c_table_name) if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) @@ -1232,7 +1231,19 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef PyObject** access = col.cursor.chunk.buffers[1] + cdef PyObject* cell = access[col.cursor.offset] + if _pandas_is_null_pyobj(cell): + raise ValueError('Cannot insert null values into a boolean column.') + elif PyBool_Check(cell): + if not line_sender_buffer_column_bool( + impl, col.name, cell == Py_True, &err): + raise c_err_to_py(err) + else: + raise ValueError( + 'Expected an object of type bool, got a ' + + _fqn(type(cell)) + '.') cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( diff --git a/test/test.py b/test/test.py index 12628464..3e2c6ac3 100755 --- a/test/test.py +++ b/test/test.py @@ -735,6 +735,37 @@ def test_bool_numpy_col(self): 'tbl1 a=t\n' + 'tbl1 a=f\n') + def test_bool_obj_col(self): + df = pd.DataFrame({'a': pd.Series([ + True, False, False, + False, True, False], + dtype='object')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n') + + df2 = pd.DataFrame({'a': pd.Series([ + True, False, 'false'], + dtype='object')}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize .* column .a. .* 2 .*false.*bool'): + _pandas(df2, table_name='tbl1') + + df3 = pd.DataFrame({'a': pd.Series([ + None, True, False], + dtype='object')}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize.*\\(None\\): Cannot insert null.*boolean column'): + _pandas(df3, table_name='tbl1') + def test_datetime64_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ pd.Timestamp('2019-01-01 00:00:00'), From 25c91bed4930c9645763309bfd8b580023b33566 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 25 Nov 2022 15:23:40 +0000 Subject: [PATCH 073/147] Added arrow-based boolean pandas datatype column support. --- src/questdb/pandas_integration.pxi | 19 +++++++++++++++--- test/test.py | 32 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 20b09ffd..a8dce901 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1101,6 +1101,12 @@ cdef void_int _pandas_resolve_args( sys.stderr.write('_pandas_resolve_args :: (F)\n') +cdef inline bint _pandas_arrow_get_bool(col_cursor_t* cursor): + return ( + (cursor.chunk.buffers[1])[cursor.offset // 8] & + (1 << (cursor.offset % 8))) + + cdef inline bint _pandas_arrow_is_valid(col_cursor_t* cursor): return ( cursor.chunk.null_count == 0 or @@ -1253,8 +1259,7 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( cdef line_sender_error* err = NULL cdef uint8_t* access = col.cursor.chunk.buffers[1] cdef uint8_t cell = access[col.cursor.offset] - cdef bint value = not not cell # Force to 0 and 1. - if not line_sender_buffer_column_bool(impl, col.name, value, &err): + if not line_sender_buffer_column_bool(impl, col.name, not not cell, &err): raise c_err_to_py(err) @@ -1262,7 +1267,15 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint value + if valid: + value = _pandas_arrow_get_bool(&col.cursor) + if not line_sender_buffer_column_bool(impl, col.name, value, &err): + raise c_err_to_py(err) + else: + raise ValueError('Cannot insert null values into a boolean column.') cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( diff --git a/test/test.py b/test/test.py index 3e2c6ac3..9418f1c4 100755 --- a/test/test.py +++ b/test/test.py @@ -735,6 +735,38 @@ def test_bool_numpy_col(self): 'tbl1 a=t\n' + 'tbl1 a=f\n') + def test_bool_arrow_col(self): + df = pd.DataFrame({'a': pd.Series([ + True, False, False, + False, True, False, + True, True, True, + False, False, False], + dtype='boolean')}) # Note `boolean` != `bool`. + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=t\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n') + + df2 = pd.DataFrame({'a': pd.Series([ + True, False, False, + None, True, False], + dtype='boolean')}) + with self.assertRaisesRegex( + qi.IngressError, + 'Failed.*at row index 3 .*.: .*insert null .*boolean col'): + _pandas(df2, table_name='tbl1') + def test_bool_obj_col(self): df = pd.DataFrame({'a': pd.Series([ True, False, False, From 8b31010b6d5a1231414cd5e7e1f4856e6b610da8 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 25 Nov 2022 15:53:33 +0000 Subject: [PATCH 074/147] Support for arrow integer columns. --- src/questdb/pandas_integration.pxi | 100 +++++++++++++++-- test/test.py | 170 +++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 8 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index a8dce901..39ecd7bd 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1379,56 +1379,140 @@ cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef uint8_t* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_i64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef int8_t* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_i64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef uint16_t* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_i64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef int16_t* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_i64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef uint32_t* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_i64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef int32_t* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_i64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef uint64_t* access + cdef uint64_t cell + if valid: + access = col.cursor.chunk.buffers[1] + cell = access[col.cursor.offset] + if cell > INT64_MAX: + raise OverflowError('uint64 value too large for int64 column type.') + if not line_sender_buffer_column_i64( + impl, + col.name, + cell, + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef int64_t* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_i64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( diff --git a/test/test.py b/test/test.py index 9418f1c4..217e0964 100755 --- a/test/test.py +++ b/test/test.py @@ -720,6 +720,176 @@ def test_f64_numpy_col(self): 'tbl1 a=NaN\n' + 'tbl1 a=1.7976931348623157e308\n') + def test_u8_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 255], # u8 max + dtype=pd.UInt8Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=255i,b="f"\n') + + def test_i8_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -128, # i8 min + 0, + None, + 127], # i8 max + dtype=pd.Int8Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-128i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=127i,b="g"\n') + + def test_u16_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 65535], # u16 max + dtype=pd.UInt16Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=65535i,b="f"\n') + + def test_i16_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -32768, # i16 min + 0, + None, + 32767], # i16 max + dtype=pd.Int16Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-32768i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=32767i,b="g"\n') + + def test_u32_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 4294967295], # u32 max + dtype=pd.UInt32Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=4294967295i,b="f"\n') + + def test_i32_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -2147483648, # i32 min + 0, + None, + 2147483647], # i32 max + dtype=pd.Int32Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-2147483648i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=2147483647i,b="g"\n') + + def test_u64_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 9223372036854775807], # i64 max + dtype=pd.UInt64Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=9223372036854775807i,b="f"\n') + + df2 = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 9223372036854775808], # i64 max + 1 + dtype=pd.UInt64Dtype())}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): + _pandas(df2, table_name='tbl1') + + def test_i64_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -9223372036854775808, # i64 min + 0, + None, + 9223372036854775807], # i64 max + dtype=pd.Int64Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-9223372036854775808i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=9223372036854775807i,b="g"\n') + def test_bool_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ True, False, False, From 6cad41b45baeb24e0444dacaad693f1d756f9803 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 28 Nov 2022 16:44:43 +0000 Subject: [PATCH 075/147] Progress handling strings. --- TODO.rst | 4 - c-questdb-client | 2 +- src/questdb/ingress.pyx | 1 + src/questdb/pandas_integration.pxi | 56 ++++++-- test/test.py | 204 ++++++++++++++++++++++++++++- 5 files changed, 249 insertions(+), 18 deletions(-) diff --git a/TODO.rst b/TODO.rst index 7bb28af2..25ac8898 100644 --- a/TODO.rst +++ b/TODO.rst @@ -6,8 +6,6 @@ TODO Build Tooling ============= -* **[HIGH]** Transition to Azure, move Linux arm to ARM pipeline without QEMU. - * **[MEDIUM]** Automate Apple Silicon as part of CI. * **[LOW]** Release to PyPI from CI. @@ -20,8 +18,6 @@ Docs are in the C client). This is to ensure they don't "bit rot" as the code changes. -* **[MEDIUM]** Document on a per-version basis. - Development =========== diff --git a/c-questdb-client b/c-questdb-client index 96cc3af6..f32af374 160000 --- a/c-questdb-client +++ b/c-questdb-client @@ -1 +1 @@ -Subproject commit 96cc3af6745a7c6aa1b8cb6cb8feef8de0a6a8eb +Subproject commit f32af3745f110cb3c57bf5ea60052e0a5ef10565 diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index ca172138..b689dd4c 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -36,6 +36,7 @@ from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t, \ from libc.stdlib cimport malloc, calloc, realloc, free, abort from libc.string cimport strncmp from libc.math cimport isnan +from libc.stdio cimport fprintf, stderr # TODO: Remove me one no longer needed from cpython.datetime cimport datetime from cpython.bool cimport bool from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 39ecd7bd..48d17817 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1115,6 +1115,23 @@ cdef inline bint _pandas_arrow_is_valid(col_cursor_t* cursor): (1 << (cursor.offset % 8)))) +cdef inline bint _pandas_arrow_str( + col_cursor_t* cursor, + size_t* len_out, + const char** buf_out): + cdef int32_t* index_access + cdef uint8_t* char_access + cdef int32_t begin + cdef bint valid = _pandas_arrow_is_valid(cursor) + if valid: + index_access = cursor.chunk.buffers[1] + char_access = cursor.chunk.buffers[2] + begin = index_access[cursor.offset] + len_out[0] = index_access[cursor.offset + 1] - begin + buf_out[0] = &char_access[begin] + return valid + + cdef inline void_int _pandas_cell_str_pyobj_to_utf8( qdb_pystr_buf* b, col_t* col, @@ -1122,14 +1139,15 @@ cdef inline void_int _pandas_cell_str_pyobj_to_utf8( line_sender_utf8* utf8_out) except -1: cdef PyObject** access = col.cursor.chunk.buffers[1] cdef PyObject* cell = access[col.cursor.offset] - if _pandas_is_null_pyobj(cell): - valid_out[0] = False - elif PyUnicode_CheckExact(cell): + if PyUnicode_CheckExact(cell): str_to_utf8(b, cell, utf8_out) valid_out[0] = True + elif _pandas_is_null_pyobj(cell): + valid_out[0] = False else: raise ValueError( - f'Expected an object of type str, got a {_fqn(type(cell))}') + 'Expected a string, ' + + f'got an object of type {_fqn(type(cell))}.') cdef void_int _pandas_serialize_cell_table__str_pyobj( @@ -1140,8 +1158,13 @@ cdef void_int _pandas_serialize_cell_table__str_pyobj( cdef PyObject** access = col.cursor.chunk.buffers[1] cdef PyObject* cell = access[col.cursor.offset] cdef line_sender_table_name c_table_name - if _pandas_is_null_pyobj(cell) or not PyUnicode_CheckExact(cell): - raise ValueError(f'Expected an object of type str, got a {_fqn(type(cell))}') + if not PyUnicode_CheckExact(cell): + if _pandas_is_null_pyobj(cell): + raise ValueError('Expected a table name, got a null value') + else: + raise ValueError( + 'Expected a table name (str object), ' + + f'got an object of type {_fqn(type(cell))}.') str_to_table_name(b, cell, &c_table_name) if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) @@ -1152,10 +1175,16 @@ cdef void_int _pandas_serialize_cell_table__str_arrow( qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL + cdef size_t len + cdef const char* buf cdef line_sender_table_name c_table_name - cdef uint8_t* validity_access = col.cursor.chunk.buffers[0] - cdef int32_t* index_access = col.cursor.chunk.buffers[1] - raise ValueError('Not implemented') + if _pandas_arrow_str(&col.cursor, &len, &buf): + if not line_sender_table_name_init(&c_table_name, len, buf, &err): + raise c_err_to_py(err) + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + else: + raise ValueError('Table name cannot be null') cdef void_int _pandas_serialize_cell_table__str_i8_cat( @@ -1202,7 +1231,12 @@ cdef void_int _pandas_serialize_cell_symbol__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + cdef line_sender_table_name c_table_name + if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i8_cat( @@ -1631,7 +1665,7 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( cell = access[col.cursor.offset] cell //= 1000 # Convert from nanoseconds to microseconds. if not line_sender_buffer_column_ts(impl, col.name, cell, &err): - raise c_err_to_py(err) + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( diff --git a/test/test.py b/test/test.py index 217e0964..72fe1e0b 100755 --- a/test/test.py +++ b/test/test.py @@ -529,6 +529,12 @@ def test_basic(self): 't2,A=a2,D=a2 E=2.0,F=2i 1520726400000000000\n' + 't1,A=a3,B=b3,C=b3,D=a3 E=3.0,F=3i 1520812800000000000\n') + def test_row_of_nulls(self): + df = pd.DataFrame({'a': ['a1', None, 'a3']}) + with self.assertRaisesRegex( + qi.IngressError, 'State error: Bad call to `at`'): + _pandas(df, table_name='tbl1', symbols=['a']) + def test_u8_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ 1, 2, 3, @@ -1086,8 +1092,96 @@ def test_datetime64_tz_arrow_at(self): qi.IngressError, "Failed.*'a'.*-2208970800000000000 is neg"): _pandas(df2, table_name='tbl1', symbols=['b'], at='a') + def _test_pyobjstr_table(self, dtype): + df = pd.DataFrame({ + '../bad col name/../it does not matter...': + pd.Series([ + 'a', # ASCII + 'b' * 127, # Max table name length. + 'q❤️p', # Mixed ASCII and UCS-2 + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype=dtype), + 'b': [1, 2, 3, 4, 5]}) + buf = _pandas(df, table_name_col=0) + self.assertEqual( + buf, + 'a b=1i\n' + + ('b' * 127) + ' b=2i\n' + + 'q❤️p b=3i\n' + + '嚜꓂ b=4i\n' + + '💩🦞 b=5i\n') + + with self.assertRaisesRegex( + qi.IngressError, "Too long"): + _pandas( + pd.DataFrame({'a': pd.Series(['b' * 128], dtype=dtype)}), + table_name_col='a') + + with self.assertRaisesRegex( + qi.IngressError, 'Failed.*Expected a table name, got a null.*'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', None], dtype=dtype), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, 'Failed.*Expected a table name, got a null.*'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', float('nan')], dtype=dtype), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, 'Failed.*Expected a table name, got a null.*'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', pd.NA], dtype=dtype), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, "''.*must have a non-zero length"): + _pandas( + pd.DataFrame({ + '/': pd.Series([''], dtype=dtype), + 'b': [1]}), + table_name_col='/') - def test_str_numpy_symbol(self): + with self.assertRaisesRegex( + qi.IngressError, "'tab..1'.*invalid dot `\.` at position 4"): + _pandas( + pd.DataFrame({ + '/': pd.Series(['tab..1'], dtype=dtype), + 'b': [1]}), + table_name_col='/') + + def test_obj_str_table(self): + self._test_pyobjstr_table('object') + + with self.assertRaisesRegex( + qi.IngressError, 'table name .*got an object of type int'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', 42], dtype='object'), + 'z': [1, 2]}), + table_name_col='.') + + def test_obj_string_table(self): + self._test_pyobjstr_table('string') + + self.assertEqual( + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', 42], dtype='string'), + 'z': [1, 2]}), + table_name_col='.'), + 'x z=1i\n' + + '42 z=2i\n') + + def _test_pyobjstr_numpy_symbol(self, dtype): df = pd.DataFrame({'a': pd.Series([ 'a', # ASCII 'q❤️p', # Mixed ASCII and UCS-2 @@ -1097,7 +1191,7 @@ def test_str_numpy_symbol(self): '', # Empty string '嚜꓂', # UCS-2, 3 bytes for UTF-8. '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype='str')}) + dtype=dtype)}) buf = _pandas(df, table_name='tbl1', symbols=True) self.assertEqual( buf, @@ -1110,6 +1204,39 @@ def test_str_numpy_symbol(self): 'tbl1,a=嚜꓂\n' + 'tbl1,a=💩🦞\n') + for null_obj in (None, float('nan'), pd.NA): + self.assertEqual( + _pandas( + pd.DataFrame({ + 'x': pd.Series(['a', null_obj], dtype=dtype), + 'y': [1, 2]}), + table_name='tbl1', symbols=[0]), + 'tbl1,x=a y=1i\n' + + 'tbl1 y=2i\n') + + def test_obj_str_numpy_symbol(self): + self._test_pyobjstr_numpy_symbol('object') + + with self.assertRaisesRegex( + qi.IngressError, 'Expected a string, got an .* type int'): + _pandas( + pd.DataFrame({ + 'x': pd.Series(['x', 42], dtype='object'), + 'y': [1, 2]}), + table_name='tbl1', symbols=[0]) + + def test_obj_string_numpy_symbol(self): + self._test_pyobjstr_numpy_symbol('string') + + self.assertEqual( + _pandas( + pd.DataFrame({ + 'x': pd.Series(['x', 42], dtype='string'), + 'y': [1, 2]}), + table_name='tbl1', symbols=[0]), + 'tbl1,x=x y=1i\n' + + 'tbl1,x=42 y=2i\n') + def test_str_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ 'a', # ASCII @@ -1133,7 +1260,80 @@ def test_str_numpy_col(self): 'tbl1 a="嚜꓂"\n' + 'tbl1 a="💩🦞"\n') + def test_str_arrow_symbol(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + None, + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='string[pyarrow]'), + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) + buf = _pandas(df, table_name='tbl1', symbols=True) + self.assertEqual( + buf, + 'tbl1,a=a b=1i\n' + + 'tbl1,a=q❤️p b=2i\n' + + 'tbl1,a=' + ('❤️' * 1200) + ' b=3i\n' + + 'tbl1,a=Questo\\ è\\ un\\ qualcosa b=4i\n' + + 'tbl1,a=щось b=5i\n' + + 'tbl1,a= b=6i\n' + + 'tbl1 b=7i\n' + + 'tbl1,a=嚜꓂ b=8i\n' + + 'tbl1,a=💩🦞 b=9i\n') + + def test_str_arrow_table(self): + df = pd.DataFrame({ + '../bad col name/../it does not matter...': pd.Series([ + 'a', # ASCII + 'b' * 127, # Max table name length. + 'q❤️p', # Mixed ASCII and UCS-2 + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='string[pyarrow]'), + 'b': [1, 2, 3, 4, 5]}) + buf = _pandas(df, table_name_col=0) + self.assertEqual( + buf, + 'a b=1i\n' + + ('b' * 127) + ' b=2i\n' + + 'q❤️p b=3i\n' + + '嚜꓂ b=4i\n' + + '💩🦞 b=5i\n') + with self.assertRaisesRegex( + qi.IngressError, "Too long"): + _pandas( + pd.DataFrame({ + 'a': pd.Series(['b' * 128], dtype='string[pyarrow]')}), + table_name_col='a') + + with self.assertRaisesRegex( + qi.IngressError, "Failed .*.*Table name cannot be null"): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', None], dtype='string[pyarrow]'), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, "''.*must have a non-zero length"): + _pandas( + pd.DataFrame({ + '/': pd.Series([''], dtype='string[pyarrow]')}), + table_name_col='/') + + with self.assertRaisesRegex( + qi.IngressError, "'tab..1'.*invalid dot `\.` at position 4"): + _pandas( + pd.DataFrame({ + '/': pd.Series(['tab..1'], dtype='string[pyarrow]')}), + table_name_col='/') if __name__ == '__main__': From 1499cff96deaf96b298d476eb69f4a8157190dcc Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 28 Nov 2022 17:07:16 +0000 Subject: [PATCH 076/147] Support for objects with integers. --- src/questdb/extra_cpython.pxd | 4 ++++ src/questdb/pandas_integration.pxi | 21 +++++++++++++++++---- test/test.py | 20 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd index 6fd605f3..af4ba18c 100644 --- a/src/questdb/extra_cpython.pxd +++ b/src/questdb/extra_cpython.pxd @@ -57,3 +57,7 @@ cdef extern from "Python.h": bint PyFloat_CheckExact(PyObject* o) double PyFloat_AS_DOUBLE(PyObject* o) + + long long PyLong_AsLongLong(PyObject* o) except? -1 + + PyObject* PyErr_Occurred() diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 48d17817..26715d98 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1274,12 +1274,12 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( cdef line_sender_error* err = NULL cdef PyObject** access = col.cursor.chunk.buffers[1] cdef PyObject* cell = access[col.cursor.offset] - if _pandas_is_null_pyobj(cell): - raise ValueError('Cannot insert null values into a boolean column.') - elif PyBool_Check(cell): + if PyBool_Check(cell): if not line_sender_buffer_column_bool( impl, col.name, cell == Py_True, &err): raise c_err_to_py(err) + elif _pandas_is_null_pyobj(cell): + raise ValueError('Cannot insert null values into a boolean column.') else: raise ValueError( 'Expected an object of type bool, got a ' + @@ -1316,7 +1316,20 @@ cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef PyObject** access = col.cursor.chunk.buffers[1] + cdef PyObject* cell = access[col.cursor.offset] + cdef int64_t value + if PyLong_CheckExact(cell): + value = PyLong_AsLongLong(cell) + if not line_sender_buffer_column_i64(impl, col.name, value, &err): + raise c_err_to_py(err) + elif _pandas_is_null_pyobj(cell): + pass + else: + raise ValueError( + 'Expected an object of type int, got an object of type ' + + _fqn(type(cell)) + '.') cdef void_int _pandas_serialize_cell_column_i64__u8_numpy( diff --git a/test/test.py b/test/test.py index 72fe1e0b..b394f4eb 100755 --- a/test/test.py +++ b/test/test.py @@ -1335,6 +1335,26 @@ def test_str_arrow_table(self): '/': pd.Series(['tab..1'], dtype='string[pyarrow]')}), table_name_col='/') + def test_pyobj_int_col(self): + self.assertEqual( + _pandas( + pd.DataFrame({ + 'a': pd.Series([1, 2, 3, None], dtype='object'), + 'b': [1, 2, 3, 4]}), + table_name='tbl1'), + 'tbl1 a=1i,b=1i\n' + + 'tbl1 a=2i,b=2i\n' + + 'tbl1 a=3i,b=3i\n' + + 'tbl1 b=4i\n') + + with self.assertRaisesRegex( + qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\."): + _pandas( + pd.DataFrame({ + 'a': pd.Series([1, 'STRING'], dtype='object'), + 'b': [1, 2]}), + table_name='tbl1') + if __name__ == '__main__': unittest.main() From 0e9e287e05128393794b4e4eb59ee6d87d37b3f8 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 28 Nov 2022 18:04:15 +0000 Subject: [PATCH 077/147] Float object support. --- src/questdb/pandas_integration.pxi | 15 +++++++++++++- test/test.py | 32 +++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 26715d98..f7f592d0 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1566,7 +1566,20 @@ cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef PyObject** access = col.cursor.chunk.buffers[1] + cdef PyObject* cell = access[col.cursor.offset] + cdef double value + if PyFloat_CheckExact(cell): + value = PyFloat_AS_DOUBLE(cell) + if not line_sender_buffer_column_f64(impl, col.name, value, &err): + raise c_err_to_py(err) + elif _pandas_is_null_pyobj(cell): + pass + else: + raise ValueError( + 'Expected an object of type float, got an object of type ' + + _fqn(type(cell)) + '.') cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( diff --git a/test/test.py b/test/test.py index b394f4eb..8af99de9 100755 --- a/test/test.py +++ b/test/test.py @@ -1339,13 +1339,16 @@ def test_pyobj_int_col(self): self.assertEqual( _pandas( pd.DataFrame({ - 'a': pd.Series([1, 2, 3, None], dtype='object'), - 'b': [1, 2, 3, 4]}), + 'a': pd.Series([1, 2, 3, None, float('nan'), pd.NA, 7], dtype='object'), + 'b': [1, 2, 3, 4, 5, 6, 7]}), table_name='tbl1'), 'tbl1 a=1i,b=1i\n' + 'tbl1 a=2i,b=2i\n' + 'tbl1 a=3i,b=3i\n' + - 'tbl1 b=4i\n') + 'tbl1 b=4i\n' + + 'tbl1 b=5i\n' + + 'tbl1 b=6i\n' + + 'tbl1 a=7i,b=7i\n') with self.assertRaisesRegex( qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\."): @@ -1355,6 +1358,29 @@ def test_pyobj_int_col(self): 'b': [1, 2]}), table_name='tbl1') + def test_pyobj_float_col(self): + self.assertEqual( + _pandas( + pd.DataFrame({ + 'a': pd.Series([1.0, 2.0, 3.0, None, float('nan'), pd.NA, 7.0], dtype='object'), + 'b': [1, 2, 3, 4, 5, 6, 7]}), + table_name='tbl1'), + 'tbl1 a=1.0,b=1i\n' + + 'tbl1 a=2.0,b=2i\n' + + 'tbl1 a=3.0,b=3i\n' + + 'tbl1 b=4i\n' + + 'tbl1 a=NaN,b=5i\n' + + 'tbl1 b=6i\n' + + 'tbl1 a=7.0,b=7i\n') + + with self.assertRaisesRegex( + qi.IngressError, "1 \\('STRING'\\): .*type float, got.*str\."): + _pandas( + pd.DataFrame({ + 'a': pd.Series([1.0, 'STRING'], dtype='object'), + 'b': [1, 2]}), + table_name='tbl1') + if __name__ == '__main__': unittest.main() From a1e7d0706d7a414b65ecc3553e3d6a4dad7d25a8 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 28 Nov 2022 21:32:06 +0000 Subject: [PATCH 078/147] arrow f32 and f64 --- src/questdb/pandas_integration.pxi | 24 ++++++++++++-- test/test.py | 50 ++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index f7f592d0..490b4b74 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1609,14 +1609,34 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef float* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_f64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef double* access + if valid: + access = col.cursor.chunk.buffers[1] + if not line_sender_buffer_column_f64( + impl, + col.name, + access[col.cursor.offset], + &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_pyobj( diff --git a/test/test.py b/test/test.py index 8af99de9..c77fce03 100755 --- a/test/test.py +++ b/test/test.py @@ -896,6 +896,56 @@ def test_i64_arrow_col(self): 'tbl1 b="f"\n' + 'tbl1 a=9223372036854775807i,b="g"\n') + def test_f32_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 3.4028234663852886e38, # f32 max + None], + dtype=pd.Float32Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0,b="a"\n' + + 'tbl1 a=2.0,b="b"\n' + + 'tbl1 a=3.0,b="c"\n' + + 'tbl1 a=0.0,b="d"\n' + + 'tbl1 a=Infinity,b="e"\n' + + 'tbl1 a=-Infinity,b="f"\n' + + 'tbl1 b="g"\n' + # This one is wierd: `nan` gets 0 in the bitmask. + 'tbl1 a=3.4028234663852886e38,b="h"\n' + + 'tbl1 b="i"\n') + + def test_f64_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 1.7976931348623157e308, # f64 max + None], + dtype=pd.Float64Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0,b="a"\n' + + 'tbl1 a=2.0,b="b"\n' + + 'tbl1 a=3.0,b="c"\n' + + 'tbl1 a=0.0,b="d"\n' + + 'tbl1 a=Infinity,b="e"\n' + + 'tbl1 a=-Infinity,b="f"\n' + + 'tbl1 b="g"\n' + # This one is wierd: `nan` gets 0 in the bitmask. + 'tbl1 a=1.7976931348623157e308,b="h"\n' + + 'tbl1 b="i"\n') + def test_bool_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ True, False, False, From 898b1577b080e8c9d15003e264077065279013d3 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 28 Nov 2022 22:14:03 +0000 Subject: [PATCH 079/147] str column pyarrow. --- src/questdb/pandas_integration.pxi | 7 ++- test/test.py | 81 ++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 490b4b74..2f5932f5 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1233,7 +1233,6 @@ cdef void_int _pandas_serialize_cell_symbol__str_arrow( col_t* col) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - cdef line_sender_table_name c_table_name if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(impl, col.name, utf8, &err): raise c_err_to_py(err) @@ -1655,7 +1654,11 @@ cdef void_int _pandas_serialize_cell_column_str__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i8_cat( diff --git a/test/test.py b/test/test.py index c77fce03..74f19bdf 100755 --- a/test/test.py +++ b/test/test.py @@ -1310,33 +1310,6 @@ def test_str_numpy_col(self): 'tbl1 a="嚜꓂"\n' + 'tbl1 a="💩🦞"\n') - def test_str_arrow_symbol(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 'a', # ASCII - 'q❤️p', # Mixed ASCII and UCS-2 - '❤️' * 1200, # Over the 1024 buffer prealloc. - 'Questo è un qualcosa', # Non-ASCII UCS-1 - 'щось', # UCS-2, 2 bytes for UTF-8. - '', # Empty string - None, - '嚜꓂', # UCS-2, 3 bytes for UTF-8. - '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype='string[pyarrow]'), - 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) - buf = _pandas(df, table_name='tbl1', symbols=True) - self.assertEqual( - buf, - 'tbl1,a=a b=1i\n' + - 'tbl1,a=q❤️p b=2i\n' + - 'tbl1,a=' + ('❤️' * 1200) + ' b=3i\n' + - 'tbl1,a=Questo\\ è\\ un\\ qualcosa b=4i\n' + - 'tbl1,a=щось b=5i\n' + - 'tbl1,a= b=6i\n' + - 'tbl1 b=7i\n' + - 'tbl1,a=嚜꓂ b=8i\n' + - 'tbl1,a=💩🦞 b=9i\n') - def test_str_arrow_table(self): df = pd.DataFrame({ '../bad col name/../it does not matter...': pd.Series([ @@ -1385,6 +1358,60 @@ def test_str_arrow_table(self): '/': pd.Series(['tab..1'], dtype='string[pyarrow]')}), table_name_col='/') + def test_str_arrow_symbol(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + None, + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='string[pyarrow]'), + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) + buf = _pandas(df, table_name='tbl1', symbols=True) + self.assertEqual( + buf, + 'tbl1,a=a b=1i\n' + + 'tbl1,a=q❤️p b=2i\n' + + 'tbl1,a=' + ('❤️' * 1200) + ' b=3i\n' + + 'tbl1,a=Questo\\ è\\ un\\ qualcosa b=4i\n' + + 'tbl1,a=щось b=5i\n' + + 'tbl1,a= b=6i\n' + + 'tbl1 b=7i\n' + + 'tbl1,a=嚜꓂ b=8i\n' + + 'tbl1,a=💩🦞 b=9i\n') + + def test_str_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + None, + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='string[pyarrow]'), + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) + buf = _pandas(df, table_name='tbl1', symbols=False) + self.assertEqual( + buf, + 'tbl1 a="a",b=1i\n' + + 'tbl1 a="q❤️p",b=2i\n' + + 'tbl1 a="' + ('❤️' * 1200) + '",b=3i\n' + + 'tbl1 a="Questo è un qualcosa",b=4i\n' + + 'tbl1 a="щось",b=5i\n' + + 'tbl1 a="",b=6i\n' + + 'tbl1 b=7i\n' + + 'tbl1 a="嚜꓂",b=8i\n' + + 'tbl1 a="💩🦞",b=9i\n') + def test_pyobj_int_col(self): self.assertEqual( _pandas( From 88e618a69c9fb54347107d2981da71fb16de665b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 30 Nov 2022 14:53:49 +0000 Subject: [PATCH 080/147] LTO, basic perf tests, removed debug logging, fixed a bug in string column detection, dropped support for (almost untestable) i64-index categories, began transition of error types to IngressError, implemented categories for table names/symbols/columns. --- .gitignore | 4 + perf/README.md | 28 + perf/gprof2dot.py | 3555 ++++++++++++++++++++++++++++ setup.py | 2 + src/questdb/ingress.pyx | 15 - src/questdb/pandas_integration.pxi | 279 ++- test/test.py | 164 +- 7 files changed, 3895 insertions(+), 152 deletions(-) create mode 100644 perf/README.md create mode 100644 perf/gprof2dot.py diff --git a/.gitignore b/.gitignore index 5043a003..81a8bad3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,10 @@ src/questdb/ingress.c src/questdb/*.html rustup-init.exe +# Linux Perf profiles +perf.data* +perf/*.svg + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/perf/README.md b/perf/README.md new file mode 100644 index 00000000..94bcf31e --- /dev/null +++ b/perf/README.md @@ -0,0 +1,28 @@ +# Profiling with Linux Perf + +https://juanjose.garciaripoll.com/blog/profiling-code-with-linux-perf/index.html + +```bash +$ TEST_QUESTDB_PATCH_PATH=1 TEST_QUESTDB_PROFILE=0 perf record -g --call-graph dwarf python3 test/test.py -v TestBencharkPandas.test_mixed_10m +test_mixed_10m (__main__.TestBencharkPandas.test_mixed_10m) ... Time: 2.128126113999315, size: 558055572 +ok + +---------------------------------------------------------------------- +Ran 1 test in 10.188s + +OK +[ perf record: Woken up 1337 times to write data ] +Warning: +Processed 55721 events and lost 107 chunks! + +Check IO/CPU overload! + +[ perf record: Captured and wrote 402.922 MB perf.data (50252 samples) ] +``` + +# Rendering results + +```bash +$ perf script | python3 perf/gprof2dot.py --format=perf | dot -Tsvg > perf/profile_graph.svg +$ (cd perf && python3 -m http.server) +``` \ No newline at end of file diff --git a/perf/gprof2dot.py b/perf/gprof2dot.py new file mode 100644 index 00000000..99554b2a --- /dev/null +++ b/perf/gprof2dot.py @@ -0,0 +1,3555 @@ +#!/usr/bin/env python3 +# +# Copyright 2008-2017 Jose Fonseca +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +"""Generate a dot graph from the output of several profilers.""" + +__author__ = "Jose Fonseca et al" + + +import sys +import math +import os.path +import re +import textwrap +import optparse +import xml.parsers.expat +import collections +import locale +import json +import fnmatch + +# Python 2.x/3.x compatibility +if sys.version_info[0] >= 3: + PYTHON_3 = True + def compat_iteritems(x): return x.items() # No iteritems() in Python 3 + def compat_itervalues(x): return x.values() # No itervalues() in Python 3 + def compat_keys(x): return list(x.keys()) # keys() is a generator in Python 3 + basestring = str # No class basestring in Python 3 + unichr = chr # No unichr in Python 3 + xrange = range # No xrange in Python 3 +else: + PYTHON_3 = False + def compat_iteritems(x): return x.iteritems() + def compat_itervalues(x): return x.itervalues() + def compat_keys(x): return x.keys() + + + +######################################################################## +# Model + + +MULTIPLICATION_SIGN = unichr(0xd7) + + +def times(x): + return "%u%s" % (x, MULTIPLICATION_SIGN) + +def percentage(p): + return "%.02f%%" % (p*100.0,) + +def add(a, b): + return a + b + +def fail(a, b): + assert False + + +tol = 2 ** -23 + +def ratio(numerator, denominator): + try: + ratio = float(numerator)/float(denominator) + except ZeroDivisionError: + # 0/0 is undefined, but 1.0 yields more useful results + return 1.0 + if ratio < 0.0: + if ratio < -tol: + sys.stderr.write('warning: negative ratio (%s/%s)\n' % (numerator, denominator)) + return 0.0 + if ratio > 1.0: + if ratio > 1.0 + tol: + sys.stderr.write('warning: ratio greater than one (%s/%s)\n' % (numerator, denominator)) + return 1.0 + return ratio + + +class UndefinedEvent(Exception): + """Raised when attempting to get an event which is undefined.""" + + def __init__(self, event): + Exception.__init__(self) + self.event = event + + def __str__(self): + return 'unspecified event %s' % self.event.name + + +class Event(object): + """Describe a kind of event, and its basic operations.""" + + def __init__(self, name, null, aggregator, formatter = str): + self.name = name + self._null = null + self._aggregator = aggregator + self._formatter = formatter + + def __eq__(self, other): + return self is other + + def __hash__(self): + return id(self) + + def null(self): + return self._null + + def aggregate(self, val1, val2): + """Aggregate two event values.""" + assert val1 is not None + assert val2 is not None + return self._aggregator(val1, val2) + + def format(self, val): + """Format an event value.""" + assert val is not None + return self._formatter(val) + + +CALLS = Event("Calls", 0, add, times) +SAMPLES = Event("Samples", 0, add, times) +SAMPLES2 = Event("Samples", 0, add, times) + +# Count of samples where a given function was either executing or on the stack. +# This is used to calculate the total time ratio according to the +# straightforward method described in Mike Dunlavey's answer to +# stackoverflow.com/questions/1777556/alternatives-to-gprof, item 4 (the myth +# "that recursion is a tricky confusing issue"), last edited 2012-08-30: it's +# just the ratio of TOTAL_SAMPLES over the number of samples in the profile. +# +# Used only when totalMethod == callstacks +TOTAL_SAMPLES = Event("Samples", 0, add, times) + +TIME = Event("Time", 0.0, add, lambda x: '(' + str(x) + ')') +TIME_RATIO = Event("Time ratio", 0.0, add, lambda x: '(' + percentage(x) + ')') +TOTAL_TIME = Event("Total time", 0.0, fail) +TOTAL_TIME_RATIO = Event("Total time ratio", 0.0, fail, percentage) + +labels = { + 'self-time': TIME, + 'self-time-percentage': TIME_RATIO, + 'total-time': TOTAL_TIME, + 'total-time-percentage': TOTAL_TIME_RATIO, +} +defaultLabelNames = ['total-time-percentage', 'self-time-percentage'] + +totalMethod = 'callratios' + + +class Object(object): + """Base class for all objects in profile which can store events.""" + + def __init__(self, events=None): + if events is None: + self.events = {} + else: + self.events = events + + def __hash__(self): + return id(self) + + def __eq__(self, other): + return self is other + + def __lt__(self, other): + return id(self) < id(other) + + def __contains__(self, event): + return event in self.events + + def __getitem__(self, event): + try: + return self.events[event] + except KeyError: + raise UndefinedEvent(event) + + def __setitem__(self, event, value): + if value is None: + if event in self.events: + del self.events[event] + else: + self.events[event] = value + + +class Call(Object): + """A call between functions. + + There should be at most one call object for every pair of functions. + """ + + def __init__(self, callee_id): + Object.__init__(self) + self.callee_id = callee_id + self.ratio = None + self.weight = None + + +class Function(Object): + """A function.""" + + def __init__(self, id, name): + Object.__init__(self) + self.id = id + self.name = name + self.module = None + self.process = None + self.calls = {} + self.called = None + self.weight = None + self.cycle = None + self.filename = None + + def add_call(self, call): + if call.callee_id in self.calls: + sys.stderr.write('warning: overwriting call from function %s to %s\n' % (str(self.id), str(call.callee_id))) + self.calls[call.callee_id] = call + + def get_call(self, callee_id): + if not callee_id in self.calls: + call = Call(callee_id) + call[SAMPLES] = 0 + call[SAMPLES2] = 0 + call[CALLS] = 0 + self.calls[callee_id] = call + return self.calls[callee_id] + + _parenthesis_re = re.compile(r'\([^()]*\)') + _angles_re = re.compile(r'<[^<>]*>') + _const_re = re.compile(r'\s+const$') + + def stripped_name(self): + """Remove extraneous information from C++ demangled function names.""" + + name = self.name + + # Strip function parameters from name by recursively removing paired parenthesis + while True: + name, n = self._parenthesis_re.subn('', name) + if not n: + break + + # Strip const qualifier + name = self._const_re.sub('', name) + + # Strip template parameters from name by recursively removing paired angles + while True: + name, n = self._angles_re.subn('', name) + if not n: + break + + return name + + # TODO: write utility functions + + def __repr__(self): + return self.name + + def dump(self, sep1=",\n\t", sep2=":=", sep3="\n"): + """ Returns as a string all information available in this Function object + separators sep1:between entries + sep2:between attribute name and value, + sep3: inserted at end + """ + return sep1.join("".join(k,sep2,v) for (k,v) in sorted(self.__dict__.items())) + sep3 + +class Cycle(Object): + """A cycle made from recursive function calls.""" + + def __init__(self): + Object.__init__(self) + self.functions = set() + + def add_function(self, function): + assert function not in self.functions + self.functions.add(function) + if function.cycle is not None: + for other in function.cycle.functions: + if function not in self.functions: + self.add_function(other) + function.cycle = self + + +class Profile(Object): + """The whole profile.""" + + def __init__(self): + Object.__init__(self) + self.functions = {} + self.cycles = [] + + def add_function(self, function): + if function.id in self.functions: + sys.stderr.write('warning: overwriting function %s (id %s)\n' % (function.name, str(function.id))) + self.functions[function.id] = function + + def add_cycle(self, cycle): + self.cycles.append(cycle) + + def validate(self): + """Validate the edges.""" + + for function in compat_itervalues(self.functions): + for callee_id in compat_keys(function.calls): + assert function.calls[callee_id].callee_id == callee_id + if callee_id not in self.functions: + sys.stderr.write('warning: call to undefined function %s from function %s\n' % (str(callee_id), function.name)) + del function.calls[callee_id] + + def find_cycles(self): + """Find cycles using Tarjan's strongly connected components algorithm.""" + + # Apply the Tarjan's algorithm successively until all functions are visited + stack = [] + data = {} + order = 0 + for function in compat_itervalues(self.functions): + order = self._tarjan(function, order, stack, data) + cycles = [] + for function in compat_itervalues(self.functions): + if function.cycle is not None and function.cycle not in cycles: + cycles.append(function.cycle) + self.cycles = cycles + if 0: + for cycle in cycles: + sys.stderr.write("Cycle:\n") + for member in cycle.functions: + sys.stderr.write("\tFunction %s\n" % member.name) + + def prune_root(self, roots, depth=-1): + visited = set() + frontier = set([(root_node, depth) for root_node in roots]) + while len(frontier) > 0: + node, node_depth = frontier.pop() + visited.add(node) + if node_depth == 0: + continue + f = self.functions[node] + newNodes = set(f.calls.keys()) - visited + frontier = frontier.union({(new_node, node_depth - 1) for new_node in newNodes}) + subtreeFunctions = {} + for n in visited: + f = self.functions[n] + newCalls = {} + for c in f.calls.keys(): + if c in visited: + newCalls[c] = f.calls[c] + f.calls = newCalls + subtreeFunctions[n] = f + self.functions = subtreeFunctions + + def prune_leaf(self, leafs, depth=-1): + edgesUp = collections.defaultdict(set) + for f in self.functions.keys(): + for n in self.functions[f].calls.keys(): + edgesUp[n].add(f) + # build the tree up + visited = set() + frontier = set([(leaf_node, depth) for leaf_node in leafs]) + while len(frontier) > 0: + node, node_depth = frontier.pop() + visited.add(node) + if node_depth == 0: + continue + newNodes = edgesUp[node] - visited + frontier = frontier.union({(new_node, node_depth - 1) for new_node in newNodes}) + downTree = set(self.functions.keys()) + upTree = visited + path = downTree.intersection(upTree) + pathFunctions = {} + for n in path: + f = self.functions[n] + newCalls = {} + for c in f.calls.keys(): + if c in path: + newCalls[c] = f.calls[c] + f.calls = newCalls + pathFunctions[n] = f + self.functions = pathFunctions + + def getFunctionIds(self, funcName): + function_names = {v.name: k for (k, v) in self.functions.items()} + return [function_names[name] for name in fnmatch.filter(function_names.keys(), funcName)] + + def getFunctionId(self, funcName): + for f in self.functions: + if self.functions[f].name == funcName: + return f + return False + + def printFunctionIds(self, selector=None, file=sys.stderr): + """ Print to file function entries selected by fnmatch.fnmatch like in + method getFunctionIds, with following extensions: + - selector starts with "%": dump all information available + - selector is '+' or '-': select all function entries + """ + if selector is None or selector in ("+", "*"): + v = ",\n".join(("%s:\t%s" % (kf,self.functions[kf].name) + for kf in self.functions.keys())) + else: + if selector[0]=="%": + selector=selector[1:] + function_info={k:v for (k,v) + in self.functions.items() + if fnmatch.fnmatch(v.name,selector)} + v = ",\n".join( ("%s\t({k})\t(%s)::\n\t%s" % (v.name,type(v),v.dump()) + for (k,v) in function_info.items() + )) + + else: + function_names = (v.name for v in self.functions.values()) + v = ",\n".join( ( nm for nm in fnmatch.filter(function_names,selector ))) + + file.write(v+"\n") + file.flush() + + class _TarjanData: + def __init__(self, order): + self.order = order + self.lowlink = order + self.onstack = False + + def _tarjan(self, function, order, stack, data): + """Tarjan's strongly connected components algorithm. + + See also: + - http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm + """ + + try: + func_data = data[function.id] + return order + except KeyError: + func_data = self._TarjanData(order) + data[function.id] = func_data + order += 1 + pos = len(stack) + stack.append(function) + func_data.onstack = True + for call in compat_itervalues(function.calls): + try: + callee_data = data[call.callee_id] + if callee_data.onstack: + func_data.lowlink = min(func_data.lowlink, callee_data.order) + except KeyError: + callee = self.functions[call.callee_id] + order = self._tarjan(callee, order, stack, data) + callee_data = data[call.callee_id] + func_data.lowlink = min(func_data.lowlink, callee_data.lowlink) + if func_data.lowlink == func_data.order: + # Strongly connected component found + members = stack[pos:] + del stack[pos:] + if len(members) > 1: + cycle = Cycle() + for member in members: + cycle.add_function(member) + data[member.id].onstack = False + else: + for member in members: + data[member.id].onstack = False + return order + + def call_ratios(self, event): + # Aggregate for incoming calls + cycle_totals = {} + for cycle in self.cycles: + cycle_totals[cycle] = 0.0 + function_totals = {} + for function in compat_itervalues(self.functions): + function_totals[function] = 0.0 + + # Pass 1: function_total gets the sum of call[event] for all + # incoming arrows. Same for cycle_total for all arrows + # that are coming into the *cycle* but are not part of it. + for function in compat_itervalues(self.functions): + for call in compat_itervalues(function.calls): + if call.callee_id != function.id: + callee = self.functions[call.callee_id] + if event in call.events: + function_totals[callee] += call[event] + if callee.cycle is not None and callee.cycle is not function.cycle: + cycle_totals[callee.cycle] += call[event] + else: + sys.stderr.write("call_ratios: No data for " + function.name + " call to " + callee.name + "\n") + + # Pass 2: Compute the ratios. Each call[event] is scaled by the + # function_total of the callee. Calls into cycles use the + # cycle_total, but not calls within cycles. + for function in compat_itervalues(self.functions): + for call in compat_itervalues(function.calls): + assert call.ratio is None + if call.callee_id != function.id: + callee = self.functions[call.callee_id] + if event in call.events: + if callee.cycle is not None and callee.cycle is not function.cycle: + total = cycle_totals[callee.cycle] + else: + total = function_totals[callee] + call.ratio = ratio(call[event], total) + else: + # Warnings here would only repeat those issued above. + call.ratio = 0.0 + + def integrate(self, outevent, inevent): + """Propagate function time ratio along the function calls. + + Must be called after finding the cycles. + + See also: + - http://citeseer.ist.psu.edu/graham82gprof.html + """ + + # Sanity checking + assert outevent not in self + for function in compat_itervalues(self.functions): + assert outevent not in function + assert inevent in function + for call in compat_itervalues(function.calls): + assert outevent not in call + if call.callee_id != function.id: + assert call.ratio is not None + + # Aggregate the input for each cycle + for cycle in self.cycles: + total = inevent.null() + for function in compat_itervalues(self.functions): + total = inevent.aggregate(total, function[inevent]) + self[inevent] = total + + # Integrate along the edges + total = inevent.null() + for function in compat_itervalues(self.functions): + total = inevent.aggregate(total, function[inevent]) + self._integrate_function(function, outevent, inevent) + self[outevent] = total + + def _integrate_function(self, function, outevent, inevent): + if function.cycle is not None: + return self._integrate_cycle(function.cycle, outevent, inevent) + else: + if outevent not in function: + total = function[inevent] + for call in compat_itervalues(function.calls): + if call.callee_id != function.id: + total += self._integrate_call(call, outevent, inevent) + function[outevent] = total + return function[outevent] + + def _integrate_call(self, call, outevent, inevent): + assert outevent not in call + assert call.ratio is not None + callee = self.functions[call.callee_id] + subtotal = call.ratio *self._integrate_function(callee, outevent, inevent) + call[outevent] = subtotal + return subtotal + + def _integrate_cycle(self, cycle, outevent, inevent): + if outevent not in cycle: + + # Compute the outevent for the whole cycle + total = inevent.null() + for member in cycle.functions: + subtotal = member[inevent] + for call in compat_itervalues(member.calls): + callee = self.functions[call.callee_id] + if callee.cycle is not cycle: + subtotal += self._integrate_call(call, outevent, inevent) + total += subtotal + cycle[outevent] = total + + # Compute the time propagated to callers of this cycle + callees = {} + for function in compat_itervalues(self.functions): + if function.cycle is not cycle: + for call in compat_itervalues(function.calls): + callee = self.functions[call.callee_id] + if callee.cycle is cycle: + try: + callees[callee] += call.ratio + except KeyError: + callees[callee] = call.ratio + + for member in cycle.functions: + member[outevent] = outevent.null() + + for callee, call_ratio in compat_iteritems(callees): + ranks = {} + call_ratios = {} + partials = {} + self._rank_cycle_function(cycle, callee, ranks) + self._call_ratios_cycle(cycle, callee, ranks, call_ratios, set()) + partial = self._integrate_cycle_function(cycle, callee, call_ratio, partials, ranks, call_ratios, outevent, inevent) + + # Ensure `partial == max(partials.values())`, but with round-off tolerance + max_partial = max(partials.values()) + assert abs(partial - max_partial) <= 1e-7*max_partial + + assert abs(call_ratio*total - partial) <= 0.001*call_ratio*total + + return cycle[outevent] + + def _rank_cycle_function(self, cycle, function, ranks): + """Dijkstra's shortest paths algorithm. + + See also: + - http://en.wikipedia.org/wiki/Dijkstra's_algorithm + """ + + import heapq + Q = [] + Qd = {} + p = {} + visited = set([function]) + + ranks[function] = 0 + for call in compat_itervalues(function.calls): + if call.callee_id != function.id: + callee = self.functions[call.callee_id] + if callee.cycle is cycle: + ranks[callee] = 1 + item = [ranks[callee], function, callee] + heapq.heappush(Q, item) + Qd[callee] = item + + while Q: + cost, parent, member = heapq.heappop(Q) + if member not in visited: + p[member]= parent + visited.add(member) + for call in compat_itervalues(member.calls): + if call.callee_id != member.id: + callee = self.functions[call.callee_id] + if callee.cycle is cycle: + member_rank = ranks[member] + rank = ranks.get(callee) + if rank is not None: + if rank > 1 + member_rank: + rank = 1 + member_rank + ranks[callee] = rank + Qd_callee = Qd[callee] + Qd_callee[0] = rank + Qd_callee[1] = member + heapq._siftdown(Q, 0, Q.index(Qd_callee)) + else: + rank = 1 + member_rank + ranks[callee] = rank + item = [rank, member, callee] + heapq.heappush(Q, item) + Qd[callee] = item + + def _call_ratios_cycle(self, cycle, function, ranks, call_ratios, visited): + if function not in visited: + visited.add(function) + for call in compat_itervalues(function.calls): + if call.callee_id != function.id: + callee = self.functions[call.callee_id] + if callee.cycle is cycle: + if ranks[callee] > ranks[function]: + call_ratios[callee] = call_ratios.get(callee, 0.0) + call.ratio + self._call_ratios_cycle(cycle, callee, ranks, call_ratios, visited) + + def _integrate_cycle_function(self, cycle, function, partial_ratio, partials, ranks, call_ratios, outevent, inevent): + if function not in partials: + partial = partial_ratio*function[inevent] + for call in compat_itervalues(function.calls): + if call.callee_id != function.id: + callee = self.functions[call.callee_id] + if callee.cycle is not cycle: + assert outevent in call + partial += partial_ratio*call[outevent] + else: + if ranks[callee] > ranks[function]: + callee_partial = self._integrate_cycle_function(cycle, callee, partial_ratio, partials, ranks, call_ratios, outevent, inevent) + call_ratio = ratio(call.ratio, call_ratios[callee]) + call_partial = call_ratio*callee_partial + try: + call[outevent] += call_partial + except UndefinedEvent: + call[outevent] = call_partial + partial += call_partial + partials[function] = partial + try: + function[outevent] += partial + except UndefinedEvent: + function[outevent] = partial + return partials[function] + + def aggregate(self, event): + """Aggregate an event for the whole profile.""" + + total = event.null() + for function in compat_itervalues(self.functions): + try: + total = event.aggregate(total, function[event]) + except UndefinedEvent: + return + self[event] = total + + def ratio(self, outevent, inevent): + assert outevent not in self + assert inevent in self + for function in compat_itervalues(self.functions): + assert outevent not in function + assert inevent in function + function[outevent] = ratio(function[inevent], self[inevent]) + for call in compat_itervalues(function.calls): + assert outevent not in call + if inevent in call: + call[outevent] = ratio(call[inevent], self[inevent]) + self[outevent] = 1.0 + + def prune(self, node_thres, edge_thres, paths, color_nodes_by_selftime): + """Prune the profile""" + + # compute the prune ratios + for function in compat_itervalues(self.functions): + try: + function.weight = function[TOTAL_TIME_RATIO] + except UndefinedEvent: + pass + + for call in compat_itervalues(function.calls): + callee = self.functions[call.callee_id] + + if TOTAL_TIME_RATIO in call: + # handle exact cases first + call.weight = call[TOTAL_TIME_RATIO] + else: + try: + # make a safe estimate + call.weight = min(function[TOTAL_TIME_RATIO], callee[TOTAL_TIME_RATIO]) + except UndefinedEvent: + pass + + # prune the nodes + for function_id in compat_keys(self.functions): + function = self.functions[function_id] + if function.weight is not None: + if function.weight < node_thres: + del self.functions[function_id] + + # prune file paths + for function_id in compat_keys(self.functions): + function = self.functions[function_id] + if paths and function.filename and not any(function.filename.startswith(path) for path in paths): + del self.functions[function_id] + elif paths and function.module and not any((function.module.find(path)>-1) for path in paths): + del self.functions[function_id] + + # prune the edges + for function in compat_itervalues(self.functions): + for callee_id in compat_keys(function.calls): + call = function.calls[callee_id] + if callee_id not in self.functions or call.weight is not None and call.weight < edge_thres: + del function.calls[callee_id] + + if color_nodes_by_selftime: + weights = [] + for function in compat_itervalues(self.functions): + try: + weights.append(function[TIME_RATIO]) + except UndefinedEvent: + pass + max_ratio = max(weights or [1]) + + # apply rescaled weights for coloriung + for function in compat_itervalues(self.functions): + try: + function.weight = function[TIME_RATIO] / max_ratio + except (ZeroDivisionError, UndefinedEvent): + pass + + def dump(self): + for function in compat_itervalues(self.functions): + sys.stderr.write('Function %s:\n' % (function.name,)) + self._dump_events(function.events) + for call in compat_itervalues(function.calls): + callee = self.functions[call.callee_id] + sys.stderr.write(' Call %s:\n' % (callee.name,)) + self._dump_events(call.events) + for cycle in self.cycles: + sys.stderr.write('Cycle:\n') + self._dump_events(cycle.events) + for function in cycle.functions: + sys.stderr.write(' Function %s\n' % (function.name,)) + + def _dump_events(self, events): + for event, value in compat_iteritems(events): + sys.stderr.write(' %s: %s\n' % (event.name, event.format(value))) + + + +######################################################################## +# Parsers + + +class Struct: + """Masquerade a dictionary with a structure-like behavior.""" + + def __init__(self, attrs = None): + if attrs is None: + attrs = {} + self.__dict__['_attrs'] = attrs + + def __getattr__(self, name): + try: + return self._attrs[name] + except KeyError: + raise AttributeError(name) + + def __setattr__(self, name, value): + self._attrs[name] = value + + def __str__(self): + return str(self._attrs) + + def __repr__(self): + return repr(self._attrs) + + +class ParseError(Exception): + """Raised when parsing to signal mismatches.""" + + def __init__(self, msg, line): + Exception.__init__(self) + self.msg = msg + # TODO: store more source line information + self.line = line + + def __str__(self): + return '%s: %r' % (self.msg, self.line) + + +class Parser: + """Parser interface.""" + + stdinInput = True + multipleInput = False + + def __init__(self): + pass + + def parse(self): + raise NotImplementedError + + +class JsonParser(Parser): + """Parser for a custom JSON representation of profile data. + + See schema.json for details. + """ + + + def __init__(self, stream): + Parser.__init__(self) + self.stream = stream + + def parse(self): + + obj = json.load(self.stream) + + assert obj['version'] == 0 + + profile = Profile() + profile[SAMPLES] = 0 + + fns = obj['functions'] + + for functionIndex in range(len(fns)): + fn = fns[functionIndex] + function = Function(functionIndex, fn['name']) + try: + function.module = fn['module'] + except KeyError: + pass + try: + function.process = fn['process'] + except KeyError: + pass + function[SAMPLES] = 0 + function.called = 0 + profile.add_function(function) + + for event in obj['events']: + callchain = [] + + for functionIndex in event['callchain']: + function = profile.functions[functionIndex] + callchain.append(function) + + # increment the call count of the first in the callchain + function = profile.functions[event['callchain'][0]] + function.called = function.called + 1 + + cost = event['cost'][0] + + callee = callchain[0] + callee[SAMPLES] += cost + profile[SAMPLES] += cost + + for caller in callchain[1:]: + try: + call = caller.calls[callee.id] + except KeyError: + call = Call(callee.id) + call[SAMPLES2] = cost + caller.add_call(call) + else: + call[SAMPLES2] += cost + + callee = caller + + if False: + profile.dump() + + # compute derived data + profile.validate() + profile.find_cycles() + profile.ratio(TIME_RATIO, SAMPLES) + profile.call_ratios(SAMPLES2) + profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + + return profile + + +class LineParser(Parser): + """Base class for parsers that read line-based formats.""" + + def __init__(self, stream): + Parser.__init__(self) + self._stream = stream + self.__line = None + self.__eof = False + self.line_no = 0 + + def readline(self): + line = self._stream.readline() + if not line: + self.__line = '' + self.__eof = True + else: + self.line_no += 1 + line = line.rstrip('\r\n') + if not PYTHON_3: + encoding = self._stream.encoding + if encoding is None: + encoding = locale.getpreferredencoding() + line = line.decode(encoding) + self.__line = line + + def lookahead(self): + assert self.__line is not None + return self.__line + + def consume(self): + assert self.__line is not None + line = self.__line + self.readline() + return line + + def eof(self): + assert self.__line is not None + return self.__eof + + +XML_ELEMENT_START, XML_ELEMENT_END, XML_CHARACTER_DATA, XML_EOF = range(4) + + +class XmlToken: + + def __init__(self, type, name_or_data, attrs = None, line = None, column = None): + assert type in (XML_ELEMENT_START, XML_ELEMENT_END, XML_CHARACTER_DATA, XML_EOF) + self.type = type + self.name_or_data = name_or_data + self.attrs = attrs + self.line = line + self.column = column + + def __str__(self): + if self.type == XML_ELEMENT_START: + return '<' + self.name_or_data + ' ...>' + if self.type == XML_ELEMENT_END: + return '' + if self.type == XML_CHARACTER_DATA: + return self.name_or_data + if self.type == XML_EOF: + return 'end of file' + assert 0 + + +class XmlTokenizer: + """Expat based XML tokenizer.""" + + def __init__(self, fp, skip_ws = True): + self.fp = fp + self.tokens = [] + self.index = 0 + self.final = False + self.skip_ws = skip_ws + + self.character_pos = 0, 0 + self.character_data = '' + + self.parser = xml.parsers.expat.ParserCreate() + self.parser.StartElementHandler = self.handle_element_start + self.parser.EndElementHandler = self.handle_element_end + self.parser.CharacterDataHandler = self.handle_character_data + + def handle_element_start(self, name, attributes): + self.finish_character_data() + line, column = self.pos() + token = XmlToken(XML_ELEMENT_START, name, attributes, line, column) + self.tokens.append(token) + + def handle_element_end(self, name): + self.finish_character_data() + line, column = self.pos() + token = XmlToken(XML_ELEMENT_END, name, None, line, column) + self.tokens.append(token) + + def handle_character_data(self, data): + if not self.character_data: + self.character_pos = self.pos() + self.character_data += data + + def finish_character_data(self): + if self.character_data: + if not self.skip_ws or not self.character_data.isspace(): + line, column = self.character_pos + token = XmlToken(XML_CHARACTER_DATA, self.character_data, None, line, column) + self.tokens.append(token) + self.character_data = '' + + def next(self): + size = 16*1024 + while self.index >= len(self.tokens) and not self.final: + self.tokens = [] + self.index = 0 + data = self.fp.read(size) + self.final = len(data) < size + self.parser.Parse(data, self.final) + if self.index >= len(self.tokens): + line, column = self.pos() + token = XmlToken(XML_EOF, None, None, line, column) + else: + token = self.tokens[self.index] + self.index += 1 + return token + + def pos(self): + return self.parser.CurrentLineNumber, self.parser.CurrentColumnNumber + + +class XmlTokenMismatch(Exception): + + def __init__(self, expected, found): + Exception.__init__(self) + self.expected = expected + self.found = found + + def __str__(self): + return '%u:%u: %s expected, %s found' % (self.found.line, self.found.column, str(self.expected), str(self.found)) + + +class XmlParser(Parser): + """Base XML document parser.""" + + def __init__(self, fp): + Parser.__init__(self) + self.tokenizer = XmlTokenizer(fp) + self.consume() + + def consume(self): + self.token = self.tokenizer.next() + + def match_element_start(self, name): + return self.token.type == XML_ELEMENT_START and self.token.name_or_data == name + + def match_element_end(self, name): + return self.token.type == XML_ELEMENT_END and self.token.name_or_data == name + + def element_start(self, name): + while self.token.type == XML_CHARACTER_DATA: + self.consume() + if self.token.type != XML_ELEMENT_START: + raise XmlTokenMismatch(XmlToken(XML_ELEMENT_START, name), self.token) + if self.token.name_or_data != name: + raise XmlTokenMismatch(XmlToken(XML_ELEMENT_START, name), self.token) + attrs = self.token.attrs + self.consume() + return attrs + + def element_end(self, name): + while self.token.type == XML_CHARACTER_DATA: + self.consume() + if self.token.type != XML_ELEMENT_END: + raise XmlTokenMismatch(XmlToken(XML_ELEMENT_END, name), self.token) + if self.token.name_or_data != name: + raise XmlTokenMismatch(XmlToken(XML_ELEMENT_END, name), self.token) + self.consume() + + def character_data(self, strip = True): + data = '' + while self.token.type == XML_CHARACTER_DATA: + data += self.token.name_or_data + self.consume() + if strip: + data = data.strip() + return data + + +class GprofParser(Parser): + """Parser for GNU gprof output. + + See also: + - Chapter "Interpreting gprof's Output" from the GNU gprof manual + http://sourceware.org/binutils/docs-2.18/gprof/Call-Graph.html#Call-Graph + - File "cg_print.c" from the GNU gprof source code + http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/gprof/cg_print.c?rev=1.12&cvsroot=src + """ + + def __init__(self, fp): + Parser.__init__(self) + self.fp = fp + self.functions = {} + self.cycles = {} + + def readline(self): + line = self.fp.readline() + if not line: + sys.stderr.write('error: unexpected end of file\n') + sys.exit(1) + line = line.rstrip('\r\n') + return line + + _int_re = re.compile(r'^\d+$') + _float_re = re.compile(r'^\d+\.\d+$') + + def translate(self, mo): + """Extract a structure from a match object, while translating the types in the process.""" + attrs = {} + groupdict = mo.groupdict() + for name, value in compat_iteritems(groupdict): + if value is None: + value = None + elif self._int_re.match(value): + value = int(value) + elif self._float_re.match(value): + value = float(value) + attrs[name] = (value) + return Struct(attrs) + + _cg_header_re = re.compile( + # original gprof header + r'^\s+called/total\s+parents\s*$|' + + r'^index\s+%time\s+self\s+descendents\s+called\+self\s+name\s+index\s*$|' + + r'^\s+called/total\s+children\s*$|' + + # GNU gprof header + r'^index\s+%\s+time\s+self\s+children\s+called\s+name\s*$' + ) + + _cg_ignore_re = re.compile( + # spontaneous + r'^\s+\s*$|' + # internal calls (such as "mcount") + r'^.*\((\d+)\)$' + ) + + _cg_primary_re = re.compile( + r'^\[(?P\d+)\]?' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?:(?P\d+)(?:\+(?P\d+))?)?' + + r'\s+(?P\S.*?)' + + r'(?:\s+\d+)>)?' + + r'\s\[(\d+)\]$' + ) + + _cg_parent_re = re.compile( + r'^\s+(?P\d+\.\d+)?' + + r'\s+(?P\d+\.\d+)?' + + r'\s+(?P\d+)(?:/(?P\d+))?' + + r'\s+(?P\S.*?)' + + r'(?:\s+\d+)>)?' + + r'\s\[(?P\d+)\]$' + ) + + _cg_child_re = _cg_parent_re + + _cg_cycle_header_re = re.compile( + r'^\[(?P\d+)\]?' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?:(?P\d+)(?:\+(?P\d+))?)?' + + r'\s+\d+)\sas\sa\swhole>' + + r'\s\[(\d+)\]$' + ) + + _cg_cycle_member_re = re.compile( + r'^\s+(?P\d+\.\d+)?' + + r'\s+(?P\d+\.\d+)?' + + r'\s+(?P\d+)(?:\+(?P\d+))?' + + r'\s+(?P\S.*?)' + + r'(?:\s+\d+)>)?' + + r'\s\[(?P\d+)\]$' + ) + + _cg_sep_re = re.compile(r'^--+$') + + def parse_function_entry(self, lines): + parents = [] + children = [] + + while True: + if not lines: + sys.stderr.write('warning: unexpected end of entry\n') + line = lines.pop(0) + if line.startswith('['): + break + + # read function parent line + mo = self._cg_parent_re.match(line) + if not mo: + if self._cg_ignore_re.match(line): + continue + sys.stderr.write('warning: unrecognized call graph entry: %r\n' % line) + else: + parent = self.translate(mo) + parents.append(parent) + + # read primary line + mo = self._cg_primary_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry: %r\n' % line) + return + else: + function = self.translate(mo) + + while lines: + line = lines.pop(0) + + # read function subroutine line + mo = self._cg_child_re.match(line) + if not mo: + if self._cg_ignore_re.match(line): + continue + sys.stderr.write('warning: unrecognized call graph entry: %r\n' % line) + else: + child = self.translate(mo) + children.append(child) + + function.parents = parents + function.children = children + + self.functions[function.index] = function + + def parse_cycle_entry(self, lines): + + # read cycle header line + line = lines[0] + mo = self._cg_cycle_header_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry: %r\n' % line) + return + cycle = self.translate(mo) + + # read cycle member lines + cycle.functions = [] + for line in lines[1:]: + mo = self._cg_cycle_member_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry: %r\n' % line) + continue + call = self.translate(mo) + cycle.functions.append(call) + + self.cycles[cycle.cycle] = cycle + + def parse_cg_entry(self, lines): + if lines[0].startswith("["): + self.parse_cycle_entry(lines) + else: + self.parse_function_entry(lines) + + def parse_cg(self): + """Parse the call graph.""" + + # skip call graph header + while not self._cg_header_re.match(self.readline()): + pass + line = self.readline() + while self._cg_header_re.match(line): + line = self.readline() + + # process call graph entries + entry_lines = [] + while line != '\014': # form feed + if line and not line.isspace(): + if self._cg_sep_re.match(line): + self.parse_cg_entry(entry_lines) + entry_lines = [] + else: + entry_lines.append(line) + line = self.readline() + + def parse(self): + self.parse_cg() + self.fp.close() + + profile = Profile() + profile[TIME] = 0.0 + + cycles = {} + for index in self.cycles: + cycles[index] = Cycle() + + for entry in compat_itervalues(self.functions): + # populate the function + function = Function(entry.index, entry.name) + function[TIME] = entry.self + if entry.called is not None: + function.called = entry.called + if entry.called_self is not None: + call = Call(entry.index) + call[CALLS] = entry.called_self + function.called += entry.called_self + + # populate the function calls + for child in entry.children: + call = Call(child.index) + + assert child.called is not None + call[CALLS] = child.called + + if child.index not in self.functions: + # NOTE: functions that were never called but were discovered by gprof's + # static call graph analysis dont have a call graph entry so we need + # to add them here + missing = Function(child.index, child.name) + function[TIME] = 0.0 + function.called = 0 + profile.add_function(missing) + + function.add_call(call) + + profile.add_function(function) + + if entry.cycle is not None: + try: + cycle = cycles[entry.cycle] + except KeyError: + sys.stderr.write('warning: entry missing\n' % entry.cycle) + cycle = Cycle() + cycles[entry.cycle] = cycle + cycle.add_function(function) + + profile[TIME] = profile[TIME] + function[TIME] + + for cycle in compat_itervalues(cycles): + profile.add_cycle(cycle) + + # Compute derived events + profile.validate() + profile.ratio(TIME_RATIO, TIME) + profile.call_ratios(CALLS) + profile.integrate(TOTAL_TIME, TIME) + profile.ratio(TOTAL_TIME_RATIO, TOTAL_TIME) + + return profile + + +# Clone&hack of GprofParser for VTune Amplifier XE 2013 gprof-cc output. +# Tested only with AXE 2013 for Windows. +# - Use total times as reported by AXE. +# - In the absence of call counts, call ratios are faked from the relative +# proportions of total time. This affects only the weighting of the calls. +# - Different header, separator, and end marker. +# - Extra whitespace after function names. +# - You get a full entry for , which does not have parents. +# - Cycles do have parents. These are saved but unused (as they are +# for functions). +# - Disambiguated "unrecognized call graph entry" error messages. +# Notes: +# - Total time of functions as reported by AXE passes the val3 test. +# - CPU Time:Children in the input is sometimes a negative number. This +# value goes to the variable descendants, which is unused. +# - The format of gprof-cc reports is unaffected by the use of +# -knob enable-call-counts=true (no call counts, ever), or +# -show-as=samples (results are quoted in seconds regardless). +class AXEParser(Parser): + "Parser for VTune Amplifier XE 2013 gprof-cc report output." + + def __init__(self, fp): + Parser.__init__(self) + self.fp = fp + self.functions = {} + self.cycles = {} + + def readline(self): + line = self.fp.readline() + if not line: + sys.stderr.write('error: unexpected end of file\n') + sys.exit(1) + line = line.rstrip('\r\n') + return line + + _int_re = re.compile(r'^\d+$') + _float_re = re.compile(r'^\d+\.\d+$') + + def translate(self, mo): + """Extract a structure from a match object, while translating the types in the process.""" + attrs = {} + groupdict = mo.groupdict() + for name, value in compat_iteritems(groupdict): + if value is None: + value = None + elif self._int_re.match(value): + value = int(value) + elif self._float_re.match(value): + value = float(value) + attrs[name] = (value) + return Struct(attrs) + + _cg_header_re = re.compile( + '^Index |' + '^-----+ ' + ) + + _cg_footer_re = re.compile(r'^Index\s+Function\s*$') + + _cg_primary_re = re.compile( + r'^\[(?P\d+)\]?' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\S.*?)' + + r'(?:\s+\d+)>)?' + + r'\s+\[(\d+)\]' + + r'\s*$' + ) + + _cg_parent_re = re.compile( + r'^\s+(?P\d+\.\d+)?' + + r'\s+(?P\d+\.\d+)?' + + r'\s+(?P\S.*?)' + + r'(?:\s+\d+)>)?' + + r'(?:\s+\[(?P\d+)\]\s*)?' + + r'\s*$' + ) + + _cg_child_re = _cg_parent_re + + _cg_cycle_header_re = re.compile( + r'^\[(?P\d+)\]?' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+(?P\d+\.\d+)' + + r'\s+\d+)\sas\sa\swhole>' + + r'\s+\[(\d+)\]' + + r'\s*$' + ) + + _cg_cycle_member_re = re.compile( + r'^\s+(?P\d+\.\d+)?' + + r'\s+(?P\d+\.\d+)?' + + r'\s+(?P\S.*?)' + + r'(?:\s+\d+)>)?' + + r'\s+\[(?P\d+)\]' + + r'\s*$' + ) + + def parse_function_entry(self, lines): + parents = [] + children = [] + + while True: + if not lines: + sys.stderr.write('warning: unexpected end of entry\n') + return + line = lines.pop(0) + if line.startswith('['): + break + + # read function parent line + mo = self._cg_parent_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry (1): %r\n' % line) + else: + parent = self.translate(mo) + if parent.name != '': + parents.append(parent) + + # read primary line + mo = self._cg_primary_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry (2): %r\n' % line) + return + else: + function = self.translate(mo) + + while lines: + line = lines.pop(0) + + # read function subroutine line + mo = self._cg_child_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry (3): %r\n' % line) + else: + child = self.translate(mo) + if child.name != '': + children.append(child) + + if function.name != '': + function.parents = parents + function.children = children + + self.functions[function.index] = function + + def parse_cycle_entry(self, lines): + + # Process the parents that were not there in gprof format. + parents = [] + while True: + if not lines: + sys.stderr.write('warning: unexpected end of cycle entry\n') + return + line = lines.pop(0) + if line.startswith('['): + break + mo = self._cg_parent_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry (6): %r\n' % line) + else: + parent = self.translate(mo) + if parent.name != '': + parents.append(parent) + + # read cycle header line + mo = self._cg_cycle_header_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry (4): %r\n' % line) + return + cycle = self.translate(mo) + + # read cycle member lines + cycle.functions = [] + for line in lines[1:]: + mo = self._cg_cycle_member_re.match(line) + if not mo: + sys.stderr.write('warning: unrecognized call graph entry (5): %r\n' % line) + continue + call = self.translate(mo) + cycle.functions.append(call) + + cycle.parents = parents + self.cycles[cycle.cycle] = cycle + + def parse_cg_entry(self, lines): + if any("as a whole" in linelooper for linelooper in lines): + self.parse_cycle_entry(lines) + else: + self.parse_function_entry(lines) + + def parse_cg(self): + """Parse the call graph.""" + + # skip call graph header + line = self.readline() + while self._cg_header_re.match(line): + line = self.readline() + + # process call graph entries + entry_lines = [] + # An EOF in readline terminates the program without returning. + while not self._cg_footer_re.match(line): + if line.isspace(): + self.parse_cg_entry(entry_lines) + entry_lines = [] + else: + entry_lines.append(line) + line = self.readline() + + def parse(self): + sys.stderr.write('warning: for axe format, edge weights are unreliable estimates derived from function total times.\n') + self.parse_cg() + self.fp.close() + + profile = Profile() + profile[TIME] = 0.0 + + cycles = {} + for index in self.cycles: + cycles[index] = Cycle() + + for entry in compat_itervalues(self.functions): + # populate the function + function = Function(entry.index, entry.name) + function[TIME] = entry.self + function[TOTAL_TIME_RATIO] = entry.percentage_time / 100.0 + + # populate the function calls + for child in entry.children: + call = Call(child.index) + # The following bogus value affects only the weighting of + # the calls. + call[TOTAL_TIME_RATIO] = function[TOTAL_TIME_RATIO] + + if child.index not in self.functions: + # NOTE: functions that were never called but were discovered by gprof's + # static call graph analysis dont have a call graph entry so we need + # to add them here + # FIXME: Is this applicable? + missing = Function(child.index, child.name) + function[TIME] = 0.0 + profile.add_function(missing) + + function.add_call(call) + + profile.add_function(function) + + if entry.cycle is not None: + try: + cycle = cycles[entry.cycle] + except KeyError: + sys.stderr.write('warning: entry missing\n' % entry.cycle) + cycle = Cycle() + cycles[entry.cycle] = cycle + cycle.add_function(function) + + profile[TIME] = profile[TIME] + function[TIME] + + for cycle in compat_itervalues(cycles): + profile.add_cycle(cycle) + + # Compute derived events. + profile.validate() + profile.ratio(TIME_RATIO, TIME) + # Lacking call counts, fake call ratios based on total times. + profile.call_ratios(TOTAL_TIME_RATIO) + # The TOTAL_TIME_RATIO of functions is already set. Propagate that + # total time to the calls. (TOTAL_TIME is neither set nor used.) + for function in compat_itervalues(profile.functions): + for call in compat_itervalues(function.calls): + if call.ratio is not None: + callee = profile.functions[call.callee_id] + call[TOTAL_TIME_RATIO] = call.ratio * callee[TOTAL_TIME_RATIO] + + return profile + + +class CallgrindParser(LineParser): + """Parser for valgrind's callgrind tool. + + See also: + - http://valgrind.org/docs/manual/cl-format.html + """ + + _call_re = re.compile(r'^calls=\s*(\d+)\s+((\d+|\+\d+|-\d+|\*)\s+)+$') + + def __init__(self, infile): + LineParser.__init__(self, infile) + + # Textual positions + self.position_ids = {} + self.positions = {} + + # Numeric positions + self.num_positions = 1 + self.cost_positions = ['line'] + self.last_positions = [0] + + # Events + self.num_events = 0 + self.cost_events = [] + + self.profile = Profile() + self.profile[SAMPLES] = 0 + + def parse(self): + # read lookahead + self.readline() + + self.parse_key('version') + self.parse_key('creator') + while self.parse_part(): + pass + if not self.eof(): + sys.stderr.write('warning: line %u: unexpected line\n' % self.line_no) + sys.stderr.write('%s\n' % self.lookahead()) + + # compute derived data + self.profile.validate() + self.profile.find_cycles() + self.profile.ratio(TIME_RATIO, SAMPLES) + self.profile.call_ratios(SAMPLES2) + self.profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + + return self.profile + + def parse_part(self): + if not self.parse_header_line(): + return False + while self.parse_header_line(): + pass + if not self.parse_body_line(): + return False + while self.parse_body_line(): + pass + return True + + def parse_header_line(self): + return \ + self.parse_empty() or \ + self.parse_comment() or \ + self.parse_part_detail() or \ + self.parse_description() or \ + self.parse_event_specification() or \ + self.parse_cost_line_def() or \ + self.parse_cost_summary() + + _detail_keys = set(('cmd', 'pid', 'thread', 'part')) + + def parse_part_detail(self): + return self.parse_keys(self._detail_keys) + + def parse_description(self): + return self.parse_key('desc') is not None + + def parse_event_specification(self): + event = self.parse_key('event') + if event is None: + return False + return True + + def parse_cost_line_def(self): + pair = self.parse_keys(('events', 'positions')) + if pair is None: + return False + key, value = pair + items = value.split() + if key == 'events': + self.num_events = len(items) + self.cost_events = items + if key == 'positions': + self.num_positions = len(items) + self.cost_positions = items + self.last_positions = [0]*self.num_positions + return True + + def parse_cost_summary(self): + pair = self.parse_keys(('summary', 'totals')) + if pair is None: + return False + return True + + def parse_body_line(self): + return \ + self.parse_empty() or \ + self.parse_comment() or \ + self.parse_cost_line() or \ + self.parse_position_spec() or \ + self.parse_association_spec() + + __subpos_re = r'(0x[0-9a-fA-F]+|\d+|\+\d+|-\d+|\*)' + _cost_re = re.compile(r'^' + + __subpos_re + r'( +' + __subpos_re + r')*' + + r'( +\d+)*' + + '$') + + def parse_cost_line(self, calls=None): + line = self.lookahead().rstrip() + mo = self._cost_re.match(line) + if not mo: + return False + + function = self.get_function() + + if calls is None: + # Unlike other aspects, call object (cob) is relative not to the + # last call object, but to the caller's object (ob), so try to + # update it when processing a functions cost line + try: + self.positions['cob'] = self.positions['ob'] + except KeyError: + pass + + values = line.split() + assert len(values) <= self.num_positions + self.num_events + + positions = values[0 : self.num_positions] + events = values[self.num_positions : ] + events += ['0']*(self.num_events - len(events)) + + for i in range(self.num_positions): + position = positions[i] + if position == '*': + position = self.last_positions[i] + elif position[0] in '-+': + position = self.last_positions[i] + int(position) + elif position.startswith('0x'): + position = int(position, 16) + else: + position = int(position) + self.last_positions[i] = position + + events = [float(event) for event in events] + + if calls is None: + function[SAMPLES] += events[0] + self.profile[SAMPLES] += events[0] + else: + callee = self.get_callee() + callee.called += calls + + try: + call = function.calls[callee.id] + except KeyError: + call = Call(callee.id) + call[CALLS] = calls + call[SAMPLES2] = events[0] + function.add_call(call) + else: + call[CALLS] += calls + call[SAMPLES2] += events[0] + + self.consume() + return True + + def parse_association_spec(self): + line = self.lookahead() + if not line.startswith('calls='): + return False + + _, values = line.split('=', 1) + values = values.strip().split() + calls = int(values[0]) + call_position = values[1:] + self.consume() + + self.parse_cost_line(calls) + + return True + + _position_re = re.compile(r'^(?P[cj]?(?:ob|fl|fi|fe|fn))=\s*(?:\((?P\d+)\))?(?:\s*(?P.+))?') + + _position_table_map = { + 'ob': 'ob', + 'fl': 'fl', + 'fi': 'fl', + 'fe': 'fl', + 'fn': 'fn', + 'cob': 'ob', + 'cfl': 'fl', + 'cfi': 'fl', + 'cfe': 'fl', + 'cfn': 'fn', + 'jfi': 'fl', + } + + _position_map = { + 'ob': 'ob', + 'fl': 'fl', + 'fi': 'fl', + 'fe': 'fl', + 'fn': 'fn', + 'cob': 'cob', + 'cfl': 'cfl', + 'cfi': 'cfl', + 'cfe': 'cfl', + 'cfn': 'cfn', + 'jfi': 'jfi', + } + + def parse_position_spec(self): + line = self.lookahead() + + if line.startswith('jump=') or line.startswith('jcnd='): + self.consume() + return True + + mo = self._position_re.match(line) + if not mo: + return False + + position, id, name = mo.groups() + if id: + table = self._position_table_map[position] + if name: + self.position_ids[(table, id)] = name + else: + name = self.position_ids.get((table, id), '') + self.positions[self._position_map[position]] = name + + self.consume() + return True + + def parse_empty(self): + if self.eof(): + return False + line = self.lookahead() + if line.strip(): + return False + self.consume() + return True + + def parse_comment(self): + line = self.lookahead() + if not line.startswith('#'): + return False + self.consume() + return True + + _key_re = re.compile(r'^(\w+):') + + def parse_key(self, key): + pair = self.parse_keys((key,)) + if not pair: + return None + key, value = pair + return value + + def parse_keys(self, keys): + line = self.lookahead() + mo = self._key_re.match(line) + if not mo: + return None + key, value = line.split(':', 1) + if key not in keys: + return None + value = value.strip() + self.consume() + return key, value + + def make_function(self, module, filename, name): + # FIXME: module and filename are not being tracked reliably + #id = '|'.join((module, filename, name)) + id = name + try: + function = self.profile.functions[id] + except KeyError: + function = Function(id, name) + if module: + function.module = os.path.basename(module) + function[SAMPLES] = 0 + function.called = 0 + self.profile.add_function(function) + return function + + def get_function(self): + module = self.positions.get('ob', '') + filename = self.positions.get('fl', '') + function = self.positions.get('fn', '') + return self.make_function(module, filename, function) + + def get_callee(self): + module = self.positions.get('cob', '') + filename = self.positions.get('cfi', '') + function = self.positions.get('cfn', '') + return self.make_function(module, filename, function) + + def readline(self): + # Override LineParser.readline to ignore comment lines + while True: + LineParser.readline(self) + if self.eof() or not self.lookahead().startswith('#'): + break + + +class PerfParser(LineParser): + """Parser for linux perf callgraph output. + + It expects output generated with + + perf record -g + perf script | gprof2dot.py --format=perf + """ + + def __init__(self, infile): + LineParser.__init__(self, infile) + self.profile = Profile() + + def readline(self): + # Override LineParser.readline to ignore comment lines + while True: + LineParser.readline(self) + if self.eof() or not self.lookahead().startswith('#'): + break + + def parse(self): + # read lookahead + self.readline() + + profile = self.profile + profile[SAMPLES] = 0 + while not self.eof(): + self.parse_event() + + # compute derived data + profile.validate() + profile.find_cycles() + profile.ratio(TIME_RATIO, SAMPLES) + profile.call_ratios(SAMPLES2) + if totalMethod == "callratios": + # Heuristic approach. TOTAL_SAMPLES is unused. + profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + elif totalMethod == "callstacks": + # Use the actual call chains for functions. + profile[TOTAL_SAMPLES] = profile[SAMPLES] + profile.ratio(TOTAL_TIME_RATIO, TOTAL_SAMPLES) + # Then propagate that total time to the calls. + for function in compat_itervalues(profile.functions): + for call in compat_itervalues(function.calls): + if call.ratio is not None: + callee = profile.functions[call.callee_id] + call[TOTAL_TIME_RATIO] = call.ratio * callee[TOTAL_TIME_RATIO] + else: + assert False + + return profile + + def parse_event(self): + if self.eof(): + return + + line = self.consume() + assert line + + callchain = self.parse_callchain() + if not callchain: + return + + callee = callchain[0] + callee[SAMPLES] += 1 + self.profile[SAMPLES] += 1 + + for caller in callchain[1:]: + try: + call = caller.calls[callee.id] + except KeyError: + call = Call(callee.id) + call[SAMPLES2] = 1 + caller.add_call(call) + else: + call[SAMPLES2] += 1 + + callee = caller + + # Increment TOTAL_SAMPLES only once on each function. + stack = set(callchain) + for function in stack: + function[TOTAL_SAMPLES] += 1 + + def parse_callchain(self): + callchain = [] + while self.lookahead(): + function = self.parse_call() + if function is None: + break + callchain.append(function) + if self.lookahead() == '': + self.consume() + return callchain + + call_re = re.compile(r'^\s+(?P
[0-9a-fA-F]+)\s+(?P.*)\s+\((?P.*)\)$') + addr2_re = re.compile(r'\+0x[0-9a-fA-F]+$') + + def parse_call(self): + line = self.consume() + mo = self.call_re.match(line) + assert mo + if not mo: + return None + + function_name = mo.group('symbol') + + # If present, amputate program counter from function name. + if function_name: + function_name = re.sub(self.addr2_re, '', function_name) + + if not function_name or function_name == '[unknown]': + function_name = mo.group('address') + + module = mo.group('module') + + function_id = function_name + ':' + module + + try: + function = self.profile.functions[function_id] + except KeyError: + function = Function(function_id, function_name) + function.module = os.path.basename(module) + function[SAMPLES] = 0 + function[TOTAL_SAMPLES] = 0 + self.profile.add_function(function) + + return function + + +class OprofileParser(LineParser): + """Parser for oprofile callgraph output. + + See also: + - http://oprofile.sourceforge.net/doc/opreport.html#opreport-callgraph + """ + + _fields_re = { + 'samples': r'(\d+)', + '%': r'(\S+)', + 'linenr info': r'(?P\(no location information\)|\S+:\d+)', + 'image name': r'(?P\S+(?:\s\(tgid:[^)]*\))?)', + 'app name': r'(?P\S+)', + 'symbol name': r'(?P\(no symbols\)|.+?)', + } + + def __init__(self, infile): + LineParser.__init__(self, infile) + self.entries = {} + self.entry_re = None + + def add_entry(self, callers, function, callees): + try: + entry = self.entries[function.id] + except KeyError: + self.entries[function.id] = (callers, function, callees) + else: + callers_total, function_total, callees_total = entry + self.update_subentries_dict(callers_total, callers) + function_total.samples += function.samples + self.update_subentries_dict(callees_total, callees) + + def update_subentries_dict(self, totals, partials): + for partial in compat_itervalues(partials): + try: + total = totals[partial.id] + except KeyError: + totals[partial.id] = partial + else: + total.samples += partial.samples + + def parse(self): + # read lookahead + self.readline() + + self.parse_header() + while self.lookahead(): + self.parse_entry() + + profile = Profile() + + reverse_call_samples = {} + + # populate the profile + profile[SAMPLES] = 0 + for _callers, _function, _callees in compat_itervalues(self.entries): + function = Function(_function.id, _function.name) + function[SAMPLES] = _function.samples + profile.add_function(function) + profile[SAMPLES] += _function.samples + + if _function.application: + function.process = os.path.basename(_function.application) + if _function.image: + function.module = os.path.basename(_function.image) + + total_callee_samples = 0 + for _callee in compat_itervalues(_callees): + total_callee_samples += _callee.samples + + for _callee in compat_itervalues(_callees): + if not _callee.self: + call = Call(_callee.id) + call[SAMPLES2] = _callee.samples + function.add_call(call) + + # compute derived data + profile.validate() + profile.find_cycles() + profile.ratio(TIME_RATIO, SAMPLES) + profile.call_ratios(SAMPLES2) + profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + + return profile + + def parse_header(self): + while not self.match_header(): + self.consume() + line = self.lookahead() + fields = re.split(r'\s\s+', line) + entry_re = r'^\s*' + r'\s+'.join([self._fields_re[field] for field in fields]) + r'(?P\s+\[self\])?$' + self.entry_re = re.compile(entry_re) + self.skip_separator() + + def parse_entry(self): + callers = self.parse_subentries() + if self.match_primary(): + function = self.parse_subentry() + if function is not None: + callees = self.parse_subentries() + self.add_entry(callers, function, callees) + self.skip_separator() + + def parse_subentries(self): + subentries = {} + while self.match_secondary(): + subentry = self.parse_subentry() + subentries[subentry.id] = subentry + return subentries + + def parse_subentry(self): + entry = Struct() + line = self.consume() + mo = self.entry_re.match(line) + if not mo: + raise ParseError('failed to parse', line) + fields = mo.groupdict() + entry.samples = int(mo.group(1)) + if 'source' in fields and fields['source'] != '(no location information)': + source = fields['source'] + filename, lineno = source.split(':') + entry.filename = filename + entry.lineno = int(lineno) + else: + source = '' + entry.filename = None + entry.lineno = None + entry.image = fields.get('image', '') + entry.application = fields.get('application', '') + if 'symbol' in fields and fields['symbol'] != '(no symbols)': + entry.symbol = fields['symbol'] + else: + entry.symbol = '' + if entry.symbol.startswith('"') and entry.symbol.endswith('"'): + entry.symbol = entry.symbol[1:-1] + entry.id = ':'.join((entry.application, entry.image, source, entry.symbol)) + entry.self = fields.get('self', None) != None + if entry.self: + entry.id += ':self' + if entry.symbol: + entry.name = entry.symbol + else: + entry.name = entry.image + return entry + + def skip_separator(self): + while not self.match_separator(): + self.consume() + self.consume() + + def match_header(self): + line = self.lookahead() + return line.startswith('samples') + + def match_separator(self): + line = self.lookahead() + return line == '-'*len(line) + + def match_primary(self): + line = self.lookahead() + return not line[:1].isspace() + + def match_secondary(self): + line = self.lookahead() + return line[:1].isspace() + + +class HProfParser(LineParser): + """Parser for java hprof output + + See also: + - http://java.sun.com/developer/technicalArticles/Programming/HPROF.html + """ + + trace_re = re.compile(r'\t(.*)\((.*):(.*)\)') + trace_id_re = re.compile(r'^TRACE (\d+):$') + + def __init__(self, infile): + LineParser.__init__(self, infile) + self.traces = {} + self.samples = {} + + def parse(self): + # read lookahead + self.readline() + + while not self.lookahead().startswith('------'): self.consume() + while not self.lookahead().startswith('TRACE '): self.consume() + + self.parse_traces() + + while not self.lookahead().startswith('CPU'): + self.consume() + + self.parse_samples() + + # populate the profile + profile = Profile() + profile[SAMPLES] = 0 + + functions = {} + + # build up callgraph + for id, trace in compat_iteritems(self.traces): + if not id in self.samples: continue + mtime = self.samples[id][0] + last = None + + for func, file, line in trace: + if not func in functions: + function = Function(func, func) + function[SAMPLES] = 0 + profile.add_function(function) + functions[func] = function + + function = functions[func] + # allocate time to the deepest method in the trace + if not last: + function[SAMPLES] += mtime + profile[SAMPLES] += mtime + else: + c = function.get_call(last) + c[SAMPLES2] += mtime + + last = func + + # compute derived data + profile.validate() + profile.find_cycles() + profile.ratio(TIME_RATIO, SAMPLES) + profile.call_ratios(SAMPLES2) + profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + + return profile + + def parse_traces(self): + while self.lookahead().startswith('TRACE '): + self.parse_trace() + + def parse_trace(self): + l = self.consume() + mo = self.trace_id_re.match(l) + tid = mo.group(1) + last = None + trace = [] + + while self.lookahead().startswith('\t'): + l = self.consume() + match = self.trace_re.search(l) + if not match: + #sys.stderr.write('Invalid line: %s\n' % l) + break + else: + function_name, file, line = match.groups() + trace += [(function_name, file, line)] + + self.traces[int(tid)] = trace + + def parse_samples(self): + self.consume() + self.consume() + + while not self.lookahead().startswith('CPU'): + rank, percent_self, percent_accum, count, traceid, method = self.lookahead().split() + self.samples[int(traceid)] = (int(count), method) + self.consume() + + +class SysprofParser(XmlParser): + + def __init__(self, stream): + XmlParser.__init__(self, stream) + + def parse(self): + objects = {} + nodes = {} + + self.element_start('profile') + while self.token.type == XML_ELEMENT_START: + if self.token.name_or_data == 'objects': + assert not objects + objects = self.parse_items('objects') + elif self.token.name_or_data == 'nodes': + assert not nodes + nodes = self.parse_items('nodes') + else: + self.parse_value(self.token.name_or_data) + self.element_end('profile') + + return self.build_profile(objects, nodes) + + def parse_items(self, name): + assert name[-1] == 's' + items = {} + self.element_start(name) + while self.token.type == XML_ELEMENT_START: + id, values = self.parse_item(name[:-1]) + assert id not in items + items[id] = values + self.element_end(name) + return items + + def parse_item(self, name): + attrs = self.element_start(name) + id = int(attrs['id']) + values = self.parse_values() + self.element_end(name) + return id, values + + def parse_values(self): + values = {} + while self.token.type == XML_ELEMENT_START: + name = self.token.name_or_data + value = self.parse_value(name) + assert name not in values + values[name] = value + return values + + def parse_value(self, tag): + self.element_start(tag) + value = self.character_data() + self.element_end(tag) + if value.isdigit(): + return int(value) + if value.startswith('"') and value.endswith('"'): + return value[1:-1] + return value + + def build_profile(self, objects, nodes): + profile = Profile() + + profile[SAMPLES] = 0 + for id, object in compat_iteritems(objects): + # Ignore fake objects (process names, modules, "Everything", "kernel", etc.) + if object['self'] == 0: + continue + + function = Function(id, object['name']) + function[SAMPLES] = object['self'] + profile.add_function(function) + profile[SAMPLES] += function[SAMPLES] + + for id, node in compat_iteritems(nodes): + # Ignore fake calls + if node['self'] == 0: + continue + + # Find a non-ignored parent + parent_id = node['parent'] + while parent_id != 0: + parent = nodes[parent_id] + caller_id = parent['object'] + if objects[caller_id]['self'] != 0: + break + parent_id = parent['parent'] + if parent_id == 0: + continue + + callee_id = node['object'] + + assert objects[caller_id]['self'] + assert objects[callee_id]['self'] + + function = profile.functions[caller_id] + + samples = node['self'] + try: + call = function.calls[callee_id] + except KeyError: + call = Call(callee_id) + call[SAMPLES2] = samples + function.add_call(call) + else: + call[SAMPLES2] += samples + + # Compute derived events + profile.validate() + profile.find_cycles() + profile.ratio(TIME_RATIO, SAMPLES) + profile.call_ratios(SAMPLES2) + profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + + return profile + + +class XPerfParser(Parser): + """Parser for CSVs generated by XPerf, from Microsoft Windows Performance Tools. + """ + + def __init__(self, stream): + Parser.__init__(self) + self.stream = stream + self.profile = Profile() + self.profile[SAMPLES] = 0 + self.column = {} + + def parse(self): + import csv + reader = csv.reader( + self.stream, + delimiter = ',', + quotechar = None, + escapechar = None, + doublequote = False, + skipinitialspace = True, + lineterminator = '\r\n', + quoting = csv.QUOTE_NONE) + header = True + for row in reader: + if header: + self.parse_header(row) + header = False + else: + self.parse_row(row) + + # compute derived data + self.profile.validate() + self.profile.find_cycles() + self.profile.ratio(TIME_RATIO, SAMPLES) + self.profile.call_ratios(SAMPLES2) + self.profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + + return self.profile + + def parse_header(self, row): + for column in range(len(row)): + name = row[column] + assert name not in self.column + self.column[name] = column + + def parse_row(self, row): + fields = {} + for name, column in compat_iteritems(self.column): + value = row[column] + for factory in int, float: + try: + value = factory(value) + except ValueError: + pass + else: + break + fields[name] = value + + process = fields['Process Name'] + symbol = fields['Module'] + '!' + fields['Function'] + weight = fields['Weight'] + count = fields['Count'] + + if process == 'Idle': + return + + function = self.get_function(process, symbol) + function[SAMPLES] += weight * count + self.profile[SAMPLES] += weight * count + + stack = fields['Stack'] + if stack != '?': + stack = stack.split('/') + assert stack[0] == '[Root]' + if stack[-1] != symbol: + # XXX: some cases the sampled function does not appear in the stack + stack.append(symbol) + caller = None + for symbol in stack[1:]: + callee = self.get_function(process, symbol) + if caller is not None: + try: + call = caller.calls[callee.id] + except KeyError: + call = Call(callee.id) + call[SAMPLES2] = count + caller.add_call(call) + else: + call[SAMPLES2] += count + caller = callee + + def get_function(self, process, symbol): + function_id = process + '!' + symbol + + try: + function = self.profile.functions[function_id] + except KeyError: + module, name = symbol.split('!', 1) + function = Function(function_id, name) + function.process = process + function.module = module + function[SAMPLES] = 0 + self.profile.add_function(function) + + return function + + +class SleepyParser(Parser): + """Parser for GNU gprof output. + + See also: + - http://www.codersnotes.com/sleepy/ + - http://sleepygraph.sourceforge.net/ + """ + + stdinInput = False + + def __init__(self, filename): + Parser.__init__(self) + + from zipfile import ZipFile + + self.database = ZipFile(filename) + + self.symbols = {} + self.calls = {} + + self.profile = Profile() + + _symbol_re = re.compile( + r'^(?P\w+)' + + r'\s+"(?P[^"]*)"' + + r'\s+"(?P[^"]*)"' + + r'\s+"(?P[^"]*)"' + + r'\s+(?P\d+)$' + ) + + def openEntry(self, name): + # Some versions of verysleepy use lowercase filenames + for database_name in self.database.namelist(): + if name.lower() == database_name.lower(): + name = database_name + break + + return self.database.open(name, 'r') + + def parse_symbols(self): + for line in self.openEntry('Symbols.txt'): + line = line.decode('UTF-8').rstrip('\r\n') + + mo = self._symbol_re.match(line) + if mo: + symbol_id, module, procname, sourcefile, sourceline = mo.groups() + + function_id = ':'.join([module, procname]) + + try: + function = self.profile.functions[function_id] + except KeyError: + function = Function(function_id, procname) + function.module = module + function[SAMPLES] = 0 + self.profile.add_function(function) + + self.symbols[symbol_id] = function + + def parse_callstacks(self): + for line in self.openEntry('Callstacks.txt'): + line = line.decode('UTF-8').rstrip('\r\n') + + fields = line.split() + samples = float(fields[0]) + callstack = fields[1:] + + callstack = [self.symbols[symbol_id] for symbol_id in callstack] + + callee = callstack[0] + + callee[SAMPLES] += samples + self.profile[SAMPLES] += samples + + for caller in callstack[1:]: + try: + call = caller.calls[callee.id] + except KeyError: + call = Call(callee.id) + call[SAMPLES2] = samples + caller.add_call(call) + else: + call[SAMPLES2] += samples + + callee = caller + + def parse(self): + profile = self.profile + profile[SAMPLES] = 0 + + self.parse_symbols() + self.parse_callstacks() + + # Compute derived events + profile.validate() + profile.find_cycles() + profile.ratio(TIME_RATIO, SAMPLES) + profile.call_ratios(SAMPLES2) + profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + + return profile + + +class PstatsParser: + """Parser python profiling statistics saved with te pstats module.""" + + stdinInput = False + multipleInput = True + + def __init__(self, *filename): + import pstats + try: + self.stats = pstats.Stats(*filename) + except ValueError: + if PYTHON_3: + sys.stderr.write('error: failed to load %s, maybe they are generated by different python version?\n' % ', '.join(filename)) + sys.exit(1) + import hotshot.stats + self.stats = hotshot.stats.load(filename[0]) + self.profile = Profile() + self.function_ids = {} + + def get_function_name(self, key): + filename, line, name = key + module = os.path.splitext(filename)[0] + module = os.path.basename(module) + return "%s:%d:%s" % (module, line, name) + + def get_function(self, key): + try: + id = self.function_ids[key] + except KeyError: + id = len(self.function_ids) + name = self.get_function_name(key) + function = Function(id, name) + function.filename = key[0] + self.profile.functions[id] = function + self.function_ids[key] = id + else: + function = self.profile.functions[id] + return function + + def parse(self): + self.profile[TIME] = 0.0 + self.profile[TOTAL_TIME] = self.stats.total_tt + for fn, (cc, nc, tt, ct, callers) in compat_iteritems(self.stats.stats): + callee = self.get_function(fn) + callee.called = nc + callee[TOTAL_TIME] = ct + callee[TIME] = tt + self.profile[TIME] += tt + self.profile[TOTAL_TIME] = max(self.profile[TOTAL_TIME], ct) + for fn, value in compat_iteritems(callers): + caller = self.get_function(fn) + call = Call(callee.id) + if isinstance(value, tuple): + for i in xrange(0, len(value), 4): + nc, cc, tt, ct = value[i:i+4] + if CALLS in call: + call[CALLS] += cc + else: + call[CALLS] = cc + + if TOTAL_TIME in call: + call[TOTAL_TIME] += ct + else: + call[TOTAL_TIME] = ct + + else: + call[CALLS] = value + call[TOTAL_TIME] = ratio(value, nc)*ct + + caller.add_call(call) + + if False: + self.stats.print_stats() + self.stats.print_callees() + + # Compute derived events + self.profile.validate() + self.profile.ratio(TIME_RATIO, TIME) + self.profile.ratio(TOTAL_TIME_RATIO, TOTAL_TIME) + + return self.profile + +class DtraceParser(LineParser): + """Parser for linux perf callgraph output. + + It expects output generated with + + # Refer to https://github.com/brendangregg/FlameGraph#dtrace + # 60 seconds of user-level stacks, including time spent in-kernel, for PID 12345 at 97 Hertz + sudo dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345/ { @[ustack()] = count(); } tick-60s { exit(0); }' -o out.user_stacks + + # The dtrace output + gprof2dot.py -f dtrace out.user_stacks + + # Notice: sometimes, the dtrace outputs format may be latin-1, and gprof2dot will fail to parse it. + # To solve this problem, you should use iconv to convert to UTF-8 explicitly. + # TODO: add an encoding flag to tell gprof2dot how to decode the profile file. + iconv -f ISO-8859-1 -t UTF-8 out.user_stacks | gprof2dot.py -f dtrace + """ + + def __init__(self, infile): + LineParser.__init__(self, infile) + self.profile = Profile() + + def readline(self): + # Override LineParser.readline to ignore comment lines + while True: + LineParser.readline(self) + if self.eof(): + break + + line = self.lookahead().strip() + if line.startswith('CPU'): + # The format likes: + # CPU ID FUNCTION:NAME + # 1 29684 :tick-60s + # Skip next line + LineParser.readline(self) + elif not line == '': + break + + + def parse(self): + # read lookahead + self.readline() + + profile = self.profile + profile[SAMPLES] = 0 + while not self.eof(): + self.parse_event() + + # compute derived data + profile.validate() + profile.find_cycles() + profile.ratio(TIME_RATIO, SAMPLES) + profile.call_ratios(SAMPLES2) + if totalMethod == "callratios": + # Heuristic approach. TOTAL_SAMPLES is unused. + profile.integrate(TOTAL_TIME_RATIO, TIME_RATIO) + elif totalMethod == "callstacks": + # Use the actual call chains for functions. + profile[TOTAL_SAMPLES] = profile[SAMPLES] + profile.ratio(TOTAL_TIME_RATIO, TOTAL_SAMPLES) + # Then propagate that total time to the calls. + for function in compat_itervalues(profile.functions): + for call in compat_itervalues(function.calls): + if call.ratio is not None: + callee = profile.functions[call.callee_id] + call[TOTAL_TIME_RATIO] = call.ratio * callee[TOTAL_TIME_RATIO] + else: + assert False + + return profile + + def parse_event(self): + if self.eof(): + return + + callchain, count = self.parse_callchain() + if not callchain: + return + + callee = callchain[0] + callee[SAMPLES] += count + self.profile[SAMPLES] += count + + for caller in callchain[1:]: + try: + call = caller.calls[callee.id] + except KeyError: + call = Call(callee.id) + call[SAMPLES2] = count + caller.add_call(call) + else: + call[SAMPLES2] += count + + callee = caller + + # Increment TOTAL_SAMPLES only once on each function. + stack = set(callchain) + for function in stack: + function[TOTAL_SAMPLES] += count + + + def parse_callchain(self): + callchain = [] + count = 0 + while self.lookahead(): + function, count = self.parse_call() + if function is None: + break + callchain.append(function) + return callchain, count + + call_re = re.compile(r'^\s+(?P.*)`(?P.*)') + addr2_re = re.compile(r'\+0x[0-9a-fA-F]+$') + + def parse_call(self): + line = self.consume() + mo = self.call_re.match(line) + if not mo: + # The line must be the stack count + return None, int(line.strip()) + + function_name = mo.group('symbol') + + # If present, amputate program counter from function name. + if function_name: + function_name = re.sub(self.addr2_re, '', function_name) + + # if not function_name or function_name == '[unknown]': + # function_name = mo.group('address') + + module = mo.group('module') + + function_id = function_name + ':' + module + + try: + function = self.profile.functions[function_id] + except KeyError: + function = Function(function_id, function_name) + function.module = os.path.basename(module) + function[SAMPLES] = 0 + function[TOTAL_SAMPLES] = 0 + self.profile.add_function(function) + + return function, None + +formats = { + "axe": AXEParser, + "callgrind": CallgrindParser, + "hprof": HProfParser, + "json": JsonParser, + "oprofile": OprofileParser, + "perf": PerfParser, + "prof": GprofParser, + "pstats": PstatsParser, + "sleepy": SleepyParser, + "sysprof": SysprofParser, + "xperf": XPerfParser, + "dtrace": DtraceParser, +} + + +######################################################################## +# Output + + +class Theme: + + def __init__(self, + bgcolor = (0.0, 0.0, 1.0), + mincolor = (0.0, 0.0, 0.0), + maxcolor = (0.0, 0.0, 1.0), + fontname = "Arial", + fontcolor = "white", + nodestyle = "filled", + minfontsize = 10.0, + maxfontsize = 10.0, + minpenwidth = 0.5, + maxpenwidth = 4.0, + gamma = 2.2, + skew = 1.0): + self.bgcolor = bgcolor + self.mincolor = mincolor + self.maxcolor = maxcolor + self.fontname = fontname + self.fontcolor = fontcolor + self.nodestyle = nodestyle + self.minfontsize = minfontsize + self.maxfontsize = maxfontsize + self.minpenwidth = minpenwidth + self.maxpenwidth = maxpenwidth + self.gamma = gamma + self.skew = skew + + def graph_bgcolor(self): + return self.hsl_to_rgb(*self.bgcolor) + + def graph_fontname(self): + return self.fontname + + def graph_fontcolor(self): + return self.fontcolor + + def graph_fontsize(self): + return self.minfontsize + + def node_bgcolor(self, weight): + return self.color(weight) + + def node_fgcolor(self, weight): + if self.nodestyle == "filled": + return self.graph_bgcolor() + else: + return self.color(weight) + + def node_fontsize(self, weight): + return self.fontsize(weight) + + def node_style(self): + return self.nodestyle + + def edge_color(self, weight): + return self.color(weight) + + def edge_fontsize(self, weight): + return self.fontsize(weight) + + def edge_penwidth(self, weight): + return max(weight*self.maxpenwidth, self.minpenwidth) + + def edge_arrowsize(self, weight): + return 0.5 * math.sqrt(self.edge_penwidth(weight)) + + def fontsize(self, weight): + return max(weight**2 * self.maxfontsize, self.minfontsize) + + def color(self, weight): + weight = min(max(weight, 0.0), 1.0) + + hmin, smin, lmin = self.mincolor + hmax, smax, lmax = self.maxcolor + + if self.skew < 0: + raise ValueError("Skew must be greater than 0") + elif self.skew == 1.0: + h = hmin + weight*(hmax - hmin) + s = smin + weight*(smax - smin) + l = lmin + weight*(lmax - lmin) + else: + base = self.skew + h = hmin + ((hmax-hmin)*(-1.0 + (base ** weight)) / (base - 1.0)) + s = smin + ((smax-smin)*(-1.0 + (base ** weight)) / (base - 1.0)) + l = lmin + ((lmax-lmin)*(-1.0 + (base ** weight)) / (base - 1.0)) + + return self.hsl_to_rgb(h, s, l) + + def hsl_to_rgb(self, h, s, l): + """Convert a color from HSL color-model to RGB. + + See also: + - http://www.w3.org/TR/css3-color/#hsl-color + """ + + h = h % 1.0 + s = min(max(s, 0.0), 1.0) + l = min(max(l, 0.0), 1.0) + + if l <= 0.5: + m2 = l*(s + 1.0) + else: + m2 = l + s - l*s + m1 = l*2.0 - m2 + r = self._hue_to_rgb(m1, m2, h + 1.0/3.0) + g = self._hue_to_rgb(m1, m2, h) + b = self._hue_to_rgb(m1, m2, h - 1.0/3.0) + + # Apply gamma correction + r **= self.gamma + g **= self.gamma + b **= self.gamma + + return (r, g, b) + + def _hue_to_rgb(self, m1, m2, h): + if h < 0.0: + h += 1.0 + elif h > 1.0: + h -= 1.0 + if h*6 < 1.0: + return m1 + (m2 - m1)*h*6.0 + elif h*2 < 1.0: + return m2 + elif h*3 < 2.0: + return m1 + (m2 - m1)*(2.0/3.0 - h)*6.0 + else: + return m1 + + +TEMPERATURE_COLORMAP = Theme( + mincolor = (2.0/3.0, 0.80, 0.25), # dark blue + maxcolor = (0.0, 1.0, 0.5), # satured red + gamma = 1.0 +) + +PINK_COLORMAP = Theme( + mincolor = (0.0, 1.0, 0.90), # pink + maxcolor = (0.0, 1.0, 0.5), # satured red +) + +GRAY_COLORMAP = Theme( + mincolor = (0.0, 0.0, 0.85), # light gray + maxcolor = (0.0, 0.0, 0.0), # black +) + +BW_COLORMAP = Theme( + minfontsize = 8.0, + maxfontsize = 24.0, + mincolor = (0.0, 0.0, 0.0), # black + maxcolor = (0.0, 0.0, 0.0), # black + minpenwidth = 0.1, + maxpenwidth = 8.0, +) + +PRINT_COLORMAP = Theme( + minfontsize = 18.0, + maxfontsize = 30.0, + fontcolor = "black", + nodestyle = "solid", + mincolor = (0.0, 0.0, 0.0), # black + maxcolor = (0.0, 0.0, 0.0), # black + minpenwidth = 0.1, + maxpenwidth = 8.0, +) + + +themes = { + "color": TEMPERATURE_COLORMAP, + "pink": PINK_COLORMAP, + "gray": GRAY_COLORMAP, + "bw": BW_COLORMAP, + "print": PRINT_COLORMAP, +} + + +def sorted_iteritems(d): + # Used mostly for result reproducibility (while testing.) + keys = compat_keys(d) + keys.sort() + for key in keys: + value = d[key] + yield key, value + + +class DotWriter: + """Writer for the DOT language. + + See also: + - "The DOT Language" specification + http://www.graphviz.org/doc/info/lang.html + """ + + strip = False + wrap = False + + def __init__(self, fp): + self.fp = fp + + def wrap_function_name(self, name): + """Split the function name on multiple lines.""" + + if len(name) > 32: + ratio = 2.0/3.0 + height = max(int(len(name)/(1.0 - ratio) + 0.5), 1) + width = max(len(name)/height, 32) + # TODO: break lines in symbols + name = textwrap.fill(name, width, break_long_words=False) + + # Take away spaces + name = name.replace(", ", ",") + name = name.replace("> >", ">>") + name = name.replace("> >", ">>") # catch consecutive + + return name + + show_function_events = [TOTAL_TIME_RATIO, TIME_RATIO] + show_edge_events = [TOTAL_TIME_RATIO, CALLS] + + def graph(self, profile, theme): + self.begin_graph() + + fontname = theme.graph_fontname() + fontcolor = theme.graph_fontcolor() + nodestyle = theme.node_style() + + self.attr('graph', fontname=fontname, ranksep=0.25, nodesep=0.125) + self.attr('node', fontname=fontname, shape="box", style=nodestyle, fontcolor=fontcolor, width=0, height=0) + self.attr('edge', fontname=fontname) + + for _, function in sorted_iteritems(profile.functions): + labels = [] + if function.process is not None: + labels.append(function.process) + if function.module is not None: + labels.append(function.module) + + if self.strip: + function_name = function.stripped_name() + else: + function_name = function.name + + # dot can't parse quoted strings longer than YY_BUF_SIZE, which + # defaults to 16K. But some annotated C++ functions (e.g., boost, + # https://github.com/jrfonseca/gprof2dot/issues/30) can exceed that + MAX_FUNCTION_NAME = 4096 + if len(function_name) >= MAX_FUNCTION_NAME: + sys.stderr.write('warning: truncating function name with %u chars (%s)\n' % (len(function_name), function_name[:32] + '...')) + function_name = function_name[:MAX_FUNCTION_NAME - 1] + unichr(0x2026) + + if self.wrap: + function_name = self.wrap_function_name(function_name) + labels.append(function_name) + + for event in self.show_function_events: + if event in function.events: + label = event.format(function[event]) + labels.append(label) + if function.called is not None: + labels.append("%u%s" % (function.called, MULTIPLICATION_SIGN)) + + if function.weight is not None: + weight = function.weight + else: + weight = 0.0 + + label = '\n'.join(labels) + self.node(function.id, + label = label, + color = self.color(theme.node_bgcolor(weight)), + fontcolor = self.color(theme.node_fgcolor(weight)), + fontsize = "%.2f" % theme.node_fontsize(weight), + tooltip = function.filename, + ) + + for _, call in sorted_iteritems(function.calls): + callee = profile.functions[call.callee_id] + + labels = [] + for event in self.show_edge_events: + if event in call.events: + label = event.format(call[event]) + labels.append(label) + + if call.weight is not None: + weight = call.weight + elif callee.weight is not None: + weight = callee.weight + else: + weight = 0.0 + + label = '\n'.join(labels) + + self.edge(function.id, call.callee_id, + label = label, + color = self.color(theme.edge_color(weight)), + fontcolor = self.color(theme.edge_color(weight)), + fontsize = "%.2f" % theme.edge_fontsize(weight), + penwidth = "%.2f" % theme.edge_penwidth(weight), + labeldistance = "%.2f" % theme.edge_penwidth(weight), + arrowsize = "%.2f" % theme.edge_arrowsize(weight), + ) + + self.end_graph() + + def begin_graph(self): + self.write('digraph {\n') + + def end_graph(self): + self.write('}\n') + + def attr(self, what, **attrs): + self.write("\t") + self.write(what) + self.attr_list(attrs) + self.write(";\n") + + def node(self, node, **attrs): + self.write("\t") + self.id(node) + self.attr_list(attrs) + self.write(";\n") + + def edge(self, src, dst, **attrs): + self.write("\t") + self.id(src) + self.write(" -> ") + self.id(dst) + self.attr_list(attrs) + self.write(";\n") + + def attr_list(self, attrs): + if not attrs: + return + self.write(' [') + first = True + for name, value in sorted_iteritems(attrs): + if value is None: + continue + if first: + first = False + else: + self.write(", ") + self.id(name) + self.write('=') + self.id(value) + self.write(']') + + def id(self, id): + if isinstance(id, (int, float)): + s = str(id) + elif isinstance(id, basestring): + if id.isalnum() and not id.startswith('0x'): + s = id + else: + s = self.escape(id) + else: + raise TypeError + self.write(s) + + def color(self, rgb): + r, g, b = rgb + + def float2int(f): + if f <= 0.0: + return 0 + if f >= 1.0: + return 255 + return int(255.0*f + 0.5) + + return "#" + "".join(["%02x" % float2int(c) for c in (r, g, b)]) + + def escape(self, s): + if not PYTHON_3: + s = s.encode('utf-8') + s = s.replace('\\', r'\\') + s = s.replace('\n', r'\n') + s = s.replace('\t', r'\t') + s = s.replace('"', r'\"') + return '"' + s + '"' + + def write(self, s): + self.fp.write(s) + + + +######################################################################## +# Main program + + +def naturalJoin(values): + if len(values) >= 2: + return ', '.join(values[:-1]) + ' or ' + values[-1] + + else: + return ''.join(values) + + +def main(argv=sys.argv[1:]): + """Main program.""" + + global totalMethod + + formatNames = list(formats.keys()) + formatNames.sort() + + themeNames = list(themes.keys()) + themeNames.sort() + + labelNames = list(labels.keys()) + labelNames.sort() + + optparser = optparse.OptionParser( + usage="\n\t%prog [options] [file] ...") + optparser.add_option( + '-o', '--output', metavar='FILE', + type="string", dest="output", + help="output filename [stdout]") + optparser.add_option( + '-n', '--node-thres', metavar='PERCENTAGE', + type="float", dest="node_thres", default=0.5, + help="eliminate nodes below this threshold [default: %default]") + optparser.add_option( + '-e', '--edge-thres', metavar='PERCENTAGE', + type="float", dest="edge_thres", default=0.1, + help="eliminate edges below this threshold [default: %default]") + optparser.add_option( + '-f', '--format', + type="choice", choices=formatNames, + dest="format", default="prof", + help="profile format: %s [default: %%default]" % naturalJoin(formatNames)) + optparser.add_option( + '--total', + type="choice", choices=('callratios', 'callstacks'), + dest="totalMethod", default=totalMethod, + help="preferred method of calculating total time: callratios or callstacks (currently affects only perf format) [default: %default]") + optparser.add_option( + '-c', '--colormap', + type="choice", choices=themeNames, + dest="theme", default="color", + help="color map: %s [default: %%default]" % naturalJoin(themeNames)) + optparser.add_option( + '-s', '--strip', + action="store_true", + dest="strip", default=False, + help="strip function parameters, template parameters, and const modifiers from demangled C++ function names") + optparser.add_option( + '--color-nodes-by-selftime', + action="store_true", + dest="color_nodes_by_selftime", default=False, + help="color nodes by self time, rather than by total time (sum of self and descendants)") + optparser.add_option( + '--colour-nodes-by-selftime', + action="store_true", + dest="color_nodes_by_selftime", + help=optparse.SUPPRESS_HELP) + optparser.add_option( + '-w', '--wrap', + action="store_true", + dest="wrap", default=False, + help="wrap function names") + optparser.add_option( + '--show-samples', + action="store_true", + dest="show_samples", default=False, + help="show function samples") + optparser.add_option( + '--node-label', metavar='MEASURE', + type='choice', choices=labelNames, + action='append', + dest='node_labels', + help="measurements to on show the node (can be specified multiple times): %s [default: %s]" % ( + naturalJoin(labelNames), ', '.join(defaultLabelNames))) + # add option to show information on available entries () + optparser.add_option( + '--list-functions', + type="string", + dest="list_functions", default=None, + help="""\ +list functions available for selection in -z or -l, requires selector argument +( use '+' to select all). +Recall that the selector argument is used with Unix/Bash globbing/pattern matching, +and that entries are formatted '::'. When argument starts +with '%', a dump of all available information is performed for selected entries, + after removal of leading '%'. +""") + # add option to create subtree or show paths + optparser.add_option( + '-z', '--root', + type="string", + dest="root", default="", + help="prune call graph to show only descendants of specified root function") + optparser.add_option( + '-l', '--leaf', + type="string", + dest="leaf", default="", + help="prune call graph to show only ancestors of specified leaf function") + optparser.add_option( + '--depth', + type="int", + dest="depth", default=-1, + help="prune call graph to show only descendants or ancestors until specified depth") + # add a new option to control skew of the colorization curve + optparser.add_option( + '--skew', + type="float", dest="theme_skew", default=1.0, + help="skew the colorization curve. Values < 1.0 give more variety to lower percentages. Values > 1.0 give less variety to lower percentages") + # add option for filtering by file path + optparser.add_option( + '-p', '--path', action="append", + type="string", dest="filter_paths", + help="Filter all modules not in a specified path") + (options, args) = optparser.parse_args(argv) + + if len(args) > 1 and options.format != 'pstats': + optparser.error('incorrect number of arguments') + + try: + theme = themes[options.theme] + except KeyError: + optparser.error('invalid colormap \'%s\'' % options.theme) + + # set skew on the theme now that it has been picked. + if options.theme_skew: + theme.skew = options.theme_skew + + totalMethod = options.totalMethod + + try: + Format = formats[options.format] + except KeyError: + optparser.error('invalid format \'%s\'' % options.format) + + if Format.stdinInput: + if not args: + fp = sys.stdin + elif PYTHON_3: + fp = open(args[0], 'rt', encoding='UTF-8') + else: + fp = open(args[0], 'rt') + parser = Format(fp) + elif Format.multipleInput: + if not args: + optparser.error('at least a file must be specified for %s input' % options.format) + parser = Format(*args) + else: + if len(args) != 1: + optparser.error('exactly one file must be specified for %s input' % options.format) + parser = Format(args[0]) + + profile = parser.parse() + + if options.output is None: + if PYTHON_3: + output = open(sys.stdout.fileno(), mode='wt', encoding='UTF-8', closefd=False) + else: + output = sys.stdout + else: + if PYTHON_3: + output = open(options.output, 'wt', encoding='UTF-8') + else: + output = open(options.output, 'wt') + + dot = DotWriter(output) + dot.strip = options.strip + dot.wrap = options.wrap + + labelNames = options.node_labels or defaultLabelNames + dot.show_function_events = [labels[l] for l in labelNames] + if options.show_samples: + dot.show_function_events.append(SAMPLES) + + profile = profile + profile.prune(options.node_thres/100.0, options.edge_thres/100.0, options.filter_paths, options.color_nodes_by_selftime) + + if options.list_functions: + profile.printFunctionIds(selector=options.list_functions) + sys.exit(0) + + if options.root: + rootIds = profile.getFunctionIds(options.root) + if not rootIds: + sys.stderr.write('root node ' + options.root + ' not found (might already be pruned : try -e0 -n0 flags)\n') + sys.exit(1) + profile.prune_root(rootIds, options.depth) + if options.leaf: + leafIds = profile.getFunctionIds(options.leaf) + if not leafIds: + sys.stderr.write('leaf node ' + options.leaf + ' not found (maybe already pruned : try -e0 -n0 flags)\n') + sys.exit(1) + profile.prune_leaf(leafIds, options.depth) + + dot.graph(profile, theme) + + +if __name__ == '__main__': + main() diff --git a/setup.py b/setup.py index 5afb8322..0b4cff6c 100755 --- a/setup.py +++ b/setup.py @@ -42,6 +42,8 @@ def ingress_extension(): else: questdb_client_lib_dir = questdb_rs_ffi_dir / 'target' / 'release' pystr_to_utf8_lib_dir = pystr_to_utf8_dir / 'target' / 'release' + extra_compile_args.append('-flto') + extra_link_args.append('-flto') if PLATFORM == 'darwin': lib_prefix = 'lib' diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index b689dd4c..d8f97df2 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -988,22 +988,7 @@ cdef class Buffer: """ # See https://cython.readthedocs.io/en/latest/src/userguide/ # numpy_tutorial.html#numpy-tutorial - import sys - sys.stderr.write('pandas :: (A) ' + - f'table_name: {table_name}, ' + - f'table_name_col: {table_name_col}, ' + - f'symbols: {symbols}, ' + - f'at: {at}, ' + - f'sort: {sort}' + - '\n') _pandas(self._impl, self._b, data, table_name, table_name_col, symbols, at, sort) - sys.stderr.write('pandas :: (B) ' + - f'table_name: {table_name}, ' + - f'table_name_col: {table_name_col}, ' + - f'symbols: {symbols}, ' + - f'at: {at}, ' + - f'sort: {sort}' + - '\n') _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 2f5932f5..11ec1498 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1,7 +1,5 @@ # See: pandas_integration.md for technical overview. -import sys # TODO, remove me. - cdef enum col_access_tag_t: numpy arrow @@ -75,7 +73,6 @@ cdef enum col_source_t: col_source_str_i8_cat = 403000 col_source_str_i16_cat = 404000 col_source_str_i32_cat = 405000 - col_source_str_i64_cat = 406000 col_source_dt64ns_numpy = 501000 col_source_dt64ns_tz_arrow = 502000 @@ -90,7 +87,6 @@ cdef dict _TARGET_TO_SOURCES = { col_source_t.col_source_str_i8_cat, col_source_t.col_source_str_i16_cat, col_source_t.col_source_str_i32_cat, - col_source_t.col_source_str_i64_cat, }, col_target_t.col_target_symbol: { col_source_t.col_source_str_pyobj, @@ -98,7 +94,6 @@ cdef dict _TARGET_TO_SOURCES = { col_source_t.col_source_str_i8_cat, col_source_t.col_source_str_i16_cat, col_source_t.col_source_str_i32_cat, - col_source_t.col_source_str_i64_cat, }, col_target_t.col_target_column_bool: { col_source_t.col_source_bool_pyobj, @@ -137,7 +132,6 @@ cdef dict _TARGET_TO_SOURCES = { col_source_t.col_source_str_i8_cat, col_source_t.col_source_str_i16_cat, col_source_t.col_source_str_i32_cat, - col_source_t.col_source_str_i64_cat, }, col_target_t.col_target_column_ts: { col_source_t.col_source_dt64ns_numpy, @@ -186,8 +180,6 @@ cdef enum col_dispatch_code_t: col_target_t.col_target_table + col_source_t.col_source_str_i16_cat col_dispatch_code_table__str_i32_cat = \ col_target_t.col_target_table + col_source_t.col_source_str_i32_cat - col_dispatch_code_table__str_i64_cat = \ - col_target_t.col_target_table + col_source_t.col_source_str_i64_cat col_dispatch_code_symbol__str_pyobj = \ col_target_t.col_target_symbol + col_source_t.col_source_str_pyobj @@ -199,8 +191,6 @@ cdef enum col_dispatch_code_t: col_target_t.col_target_symbol + col_source_t.col_source_str_i16_cat col_dispatch_code_symbol__str_i32_cat = \ col_target_t.col_target_symbol + col_source_t.col_source_str_i32_cat - col_dispatch_code_symbol__str_i64_cat = \ - col_target_t.col_target_symbol + col_source_t.col_source_str_i64_cat col_dispatch_code_column_bool__bool_pyobj = \ col_target_t.col_target_column_bool + col_source_t.col_source_bool_pyobj @@ -265,8 +255,6 @@ cdef enum col_dispatch_code_t: col_target_t.col_target_column_str + col_source_t.col_source_str_i16_cat col_dispatch_code_column_str__str_i32_cat = \ col_target_t.col_target_column_str + col_source_t.col_source_str_i32_cat - col_dispatch_code_column_str__str_i64_cat = \ - col_target_t.col_target_column_str + col_source_t.col_source_str_i64_cat col_dispatch_code_column_ts__dt64ns_numpy = \ col_target_t.col_target_column_ts + col_source_t.col_source_dt64ns_numpy @@ -443,7 +431,9 @@ cdef ssize_t _pandas_resolve_table_name( str_to_table_name(b, table_name, name_out) return -1 # Magic value for "no column index". except IngressError as ie: - raise ValueError(f'Bad argument `table_name`: {ie}') + raise IngressError( + IngressErrorCode.BadDataFrame, + f'Bad argument `table_name`: {ie}') else: raise TypeError('Bad argument `table_name`: Must be str.') elif table_name_col is not None: @@ -577,15 +567,17 @@ cdef void_int _pandas_resolve_symbols( if symbols == 'auto': for col_index in range(col_count): entry = tagged_cols[col_index] - if isinstance(entry.dtype, _PANDAS.CategoricalDtype): - entry.meta_target = meta_target_t.meta_target_symbol + if entry.meta_target == meta_target_t.meta_target_field: + if isinstance(entry.dtype, _PANDAS.CategoricalDtype): + entry.meta_target = meta_target_t.meta_target_symbol elif symbols is False: pass elif symbols is True: for col_index in range(col_count): if _pandas_column_is_str(data, col_index): entry = tagged_cols[col_index] - entry.meta_target = meta_target_t.meta_target_symbol + if entry.meta_target == meta_target_t.meta_target_field: + entry.meta_target = meta_target_t.meta_target_symbol else: if not isinstance(symbols, (tuple, list)): raise TypeError( @@ -706,30 +698,21 @@ cdef void_int _pandas_series_as_pybuf( cdef ArrowArray* mapped cdef int get_buf_ret cdef Py_buffer* view - sys.stderr.write(f'_pandas_series_as_pybuf :: (A) entry.name: {entry.name}\n') - sys.stderr.write('_pandas_series_as_pybuf :: (C)\n') if not PyObject_CheckBuffer(nparr): - sys.stderr.write('_pandas_series_as_pybuf :: (D)\n') raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + f'{entry.series!r} ({_fqn(type(entry.series))})') - sys.stderr.write('_pandas_series_as_pybuf :: (E)\n') col_out.tag = col_access_tag_t.numpy - sys.stderr.write('_pandas_series_as_pybuf :: (F)\n') try: - sys.stderr.write(f'_pandas_series_as_pybuf :: (G) {col_out.pybuf.buf}, nparr: {nparr!r}\n') # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. view = &col_out.pybuf get_buf_ret = PyObject_GetBuffer(nparr, view, PyBUF_SIMPLE) - sys.stderr.write(f'_pandas_series_as_pybuf :: (H1) {col_out.pybuf.buf}, ret: {get_buf_ret}, ndim: {col_out.pybuf.ndim}, itemsize: {col_out.pybuf.itemsize}, len: {col_out.pybuf.len}, count: {col_out.pybuf.len // col_out.pybuf.itemsize}\n') except BufferError as be: - sys.stderr.write('_pandas_series_as_pybuf :: (I)\n') raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + f'{entry.series!r} ({_fqn(type(entry.series))})') from be - sys.stderr.write('_pandas_series_as_pybuf :: (J)\n') _pandas_alloc_chunks(1, col_out) mapped = &col_out.chunks.chunks[0] @@ -786,7 +769,7 @@ cdef void_int _pandas_series_as_arrow( cdef const char* _ARROW_FMT_INT8 = "c" cdef const char* _ARROW_FMT_INT16 = "s" cdef const char* _ARROW_FMT_INT32 = "i" -cdef const char* _ARROW_FMT_INT64 = "l" +cdef const char* _ARROW_FMT_SML_STR = "u" cdef void_int _pandas_category_series_as_arrow( @@ -803,12 +786,18 @@ cdef void_int _pandas_category_series_as_arrow( col_out.source = col_source_t.col_source_str_i16_cat elif strncmp(format, _ARROW_FMT_INT32, 1) == 0: col_out.source = col_source_t.col_source_str_i32_cat - elif strncmp(format, _ARROW_FMT_INT64, 1) == 0: - col_out.source = col_source_t.col_source_str_i64_cat else: - raise TypeError( + raise IngressError( + IngressErrorCode.BadDataFrame, f'Bad column {entry.name!r}: Expected an arrow category index ' + - f'format, got {(format).decode("utf-8")!r}') + f'format, got {(format).decode("utf-8")!r}.') + + format = col_out.arrow_schema.dictionary.format + if strncmp(format, _ARROW_FMT_SML_STR, 1) != 0: + raise IngressError( + IngressErrorCode.BadDataFrame, + f'Bad column {entry.name!r}: Expected a category of strings, ' + + f'got a category of {entry.series.dtype.categories.dtype!r}.') cdef inline bint _pandas_is_float_nan(PyObject* obj): @@ -833,10 +822,8 @@ cdef void_int _pandas_series_sniff_pyobj( cdef size_t n_elements = len(entry.series) cdef PyObject** obj_arr cdef PyObject* obj - sys.stderr.write(f'_pandas_series_sniff_pyobj :: (A) buf: {col_out.pybuf.buf}, n_elements: {n_elements}, series:\n{entry.series}\n') _pandas_series_as_pybuf(entry, col_out) obj_arr = (col_out.pybuf.buf) - sys.stderr.write('_pandas_series_sniff_pyobj :: (B)\n') for el_index in range(n_elements): obj = obj_arr[el_index] if not _pandas_is_null_pyobj(obj): @@ -849,24 +836,23 @@ cdef void_int _pandas_series_sniff_pyobj( elif PyUnicode_CheckExact(obj): col_out.source = col_source_t.col_source_str_pyobj elif PyBytes_CheckExact(obj): - raise ValueError( + raise IngressError( + IngressErrorCode.BadDataFrame, f'Bad column {entry.name!r}: ' + 'Unsupported object column containing bytes.' + 'If this is a string column, decode it first. ' + 'See: https://stackoverflow.com/questions/40389764/') else: - raise TypeError( + raise IngressError( + IngressErrorCode.BadDataFrame, f'Bad column {entry.name!r}: ' + f'Unsupported object column containing an {_fqn(type(obj))}') - sys.stderr.write('_pandas_series_sniff_pyobj :: (D)\n') return 0 - sys.stderr.write('_pandas_series_sniff_pyobj :: (E)\n') - # TODO: Test all-null columns (this will probably break the API). + # TODO: Test all-nulls column. # We haven't returned yet, so we've hit an object column that # exclusively has null values. We will just skip this column. col_out.source = col_source_t.col_source_nulls - sys.stderr.write('_pandas_series_sniff_pyobj :: (F)\n') cdef void_int _pandas_resolve_source_and_buffers( @@ -960,7 +946,8 @@ cdef void_int _pandas_resolve_source_and_buffers( col_out.source = col_source_t.col_source_str_pyobj _pandas_series_as_pybuf(entry, col_out) else: - raise ValueError( + raise IngressError( + IngressErrorCode.BadDataFrame, f'Unknown string dtype storage: f{dtype.storage} ' + f'for column {entry.name} of dtype {dtype}.') elif isinstance(dtype, _PANDAS.CategoricalDtype): @@ -978,11 +965,10 @@ cdef void_int _pandas_resolve_source_and_buffers( col_source_t.col_source_dt64ns_numpy, 'datetime64[ns]') elif isinstance(dtype, _NUMPY_OBJECT): - sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (A)\n') _pandas_series_sniff_pyobj(entry, col_out) - sys.stderr.write(f'_pandas_resolve_source_and_buffers :: (B)\n') else: - raise ValueError( + raise IngressError( + IngressErrorCode.BadDataFrame, f'Unsupported dtype {dtype} for column {entry.name}. ' + 'Raise an issue if you think it should be supported: ' + 'https://github.com/questdb/py-questdb-client/issues.') @@ -1000,9 +986,10 @@ cdef void_int _pandas_resolve_target( if col_out.source in target_sources: col_out.target = target return 0 - raise ValueError( + raise IngressError( + IngressErrorCode.BadDataFrame, f'Could not map column source type (code {col_out.source} for ' + - f'{entry.dtype!r}) {entry.name}.') + f'column {entry.name} ({entry.dtype!r}) to any ILP type.') cdef void _pandas_init_cursor(col_t* col_out): @@ -1020,29 +1007,19 @@ cdef void_int _pandas_resolve_col( # Since we don't need to send the column names for 'table' and 'at' columns, # we don't need to validate and encode them as column names. - sys.stderr.write(f'_pandas_resolve_col :: (A) name: {entry.name}, dtype: {entry.dtype}\n') if ((entry.meta_target != meta_target_t.meta_target_table) and (entry.meta_target != meta_target_t.meta_target_at)): - sys.stderr.write('_pandas_resolve_col :: (B)\n') str_to_column_name(b, entry.name, &col_out.name) - sys.stderr.write('_pandas_resolve_col :: (C)\n') - sys.stderr.write('_pandas_resolve_col :: (D)\n') _pandas_resolve_source_and_buffers(entry, col_out) - sys.stderr.write('_pandas_resolve_col :: (E)\n') _pandas_resolve_target(entry, col_out) - sys.stderr.write('_pandas_resolve_col :: (F)\n') if col_out.source not in _TARGET_TO_SOURCES[col_out.target]: - sys.stderr.write('_pandas_resolve_col :: (G)\n') raise ValueError( f'Bad value: Column {entry.name!r} ({entry.dtype}) is not ' + f'supported as a {_TARGET_NAMES[col_out.target]} column.') - sys.stderr.write('_pandas_resolve_col :: (H)\n') col_out.dispatch_code = ( col_out.source + col_out.target) - sys.stderr.write('_pandas_resolve_col :: (I)\n') _pandas_init_cursor(col_out) - sys.stderr.write('_pandas_resolve_col :: (J)\n') cdef void_int _pandas_resolve_cols( @@ -1067,7 +1044,6 @@ cdef void_int _pandas_resolve_args( cdef ssize_t name_col cdef ssize_t at_col - sys.stderr.write('_pandas_resolve_args :: (A)\n') # List of Lists with col index, col name, series object, sorting key. cdef list tagged_cols = [ TaggedEntry( @@ -1077,7 +1053,6 @@ cdef void_int _pandas_resolve_args( series, meta_target_t.meta_target_field) # Later resolved to a target. for index, (name, series) in enumerate(data.items())] - sys.stderr.write('_pandas_resolve_args :: (A)\n') name_col = _pandas_resolve_table_name( b, data, @@ -1086,19 +1061,14 @@ cdef void_int _pandas_resolve_args( table_name_col, col_count, c_table_name_out) - sys.stderr.write('_pandas_resolve_args :: (B)\n') at_col = _pandas_resolve_at(data, tagged_cols, at, col_count, at_value_out) - sys.stderr.write('_pandas_resolve_args :: (C)\n') _pandas_resolve_symbols( data, tagged_cols, name_col, at_col, symbols, col_count) - sys.stderr.write('_pandas_resolve_args :: (D)\n') # Sort with table name is first, then the symbols, then fields, then at. # Note: Python 3.6+ guarantees stable sort. tagged_cols.sort(key=lambda x: (x).meta_target) - sys.stderr.write('_pandas_resolve_args :: (E)\n') _pandas_resolve_cols(b, tagged_cols, cols_out) - sys.stderr.write('_pandas_resolve_args :: (F)\n') cdef inline bint _pandas_arrow_get_bool(col_cursor_t* cursor): @@ -1115,6 +1085,57 @@ cdef inline bint _pandas_arrow_is_valid(col_cursor_t* cursor): (1 << (cursor.offset % 8)))) +cdef inline void _pandas_arrow_get_cat_value( + col_cursor_t* cursor, + size_t key, + size_t* len_out, + const char** buf_out): + cdef int32_t* value_index_access + cdef int32_t value_begin + cdef uint8_t* value_char_access + value_index_access = cursor.chunk.dictionary.buffers[1] + value_begin = value_index_access[key] + len_out[0] = value_index_access[key + 1] - value_begin + value_char_access = cursor.chunk.dictionary.buffers[2] + buf_out[0] = &value_char_access[value_begin] + + +cdef inline bint _pandas_arrow_get_cat_i8( + col_cursor_t* cursor, size_t* len_out, const char** buf_out): + cdef bint valid = _pandas_arrow_is_valid(cursor) + cdef int8_t* key_access + cdef int8_t key + if valid: + key_access = cursor.chunk.buffers[1] + key = key_access[cursor.offset] + _pandas_arrow_get_cat_value(cursor, key, len_out, buf_out) + return valid + + +cdef inline bint _pandas_arrow_get_cat_i16( + col_cursor_t* cursor, size_t* len_out, const char** buf_out): + cdef bint valid = _pandas_arrow_is_valid(cursor) + cdef int16_t* key_access + cdef int16_t key + if valid: + key_access = cursor.chunk.buffers[1] + key = key_access[cursor.offset] + _pandas_arrow_get_cat_value(cursor, key, len_out, buf_out) + return valid + + +cdef inline bint _pandas_arrow_get_cat_i32( + col_cursor_t* cursor, size_t* len_out, const char** buf_out): + cdef bint valid = _pandas_arrow_is_valid(cursor) + cdef int32_t* key_access + cdef int32_t key + if valid: + key_access = cursor.chunk.buffers[1] + key = key_access[cursor.offset] + _pandas_arrow_get_cat_value(cursor, key, len_out, buf_out) + return valid + + cdef inline bint _pandas_arrow_str( col_cursor_t* cursor, size_t* len_out, @@ -1175,11 +1196,11 @@ cdef void_int _pandas_serialize_cell_table__str_arrow( qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL - cdef size_t len + cdef size_t c_len cdef const char* buf cdef line_sender_table_name c_table_name - if _pandas_arrow_str(&col.cursor, &len, &buf): - if not line_sender_table_name_init(&c_table_name, len, buf, &err): + if _pandas_arrow_str(&col.cursor, &c_len, &buf): + if not line_sender_table_name_init(&c_table_name, c_len, buf, &err): raise c_err_to_py(err) if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) @@ -1191,28 +1212,51 @@ cdef void_int _pandas_serialize_cell_table__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef size_t c_len + cdef const char* c_buf + cdef line_sender_table_name c_table_name + if _pandas_arrow_get_cat_i8(&col.cursor, &c_len, &c_buf): + if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): + raise c_err_to_py(err) + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + else: + raise ValueError('Table name cannot be null') cdef void_int _pandas_serialize_cell_table__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef size_t c_len + cdef const char* c_buf + cdef line_sender_table_name c_table_name + if _pandas_arrow_get_cat_i16(&col.cursor, &c_len, &c_buf): + if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): + raise c_err_to_py(err) + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + else: + raise ValueError('Table name cannot be null') cdef void_int _pandas_serialize_cell_table__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') - - -cdef void_int _pandas_serialize_cell_table__str_i64_cat( - line_sender_buffer* impl, - qdb_pystr_buf* b, - col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef size_t c_len + cdef const char* c_buf + cdef line_sender_table_name c_table_name + if _pandas_arrow_get_cat_i32(&col.cursor, &c_len, &c_buf): + if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): + raise c_err_to_py(err) + if not line_sender_buffer_table(impl, c_table_name, &err): + raise c_err_to_py(err) + else: + raise ValueError('Table name cannot be null') cdef void_int _pandas_serialize_cell_symbol__str_pyobj( @@ -1242,28 +1286,33 @@ cdef void_int _pandas_serialize_cell_symbol__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') - - -cdef void_int _pandas_serialize_cell_symbol__str_i64_cat( - line_sender_buffer* impl, - qdb_pystr_buf* b, - col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( @@ -1665,28 +1714,33 @@ cdef void_int _pandas_serialize_cell_column_str__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, col_t* col) except -1: - raise ValueError('nyi') - - -cdef void_int _pandas_serialize_cell_column_str__str_i64_cat( - line_sender_buffer* impl, - qdb_pystr_buf* b, - col_t* col) except -1: - raise ValueError('nyi') + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): + if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( @@ -1775,8 +1829,6 @@ cdef void_int _pandas_serialize_cell( _pandas_serialize_cell_table__str_i16_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i32_cat: _pandas_serialize_cell_table__str_i32_cat(impl, b, col) - elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i64_cat: - _pandas_serialize_cell_table__str_i64_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_pyobj: _pandas_serialize_cell_symbol__str_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_arrow: @@ -1787,8 +1839,6 @@ cdef void_int _pandas_serialize_cell( _pandas_serialize_cell_symbol__str_i16_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i32_cat: _pandas_serialize_cell_symbol__str_i32_cat(impl, b, col) - elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i64_cat: - _pandas_serialize_cell_symbol__str_i64_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_pyobj: _pandas_serialize_cell_column_bool__bool_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_numpy: @@ -1849,8 +1899,6 @@ cdef void_int _pandas_serialize_cell( _pandas_serialize_cell_column_str__str_i16_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i32_cat: _pandas_serialize_cell_column_str__str_i32_cat(impl, b, col) - elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i64_cat: - _pandas_serialize_cell_column_str__str_i64_cat(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_numpy: _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_arrow: @@ -1913,15 +1961,10 @@ cdef void_int _pandas( _pandas_may_import_deps() try: - sys.stderr.write(' :: :: (A)\n') qdb_pystr_buf_clear(b) - sys.stderr.write(' :: :: (B)\n') _check_is_pandas_dataframe(data) - sys.stderr.write(' :: :: (C)\n') col_count = len(data.columns) - sys.stderr.write(' :: :: (D)\n') cols = col_t_arr_new(col_count) - sys.stderr.write(' :: :: (E)\n') _pandas_resolve_args( data, table_name, @@ -1933,16 +1976,13 @@ cdef void_int _pandas( &c_table_name, &at_value, &cols) - sys.stderr.write(' :: :: (F)\n') # We've used the str buffer up to a point for the headers. # Instead of clearing it (which would clear the headers' memory) # we will truncate (rewind) back to this position. str_buf_marker = qdb_pystr_buf_tell(b) - sys.stderr.write(' :: :: (G)\n') row_count = len(data) - sys.stderr.write(' :: :: (H)\n') line_sender_buffer_clear_marker(impl) # On error, undo all added lines. @@ -1950,30 +1990,22 @@ cdef void_int _pandas( raise c_err_to_py(err) try: - sys.stderr.write(' :: :: (I)\n') for row_index in range(row_count): # TODO: Occasional GIL release logic. This should be twice as # often as `sys.getswitchinterval()`. # TODO: Potentially avoid the GIL altogether if we can get away with it. # This is column-type dependent. Some basic analysis is required. # We need a `GilController` object so that we can raise exceptions. - sys.stderr.write(' :: :: (J)\n') qdb_pystr_buf_truncate(b, str_buf_marker) - sys.stderr.write(' :: :: (K)\n') - sys.stderr.write(' :: :: (M)\n') # Fixed table-name. if c_table_name.buf != NULL: if not line_sender_buffer_table(impl, c_table_name, &err): raise c_err_to_py(err) - sys.stderr.write(' :: :: (N)\n') # Serialize columns cells. # Note: Columns are sorted: table name, symbols, fields, at. for col_index in range(col_count): - sys.stderr.write(' :: :: (O)\n') col = &cols.d[col_index] - # TODO: Wrap error exceptions messaging with column name - # and row index. Ideally, extract value in python too. try: _pandas_serialize_cell(impl, b, col) except Exception as e: @@ -1984,35 +2016,20 @@ cdef void_int _pandas( f' at row index {row_index} (' + repr(data.iloc[row_index, col.orig_index]) + f'): {e} [dc={col.dispatch_code}]') from e - sys.stderr.write(' :: :: (P)\n') _pandas_col_advance(col) - sys.stderr.write(' :: :: (Q)\n') - sys.stderr.write(' :: :: (R)\n') # Fixed "at" value (not from a column). if at_value == 0: - sys.stderr.write(' :: :: (S)\n') if not line_sender_buffer_at_now(impl, &err): raise c_err_to_py(err) - sys.stderr.write(' :: :: (T)\n') elif at_value > 0: - sys.stderr.write(' :: :: (U)\n') if not line_sender_buffer_at(impl, at_value, &err): raise c_err_to_py(err) - sys.stderr.write(' :: :: (V)\n') except: - sys.stderr.write(' :: :: (W)\n') if not line_sender_buffer_rewind_to_marker(impl, &err): raise c_err_to_py(err) - sys.stderr.write(' :: :: (X)\n') raise - sys.stderr.write(' :: :: (Y)\n') finally: - sys.stderr.write(' :: :: (Z)\n') line_sender_buffer_clear_marker(impl) - sys.stderr.write(' :: :: (a)\n') col_t_arr_release(&cols) - sys.stderr.write(' :: :: (b)\n') qdb_pystr_buf_clear(b) - sys.stderr.write(' :: :: (c)\n') - sys.stderr.write(' :: :: (d)\n') diff --git a/test/test.py b/test/test.py index 74f19bdf..c59ce572 100755 --- a/test/test.py +++ b/test/test.py @@ -9,6 +9,7 @@ import numpy as np import pandas as pd import zoneinfo +import itertools import patch_path from mock_server import Server @@ -474,7 +475,8 @@ def test_bad_table_name_type(self): _pandas(DF1, table_name=1.5) def test_invalid_table_name(self): - with self.assertRaisesRegex(ValueError, '`table_name`: Bad string "."'): + with self.assertRaisesRegex( + qi.IngressError, '`table_name`: Bad string "."'): _pandas(DF1, table_name='.') def test_invalid_column_dtype(self): @@ -1201,7 +1203,7 @@ def _test_pyobjstr_table(self, dtype): table_name_col='/') with self.assertRaisesRegex( - qi.IngressError, "'tab..1'.*invalid dot `\.` at position 4"): + qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): _pandas( pd.DataFrame({ '/': pd.Series(['tab..1'], dtype=dtype), @@ -1352,7 +1354,7 @@ def test_str_arrow_table(self): table_name_col='/') with self.assertRaisesRegex( - qi.IngressError, "'tab..1'.*invalid dot `\.` at position 4"): + qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): _pandas( pd.DataFrame({ '/': pd.Series(['tab..1'], dtype='string[pyarrow]')}), @@ -1428,7 +1430,7 @@ def test_pyobj_int_col(self): 'tbl1 a=7i,b=7i\n') with self.assertRaisesRegex( - qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\."): + qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\\."): _pandas( pd.DataFrame({ 'a': pd.Series([1, 'STRING'], dtype='object'), @@ -1451,13 +1453,163 @@ def test_pyobj_float_col(self): 'tbl1 a=7.0,b=7i\n') with self.assertRaisesRegex( - qi.IngressError, "1 \\('STRING'\\): .*type float, got.*str\."): + qi.IngressError, "1 \\('STRING'\\): .*type float, got.*str\\."): _pandas( pd.DataFrame({ 'a': pd.Series([1.0, 'STRING'], dtype='object'), 'b': [1, 2]}), table_name='tbl1') + def test_bad_category(self): + # We only support string categories + # (unless anyone asks for additional ones). + # We want to test others are rejected. + with self.assertRaisesRegex( + qi.IngressError, "Bad column 'a'.*got a category of .*int64"): + _pandas( + pd.DataFrame({'a': pd.Series([1, 2, 3, 2], dtype='category')}), + table_name='tbl1') + + def _test_cat_table(self, count): + slist = [f's{i}' for i in range(count)] + + df = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + buf = _pandas(df, table_name_col=0) + exp = ''.join( + f'{s} b={i}i\n' + for i, s in enumerate(slist)) + self.assertEqual(buf, exp) + + slist[2] = None + df2 = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + with self.assertRaisesRegex( + qi.IngressError, 'Table name cannot be null'): + _pandas(df2, table_name_col=0) + + def test_cat_i8_table(self): + self._test_cat_table(30) + self._test_cat_table(127) + + def test_cat_i8_symbol(self): + df = pd.DataFrame({ + 'a': pd.Series(['a', 'b', 'c', 'a', None, 'c'], dtype='category'), + 'b': [1, 2, 3, 4, 5, 6]}) + + # Note that since `symbols='auto'`` is the default, categories are + # automatically sent as symbols. + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1,a=a b=1i\n' + + 'tbl1,a=b b=2i\n' + + 'tbl1,a=c b=3i\n' + + 'tbl1,a=a b=4i\n' + + 'tbl1 b=5i\n' + + 'tbl1,a=c b=6i\n') + + def test_cat_i8_str(self): + df = pd.DataFrame({ + 'a': pd.Series(['a', 'b', 'c', 'a', None, 'c'], dtype='category'), + 'b': [1, 2, 3, 4, 5, 6]}) + + buf = _pandas(df, table_name='tbl1', symbols=False) + self.assertEqual( + buf, + 'tbl1 a="a",b=1i\n' + + 'tbl1 a="b",b=2i\n' + + 'tbl1 a="c",b=3i\n' + + 'tbl1 a="a",b=4i\n' + + 'tbl1 b=5i\n' + + 'tbl1 a="c",b=6i\n') + + def test_cat_i16_table(self): + self._test_cat_table(128) + self._test_cat_table(4000) + self._test_cat_table(32767) + + def test_cat_i32_table(self): + self._test_cat_table(32768) + self._test_cat_table(100000) + + # TODO: Test cat 16 and 32 symbols and strings. + +if False: + class TestBencharkPandas(unittest.TestCase): + def test_pystr_i64_10m(self): + # This is a benchmark, not a test. + # It is useful to run it manually to check performance. + slist = [f's{i:09}' for i in range(10_000_000)] + df = pd.DataFrame({ + 'a': slist, + 'b': list(range(len(slist)))}) + + # Warm up + _pandas(df, table_name='tbl1', symbols=True) + + # Run + t0 = time.monotonic() + _pandas(df, table_name='tbl1', symbols=True) + t1 = time.monotonic() + print('Time:', t1 - t0) + + def test_mixed_10m(self): + # This is a benchmark, not a test. + # It is useful to run it manually to check performance. + count = 10_000_000 + slist = [f's{i:09}' for i in range(count)] + df = pd.DataFrame({ + 'col1': pd.Series(slist, dtype='string[pyarrow]'), + 'col2': list(range(len(slist))), + 'col2': [float(i / 2) for i in range(len(slist))], + 'col3': [float(i / 2) + 1.0 for i in range(len(slist))], + 'col4': pd.Categorical( + ['a', 'b', 'c', 'a', None, 'c', 'a', float('nan')] * + (count // 8))}) + + # Warm up + _pandas(df, table_name='tbl1', symbols=True) + + # Run + t0 = time.monotonic() + buf = _pandas(df, table_name='tbl1', symbols=True) + t1 = time.monotonic() + print(f'Time: {t1 - t0}, size: {len(buf)}') + + def test_string_escaping_10m(self): + count = 10_000_000 + slist = [f's={i:09}==abc \\' for i in range(count)] + series = pd.Series(slist, dtype='string[pyarrow]') + df = pd.DataFrame({ + 'col1': series, + 'col2': series, + 'col3': series, + 'col4': series, + 'col5': series, + 'col6': series}) + + # Warm up + _pandas(df, table_name='tbl1', symbols=True) + + # Run + t0 = time.monotonic() + buf = _pandas(df, table_name='tbl1', symbols=True) + t1 = time.monotonic() + print(f'Time: {t1 - t0}, size: {len(buf)}') + + +# TODO: Test all datatypes, but no rows. +# TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. +# TODO: Test all datatypes, but multiple row chunks. + if __name__ == '__main__': - unittest.main() + if os.environ['TEST_QUESTDB_PROFILE'] == '1': + import cProfile + cProfile.run('unittest.main()', sort='cumtime') + else: + unittest.main() From 0158fadca5cc0a86bfbe560f963a205d9d7f1e7a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 30 Nov 2022 15:20:19 +0000 Subject: [PATCH 081/147] Tests for categories. --- test/test.py | 105 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/test/test.py b/test/test.py index c59ce572..91291132 100755 --- a/test/test.py +++ b/test/test.py @@ -1495,38 +1495,6 @@ def test_cat_i8_table(self): self._test_cat_table(30) self._test_cat_table(127) - def test_cat_i8_symbol(self): - df = pd.DataFrame({ - 'a': pd.Series(['a', 'b', 'c', 'a', None, 'c'], dtype='category'), - 'b': [1, 2, 3, 4, 5, 6]}) - - # Note that since `symbols='auto'`` is the default, categories are - # automatically sent as symbols. - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1,a=a b=1i\n' + - 'tbl1,a=b b=2i\n' + - 'tbl1,a=c b=3i\n' + - 'tbl1,a=a b=4i\n' + - 'tbl1 b=5i\n' + - 'tbl1,a=c b=6i\n') - - def test_cat_i8_str(self): - df = pd.DataFrame({ - 'a': pd.Series(['a', 'b', 'c', 'a', None, 'c'], dtype='category'), - 'b': [1, 2, 3, 4, 5, 6]}) - - buf = _pandas(df, table_name='tbl1', symbols=False) - self.assertEqual( - buf, - 'tbl1 a="a",b=1i\n' + - 'tbl1 a="b",b=2i\n' + - 'tbl1 a="c",b=3i\n' + - 'tbl1 a="a",b=4i\n' + - 'tbl1 b=5i\n' + - 'tbl1 a="c",b=6i\n') - def test_cat_i16_table(self): self._test_cat_table(128) self._test_cat_table(4000) @@ -1534,9 +1502,78 @@ def test_cat_i16_table(self): def test_cat_i32_table(self): self._test_cat_table(32768) - self._test_cat_table(100000) + self._test_cat_table(40000) + + def _test_cat_symbol(self, count): + slist = [f's{i}' for i in range(count)] + + df = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + buf = _pandas(df, table_name='tbl1', symbols=True) + exp = ''.join( + f'tbl1,a={s} b={i}i\n' + for i, s in enumerate(slist)) + self.assertEqual(buf, exp) + + slist[2] = None + df2 = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + exp2 = exp.replace('tbl1,a=s2 b=2i\n', 'tbl1 b=2i\n') + buf2 = _pandas(df2, table_name='tbl1', symbols=True) + self.assertEqual(buf2, exp2) + + def test_cat_i8_symbol(self): + self._test_cat_symbol(30) + self._test_cat_symbol(127) + + def test_cat_i16_symbol(self): + self._test_cat_symbol(128) + self._test_cat_symbol(4000) + self._test_cat_symbol(32767) + + def test_cat_i32_symbol(self): + self._test_cat_symbol(32768) + self._test_cat_symbol(40000) + + def _test_cat_str(self, count): + slist = [f's{i}' for i in range(count)] + + df = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + buf = _pandas(df, table_name='tbl1', symbols=False) + exp = ''.join( + f'tbl1 a="{s}",b={i}i\n' + for i, s in enumerate(slist)) + self.assertEqual(buf, exp) + + slist[2] = None + df2 = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + exp2 = exp.replace('tbl1 a="s2",b=2i\n', 'tbl1 b=2i\n') + buf2 = _pandas(df2, table_name='tbl1', symbols=False) + self.assertEqual(buf2, exp2) + + def test_cat_i8_str(self): + self._test_cat_str(30) + self._test_cat_str(127) + + def test_cat_i16_str(self): + self._test_cat_str(128) + self._test_cat_str(4000) + self._test_cat_str(32767) + + def test_cat_i32_str(self): + self._test_cat_str(32768) + self._test_cat_str(40000) - # TODO: Test cat 16 and 32 symbols and strings. if False: class TestBencharkPandas(unittest.TestCase): From fd01ef3bf31721cb915239e1befc02c233594ede Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 30 Nov 2022 17:22:10 +0000 Subject: [PATCH 082/147] Releasing and reacquiring GIL to avoid starving other threads. --- pystr-to-utf8/src/lib.rs | 2 +- src/questdb/extra_cpython.pxd | 7 ++++++ src/questdb/pandas_integration.md | 8 +++--- src/questdb/pandas_integration.pxi | 39 +++++++++++++++++++++++++----- test/test.py | 8 +++--- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index 9a19cabf..0926a797 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -92,7 +92,7 @@ const MIN_BUF_LEN: usize = 1024; /// This is necessary to return "stable" addresses and avoid segfaults. /// Rust is unaware we are borrowing its memory and could try to free it as /// part of a reallocation if we were to use a `String` directly. -fn get_dest<'a>(chain: &'a mut Vec, len: usize) -> &'a mut String { +fn get_dest(chain: &mut Vec, len: usize) -> &mut String { if !chain.is_empty() { let last = chain.last_mut().unwrap(); if last.capacity() - last.len() >= len { diff --git a/src/questdb/extra_cpython.pxd b/src/questdb/extra_cpython.pxd index af4ba18c..3e794566 100644 --- a/src/questdb/extra_cpython.pxd +++ b/src/questdb/extra_cpython.pxd @@ -61,3 +61,10 @@ cdef extern from "Python.h": long long PyLong_AsLongLong(PyObject* o) except? -1 PyObject* PyErr_Occurred() + + ctypedef struct PyThreadState: + pass + + PyThreadState* PyEval_SaveThread() + + void PyEval_RestoreThread(PyThreadState* tstate) diff --git a/src/questdb/pandas_integration.md b/src/questdb/pandas_integration.md index f4f16c4c..70928f93 100644 --- a/src/questdb/pandas_integration.md +++ b/src/questdb/pandas_integration.md @@ -43,7 +43,7 @@ one-dimensional arrays that support our basic ILP supported types _only_. We can also further simplify iteration via the introduction of a cursor: a struct that is a mishmash of the simplified subsets of arrow and py buffers -that we we actually care about. +that we actually care about. ## Cherry-picking `Py_buffer` and `ArrowArray` features @@ -268,7 +268,7 @@ Name: c, dtype: float64 #### Arrow floats Pandas also has arrow-compatible floats. -These have an additiona bitvector to represent nulls. +These have an additional bitvector to represent nulls. @@ -416,7 +416,7 @@ string[python] ``` Note that by default the storage is still Python objects (sigh), -so our Rust-based conversion will will come handy here as well. +so our Rust-based conversion will come handy here as well. Note however that we need to handle nulls not as `None` objects, but as `pandas.NA` objects. @@ -453,7 +453,7 @@ string[pyarrow] [, , , ] ``` -Note that these strings will always have indicies based on `int32_t`. +Note that these strings will always have indices based on `int32_t`. Arrow also has a `pyarrow.large_string()` type, but pandas doesn't support it. diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 11ec1498..a39c53b5 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -42,11 +42,12 @@ cdef dict _TARGET_NAMES = { cdef enum col_source_t: + # Note: Hundreds digit set to 1 if GIL is required. col_source_nulls = 0 - col_source_bool_pyobj = 101000 + col_source_bool_pyobj = 101100 col_source_bool_numpy = 102000 col_source_bool_arrow = 103000 - col_source_int_pyobj = 201000 + col_source_int_pyobj = 201100 col_source_u8_numpy = 202000 col_source_i8_numpy = 203000 col_source_u16_numpy = 204000 @@ -63,12 +64,12 @@ cdef enum col_source_t: col_source_i32_arrow = 215000 col_source_u64_arrow = 216000 col_source_i64_arrow = 217000 - col_source_float_pyobj = 301000 + col_source_float_pyobj = 301100 col_source_f32_numpy = 302000 col_source_f64_numpy = 303000 col_source_f32_arrow = 304000 col_source_f64_arrow = 305000 - col_source_str_pyobj = 401000 + col_source_str_pyobj = 401100 col_source_str_arrow = 402000 col_source_str_i8_cat = 403000 col_source_str_i16_cat = 404000 @@ -77,6 +78,11 @@ cdef enum col_source_t: col_source_dt64ns_tz_arrow = 502000 +# cdef bint col_source_needs_gil(col_source_t source): +# # Check if hundreds digit is 1. +# return source // 100 % 10 == 1 + + cdef dict _TARGET_TO_SOURCES = { col_target_t.col_target_skip: { col_source_t.col_source_nulls, @@ -1939,6 +1945,16 @@ cdef void _pandas_col_advance(col_t* col): ((not new_chunk) * cursor.offset)) +# Every how many cells to release and re-acquire the Python GIL. +# +# We've done some perf testing with some mixed column dtypes. +# On a modern CPU we're doing over 8 million pandas cells per second. +# By default, `sys.getswitchinterval()` is 0.005 seconds. +# To accomodate this, we'd need to release the GIL every 40,000 cells. +# This will be divided by the column count to get the row gil blip count. +cdef size_t _CELL_GIL_BLIP_COUNT = 40000 + + cdef void_int _pandas( line_sender_buffer* impl, qdb_pystr_buf* b, @@ -1958,6 +1974,8 @@ cdef void_int _pandas( cdef size_t row_index cdef size_t col_index cdef col_t* col + cdef size_t row_gil_blip_count + cdef PyThreadState* gil_state _pandas_may_import_deps() try: @@ -1989,10 +2007,19 @@ cdef void_int _pandas( if not line_sender_buffer_set_marker(impl, &err): raise c_err_to_py(err) + row_gil_blip_count = _CELL_GIL_BLIP_COUNT // col_count + try: for row_index in range(row_count): - # TODO: Occasional GIL release logic. This should be twice as - # often as `sys.getswitchinterval()`. + if row_index % row_gil_blip_count == 0: + # Release and re-acquire the GIL every so often. + # This is to allow other python threads to run. + # If we hold the GIL for too long, we can starve other + # threads and potentially time out ongoing network activity. + gil_state = PyEval_SaveThread() + PyEval_RestoreThread(gil_state) + gil_state = NULL + # TODO: Potentially avoid the GIL altogether if we can get away with it. # This is column-type dependent. Some basic analysis is required. # We need a `GilController` object so that we can raise exceptions. diff --git a/test/test.py b/test/test.py index 91291132..2ccfe8f5 100755 --- a/test/test.py +++ b/test/test.py @@ -1602,9 +1602,9 @@ def test_mixed_10m(self): df = pd.DataFrame({ 'col1': pd.Series(slist, dtype='string[pyarrow]'), 'col2': list(range(len(slist))), - 'col2': [float(i / 2) for i in range(len(slist))], - 'col3': [float(i / 2) + 1.0 for i in range(len(slist))], - 'col4': pd.Categorical( + 'col3': [float(i / 2) for i in range(len(slist))], + 'col4': [float(i / 2) + 1.0 for i in range(len(slist))], + 'col5': pd.Categorical( ['a', 'b', 'c', 'a', None, 'c', 'a', float('nan')] * (count // 8))}) @@ -1645,7 +1645,7 @@ def test_string_escaping_10m(self): if __name__ == '__main__': - if os.environ['TEST_QUESTDB_PROFILE'] == '1': + if os.environ.get('TEST_QUESTDB_PROFILE') == '1': import cProfile cProfile.run('unittest.main()', sort='cumtime') else: From dfdd30274b0c10e1e92628cfb573f2cb9339023a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 30 Nov 2022 22:10:23 +0000 Subject: [PATCH 083/147] Fully releasing GIL whenever possible. This was fiddly to get working. --- src/questdb/ingress.pyx | 110 ++++++--- src/questdb/pandas_integration.pxi | 351 +++++++++++++++++++---------- test/test.py | 2 + 3 files changed, 322 insertions(+), 141 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index d8f97df2..6d1ba093 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -160,36 +160,13 @@ cdef str _fqn(type obj): return f'{obj.__module__}.{obj.__qualname__}' -cdef void_int str_to_utf8( +cdef inline void_int _encode_utf8( qdb_pystr_buf* b, PyObject* string, line_sender_utf8* utf8_out) except -1: - """ - Convert a Python string to a UTF-8 borrowed buffer. - This is done without allocating new Python `bytes` objects. - In case the string is an ASCII string, it's also generally zero-copy. - The `utf8_out` param will point to (borrow from) either the ASCII buffer - inside the original Python object or a part of memory allocated inside the - `b` buffer. - """ - cdef size_t count - cdef int kind cdef uint32_t bad_codepoint = 0 - if not PyUnicode_CheckExact(string): - raise TypeError( - f'Expected a str object, not a {_fqn(type(string))}') - PyUnicode_READY(string) - count = (PyUnicode_GET_LENGTH(string)) - - # We optimize the common case of ASCII strings. - # This avoid memory allocations and copies altogether. - # We get away with this because ASCII is a subset of UTF-8. - if PyUnicode_IS_COMPACT_ASCII(string): - utf8_out.len = count - utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) - return 0 - - kind = PyUnicode_KIND(string) + cdef size_t count = (PyUnicode_GET_LENGTH(string)) + cdef int kind = PyUnicode_KIND(string) if kind == PyUnicode_1BYTE_KIND: # No error handling for UCS1: All code points translate into valid UTF8. qdb_ucs1_to_utf8( @@ -225,6 +202,57 @@ cdef void_int str_to_utf8( raise ValueError(f'Unknown UCS kind: {kind}.') +cdef void_int str_to_utf8( + qdb_pystr_buf* b, + PyObject* string, + line_sender_utf8* utf8_out) except -1: + """ + Convert a Python string to a UTF-8 borrowed buffer. + This is done without allocating new Python `bytes` objects. + In case the string is an ASCII string, it's also generally zero-copy. + The `utf8_out` param will point to (borrow from) either the ASCII buffer + inside the original Python object or a part of memory allocated inside the + `b` buffer. + + If you need to use `utf8_out` without the GIL, call `qdb_pystr_buf_copy`. + """ + if not PyUnicode_CheckExact(string): + raise TypeError( + 'Expected a str object, not an object of type ' + + _fqn(type(string))) + PyUnicode_READY(string) + + # We optimize the common case of ASCII strings. + # This avoid memory allocations and copies altogether. + # We get away with this because ASCII is a subset of UTF-8. + if PyUnicode_IS_COMPACT_ASCII(string): + utf8_out.len = (PyUnicode_GET_LENGTH(string)) + utf8_out.buf = (PyUnicode_1BYTE_DATA(string)) + return 0 + + _encode_utf8(b, string, utf8_out) + + + +cdef void_int str_to_utf8_copy( + qdb_pystr_buf* b, + PyObject* string, + line_sender_utf8* utf8_out) except -1: + """ + Variant of `str_to_utf8` that always copies the string to a new buffer. + + The resulting `utf8_out` can be used when not holding the GIL: + The pointed-to memory is owned by `b`. + """ + if not PyUnicode_CheckExact(string): + raise TypeError( + 'Expected a str object, not an object of type ' + + _fqn(type(string))) + + PyUnicode_READY(string) + _encode_utf8(b, string, utf8_out) + + cdef void_int str_to_table_name( qdb_pystr_buf* b, PyObject* string, @@ -240,6 +268,21 @@ cdef void_int str_to_table_name( raise c_err_to_py(err) +cdef void_int str_to_table_name_copy( + qdb_pystr_buf* b, + PyObject* string, + line_sender_table_name* name_out) except -1: + """ + Python string to copied C table name. + Also see `str_to_utf8_copy`. + """ + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + str_to_utf8_copy(b, string, &utf8) + if not line_sender_table_name_init(name_out, utf8.len, utf8.buf, &err): + raise c_err_to_py(err) + + cdef void_int str_to_column_name( qdb_pystr_buf* b, str string, @@ -255,6 +298,21 @@ cdef void_int str_to_column_name( raise c_err_to_py(err) +cdef void_int str_to_column_name_copy( + qdb_pystr_buf* b, + str string, + line_sender_column_name* name_out) except -1: + """ + Python string to copied C column name. + Also see `str_to_utf8_copy`. + """ + cdef line_sender_error* err = NULL + cdef line_sender_utf8 utf8 + str_to_utf8_copy(b, string, &utf8) + if not line_sender_column_name_init(name_out, utf8.len, utf8.buf, &err): + raise c_err_to_py(err) + + cdef int64_t datetime_to_micros(datetime dt): """ Convert a `datetime.datetime` to microseconds since the epoch. diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index a39c53b5..745f3b8e 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -78,9 +78,9 @@ cdef enum col_source_t: col_source_dt64ns_tz_arrow = 502000 -# cdef bint col_source_needs_gil(col_source_t source): -# # Check if hundreds digit is 1. -# return source // 100 % 10 == 1 +cdef bint col_source_needs_gil(col_source_t source): + # Check if hundreds digit is 1. + return source // 100 % 10 == 1 cdef dict _TARGET_TO_SOURCES = { @@ -434,7 +434,7 @@ cdef ssize_t _pandas_resolve_table_name( 'Can specify only one of `table_name` or `table_name_col`.') if isinstance(table_name, str): try: - str_to_table_name(b, table_name, name_out) + str_to_table_name_copy(b, table_name, name_out) return -1 # Magic value for "no column index". except IngressError as ie: raise IngressError( @@ -1015,7 +1015,7 @@ cdef void_int _pandas_resolve_col( # we don't need to validate and encode them as column names. if ((entry.meta_target != meta_target_t.meta_target_table) and (entry.meta_target != meta_target_t.meta_target_at)): - str_to_column_name(b, entry.name, &col_out.name) + str_to_column_name_copy(b, entry.name, &col_out.name) _pandas_resolve_source_and_buffers(entry, col_out) _pandas_resolve_target(entry, col_out) @@ -1029,11 +1029,19 @@ cdef void_int _pandas_resolve_col( cdef void_int _pandas_resolve_cols( - qdb_pystr_buf*b, list tagged_cols, col_t_arr* cols_out) except -1: + qdb_pystr_buf*b, + list tagged_cols, + col_t_arr* cols_out, + bint* any_cols_need_gil_out) except -1: cdef size_t index cdef size_t len_tagged_cols = len(tagged_cols) + cdef col_t* col + any_cols_need_gil_out[0] = False for index in range(len_tagged_cols): - _pandas_resolve_col(b, index, tagged_cols[index], &cols_out.d[index]) + col = &cols_out.d[index] + _pandas_resolve_col(b, index, tagged_cols[index], col) + if col_source_needs_gil(col.source): + any_cols_need_gil_out[0] = True cdef void_int _pandas_resolve_args( @@ -1046,7 +1054,8 @@ cdef void_int _pandas_resolve_args( size_t col_count, line_sender_table_name* c_table_name_out, int64_t* at_value_out, - col_t_arr* cols_out) except -1: + col_t_arr* cols_out, + bint* any_cols_need_gil_out) except -1: cdef ssize_t name_col cdef ssize_t at_col @@ -1074,7 +1083,13 @@ cdef void_int _pandas_resolve_args( # Sort with table name is first, then the symbols, then fields, then at. # Note: Python 3.6+ guarantees stable sort. tagged_cols.sort(key=lambda x: (x).meta_target) - _pandas_resolve_cols(b, tagged_cols, cols_out) + _pandas_resolve_cols(b, tagged_cols, cols_out, any_cols_need_gil_out) + + +cdef void _ensure_has_gil(PyThreadState** gs): + if gs[0] != NULL: + PyEval_RestoreThread(gs[0]) + gs[0] = NULL cdef inline bint _pandas_arrow_get_bool(col_cursor_t* cursor): @@ -1200,68 +1215,84 @@ cdef void_int _pandas_serialize_cell_table__str_pyobj( cdef void_int _pandas_serialize_cell_table__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef size_t c_len cdef const char* buf cdef line_sender_table_name c_table_name if _pandas_arrow_str(&col.cursor, &c_len, &buf): if not line_sender_table_name_init(&c_table_name, c_len, buf, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) if not line_sender_buffer_table(impl, c_table_name, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) else: + _ensure_has_gil(gs) raise ValueError('Table name cannot be null') cdef void_int _pandas_serialize_cell_table__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef size_t c_len cdef const char* c_buf cdef line_sender_table_name c_table_name if _pandas_arrow_get_cat_i8(&col.cursor, &c_len, &c_buf): if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) if not line_sender_buffer_table(impl, c_table_name, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) else: + _ensure_has_gil(gs) raise ValueError('Table name cannot be null') cdef void_int _pandas_serialize_cell_table__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef size_t c_len cdef const char* c_buf cdef line_sender_table_name c_table_name if _pandas_arrow_get_cat_i16(&col.cursor, &c_len, &c_buf): if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) if not line_sender_buffer_table(impl, c_table_name, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) else: + _ensure_has_gil(gs) raise ValueError('Table name cannot be null') cdef void_int _pandas_serialize_cell_table__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef size_t c_len cdef const char* c_buf cdef line_sender_table_name c_table_name if _pandas_arrow_get_cat_i32(&col.cursor, &c_len, &c_buf): if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) if not line_sender_buffer_table(impl, c_table_name, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) else: + _ensure_has_gil(gs) raise ValueError('Table name cannot be null') @@ -1280,44 +1311,52 @@ cdef void_int _pandas_serialize_cell_symbol__str_pyobj( cdef void_int _pandas_serialize_cell_symbol__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1343,26 +1382,31 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint8_t* access = col.cursor.chunk.buffers[1] cdef uint8_t cell = access[col.cursor.offset] if not line_sender_buffer_column_bool(impl, col.name, not not cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef bint value if valid: value = _pandas_arrow_get_bool(&col.cursor) if not line_sender_buffer_column_bool(impl, col.name, value, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) else: + _ensure_has_gil(gs) raise ValueError('Cannot insert null values into a boolean column.') @@ -1389,97 +1433,115 @@ cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( cdef void_int _pandas_serialize_cell_column_i64__u8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint8_t* access = col.cursor.chunk.buffers[1] cdef uint8_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i8_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int8_t* access = col.cursor.chunk.buffers[1] cdef int8_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint16_t* access = col.cursor.chunk.buffers[1] cdef uint16_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i16_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int16_t* access = col.cursor.chunk.buffers[1] cdef int16_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint32_t* access = col.cursor.chunk.buffers[1] cdef uint32_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int32_t* access = col.cursor.chunk.buffers[1] cdef int32_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint64_t* access = col.cursor.chunk.buffers[1] cdef uint64_t cell = access[col.cursor.offset] if cell > INT64_MAX: + _ensure_has_gil(gs) raise OverflowError('uint64 value too large for int64 column type.') if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef uint8_t* access @@ -1490,13 +1552,15 @@ cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef int8_t* access @@ -1507,13 +1571,15 @@ cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef uint16_t* access @@ -1524,13 +1590,15 @@ cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef int16_t* access @@ -1541,13 +1609,15 @@ cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef uint32_t* access @@ -1558,13 +1628,15 @@ cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef int32_t* access @@ -1575,13 +1647,15 @@ cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef uint64_t* access @@ -1590,19 +1664,22 @@ cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( access = col.cursor.chunk.buffers[1] cell = access[col.cursor.offset] if cell > INT64_MAX: + _ensure_has_gil(gs) raise OverflowError('uint64 value too large for int64 column type.') if not line_sender_buffer_column_i64( impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef int64_t* access @@ -1613,6 +1690,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1639,30 +1717,35 @@ cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL # Note: This is the C `float` type, not the Python `float` type. cdef float* access = col.cursor.chunk.buffers[1] cdef float cell = access[col.cursor.offset] if not line_sender_buffer_column_f64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__f64_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef double* access = col.cursor.chunk.buffers[1] cdef double cell = access[col.cursor.offset] if not line_sender_buffer_column_f64(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef float* access @@ -1673,13 +1756,15 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef double* access @@ -1690,6 +1775,7 @@ cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( col.name, access[col.cursor.offset], &err): + _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1708,63 +1794,74 @@ cdef void_int _pandas_serialize_cell_column_str__str_pyobj( cdef void_int _pandas_serialize_cell_column_str__str_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i8_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i16_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i32_cat( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] cell //= 1000 # Convert from nanoseconds to microseconds. if not line_sender_buffer_column_ts(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef int64_t cell @@ -1774,29 +1871,34 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( cell = access[col.cursor.offset] cell //= 1000 # Convert from nanoseconds to microseconds. if not line_sender_buffer_column_ts(impl, col.name, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] if cell == 0: if not line_sender_buffer_at_now(impl, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) else: # Note: impl will validate against negative numbers. if not line_sender_buffer_at(impl, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef bint valid = _pandas_arrow_is_valid(&col.cursor) cdef int64_t* access @@ -1809,17 +1911,20 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( if cell == 0: if not line_sender_buffer_at_now(impl, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) else: # Note: impl will validate against negative numbers. if not line_sender_buffer_at(impl, cell, &err): + _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell( line_sender_buffer* impl, qdb_pystr_buf* b, - col_t* col) except -1: + col_t* col, + PyThreadState** gs) except -1: cdef col_dispatch_code_t dc = col.dispatch_code # Note!: Code below will generate a `switch` statement. # Ensure this happens! Don't break the `dc == ...` pattern. @@ -1828,92 +1933,93 @@ cdef void_int _pandas_serialize_cell( elif dc == col_dispatch_code_t.col_dispatch_code_table__str_pyobj: _pandas_serialize_cell_table__str_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_arrow: - _pandas_serialize_cell_table__str_arrow(impl, b, col) + _pandas_serialize_cell_table__str_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i8_cat: - _pandas_serialize_cell_table__str_i8_cat(impl, b, col) + _pandas_serialize_cell_table__str_i8_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i16_cat: - _pandas_serialize_cell_table__str_i16_cat(impl, b, col) + _pandas_serialize_cell_table__str_i16_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i32_cat: - _pandas_serialize_cell_table__str_i32_cat(impl, b, col) + _pandas_serialize_cell_table__str_i32_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_pyobj: _pandas_serialize_cell_symbol__str_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_arrow: - _pandas_serialize_cell_symbol__str_arrow(impl, b, col) + _pandas_serialize_cell_symbol__str_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i8_cat: - _pandas_serialize_cell_symbol__str_i8_cat(impl, b, col) + _pandas_serialize_cell_symbol__str_i8_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i16_cat: - _pandas_serialize_cell_symbol__str_i16_cat(impl, b, col) + _pandas_serialize_cell_symbol__str_i16_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i32_cat: - _pandas_serialize_cell_symbol__str_i32_cat(impl, b, col) + _pandas_serialize_cell_symbol__str_i32_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_pyobj: _pandas_serialize_cell_column_bool__bool_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_numpy: - _pandas_serialize_cell_column_bool__bool_numpy(impl, b, col) + _pandas_serialize_cell_column_bool__bool_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_arrow: - _pandas_serialize_cell_column_bool__bool_arrow(impl, b, col) + _pandas_serialize_cell_column_bool__bool_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__int_pyobj: _pandas_serialize_cell_column_i64__int_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_numpy: - _pandas_serialize_cell_column_i64__u8_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__u8_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_numpy: - _pandas_serialize_cell_column_i64__i8_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__i8_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_numpy: - _pandas_serialize_cell_column_i64__u16_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__u16_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_numpy: - _pandas_serialize_cell_column_i64__i16_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__i16_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_numpy: - _pandas_serialize_cell_column_i64__u32_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__u32_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_numpy: - _pandas_serialize_cell_column_i64__i32_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__i32_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_numpy: - _pandas_serialize_cell_column_i64__u64_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__u64_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_numpy: - _pandas_serialize_cell_column_i64__i64_numpy(impl, b, col) + _pandas_serialize_cell_column_i64__i64_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_arrow: - _pandas_serialize_cell_column_i64__u8_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__u8_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_arrow: - _pandas_serialize_cell_column_i64__i8_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__i8_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_arrow: - _pandas_serialize_cell_column_i64__u16_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__u16_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_arrow: - _pandas_serialize_cell_column_i64__i16_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__i16_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_arrow: - _pandas_serialize_cell_column_i64__u32_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__u32_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_arrow: - _pandas_serialize_cell_column_i64__i32_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__i32_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_arrow: - _pandas_serialize_cell_column_i64__u64_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__u64_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_arrow: - _pandas_serialize_cell_column_i64__i64_arrow(impl, b, col) + _pandas_serialize_cell_column_i64__i64_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__float_pyobj: _pandas_serialize_cell_column_f64__float_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_numpy: - _pandas_serialize_cell_column_f64__f32_numpy(impl, b, col) + _pandas_serialize_cell_column_f64__f32_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_numpy: - _pandas_serialize_cell_column_f64__f64_numpy(impl, b, col) + _pandas_serialize_cell_column_f64__f64_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_arrow: - _pandas_serialize_cell_column_f64__f32_arrow(impl, b, col) + _pandas_serialize_cell_column_f64__f32_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_arrow: - _pandas_serialize_cell_column_f64__f64_arrow(impl, b, col) + _pandas_serialize_cell_column_f64__f64_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_pyobj: _pandas_serialize_cell_column_str__str_pyobj(impl, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_arrow: - _pandas_serialize_cell_column_str__str_arrow(impl, b, col) + _pandas_serialize_cell_column_str__str_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i8_cat: - _pandas_serialize_cell_column_str__str_i8_cat(impl, b, col) + _pandas_serialize_cell_column_str__str_i8_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i16_cat: - _pandas_serialize_cell_column_str__str_i16_cat(impl, b, col) + _pandas_serialize_cell_column_str__str_i16_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i32_cat: - _pandas_serialize_cell_column_str__str_i32_cat(impl, b, col) + _pandas_serialize_cell_column_str__str_i32_cat(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_numpy: - _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col) + _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_arrow: - _pandas_serialize_cell_column_ts__dt64ns_tz_arrow(impl, b, col) + _pandas_serialize_cell_column_ts__dt64ns_tz_arrow(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_numpy: - _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col) + _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_tz_arrow: - _pandas_serialize_cell_at_dt64ns_tz_arrow(impl, b, col) + _pandas_serialize_cell_at_dt64ns_tz_arrow(impl, b, col, gs) else: + _ensure_has_gil(gs) raise RuntimeError(f"Unknown column dispatch code: {dc}") # See earlier note about switch statement generation. # Don't add complex conditions above! @@ -1951,8 +2057,8 @@ cdef void _pandas_col_advance(col_t* col): # On a modern CPU we're doing over 8 million pandas cells per second. # By default, `sys.getswitchinterval()` is 0.005 seconds. # To accomodate this, we'd need to release the GIL every 40,000 cells. -# This will be divided by the column count to get the row gil blip count. -cdef size_t _CELL_GIL_BLIP_COUNT = 40000 +# This will be divided by the column count to get the row gil blip interval. +cdef size_t _CELL_GIL_BLIP_INTERVAL = 40000 cdef void_int _pandas( @@ -1968,14 +2074,16 @@ cdef void_int _pandas( cdef line_sender_table_name c_table_name cdef int64_t at_value = _AT_SET_BY_COLUMN cdef col_t_arr cols = col_t_arr_blank() + cdef bint any_cols_need_gil = False cdef qdb_pystr_pos str_buf_marker cdef size_t row_count cdef line_sender_error* err = NULL cdef size_t row_index cdef size_t col_index cdef col_t* col - cdef size_t row_gil_blip_count - cdef PyThreadState* gil_state + cdef size_t row_gil_blip_interval + cdef PyThreadState* gs = NULL # GIL state. NULL means we have the GIL. + cdef bint was_serializing_cell = False _pandas_may_import_deps() try: @@ -1993,7 +2101,8 @@ cdef void_int _pandas( col_count, &c_table_name, &at_value, - &cols) + &cols, + &any_cols_need_gil) # We've used the str buffer up to a point for the headers. # Instead of clearing it (which would clear the headers' memory) @@ -2007,56 +2116,68 @@ cdef void_int _pandas( if not line_sender_buffer_set_marker(impl, &err): raise c_err_to_py(err) - row_gil_blip_count = _CELL_GIL_BLIP_COUNT // col_count - + row_gil_blip_interval = _CELL_GIL_BLIP_INTERVAL // col_count + if row_gil_blip_interval < 400: # ceiling reached at 100 columns + row_gil_blip_interval = 400 try: + # Don't move this logic up! We need the GIL to execute a `try`. + # Also we can't have any other `try` blocks between here and the + # `finally` block. + if not any_cols_need_gil: + gs = PyEval_SaveThread() + for row_index in range(row_count): - if row_index % row_gil_blip_count == 0: + if (gs == NULL) and (row_index % row_gil_blip_interval == 0): # Release and re-acquire the GIL every so often. # This is to allow other python threads to run. # If we hold the GIL for too long, we can starve other - # threads and potentially time out ongoing network activity. - gil_state = PyEval_SaveThread() - PyEval_RestoreThread(gil_state) - gil_state = NULL - - # TODO: Potentially avoid the GIL altogether if we can get away with it. - # This is column-type dependent. Some basic analysis is required. - # We need a `GilController` object so that we can raise exceptions. + # threads, for example timing out network activity. + gs = PyEval_SaveThread() + _ensure_has_gil(&gs) + qdb_pystr_buf_truncate(b, str_buf_marker) - # Fixed table-name. + + # Table-name from `table_name` arg in Python. if c_table_name.buf != NULL: if not line_sender_buffer_table(impl, c_table_name, &err): + _ensure_has_gil(&gs) raise c_err_to_py(err) # Serialize columns cells. # Note: Columns are sorted: table name, symbols, fields, at. + was_serializing_cell = True for col_index in range(col_count): col = &cols.d[col_index] - try: - _pandas_serialize_cell(impl, b, col) - except Exception as e: - raise IngressError( - IngressErrorCode.BadDataFrame, - 'Failed to serialize value of column ' + - repr(data.columns[col.orig_index]) + - f' at row index {row_index} (' + - repr(data.iloc[row_index, col.orig_index]) + - f'): {e} [dc={col.dispatch_code}]') from e + _pandas_serialize_cell(impl, b, col, &gs) # may raise _pandas_col_advance(col) + was_serializing_cell = False # Fixed "at" value (not from a column). if at_value == 0: if not line_sender_buffer_at_now(impl, &err): + _ensure_has_gil(&gs) raise c_err_to_py(err) elif at_value > 0: if not line_sender_buffer_at(impl, at_value, &err): + _ensure_has_gil(&gs) raise c_err_to_py(err) - except: + except Exception as e: + # It would be an internal bug for this to raise. if not line_sender_buffer_rewind_to_marker(impl, &err): raise c_err_to_py(err) - raise + + if was_serializing_cell: + raise IngressError( + IngressErrorCode.BadDataFrame, + 'Failed to serialize value of column ' + + repr(data.columns[col.orig_index]) + + f' at row index {row_index} (' + + repr(data.iloc[row_index, col.orig_index]) + + f'): {e} [dc={col.dispatch_code}]') from e + else: + raise finally: + _ensure_has_gil(&gs) line_sender_buffer_clear_marker(impl) col_t_arr_release(&cols) qdb_pystr_buf_clear(b) diff --git a/test/test.py b/test/test.py index 2ccfe8f5..e6ec5986 100755 --- a/test/test.py +++ b/test/test.py @@ -1574,6 +1574,8 @@ def test_cat_i32_str(self): self._test_cat_str(32768) self._test_cat_str(40000) +# TODO: Test datetime64[ns] and datetime64[ns, tz] columns fully, including None values for `at` and `column_ts`. + if False: class TestBencharkPandas(unittest.TestCase): From 5041d26019db9934d5f3c7957b5d0d492c17fecf Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 1 Dec 2022 14:17:13 +0000 Subject: [PATCH 084/147] Refactoring out benchmarks, refactoring Py str to UTF8 rust impl. --- perf/README.md | 12 ++-- proj.py | 6 ++ pystr-to-utf8/src/lib.rs | 113 +++++++++++++++++------------------ test/benchmark.py | 123 +++++++++++++++++++++++++++++++++++++++ test/test.py | 68 +--------------------- 5 files changed, 191 insertions(+), 131 deletions(-) create mode 100644 test/benchmark.py diff --git a/perf/README.md b/perf/README.md index 94bcf31e..a6ba49d8 100644 --- a/perf/README.md +++ b/perf/README.md @@ -3,21 +3,21 @@ https://juanjose.garciaripoll.com/blog/profiling-code-with-linux-perf/index.html ```bash -$ TEST_QUESTDB_PATCH_PATH=1 TEST_QUESTDB_PROFILE=0 perf record -g --call-graph dwarf python3 test/test.py -v TestBencharkPandas.test_mixed_10m -test_mixed_10m (__main__.TestBencharkPandas.test_mixed_10m) ... Time: 2.128126113999315, size: 558055572 +$ TEST_QUESTDB_PATCH_PATH=1 perf record -g --call-graph dwarf python3 test/benchmark.py -v TestBencharkPandas.test_string_encoding_1m +test_string_encoding_1m (__main__.TestBencharkPandas.test_string_encoding_1m) ... Time: 4.682273147998785, size: 4593750000 ok ---------------------------------------------------------------------- -Ran 1 test in 10.188s +Ran 1 test in 10.166s OK -[ perf record: Woken up 1337 times to write data ] +[ perf record: Woken up 1341 times to write data ] Warning: -Processed 55721 events and lost 107 chunks! +Processed 54445 events and lost 91 chunks! Check IO/CPU overload! -[ perf record: Captured and wrote 402.922 MB perf.data (50252 samples) ] +[ perf record: Captured and wrote 405.575 MB perf.data (50622 samples) ] ``` # Rendering results diff --git a/proj.py b/proj.py index 7a773a98..d48631eb 100755 --- a/proj.py +++ b/proj.py @@ -76,6 +76,12 @@ def test(all=False, patch_path='1', *args): env=env) +@command +def benchmark(*args): + env = {'TEST_QUESTDB_PATCH_PATH': '1'} + _run('python3', 'test/benchmark.py', '-v', *args, env=env) + + @command def gdb_test(*args): env = {'TEST_QUESTDB_PATCH_PATH': '1'} diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index 0926a797..e5f14261 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -103,16 +103,33 @@ fn get_dest(chain: &mut Vec, len: usize) -> &mut String { chain.last_mut().unwrap() } -#[inline] -fn encode_ucs1<'a, 'b>(chain: &'a mut Vec, buf: &'b [u8]) -> &'a str { - // len(chr(2 ** 8 - 1).encode('utf-8')) == 2 - let utf8_mult = 2; +#[inline(always)] +fn encode_loop<'a, 'b, T, F>( + utf8_mult: usize, + chain: &'a mut Vec, + buf: &'b [T], + get_char: F) -> Result<&'a str, u32> + where + F: Fn(T) -> Option, + T: Copy + Into +{ let dest = get_dest(chain, utf8_mult * buf.len()); let last = dest.len(); for &b in buf.iter() { - dest.push(b as char); + // Checking for validity is not optional: + // >>> for n in range(2 ** 16): + // >>> chr(n).encode('utf-8') + // UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' + // in position 0: surrogates not allowed + match get_char(b) { + Some(c) => dest.push(c), + None => { + dest.truncate(last); + return Err(b.into()); + } + } } - &dest[last..] + Ok(&dest[last..]) } /// Convert a Py_UCS1 string to UTF-8. @@ -125,35 +142,18 @@ pub unsafe extern "C" fn qdb_ucs1_to_utf8( size_out: *mut usize, buf_out: *mut *const c_char) { let b = &mut *b; let i = from_raw_parts(input, count); - let res = encode_ucs1(&mut b.0, i); + + // len(chr(2 ** 8 - 1).encode('utf-8')) == 2 + let utf8_mult = 2; + let res = encode_loop( + utf8_mult, + &mut b.0, + i, + |c| Some(c as char)).unwrap(); *size_out = res.len(); *buf_out = res.as_ptr() as *const c_char; } -#[inline] -fn encode_ucs2<'a, 'b>( - chain: &'a mut Vec, buf: &'b [u16]) -> Result<&'a str, u32> { - // len(chr(2 ** 16 - 1).encode('utf-8')) == 3 - let utf8_mult = 3; - let dest = get_dest(chain, utf8_mult * buf.len()); - let last = dest.len(); - for b in buf.iter() { - // Checking for validity is not optional: - // >>> for n in range(2 ** 16): - // >>> chr(n).encode('utf-8') - // UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' - // in position 0: surrogates not allowed - match char::from_u32(*b as u32) { - Some(c) => dest.push(c), - None => { - dest.truncate(last); - return Err(*b as u32); - } - } - } - Ok(&dest[last..]) -} - /// Convert a Py_UCS2 string to UTF-8. /// Returns a `buf_out` borrowed ptr of `size_out` len. /// The buffer is borrowed from `b`. @@ -168,10 +168,18 @@ pub unsafe extern "C" fn qdb_ucs2_to_utf8(b: *mut qdb_pystr_buf, bad_codepoint_out: *mut u32) -> bool { let b = &mut *b; let i = from_raw_parts(input, count); - match encode_ucs2(&mut b.0, i) { - Ok(res) => { - *size_out = res.len(); - *buf_out = res.as_ptr() as *const c_char; + + // len(chr(2 ** 16 - 1).encode('utf-8')) == 3 + let utf8_mult = 3; + let res = encode_loop( + utf8_mult, + &mut b.0, + i, + |c| char::from_u32(c as u32)); + match res { + Ok(s) => { + *size_out = s.len(); + *buf_out = s.as_ptr() as *const c_char; true } Err(bad) => { @@ -181,25 +189,6 @@ pub unsafe extern "C" fn qdb_ucs2_to_utf8(b: *mut qdb_pystr_buf, } } -#[inline] -fn encode_ucs4<'a, 'b>( - chain: &'a mut Vec, buf: &'b[u32]) -> Result<&'a str, u32> { - // Max 4 bytes allowed by RFC: https://www.rfc-editor.org/rfc/rfc3629#page-4 - let utf8_mult = 4; - let dest = get_dest(chain, utf8_mult * buf.len()); - let last = dest.len(); - for b in buf.iter() { - match char::from_u32(*b) { - Some(c) => dest.push(c), - None => { - dest.truncate(last); - return Err(*b); - } - } - } - Ok(&dest[last..]) -} - /// Convert a Py_UCS4 string to UTF-8. /// Returns a `buf_out` borrowed ptr of `size_out` len. /// The buffer is borrowed from `b`. @@ -214,10 +203,18 @@ pub unsafe extern "C" fn qdb_ucs4_to_utf8(b: *mut qdb_pystr_buf, bad_codepoint_out: *mut u32) -> bool { let b = &mut *b; let i = from_raw_parts(input, count); - match encode_ucs4(&mut b.0, i) { - Ok(res) => { - *size_out = res.len(); - *buf_out = res.as_ptr() as *const c_char; + + // Max 4 bytes allowed by RFC: https://www.rfc-editor.org/rfc/rfc3629#page-4 + let utf8_mult = 4; + let res = encode_loop( + utf8_mult, + &mut b.0, + i, + |c| char::from_u32(c)); + match res { + Ok(s) => { + *size_out = s.len(); + *buf_out = s.as_ptr() as *const c_char; true } Err(bad) => { diff --git a/test/benchmark.py b/test/benchmark.py new file mode 100644 index 00000000..7af38659 --- /dev/null +++ b/test/benchmark.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 + +import sys +import os +sys.dont_write_bytecode = True +import unittest +import time +import pandas as pd + +import patch_path +import questdb.ingress as qi + + +class TestBencharkPandas(unittest.TestCase): + def test_pystr_i64_10m(self): + # This is a benchmark, not a test. + # It is useful to run it manually to check performance. + slist = [f's{i:09}' for i in range(10_000_000)] + df = pd.DataFrame({ + 'a': slist, + 'b': list(range(len(slist)))}) + + buf = qi.Buffer() + + # Warm up and pre-size buffer + buf.pandas(df, table_name='tbl1', symbols=True) + buf.clear() + + # Run + t0 = time.monotonic() + buf.pandas(df, table_name='tbl1', symbols=True) + t1 = time.monotonic() + print(f'Time: {t1 - t0}, size: {len(buf)}') + + def test_mixed_10m(self): + # This is a benchmark, not a test. + # It is useful to run it manually to check performance. + count = 10_000_000 + slist = [f's{i:09}' for i in range(count)] + df = pd.DataFrame({ + 'col1': pd.Series(slist, dtype='string[pyarrow]'), + 'col2': list(range(len(slist))), + 'col3': [float(i / 2) for i in range(len(slist))], + 'col4': [float(i / 2) + 1.0 for i in range(len(slist))], + 'col5': pd.Categorical( + ['a', 'b', 'c', 'a', None, 'c', 'a', float('nan')] * + (count // 8))}) + + buf = qi.Buffer() + + # Warm up and pre-size buffer + buf.pandas(df, table_name='tbl1', symbols=True) + buf.clear() + + # Run + t0 = time.monotonic() + buf.pandas(df, table_name='tbl1', symbols=True) + t1 = time.monotonic() + print(f'Time: {t1 - t0}, size: {len(buf)}') + + def test_string_escaping_10m(self): + count = 10_000_000 + slist = [f's={i:09}==abc \\' for i in range(count)] + series = pd.Series(slist, dtype='string[pyarrow]') + df = pd.DataFrame({ + 'col1': series, + 'col2': series, + 'col3': series, + 'col4': series, + 'col5': series, + 'col6': series}) + + buf = qi.Buffer() + + # Warm up and pre-size buffer + buf.pandas(df, table_name='tbl1', symbols=True) + buf.clear() + + # Run + t0 = time.monotonic() + buf.pandas(df, table_name='tbl1', symbols=True) + t1 = time.monotonic() + print(f'Time: {t1 - t0}, size: {len(buf)}') + + def test_string_encoding_1m(self): + count = 1_000_000 + strs = ['a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '𐀀a𐀀b𐀀💩🦞c𐀀d𐀀ef'] # UCS-4, 4 bytes for UTF-8. + slist = strs * (count // len(strs)) + self.assertEqual(len(slist), count) + + df = pd.DataFrame({ + 'col1': slist, + 'col2': slist, + 'col3': slist, + 'col4': slist, + 'col5': slist}) + + buf = qi.Buffer() + + # Warm up and pre-size buffer + buf.pandas(df, table_name='tbl1', symbols=False) + buf.clear() + + # Run + t0 = time.monotonic() + buf.pandas(df, table_name='tbl1', symbols=False) + t1 = time.monotonic() + print(f'Time: {t1 - t0}, size: {len(buf)}') + + +if __name__ == '__main__': + if os.environ.get('TEST_QUESTDB_PROFILE') == '1': + import cProfile + cProfile.run('unittest.main()', sort='cumtime') + else: + unittest.main() diff --git a/test/test.py b/test/test.py index e6ec5986..503eecfe 100755 --- a/test/test.py +++ b/test/test.py @@ -9,7 +9,6 @@ import numpy as np import pandas as pd import zoneinfo -import itertools import patch_path from mock_server import Server @@ -1574,73 +1573,8 @@ def test_cat_i32_str(self): self._test_cat_str(32768) self._test_cat_str(40000) -# TODO: Test datetime64[ns] and datetime64[ns, tz] columns fully, including None values for `at` and `column_ts`. - - -if False: - class TestBencharkPandas(unittest.TestCase): - def test_pystr_i64_10m(self): - # This is a benchmark, not a test. - # It is useful to run it manually to check performance. - slist = [f's{i:09}' for i in range(10_000_000)] - df = pd.DataFrame({ - 'a': slist, - 'b': list(range(len(slist)))}) - - # Warm up - _pandas(df, table_name='tbl1', symbols=True) - - # Run - t0 = time.monotonic() - _pandas(df, table_name='tbl1', symbols=True) - t1 = time.monotonic() - print('Time:', t1 - t0) - - def test_mixed_10m(self): - # This is a benchmark, not a test. - # It is useful to run it manually to check performance. - count = 10_000_000 - slist = [f's{i:09}' for i in range(count)] - df = pd.DataFrame({ - 'col1': pd.Series(slist, dtype='string[pyarrow]'), - 'col2': list(range(len(slist))), - 'col3': [float(i / 2) for i in range(len(slist))], - 'col4': [float(i / 2) + 1.0 for i in range(len(slist))], - 'col5': pd.Categorical( - ['a', 'b', 'c', 'a', None, 'c', 'a', float('nan')] * - (count // 8))}) - - # Warm up - _pandas(df, table_name='tbl1', symbols=True) - - # Run - t0 = time.monotonic() - buf = _pandas(df, table_name='tbl1', symbols=True) - t1 = time.monotonic() - print(f'Time: {t1 - t0}, size: {len(buf)}') - - def test_string_escaping_10m(self): - count = 10_000_000 - slist = [f's={i:09}==abc \\' for i in range(count)] - series = pd.Series(slist, dtype='string[pyarrow]') - df = pd.DataFrame({ - 'col1': series, - 'col2': series, - 'col3': series, - 'col4': series, - 'col5': series, - 'col6': series}) - - # Warm up - _pandas(df, table_name='tbl1', symbols=True) - - # Run - t0 = time.monotonic() - buf = _pandas(df, table_name='tbl1', symbols=True) - t1 = time.monotonic() - print(f'Time: {t1 - t0}, size: {len(buf)}') - +# TODO: Test datetime64[ns] and datetime64[ns, tz] columns fully, including None values for `at` and `column_ts`. # TODO: Test all datatypes, but no rows. # TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. # TODO: Test all datatypes, but multiple row chunks. From e4135d0b544616d5e3b3a5d13ea6a0e6d05d52ee Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 1 Dec 2022 15:52:52 +0000 Subject: [PATCH 085/147] 8% perf improvements in Python string to UTF-8 conversions. --- pystr-to-utf8/src/lib.rs | 80 ++++++++++++++++++++++++++++++++++------ test/benchmark.py | 6 +-- 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/pystr-to-utf8/src/lib.rs b/pystr-to-utf8/src/lib.rs index e5f14261..aa58ac7c 100644 --- a/pystr-to-utf8/src/lib.rs +++ b/pystr-to-utf8/src/lib.rs @@ -115,19 +115,77 @@ fn encode_loop<'a, 'b, T, F>( { let dest = get_dest(chain, utf8_mult * buf.len()); let last = dest.len(); - for &b in buf.iter() { - // Checking for validity is not optional: - // >>> for n in range(2 ** 16): - // >>> chr(n).encode('utf-8') - // UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' - // in position 0: surrogates not allowed - match get_char(b) { - Some(c) => dest.push(c), - None => { - dest.truncate(last); - return Err(b.into()); + // for &b in buf.iter() { + // // Checking for validity is not optional: + // // >>> for n in range(2 ** 16): + // // >>> chr(n).encode('utf-8') + // // UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' + // // in position 0: surrogates not allowed + // match get_char(b) { + // Some(c) => dest.push(c), + // None => { + // dest.truncate(last); + // return Err(b.into()); + // } + // } + // } + // Ok(&dest[last..]) + unsafe { + let v = dest.as_mut_vec(); + v.set_len(v.capacity()); + let mut index = last; + + for &b in buf.iter() { + let c = match get_char(b) { + Some(c) => c, + None => { + v.set_len(last); + return Err(b.into()) + } + }; + let utf_c_len = c.len_utf8(); + match utf_c_len { + 1 => { + v[index] = c as u8; + }, + 2 => { + let mut codepoint_buf = [0; 4]; + let bytes = c + .encode_utf8(&mut codepoint_buf).as_bytes(); + *v.get_unchecked_mut(index) = + *bytes.get_unchecked(0); + *v.get_unchecked_mut(index + 1) = + *bytes.get_unchecked(1); + }, + 3 => { + let mut codepoint_buf = [0; 4]; + let bytes = c + .encode_utf8(&mut codepoint_buf).as_bytes(); + *v.get_unchecked_mut(index) = + *bytes.get_unchecked(0); + *v.get_unchecked_mut(index + 1) = + *bytes.get_unchecked(1); + *v.get_unchecked_mut(index + 2) = + *bytes.get_unchecked(2); + }, + 4 => { + let mut codepoint_buf = [0; 4]; + let bytes = c + .encode_utf8(&mut codepoint_buf).as_bytes(); + *v.get_unchecked_mut(index) = + *bytes.get_unchecked(0); + *v.get_unchecked_mut(index + 1) = + *bytes.get_unchecked(1); + *v.get_unchecked_mut(index + 2) = + *bytes.get_unchecked(2); + *v.get_unchecked_mut(index + 3) = + *bytes.get_unchecked(3); + }, + _ => unreachable!() } + index += utf_c_len; } + v.set_len(index); } Ok(&dest[last..]) } diff --git a/test/benchmark.py b/test/benchmark.py index 7af38659..69b29c4b 100644 --- a/test/benchmark.py +++ b/test/benchmark.py @@ -82,11 +82,11 @@ def test_string_escaping_10m(self): t1 = time.monotonic() print(f'Time: {t1 - t0}, size: {len(buf)}') - def test_string_encoding_1m(self): - count = 1_000_000 + def test_string_encoding_10m(self): + count = 10_000_000 strs = ['a', # ASCII 'q❤️p', # Mixed ASCII and UCS-2 - '❤️' * 1200, # Over the 1024 buffer prealloc. + '❤️' * 12 , # UCS-2 'Questo è un qualcosa', # Non-ASCII UCS-1 'щось', # UCS-2, 2 bytes for UTF-8. '', # Empty string From 754534ca015d6abf2ce0925f1594e29a0e10c001 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 1 Dec 2022 16:38:10 +0000 Subject: [PATCH 086/147] Multithreading benchmark. --- test/benchmark.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/benchmark.py b/test/benchmark.py index 69b29c4b..246e50a2 100644 --- a/test/benchmark.py +++ b/test/benchmark.py @@ -5,7 +5,9 @@ sys.dont_write_bytecode = True import unittest import time +import numpy as np import pandas as pd +from concurrent.futures import ThreadPoolExecutor import patch_path import questdb.ingress as qi @@ -114,6 +116,71 @@ def test_string_encoding_10m(self): t1 = time.monotonic() print(f'Time: {t1 - t0}, size: {len(buf)}') + def _test_gil_release_10m(self, threads): + count = 10_000_000 + series = pd.Series(np.arange(count), dtype='int64') + df = pd.DataFrame({ + 'col1': series, + 'col2': series, + 'col3': series, + 'col4': series, + 'col5': series, + 'col6': series}) + + tpe = ThreadPoolExecutor(max_workers=threads) + bufs = [qi.Buffer() for _ in range(threads)] + + def benchmark_run(buf): + t0 = time.monotonic() + buf.pandas(df, table_name='tbl1', symbols=True) + t1 = time.monotonic() + return buf, (t0, t1) + + # Warm up and pre-size buffer + futs = [ + tpe.submit(benchmark_run, buf) + for buf in bufs] + for fut in futs: + fut.result() # Wait for completion + for buf in bufs: + buf.clear() + + # Run + futs = [ + tpe.submit(benchmark_run, buf) + for buf in bufs] + results = [ + fut.result() + for fut in futs] + print(f'\nSize: {len(bufs[0])}') + total_time = 0 + min_time = 2 ** 64 -1 # Bigger than any `time.monotonic()` value + max_time = 0 + print('Per-thread times:') + for index, (_, (t0, t1)) in enumerate(results): + if t0 < min_time: + min_time = t0 + if t1 > max_time: + max_time = t1 + elapsed = t1 - t0 + print(f' [{index:02}]: Time: {elapsed}') + total_time += elapsed + avg_time = total_time / len(results) + print(f'Avg time: {avg_time}') + print(f'Wall time: {max_time - min_time}') + + def test_gil_release_10m_1t(self): + self._test_gil_release_10m(1) + + def test_gil_release_10m_10t(self): + self._test_gil_release_10m(10) + + def test_gil_release_10m_16t(self): + self._test_gil_release_10m(16) + + def test_gil_release_10m_32t(self): + self._test_gil_release_10m(32) + if __name__ == '__main__': if os.environ.get('TEST_QUESTDB_PROFILE') == '1': From 5915a002a1a6a1b440832e6c428ba64b78e905a5 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 1 Dec 2022 18:08:11 +0000 Subject: [PATCH 087/147] Implemented column (arrow and pybuffer) cleanup. --- src/questdb/ingress.pyx | 3 +- src/questdb/ingress_helper.h | 12 ++++++++ src/questdb/ingress_helper.pxd | 2 ++ src/questdb/pandas_integration.pxi | 49 ++++++++++++++++-------------- 4 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 src/questdb/ingress_helper.h create mode 100644 src/questdb/ingress_helper.pxd diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 6d1ba093..4b1af18c 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -34,7 +34,7 @@ API for fast data ingestion into QuestDB. from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t, \ INT64_MAX from libc.stdlib cimport malloc, calloc, realloc, free, abort -from libc.string cimport strncmp +from libc.string cimport strncmp, memset from libc.math cimport isnan from libc.stdio cimport fprintf, stderr # TODO: Remove me one no longer needed from cpython.datetime cimport datetime @@ -49,6 +49,7 @@ from .line_sender cimport * from .pystr_to_utf8 cimport * from .arrow_c_data_interface cimport * from .extra_cpython cimport * +from .ingress_helper cimport * # An int we use only for error reporting. # 0 is success. diff --git a/src/questdb/ingress_helper.h b/src/questdb/ingress_helper.h new file mode 100644 index 00000000..0c665727 --- /dev/null +++ b/src/questdb/ingress_helper.h @@ -0,0 +1,12 @@ +#pragma once +// This file is included into `ingress.c`. + + +// Cython idiosyncrasy workaround. +// If we do this in Cython it treats `buf.obj` as +// a ref-counted `object` instead of a `PyObject*`, +// so we can't check it for NULL. +inline int Py_buffer_obj_is_set(Py_buffer* buf) +{ + return buf->obj != NULL; +} \ No newline at end of file diff --git a/src/questdb/ingress_helper.pxd b/src/questdb/ingress_helper.pxd new file mode 100644 index 00000000..f615fa69 --- /dev/null +++ b/src/questdb/ingress_helper.pxd @@ -0,0 +1,2 @@ +cdef extern from "ingress_helper.h": + bint Py_buffer_obj_is_set(Py_buffer* buf) \ No newline at end of file diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 745f3b8e..57a75457 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1,10 +1,5 @@ # See: pandas_integration.md for technical overview. -cdef enum col_access_tag_t: - numpy - arrow - - cdef struct col_chunks_t: size_t n_chunks ArrowArray* chunks # We calloc `n_chunks + 1` of these. @@ -277,7 +272,6 @@ cdef enum col_dispatch_code_t: cdef struct col_t: size_t orig_index line_sender_column_name name - col_access_tag_t tag Py_buffer pybuf ArrowSchema arrow_schema # Schema of first chunk. col_chunks_t chunks @@ -288,11 +282,26 @@ cdef struct col_t: cdef void col_t_release(col_t* col): - # We can use `col.tag` to determine what to release. - # Arrow chunks might be "synthetic" borrowing from `col.pybuf`. - # TODO: Implement cleanup, PyBuffer_Release, etc. - # TODO: Do we need to call Arrow's cleanup functions when done? - pass + """ + Release a (possibly) initialized column. + + col_t objects are `calloc`ed, so uninitialized (or partially) initialized + objects will have their pointers and other values set to 0. + """ + cdef size_t chunk_index + cdef ArrowArray* chunk + + if Py_buffer_obj_is_set(&col.pybuf): + PyBuffer_Release(&col.pybuf) # Note: Sets `col.pybuf.obj` to NULL. + + for chunk_index in range(col.chunks.n_chunks): + chunk = &col.chunks.chunks[chunk_index] + if chunk.release != NULL: + chunk.release(chunk) + memset(chunk, 0, sizeof(ArrowArray)) + + if col.arrow_schema.release != NULL: + col.arrow_schema.release(&col.arrow_schema) # Calloc'd array of col_t. @@ -703,17 +712,14 @@ cdef void_int _pandas_series_as_pybuf( cdef object nparr = entry.series.to_numpy(dtype=fallback_dtype) cdef ArrowArray* mapped cdef int get_buf_ret - cdef Py_buffer* view if not PyObject_CheckBuffer(nparr): raise TypeError( f'Bad column {entry.name!r}: Expected a buffer, got ' + f'{entry.series!r} ({_fqn(type(entry.series))})') - col_out.tag = col_access_tag_t.numpy try: # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. - view = &col_out.pybuf - get_buf_ret = PyObject_GetBuffer(nparr, view, PyBUF_SIMPLE) + get_buf_ret = PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_SIMPLE) except BufferError as be: raise TypeError( @@ -751,7 +757,6 @@ cdef void_int _pandas_series_as_arrow( _pandas_series_as_pybuf(entry, col_out, fallback_dtype) return 0 - col_out.tag = col_access_tag_t.arrow array = _PYARROW.Array.from_pandas(entry.series) if isinstance(array, _PYARROW.ChunkedArray): chunks = array.chunks @@ -1176,11 +1181,11 @@ cdef inline bint _pandas_arrow_str( cdef inline void_int _pandas_cell_str_pyobj_to_utf8( qdb_pystr_buf* b, - col_t* col, + col_cursor_t* cursor, bint* valid_out, line_sender_utf8* utf8_out) except -1: - cdef PyObject** access = col.cursor.chunk.buffers[1] - cdef PyObject* cell = access[col.cursor.offset] + cdef PyObject** access = cursor.chunk.buffers[1] + cdef PyObject* cell = access[cursor.offset] if PyUnicode_CheckExact(cell): str_to_utf8(b, cell, utf8_out) valid_out[0] = True @@ -1303,7 +1308,7 @@ cdef void_int _pandas_serialize_cell_symbol__str_pyobj( cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 - _pandas_cell_str_pyobj_to_utf8(b, col, &valid, &utf8) + _pandas_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) if valid and not line_sender_buffer_symbol(impl, col.name, utf8, &err): raise c_err_to_py(err) @@ -1786,7 +1791,7 @@ cdef void_int _pandas_serialize_cell_column_str__str_pyobj( cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 - _pandas_cell_str_pyobj_to_utf8(b, col, &valid, &utf8) + _pandas_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) if valid and not line_sender_buffer_column_str(impl, col.name, utf8, &err): raise c_err_to_py(err) @@ -2177,7 +2182,7 @@ cdef void_int _pandas( else: raise finally: - _ensure_has_gil(&gs) + _ensure_has_gil(&gs) # Note: We need the GIL for cleanup. line_sender_buffer_clear_marker(impl) col_t_arr_release(&cols) qdb_pystr_buf_clear(b) From 9b75a12935974124f8aad0f33bbb8cd60dae8e89 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 1 Dec 2022 18:13:30 +0000 Subject: [PATCH 088/147] Formatting. --- src/questdb/ingress_helper.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/questdb/ingress_helper.h b/src/questdb/ingress_helper.h index 0c665727..954dcdde 100644 --- a/src/questdb/ingress_helper.h +++ b/src/questdb/ingress_helper.h @@ -6,7 +6,9 @@ // If we do this in Cython it treats `buf.obj` as // a ref-counted `object` instead of a `PyObject*`, // so we can't check it for NULL. +// Since `Py_buffer` is a Cython built-in we can't actually +// just re-define it in `extra_cpython.pxd`. inline int Py_buffer_obj_is_set(Py_buffer* buf) { return buf->obj != NULL; -} \ No newline at end of file +} From 7f8dab4d67abc86379d7b209b18fac0d61034cb8 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 1 Dec 2022 18:17:24 +0000 Subject: [PATCH 089/147] Tested all-nulls column is altogether skipped. --- src/questdb/ingress.pyx | 1 - src/questdb/pandas_integration.pxi | 1 - test/test.py | 11 +++++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 4b1af18c..fb4e4336 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -36,7 +36,6 @@ from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t, \ from libc.stdlib cimport malloc, calloc, realloc, free, abort from libc.string cimport strncmp, memset from libc.math cimport isnan -from libc.stdio cimport fprintf, stderr # TODO: Remove me one no longer needed from cpython.datetime cimport datetime from cpython.bool cimport bool from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 57a75457..955b57f1 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -860,7 +860,6 @@ cdef void_int _pandas_series_sniff_pyobj( f'Unsupported object column containing an {_fqn(type(obj))}') return 0 - # TODO: Test all-nulls column. # We haven't returned yet, so we've hit an object column that # exclusively has null values. We will just skip this column. col_out.source = col_source_t.col_source_nulls diff --git a/test/test.py b/test/test.py index 503eecfe..55b3a362 100755 --- a/test/test.py +++ b/test/test.py @@ -1573,6 +1573,17 @@ def test_cat_i32_str(self): self._test_cat_str(32768) self._test_cat_str(40000) + def test_all_nulls_pyobj_col(self): + df = pd.DataFrame({ + 'a': [None, pd.NA, float('nan')], + 'b': [1, 2, 3]}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 b=1i\n' + + 'tbl1 b=2i\n' + + 'tbl1 b=3i\n') + # TODO: Test datetime64[ns] and datetime64[ns, tz] columns fully, including None values for `at` and `column_ts`. # TODO: Test all datatypes, but no rows. From 21f39f862000bdad593fda21829979fc97fb374b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 1 Dec 2022 22:27:19 +0000 Subject: [PATCH 090/147] Refactoring and sorting columns in C. --- src/questdb/ingress.pyx | 2 +- src/questdb/pandas_integration.pxi | 424 +++++++++++++++-------------- 2 files changed, 223 insertions(+), 203 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index fb4e4336..9e5f0209 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -33,7 +33,7 @@ API for fast data ingestion into QuestDB. # For prototypes: https://github.com/cython/cython/tree/master/Cython/Includes from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t, \ INT64_MAX -from libc.stdlib cimport malloc, calloc, realloc, free, abort +from libc.stdlib cimport malloc, calloc, realloc, free, abort, qsort from libc.string cimport strncmp, memset from libc.math cimport isnan from cpython.datetime cimport datetime diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 955b57f1..dae5b159 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -269,7 +269,16 @@ cdef enum col_dispatch_code_t: col_target_t.col_target_at + col_source_t.col_source_dt64ns_tz_arrow +# Int values in order for sorting (as needed for API's sequential coupling). +cdef enum meta_target_t: + meta_target_table = col_target_t.col_target_table + meta_target_symbol = col_target_t.col_target_symbol + meta_target_field = col_target_t.col_target_column_bool + meta_target_at = col_target_t.col_target_at + + cdef struct col_t: + meta_target_t meta_target size_t orig_index line_sender_column_name name Py_buffer pybuf @@ -416,7 +425,7 @@ cdef object _check_is_pandas_dataframe(object data): cdef ssize_t _pandas_resolve_table_name( qdb_pystr_buf* b, object data, - list tagged_cols, + col_t_arr* cols, object table_name, object table_name_col, size_t col_count, @@ -436,7 +445,7 @@ cdef ssize_t _pandas_resolve_table_name( This method validates input and may raise. """ cdef size_t col_index = 0 - cdef TaggedEntry entry + cdef col_t* col if table_name is not None: if table_name_col is not None: raise ValueError( @@ -466,8 +475,8 @@ cdef ssize_t _pandas_resolve_table_name( col_index, 'Bad argument `table_name_col`: ', table_name_col) - entry = tagged_cols[col_index] - entry.meta_target = meta_target_t.meta_target_table + col = &cols.d[col_index] + col.meta_target = meta_target_t.meta_target_table name_out.len = 0 name_out.buf = NULL return col_index @@ -537,62 +546,50 @@ cdef object _pandas_check_column_is_str( f'{col_name!r} column: Must be a strings column.') -# Int values in order for sorting (as needed for API's sequential coupling). -cdef enum meta_target_t: - meta_target_table = col_target_t.col_target_table - meta_target_symbol = col_target_t.col_target_symbol - meta_target_field = col_target_t.col_target_column_bool - meta_target_at = col_target_t.col_target_at - - @cython.internal -cdef class TaggedEntry: +cdef class PandasCol: """Python object representing a column whilst parsing .pandas arguments.""" - - cdef size_t orig_index cdef str name cdef object dtype cdef object series - cdef meta_target_t meta_target def __init__( self, - size_t orig_index, str name, object dtype, - object series, - meta_target_t meta_target): - self.orig_index = orig_index + object series): self.name = name self.dtype = dtype self.series = series - self.meta_target = meta_target cdef void_int _pandas_resolve_symbols( object data, - list tagged_cols, + list pandas_cols, + col_t_arr* cols, ssize_t table_name_col, ssize_t at_col, - object symbols, - size_t col_count) except -1: + object symbols) except -1: cdef size_t col_index = 0 cdef object symbol - cdef TaggedEntry entry + cdef PandasCol pandas_col + cdef col_t* col if symbols == 'auto': - for col_index in range(col_count): - entry = tagged_cols[col_index] - if entry.meta_target == meta_target_t.meta_target_field: - if isinstance(entry.dtype, _PANDAS.CategoricalDtype): - entry.meta_target = meta_target_t.meta_target_symbol + for col_index in range(cols.size): + pandas_col = pandas_cols[col_index] + col = &cols.d[col_index] + if col.meta_target == meta_target_t.meta_target_field: + if isinstance(pandas_col.dtype, _PANDAS.CategoricalDtype): + col.meta_target = meta_target_t.meta_target_symbol elif symbols is False: pass elif symbols is True: - for col_index in range(col_count): + for col_index in range(cols.size): if _pandas_column_is_str(data, col_index): - entry = tagged_cols[col_index] - if entry.meta_target == meta_target_t.meta_target_field: - entry.meta_target = meta_target_t.meta_target_symbol + pandas_col = pandas_cols[col_index] + col = &cols.d[col_index] + if col.meta_target == meta_target_t.meta_target_field: + col.meta_target = meta_target_t.meta_target_symbol else: if not isinstance(symbols, (tuple, list)): raise TypeError( @@ -602,7 +599,7 @@ cdef void_int _pandas_resolve_symbols( if isinstance(symbol, str): _pandas_get_loc(data, symbol, 'symbols', &col_index) elif isinstance(symbol, int): - _bind_col_index('symbol', symbol, col_count, &col_index) + _bind_col_index('symbol', symbol, cols.size, &col_index) else: raise TypeError( f'Bad argument `symbols`: Elements must ' + @@ -620,8 +617,8 @@ cdef void_int _pandas_resolve_symbols( col_index, 'Bad element in argument `symbols`: ', symbol) - entry = tagged_cols[col_index] - entry.meta_target = meta_target_t.meta_target_symbol + col = &cols.d[col_index] + col.meta_target = meta_target_t.meta_target_symbol cdef void_int _pandas_get_loc( @@ -645,13 +642,13 @@ cdef int64_t _AT_SET_BY_COLUMN = -1 cdef ssize_t _pandas_resolve_at( object data, - list tagged_cols, + col_t_arr* cols, object at, size_t col_count, int64_t* at_value_out) except -2: cdef size_t col_index cdef object dtype - cdef TaggedEntry entry + cdef PandasCol pandas_col if at is None: at_value_out[0] = 0 # Special value for `at_now`. return -1 @@ -673,8 +670,8 @@ cdef ssize_t _pandas_resolve_at( dtype = data.dtypes[col_index] if _pandas_is_supported_datetime(dtype): at_value_out[0] = _AT_SET_BY_COLUMN - entry = tagged_cols[col_index] - entry.meta_target = meta_target_t.meta_target_at + col = &cols.d[col_index] + col.meta_target = meta_target_t.meta_target_at return col_index else: raise TypeError( @@ -692,12 +689,12 @@ cdef object _pandas_is_supported_datetime(object dtype): cdef void_int _pandas_alloc_chunks( - size_t n_chunks, col_t* col_out) except -1: - col_out.chunks.n_chunks = n_chunks - col_out.chunks.chunks = calloc( - col_out.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. + size_t n_chunks, col_t* col) except -1: + col.chunks.n_chunks = n_chunks + col.chunks.chunks = calloc( + col.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. sizeof(ArrowArray)) - if col_out.chunks.chunks == NULL: + if col.chunks.chunks == NULL: raise MemoryError() @@ -708,44 +705,44 @@ cdef void _pandas_free_mapped_arrow(ArrowArray* arr): cdef void_int _pandas_series_as_pybuf( - TaggedEntry entry, col_t* col_out, str fallback_dtype=None) except -1: - cdef object nparr = entry.series.to_numpy(dtype=fallback_dtype) + PandasCol pandas_col, col_t* col, str fallback_dtype=None) except -1: + cdef object nparr = pandas_col.series.to_numpy(dtype=fallback_dtype) cdef ArrowArray* mapped cdef int get_buf_ret if not PyObject_CheckBuffer(nparr): raise TypeError( - f'Bad column {entry.name!r}: Expected a buffer, got ' + - f'{entry.series!r} ({_fqn(type(entry.series))})') + f'Bad column {pandas_col.name!r}: Expected a buffer, got ' + + f'{pandas_col.series!r} ({_fqn(type(pandas_col.series))})') try: # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. - get_buf_ret = PyObject_GetBuffer(nparr, &col_out.pybuf, PyBUF_SIMPLE) + get_buf_ret = PyObject_GetBuffer(nparr, &col.pybuf, PyBUF_SIMPLE) except BufferError as be: raise TypeError( - f'Bad column {entry.name!r}: Expected a buffer, got ' + - f'{entry.series!r} ({_fqn(type(entry.series))})') from be - _pandas_alloc_chunks(1, col_out) - mapped = &col_out.chunks.chunks[0] + f'Bad column {pandas_col.name!r}: Expected a buffer, got ' + + f'{pandas_col.series!r} ({_fqn(type(pandas_col.series))})') from be + _pandas_alloc_chunks(1, col) + mapped = &col.chunks.chunks[0] # Total number of elements. mapped.length = ( - col_out.pybuf.len // col_out.pybuf.itemsize) + col.pybuf.len // col.pybuf.itemsize) mapped.null_count = 0 mapped.offset = 0 mapped.n_buffers = 2 mapped.n_children = 0 mapped.buffers = calloc(2, sizeof(const void*)) mapped.buffers[0] = NULL - mapped.buffers[1] = col_out.pybuf.buf + mapped.buffers[1] = col.pybuf.buf mapped.children = NULL mapped.dictionary = NULL mapped.release = _pandas_free_mapped_arrow # to cleanup allocated array. cdef void_int _pandas_series_as_arrow( - TaggedEntry entry, - col_t* col_out, + PandasCol pandas_col, + col_t* col, col_source_t np_fallback, str fallback_dtype=None) except -1: cdef object array @@ -753,28 +750,28 @@ cdef void_int _pandas_series_as_arrow( cdef size_t n_chunks cdef size_t chunk_index if _PYARROW is None: - col_out.source = np_fallback - _pandas_series_as_pybuf(entry, col_out, fallback_dtype) + col.source = np_fallback + _pandas_series_as_pybuf(pandas_col, col, fallback_dtype) return 0 - array = _PYARROW.Array.from_pandas(entry.series) + array = _PYARROW.Array.from_pandas(pandas_col.series) if isinstance(array, _PYARROW.ChunkedArray): chunks = array.chunks else: chunks = [array] n_chunks = len(chunks) - _pandas_alloc_chunks(n_chunks, col_out) + _pandas_alloc_chunks(n_chunks, col) for chunk_index in range(n_chunks): array = chunks[chunk_index] if chunk_index == 0: chunks[chunk_index]._export_to_c( - &col_out.chunks.chunks[chunk_index], - &col_out.arrow_schema) + &col.chunks.chunks[chunk_index], + &col.arrow_schema) else: chunks[chunk_index]._export_to_c( - &col_out.chunks.chunks[chunk_index]) + &col.chunks.chunks[chunk_index]) cdef const char* _ARROW_FMT_INT8 = "c" @@ -784,31 +781,31 @@ cdef const char* _ARROW_FMT_SML_STR = "u" cdef void_int _pandas_category_series_as_arrow( - TaggedEntry entry, col_t* col_out) except -1: + PandasCol pandas_col, col_t* col) except -1: cdef const char* format - col_out.source = col_source_t.col_source_nulls # placeholder value. - _pandas_series_as_arrow(entry, col_out, col_source_t.col_source_str_pyobj) - if col_out.source == col_source_t.col_source_str_pyobj: + col.source = col_source_t.col_source_nulls # placeholder value. + _pandas_series_as_arrow(pandas_col, col, col_source_t.col_source_str_pyobj) + if col.source == col_source_t.col_source_str_pyobj: return 0 # PyArrow wasn't imported. - format = col_out.arrow_schema.format + format = col.arrow_schema.format if strncmp(format, _ARROW_FMT_INT8, 1) == 0: - col_out.source = col_source_t.col_source_str_i8_cat + col.source = col_source_t.col_source_str_i8_cat elif strncmp(format, _ARROW_FMT_INT16, 1) == 0: - col_out.source = col_source_t.col_source_str_i16_cat + col.source = col_source_t.col_source_str_i16_cat elif strncmp(format, _ARROW_FMT_INT32, 1) == 0: - col_out.source = col_source_t.col_source_str_i32_cat + col.source = col_source_t.col_source_str_i32_cat else: raise IngressError( IngressErrorCode.BadDataFrame, - f'Bad column {entry.name!r}: Expected an arrow category index ' + + f'Bad column {pandas_col.name!r}: Expected an arrow category index ' + f'format, got {(format).decode("utf-8")!r}.') - format = col_out.arrow_schema.dictionary.format + format = col.arrow_schema.dictionary.format if strncmp(format, _ARROW_FMT_SML_STR, 1) != 0: raise IngressError( IngressErrorCode.BadDataFrame, - f'Bad column {entry.name!r}: Expected a category of strings, ' + - f'got a category of {entry.series.dtype.categories.dtype!r}.') + f'Bad column {pandas_col.name!r}: Expected a category of strings, ' + + f'got a category of {pandas_col.series.dtype.categories.dtype!r}.') cdef inline bint _pandas_is_float_nan(PyObject* obj): @@ -823,231 +820,262 @@ cdef inline bint _pandas_is_null_pyobj(PyObject* obj): cdef void_int _pandas_series_sniff_pyobj( - TaggedEntry entry, col_t* col_out) except -1: + PandasCol pandas_col, col_t* col) except -1: """ Deduct the type of the object column. Object columns can contain pretty much anything, but they usually don't. We make an educated guess by finding the first non-null value in the column. """ cdef size_t el_index - cdef size_t n_elements = len(entry.series) + cdef size_t n_elements = len(pandas_col.series) cdef PyObject** obj_arr cdef PyObject* obj - _pandas_series_as_pybuf(entry, col_out) - obj_arr = (col_out.pybuf.buf) + _pandas_series_as_pybuf(pandas_col, col) + obj_arr = (col.pybuf.buf) for el_index in range(n_elements): obj = obj_arr[el_index] if not _pandas_is_null_pyobj(obj): if PyBool_Check(obj): - col_out.source = col_source_t.col_source_bool_pyobj + col.source = col_source_t.col_source_bool_pyobj elif PyLong_CheckExact(obj): - col_out.source = col_source_t.col_source_int_pyobj + col.source = col_source_t.col_source_int_pyobj elif PyFloat_CheckExact(obj): - col_out.source = col_source_t.col_source_float_pyobj + col.source = col_source_t.col_source_float_pyobj elif PyUnicode_CheckExact(obj): - col_out.source = col_source_t.col_source_str_pyobj + col.source = col_source_t.col_source_str_pyobj elif PyBytes_CheckExact(obj): raise IngressError( IngressErrorCode.BadDataFrame, - f'Bad column {entry.name!r}: ' + + f'Bad column {pandas_col.name!r}: ' + 'Unsupported object column containing bytes.' + 'If this is a string column, decode it first. ' + 'See: https://stackoverflow.com/questions/40389764/') else: raise IngressError( IngressErrorCode.BadDataFrame, - f'Bad column {entry.name!r}: ' + + f'Bad column {pandas_col.name!r}: ' + f'Unsupported object column containing an {_fqn(type(obj))}') return 0 # We haven't returned yet, so we've hit an object column that # exclusively has null values. We will just skip this column. - col_out.source = col_source_t.col_source_nulls + col.source = col_source_t.col_source_nulls cdef void_int _pandas_resolve_source_and_buffers( - TaggedEntry entry, col_t* col_out) except -1: - cdef object dtype = entry.dtype + PandasCol pandas_col, col_t* col) except -1: + cdef object dtype = pandas_col.dtype if isinstance(dtype, _NUMPY_BOOL): - col_out.source = col_source_t.col_source_bool_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_bool_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.BooleanDtype): - col_out.source = col_source_t.col_source_bool_arrow + col.source = col_source_t.col_source_bool_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_bool_pyobj) + pandas_col, col, col_source_t.col_source_bool_pyobj) elif isinstance(dtype, _NUMPY_UINT8): - col_out.source = col_source_t.col_source_u8_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_u8_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT8): - col_out.source = col_source_t.col_source_i8_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_i8_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT16): - col_out.source = col_source_t.col_source_u16_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_u16_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT16): - col_out.source = col_source_t.col_source_i16_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_i16_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT32): - col_out.source = col_source_t.col_source_u32_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_u32_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT32): - col_out.source = col_source_t.col_source_i32_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_i32_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT64): - col_out.source = col_source_t.col_source_u64_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_u64_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT64): - col_out.source = col_source_t.col_source_i64_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_i64_numpy + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt8Dtype): - col_out.source = col_source_t.col_source_u8_arrow + col.source = col_source_t.col_source_u8_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int8Dtype): - col_out.source = col_source_t.col_source_i8_arrow + col.source = col_source_t.col_source_i8_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt16Dtype): - col_out.source = col_source_t.col_source_u16_arrow + col.source = col_source_t.col_source_u16_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int16Dtype): - col_out.source = col_source_t.col_source_i16_arrow + col.source = col_source_t.col_source_i16_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt32Dtype): - col_out.source = col_source_t.col_source_u32_arrow + col.source = col_source_t.col_source_u32_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int32Dtype): - col_out.source = col_source_t.col_source_i32_arrow + col.source = col_source_t.col_source_i32_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.UInt64Dtype): - col_out.source = col_source_t.col_source_u64_arrow + col.source = col_source_t.col_source_u64_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _PANDAS.Int64Dtype): - col_out.source = col_source_t.col_source_i64_arrow + col.source = col_source_t.col_source_i64_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_int_pyobj) + pandas_col, col, col_source_t.col_source_int_pyobj) elif isinstance(dtype, _NUMPY_FLOAT32): - col_out.source = col_source_t.col_source_f32_numpy + col.source = col_source_t.col_source_f32_numpy _pandas_series_as_pybuf( - entry, col_out) + pandas_col, col) elif isinstance(dtype, _NUMPY_FLOAT64): - col_out.source = col_source_t.col_source_f64_numpy + col.source = col_source_t.col_source_f64_numpy _pandas_series_as_pybuf( - entry, col_out) + pandas_col, col) elif isinstance(dtype, _PANDAS.Float32Dtype): - col_out.source = col_source_t.col_source_f32_arrow + col.source = col_source_t.col_source_f32_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_float_pyobj) + pandas_col, col, col_source_t.col_source_float_pyobj) elif isinstance(dtype, _PANDAS.Float64Dtype): - col_out.source = col_source_t.col_source_f64_arrow + col.source = col_source_t.col_source_f64_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_float_pyobj) + pandas_col, col, col_source_t.col_source_float_pyobj) elif isinstance(dtype, _PANDAS.StringDtype): if dtype.storage == 'pyarrow': - col_out.source = col_source_t.col_source_str_arrow + col.source = col_source_t.col_source_str_arrow _pandas_series_as_arrow( - entry, col_out, col_source_t.col_source_str_pyobj) + pandas_col, col, col_source_t.col_source_str_pyobj) elif dtype.storage == 'python': - col_out.source = col_source_t.col_source_str_pyobj - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_str_pyobj + _pandas_series_as_pybuf(pandas_col, col) else: raise IngressError( IngressErrorCode.BadDataFrame, f'Unknown string dtype storage: f{dtype.storage} ' + - f'for column {entry.name} of dtype {dtype}.') + f'for column {pandas_col.name} of dtype {dtype}.') elif isinstance(dtype, _PANDAS.CategoricalDtype): - _pandas_category_series_as_arrow(entry, col_out) + _pandas_category_series_as_arrow(pandas_col, col) elif (isinstance(dtype, _NUMPY_DATETIME64_NS) and _pandas_is_supported_datetime(dtype)): - col_out.source = col_source_t.col_source_dt64ns_numpy - _pandas_series_as_pybuf(entry, col_out) + col.source = col_source_t.col_source_dt64ns_numpy + _pandas_series_as_pybuf(pandas_col, col) elif (isinstance(dtype, _PANDAS.DatetimeTZDtype) and _pandas_is_supported_datetime(dtype)): - col_out.source = col_source_t.col_source_dt64ns_tz_arrow + col.source = col_source_t.col_source_dt64ns_tz_arrow _pandas_series_as_arrow( - entry, - col_out, + pandas_col, + col, col_source_t.col_source_dt64ns_numpy, 'datetime64[ns]') elif isinstance(dtype, _NUMPY_OBJECT): - _pandas_series_sniff_pyobj(entry, col_out) + _pandas_series_sniff_pyobj(pandas_col, col) else: raise IngressError( IngressErrorCode.BadDataFrame, - f'Unsupported dtype {dtype} for column {entry.name}. ' + + f'Unsupported dtype {dtype} for column {pandas_col.name}. ' + 'Raise an issue if you think it should be supported: ' + 'https://github.com/questdb/py-questdb-client/issues.') cdef void_int _pandas_resolve_target( - TaggedEntry entry, col_t* col_out) except -1: + PandasCol pandas_col, col_t* col) except -1: cdef col_target_t target cdef set target_sources - if entry.meta_target in _DIRECT_META_TARGETS: - col_out.target = entry.meta_target + if col.meta_target in _DIRECT_META_TARGETS: + col.target = col.meta_target return 0 for target in _FIELD_TARGETS: target_sources = _TARGET_TO_SOURCES[target] - if col_out.source in target_sources: - col_out.target = target + if col.source in target_sources: + col.target = target return 0 raise IngressError( IngressErrorCode.BadDataFrame, - f'Could not map column source type (code {col_out.source} for ' + - f'column {entry.name} ({entry.dtype!r}) to any ILP type.') + f'Could not map column source type (code {col.source} for ' + + f'column {pandas_col.name!r} ' + + f' ({pandas_col.dtype!r}) to any ILP type.') -cdef void _pandas_init_cursor(col_t* col_out): - col_out.cursor.chunk = col_out.chunks.chunks - col_out.cursor.chunk_index = 0 - col_out.cursor.offset = col_out.cursor.chunk.offset +cdef void _pandas_init_cursor(col_t* col): + col.cursor.chunk = col.chunks.chunks + col.cursor.chunk_index = 0 + col.cursor.offset = col.cursor.chunk.offset cdef void_int _pandas_resolve_col( qdb_pystr_buf* b, size_t index, - TaggedEntry entry, - col_t* col_out) except -1: - col_out.orig_index = entry.orig_index - - # Since we don't need to send the column names for 'table' and 'at' columns, - # we don't need to validate and encode them as column names. - if ((entry.meta_target != meta_target_t.meta_target_table) and - (entry.meta_target != meta_target_t.meta_target_at)): - str_to_column_name_copy(b, entry.name, &col_out.name) - - _pandas_resolve_source_and_buffers(entry, col_out) - _pandas_resolve_target(entry, col_out) - if col_out.source not in _TARGET_TO_SOURCES[col_out.target]: - raise ValueError( - f'Bad value: Column {entry.name!r} ({entry.dtype}) is not ' + - f'supported as a {_TARGET_NAMES[col_out.target]} column.') - col_out.dispatch_code = ( - col_out.source + col_out.target) - _pandas_init_cursor(col_out) + PandasCol pandas_col, + col_t* col) except -1: + # The target is resolved in stages: + # * We first assign all columns to be fields. + # * Then, depending on argument parsing some/none of the columns + # obtain a meta-target of "table", "symbol" or "at". + # * Finally, based on the source, any remaining "meta_target_field" + # columns are converted to the appropriate target. + # See: _pandas_resolve_col_targets_and_dc(..). + col.meta_target = meta_target_t.meta_target_field + col.orig_index = index # We will sort columns later. + _pandas_resolve_source_and_buffers(pandas_col, col) + _pandas_init_cursor(col) cdef void_int _pandas_resolve_cols( - qdb_pystr_buf*b, - list tagged_cols, - col_t_arr* cols_out, + qdb_pystr_buf* b, + list pandas_cols, + col_t_arr* cols, bint* any_cols_need_gil_out) except -1: cdef size_t index - cdef size_t len_tagged_cols = len(tagged_cols) + cdef size_t len_pandas_cols = len(pandas_cols) cdef col_t* col any_cols_need_gil_out[0] = False - for index in range(len_tagged_cols): - col = &cols_out.d[index] - _pandas_resolve_col(b, index, tagged_cols[index], col) + for index in range(len_pandas_cols): + col = &cols.d[index] + _pandas_resolve_col(b, index, pandas_cols[index], col) if col_source_needs_gil(col.source): any_cols_need_gil_out[0] = True +cdef void_int _pandas_resolve_cols_target_name_and_dc( + qdb_pystr_buf* b, + list pandas_cols, + col_t_arr* cols) except -1: + cdef size_t index + cdef col_t* col + cdef PandasCol pandas_col + for index in range(cols.size): + col = &cols.d[index] + pandas_col = pandas_cols[index] + _pandas_resolve_target(pandas_col, col) + if col.source not in _TARGET_TO_SOURCES[col.target]: + raise ValueError( + f'Bad value: Column {pandas_col.name!r} ' + + f'({pandas_col.dtype!r}) is not ' + + f'supported as a {_TARGET_NAMES[col.target]} column.') + col.dispatch_code = ( + col.source + col.target) + + # Since we don't need to send the column names for 'table' and + # 'at' columns, we don't need to validate and encode them as + # column names. This allows unsupported names for these columns. + if ((col.meta_target != meta_target_t.meta_target_table) and + (col.meta_target != meta_target_t.meta_target_at)): + str_to_column_name_copy(b, pandas_col.name, &col.name) + + +cdef int _pandas_compare_cols(const void* lhs, const void* rhs) nogil: + cdef col_t* lhs_col = lhs + cdef col_t* rhs_col = rhs + cdef int source_diff = lhs_col.meta_target - rhs_col.meta_target + if source_diff != 0: + return source_diff + return lhs_col.orig_index - rhs_col.orig_index + + cdef void_int _pandas_resolve_args( object data, object table_name, @@ -1058,36 +1086,28 @@ cdef void_int _pandas_resolve_args( size_t col_count, line_sender_table_name* c_table_name_out, int64_t* at_value_out, - col_t_arr* cols_out, + col_t_arr* cols, bint* any_cols_need_gil_out) except -1: cdef ssize_t name_col cdef ssize_t at_col - # List of Lists with col index, col name, series object, sorting key. - cdef list tagged_cols = [ - TaggedEntry( - index, - name, - data.dtypes[index], - series, - meta_target_t.meta_target_field) # Later resolved to a target. + cdef list pandas_cols = [ + PandasCol(name, data.dtypes[index], series) for index, (name, series) in enumerate(data.items())] + _pandas_resolve_cols(b, pandas_cols, cols, any_cols_need_gil_out) name_col = _pandas_resolve_table_name( b, data, - tagged_cols, + cols, table_name, table_name_col, col_count, c_table_name_out) - at_col = _pandas_resolve_at(data, tagged_cols, at, col_count, at_value_out) + at_col = _pandas_resolve_at(data, cols, at, col_count, at_value_out) _pandas_resolve_symbols( - data, tagged_cols, name_col, at_col, symbols, col_count) - - # Sort with table name is first, then the symbols, then fields, then at. - # Note: Python 3.6+ guarantees stable sort. - tagged_cols.sort(key=lambda x: (x).meta_target) - _pandas_resolve_cols(b, tagged_cols, cols_out, any_cols_need_gil_out) + data, pandas_cols, cols, name_col, at_col, symbols) + _pandas_resolve_cols_target_name_and_dc(b, pandas_cols, cols) + qsort(cols.d, col_count, sizeof(col_t), _pandas_compare_cols) cdef void _ensure_has_gil(PyThreadState** gs): From f28903e0a72a2bd5d439b401ac0c09845f4ed34d Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 11:29:58 +0000 Subject: [PATCH 091/147] Updated c-questdb-client submodule: Latest perf improvements. --- c-questdb-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c-questdb-client b/c-questdb-client index f32af374..7135c912 160000 --- a/c-questdb-client +++ b/c-questdb-client @@ -1 +1 @@ -Subproject commit f32af3745f110cb3c57bf5ea60052e0a5ef10565 +Subproject commit 7135c9127bedb823a4af5780f0d248f9a1bd89a2 From 8b6652a5acb9e53cd961faeff116f620935fbe3c Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 11:30:41 +0000 Subject: [PATCH 092/147] Fixed broken build. --- src/questdb/{ingress_helper.h => ingress_helper.inc} | 2 +- src/questdb/ingress_helper.pxd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/questdb/{ingress_helper.h => ingress_helper.inc} (88%) diff --git a/src/questdb/ingress_helper.h b/src/questdb/ingress_helper.inc similarity index 88% rename from src/questdb/ingress_helper.h rename to src/questdb/ingress_helper.inc index 954dcdde..b726a913 100644 --- a/src/questdb/ingress_helper.h +++ b/src/questdb/ingress_helper.inc @@ -8,7 +8,7 @@ // so we can't check it for NULL. // Since `Py_buffer` is a Cython built-in we can't actually // just re-define it in `extra_cpython.pxd`. -inline int Py_buffer_obj_is_set(Py_buffer* buf) +static int Py_buffer_obj_is_set(Py_buffer* buf) { return buf->obj != NULL; } diff --git a/src/questdb/ingress_helper.pxd b/src/questdb/ingress_helper.pxd index f615fa69..9d3651d5 100644 --- a/src/questdb/ingress_helper.pxd +++ b/src/questdb/ingress_helper.pxd @@ -1,2 +1,2 @@ -cdef extern from "ingress_helper.h": +cdef extern from "ingress_helper.inc": bint Py_buffer_obj_is_set(Py_buffer* buf) \ No newline at end of file From cba2aaf906912841c608ec0c248773e36f107ba1 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 11:31:18 +0000 Subject: [PATCH 093/147] Single logic to infer object column types. --- src/questdb/pandas_integration.pxi | 134 +++++++++++++++-------------- test/test.py | 15 ++-- 2 files changed, 78 insertions(+), 71 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index dae5b159..9a9447a4 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -78,6 +78,23 @@ cdef bint col_source_needs_gil(col_source_t source): return source // 100 % 10 == 1 +cdef set _STR_SOURCES = { + col_source_t.col_source_str_pyobj, + col_source_t.col_source_str_arrow, + col_source_t.col_source_str_i8_cat, + col_source_t.col_source_str_i16_cat, + col_source_t.col_source_str_i32_cat, +} + + +cdef dict _PYOBJ_SOURCE_DESCR = { + col_source_t.col_source_bool_pyobj: "bool", + col_source_t.col_source_int_pyobj: "int", + col_source_t.col_source_float_pyobj: "float", + col_source_t.col_source_str_pyobj: "str", +} + + cdef dict _TARGET_TO_SOURCES = { col_target_t.col_target_skip: { col_source_t.col_source_nulls, @@ -425,6 +442,7 @@ cdef object _check_is_pandas_dataframe(object data): cdef ssize_t _pandas_resolve_table_name( qdb_pystr_buf* b, object data, + list pandas_cols, col_t_arr* cols, object table_name, object table_name_col, @@ -445,6 +463,7 @@ cdef ssize_t _pandas_resolve_table_name( This method validates input and may raise. """ cdef size_t col_index = 0 + cdef PandasCol pandas_col cdef col_t* col if table_name is not None: if table_name_col is not None: @@ -470,12 +489,12 @@ cdef ssize_t _pandas_resolve_table_name( raise TypeError( 'Bad argument `table_name_col`: ' + 'must be a column name (str) or index (int).') + pandas_col = pandas_cols[col_index] + col = &cols.d[col_index] _pandas_check_column_is_str( - data, - col_index, 'Bad argument `table_name_col`: ', - table_name_col) - col = &cols.d[col_index] + pandas_col, + col.source) col.meta_target = meta_target_t.meta_target_table name_out.len = 0 name_out.buf = NULL @@ -507,43 +526,19 @@ cdef void_int _bind_col_index( col_index[0] = col_num -cdef object _pandas_column_is_str(object data, int col_index): - """ - Return True if the column at `col_index` is a string column. - """ - # NB: Returning `object` rather than `bint` to allow for exceptions. - cdef str col_kind - cdef object col - col_kind = data.dtypes[col_index].kind - if col_kind == 'S': # string, string[pyarrow] - return True - elif col_kind == 'O': # object - if len(data.index) == 0: - return True - else: - # We only check the first element and hope for the rest. - # We also accept None as a null value. - col = data.iloc[0, col_index] - return (col is None) or isinstance(col, str) - else: - return False - - -cdef object _pandas_check_column_is_str( - object data, size_t col_index, str err_msg_prefix, object col_name): - cdef str col_kind - col_kind = data.dtypes[col_index].kind - if col_kind in 'SO': - if not _pandas_column_is_str(data, col_index): - raise TypeError( - err_msg_prefix + - 'Found non-string value ' + - f'in column {col_name!r}.') - else: - raise TypeError( +cdef void_int _pandas_check_column_is_str( + str err_msg_prefix, + PandasCol pandas_col, + col_source_t source) except -1: + cdef str inferred_descr = "" + if not source in _STR_SOURCES: + if isinstance(pandas_col.dtype, _NUMPY_OBJECT): + inferred_descr = f' (inferred type: {_PYOBJ_SOURCE_DESCR[source]})' + raise IngressError( + IngressErrorCode.BadDataFrame, err_msg_prefix + - f'Bad dtype `{data.dtypes[col_index]}` for the ' + - f'{col_name!r} column: Must be a strings column.') + f'Bad dtype `{pandas_col.dtype}`{inferred_descr} for the ' + + f'{pandas_col.name!r} column: Must be a strings column.') @cython.internal @@ -585,9 +580,9 @@ cdef void_int _pandas_resolve_symbols( pass elif symbols is True: for col_index in range(cols.size): - if _pandas_column_is_str(data, col_index): + col = &cols.d[col_index] + if col.source in _STR_SOURCES: pandas_col = pandas_cols[col_index] - col = &cols.d[col_index] if col.meta_target == meta_target_t.meta_target_field: col.meta_target = meta_target_t.meta_target_symbol else: @@ -612,12 +607,12 @@ cdef void_int _pandas_resolve_symbols( raise ValueError( f'Bad argument `symbols`: Cannot use the `at` column ' + f'({data.columns[at_col]!r}) as a symbol column.') - _pandas_check_column_is_str( - data, - col_index, - 'Bad element in argument `symbols`: ', - symbol) + pandas_col = pandas_cols[col_index] col = &cols.d[col_index] + _pandas_check_column_is_str( + 'Bad argument `symbols`: ', + pandas_col, + col.source) col.meta_target = meta_target_t.meta_target_symbol @@ -637,7 +632,19 @@ cdef void_int _pandas_get_loc( # The -1 value is safe to use as a sentinel because the TimestampNanos type # already validates that the value is >= 0. -cdef int64_t _AT_SET_BY_COLUMN = -1 +cdef int64_t _AT_IS_SET_BY_COLUMN = -1 + + +cdef str _SUPPORTED_DATETIMES = 'datetime64[ns] or datetime64[ns, tz]' + + +cdef object _pandas_is_supported_datetime(object dtype): + if (isinstance(dtype, _NUMPY_DATETIME64_NS) and + (str(dtype) == 'datetime64[ns]')): + return True + if isinstance(dtype, _PANDAS.DatetimeTZDtype): + return dtype.unit == 'ns' + return False cdef ssize_t _pandas_resolve_at( @@ -669,23 +676,14 @@ cdef ssize_t _pandas_resolve_at( 'int (column index), str (colum name)') dtype = data.dtypes[col_index] if _pandas_is_supported_datetime(dtype): - at_value_out[0] = _AT_SET_BY_COLUMN + at_value_out[0] = _AT_IS_SET_BY_COLUMN col = &cols.d[col_index] col.meta_target = meta_target_t.meta_target_at return col_index else: raise TypeError( f'Bad argument `at`: Bad dtype `{dtype}` ' + - f'for the {at!r} column: Must be a datetime64[ns] column.') - - -cdef object _pandas_is_supported_datetime(object dtype): - if (isinstance(dtype, _NUMPY_DATETIME64_NS) and - (str(dtype) == 'datetime64[ns]')): - return True - if isinstance(dtype, _PANDAS.DatetimeTZDtype): - return dtype.unit == 'ns' - return False + f'for the {at!r} column: Must be a {_SUPPORTED_DATETIMES} column.') cdef void_int _pandas_alloc_chunks( @@ -797,15 +795,17 @@ cdef void_int _pandas_category_series_as_arrow( else: raise IngressError( IngressErrorCode.BadDataFrame, - f'Bad column {pandas_col.name!r}: Expected an arrow category index ' + + f'Bad column {pandas_col.name!r}: ' + + 'Expected an arrow category index ' + f'format, got {(format).decode("utf-8")!r}.') format = col.arrow_schema.dictionary.format if strncmp(format, _ARROW_FMT_SML_STR, 1) != 0: raise IngressError( IngressErrorCode.BadDataFrame, - f'Bad column {pandas_col.name!r}: Expected a category of strings, ' + - f'got a category of {pandas_col.series.dtype.categories.dtype!r}.') + f'Bad column {pandas_col.name!r}: ' + + 'Expected a category of strings, ' + + f'got a category of {pandas_col.series.dtype.categories.dtype}.') cdef inline bint _pandas_is_float_nan(PyObject* obj): @@ -854,7 +854,8 @@ cdef void_int _pandas_series_sniff_pyobj( raise IngressError( IngressErrorCode.BadDataFrame, f'Bad column {pandas_col.name!r}: ' + - f'Unsupported object column containing an {_fqn(type(obj))}') + f'Unsupported object column containing an object of type ' + + _fqn(type(obj)) + '.') return 0 # We haven't returned yet, so we've hit an object column that @@ -997,7 +998,7 @@ cdef void_int _pandas_resolve_target( IngressErrorCode.BadDataFrame, f'Could not map column source type (code {col.source} for ' + f'column {pandas_col.name!r} ' + - f' ({pandas_col.dtype!r}) to any ILP type.') + f' ({pandas_col.dtype}) to any ILP type.') cdef void _pandas_init_cursor(col_t* col): @@ -1054,7 +1055,7 @@ cdef void_int _pandas_resolve_cols_target_name_and_dc( if col.source not in _TARGET_TO_SOURCES[col.target]: raise ValueError( f'Bad value: Column {pandas_col.name!r} ' + - f'({pandas_col.dtype!r}) is not ' + + f'({pandas_col.dtype}) is not ' + f'supported as a {_TARGET_NAMES[col.target]} column.') col.dispatch_code = ( col.source + col.target) @@ -1098,6 +1099,7 @@ cdef void_int _pandas_resolve_args( name_col = _pandas_resolve_table_name( b, data, + pandas_cols, cols, table_name, table_name_col, @@ -2096,7 +2098,7 @@ cdef void_int _pandas( bint sort) except -1: cdef size_t col_count cdef line_sender_table_name c_table_name - cdef int64_t at_value = _AT_SET_BY_COLUMN + cdef int64_t at_value = _AT_IS_SET_BY_COLUMN cdef col_t_arr cols = col_t_arr_blank() cdef bint any_cols_need_gil = False cdef qdb_pystr_pos str_buf_marker diff --git a/test/test.py b/test/test.py index 55b3a362..3f40872c 100755 --- a/test/test.py +++ b/test/test.py @@ -489,11 +489,14 @@ def test_invalid_column_dtype(self): _pandas(DF1, table_name_col=-5) def test_bad_str_obj_col(self): - with self.assertRaisesRegex(TypeError, 'Found non-string value'): + with self.assertRaisesRegex(TypeError, + "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): _pandas(DF1, table_name_col='D') - with self.assertRaisesRegex(TypeError, 'Found non-string value'): + with self.assertRaisesRegex(TypeError, + "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): _pandas(DF1, table_name_col=3) - with self.assertRaisesRegex(TypeError, 'Found non-string value'): + with self.assertRaisesRegex(TypeError, + "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): _pandas(DF1, table_name_col=-1) def test_bad_symbol(self): @@ -503,9 +506,11 @@ def test_bad_symbol(self): _pandas(DF1, table_name='tbl1', symbols={}) with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): _pandas(DF1, table_name='tbl1', symbols=None) - with self.assertRaisesRegex(TypeError, '.*element.*symbols.*float.*0'): + with self.assertRaisesRegex(TypeError, + "`symbols`: Bad dtype `float64`.*'A'.*Must.*strings col"): _pandas(DF1, table_name='tbl1', symbols=(0,)) - with self.assertRaisesRegex(TypeError, '.*element.*symbols.*int.*1'): + with self.assertRaisesRegex(TypeError, + "`symbols`: Bad dtype `int64`.*'B'.*Must be a strings column."): _pandas(DF1, table_name='tbl1', symbols=[1]) def test_bad_at(self): From e07bb421c105b88a4ba5ad5d47792d5a85dafda2 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 12:01:48 +0000 Subject: [PATCH 094/147] Tests fixup. --- test/benchmark.py | 2 +- test/test.py | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/test/benchmark.py b/test/benchmark.py index 246e50a2..d9eff5d4 100644 --- a/test/benchmark.py +++ b/test/benchmark.py @@ -13,7 +13,7 @@ import questdb.ingress as qi -class TestBencharkPandas(unittest.TestCase): +class TestBenchmarkPandas(unittest.TestCase): def test_pystr_i64_10m(self): # This is a benchmark, not a test. # It is useful to run it manually to check performance. diff --git a/test/test.py b/test/test.py index 3f40872c..98cc8d1b 100755 --- a/test/test.py +++ b/test/test.py @@ -479,23 +479,26 @@ def test_invalid_table_name(self): _pandas(DF1, table_name='.') def test_invalid_column_dtype(self): - with self.assertRaisesRegex(TypeError, '`table_name_col`: Bad dtype'): + with self.assertRaisesRegex(qi.IngressError, + '`table_name_col`: Bad dtype'): _pandas(DF1, table_name_col='B') - with self.assertRaisesRegex(TypeError, '`table_name_col`: Bad dtype'): + with self.assertRaisesRegex(qi.IngressError, + '`table_name_col`: Bad dtype'): _pandas(DF1, table_name_col=1) - with self.assertRaisesRegex(TypeError, '`table_name_col`: Bad dtype'): + with self.assertRaisesRegex(qi.IngressError, + '`table_name_col`: Bad dtype'): _pandas(DF1, table_name_col=-3) with self.assertRaisesRegex(IndexError, '`table_name_col`: -5 index'): _pandas(DF1, table_name_col=-5) def test_bad_str_obj_col(self): - with self.assertRaisesRegex(TypeError, + with self.assertRaisesRegex(qi.IngressError, "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): _pandas(DF1, table_name_col='D') - with self.assertRaisesRegex(TypeError, + with self.assertRaisesRegex(qi.IngressError, "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): _pandas(DF1, table_name_col=3) - with self.assertRaisesRegex(TypeError, + with self.assertRaisesRegex(qi.IngressError, "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): _pandas(DF1, table_name_col=-1) @@ -506,10 +509,10 @@ def test_bad_symbol(self): _pandas(DF1, table_name='tbl1', symbols={}) with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): _pandas(DF1, table_name='tbl1', symbols=None) - with self.assertRaisesRegex(TypeError, + with self.assertRaisesRegex(qi.IngressError, "`symbols`: Bad dtype `float64`.*'A'.*Must.*strings col"): _pandas(DF1, table_name='tbl1', symbols=(0,)) - with self.assertRaisesRegex(TypeError, + with self.assertRaisesRegex(qi.IngressError, "`symbols`: Bad dtype `int64`.*'B'.*Must be a strings column."): _pandas(DF1, table_name='tbl1', symbols=[1]) From bd4bca6cc40dc78ce8ee988552b4a57c87c01c44 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 13:19:41 +0000 Subject: [PATCH 095/147] More tests. --- .vscode/settings.json | 5 +++- test/test.py | 70 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 0963694b..c710dcde 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { "esbonio.sphinx.confDir": "", - "cmake.configureOnOpen": false + "cmake.configureOnOpen": false, + "files.associations": { + "ingress_helper.h": "c" + } } \ No newline at end of file diff --git a/test/test.py b/test/test.py index 98cc8d1b..77c74483 100755 --- a/test/test.py +++ b/test/test.py @@ -1052,11 +1052,18 @@ def test_datetime64_numpy_col(self): 'tbl1 a=1546300804000000t\n' + 'tbl1 a=1546300805000000t\n') - # TODO: Test 0-epoch. + df = pd.DataFrame({'a': pd.Series([ + pd.Timestamp('1970-01-01 00:00:00'), + pd.Timestamp('1970-01-01 00:00:01'), + pd.Timestamp('1970-01-01 00:00:02')])}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=0t\n' + + 'tbl1 a=1000000t\n' + + 'tbl1 a=2000000t\n') def test_datetime64_tz_arrow_col(self): - # Currently broken, find `TODO: datetime[ns]+tz`. - # We're just casting `PyObject*`` to `int64_t` at the moment. tz = zoneinfo.ZoneInfo('America/New_York') df = pd.DataFrame({ 'a': [ @@ -1080,7 +1087,46 @@ def test_datetime64_tz_arrow_col(self): 'tbl1,b=sym3\n' + 'tbl1,b=sym4 a=1546318803000000t\n') - # TODO: Test 0-epoch. + # Not epoch 0. + df = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1970, month=1, day=1, + hour=0, minute=0, second=0, tz=tz), + pd.Timestamp( + year=1970, month=1, day=1, + hour=0, minute=0, second=1, tz=tz), + pd.Timestamp( + year=1970, month=1, day=1, + hour=0, minute=0, second=2, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3']}) + buf = _pandas(df, table_name='tbl1', symbols=['b']) + self.assertEqual( + buf, + # Note how these are 5hr offset from `test_datetime64_numpy_col`. + 'tbl1,b=sym1 a=18000000000t\n' + + 'tbl1,b=sym2 a=18001000000t\n' + + 'tbl1,b=sym3 a=18002000000t\n') + + # Actual epoch 0. + df = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1969, month=12, day=31, + hour=19, minute=0, second=0, tz=tz), + pd.Timestamp( + year=1969, month=12, day=31, + hour=19, minute=0, second=1, tz=tz), + pd.Timestamp( + year=1969, month=12, day=31, + hour=19, minute=0, second=2, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3']}) + buf = _pandas(df, table_name='tbl1', symbols=['b']) + self.assertEqual( + buf, + 'tbl1,b=sym1 a=0t\n' + + 'tbl1,b=sym2 a=1000000t\n' + + 'tbl1,b=sym3 a=2000000t\n') df2 = pd.DataFrame({ 'a': [ @@ -1113,11 +1159,21 @@ def test_datetime64_numpy_at(self): 'tbl1 b=5i 1546300804000000000\n' + 'tbl1 b=6i 1546300805000000000\n') - # TODO: Test 0-epoch. + df = pd.DataFrame({ + 'a': pd.Series([ + pd.Timestamp('1970-01-01 00:00:00'), + pd.Timestamp('1970-01-01 00:00:01'), + pd.Timestamp('1970-01-01 00:00:02')], + dtype='datetime64[ns]'), + 'b': [1, 2, 3]}) + buf = _pandas(df, table_name='tbl1', at='a') + self.assertEqual( + buf, + 'tbl1 b=1i\n' + # Special case for "at_now". + 'tbl1 b=2i 1000000000\n' + + 'tbl1 b=3i 2000000000\n') def test_datetime64_tz_arrow_at(self): - # Currently broken, find `TODO: datetime[ns]+tz`. - # We're just casting `PyObject*`` to `int64_t` at the moment. tz = zoneinfo.ZoneInfo('America/New_York') df = pd.DataFrame({ 'a': [ From 7c734b56d95b40114d3073b20cc69a7c66df2f02 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 18:23:54 +0000 Subject: [PATCH 096/147] Fixed a bug passing None in datetime columns. --- src/questdb/ingress.pyx | 2 +- src/questdb/pandas_integration.pxi | 24 ++++++------- test/test.py | 58 +++++++++++++++++++----------- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 9e5f0209..d3483b2f 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -32,7 +32,7 @@ API for fast data ingestion into QuestDB. # For prototypes: https://github.com/cython/cython/tree/master/Cython/Includes from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t, \ - INT64_MAX + INT64_MAX, INT64_MIN from libc.stdlib cimport malloc, calloc, realloc, free, abort, qsort from libc.string cimport strncmp, memset from libc.math cimport isnan diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 9a9447a4..2c742e31 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -378,6 +378,8 @@ cdef object _PANDAS = None # module object cdef object _PANDAS_NA = None # pandas.NA cdef object _PYARROW = None # module object, if available or None +cdef int64_t _NAT = INT64_MIN # pandas NaT + cdef object _pandas_may_import_deps(): """" @@ -1125,6 +1127,7 @@ cdef inline bint _pandas_arrow_get_bool(col_cursor_t* cursor): cdef inline bint _pandas_arrow_is_valid(col_cursor_t* cursor): + """Check if the value is set according to the validity bitmap.""" return ( cursor.chunk.null_count == 0 or ( @@ -1877,10 +1880,11 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] - cell //= 1000 # Convert from nanoseconds to microseconds. - if not line_sender_buffer_column_ts(impl, col.name, cell, &err): - _ensure_has_gil(gs) - raise c_err_to_py(err) + if cell != _NAT: + cell //= 1000 # Convert from nanoseconds to microseconds. + if not line_sender_buffer_column_ts(impl, col.name, cell, &err): + _ensure_has_gil(gs) + raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( @@ -1909,7 +1913,7 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] - if cell == 0: + if cell == _NAT: if not line_sender_buffer_at_now(impl, &err): _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1932,16 +1936,12 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( if valid: access = col.cursor.chunk.buffers[1] cell = access[col.cursor.offset] - else: - cell = 0 - - if cell == 0: - if not line_sender_buffer_at_now(impl, &err): + # Note: impl will validate against negative numbers. + if not line_sender_buffer_at(impl, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: - # Note: impl will validate against negative numbers. - if not line_sender_buffer_at(impl, cell, &err): + if not line_sender_buffer_at_now(impl, &err): _ensure_has_gil(gs) raise c_err_to_py(err) diff --git a/test/test.py b/test/test.py index 77c74483..8070224c 100755 --- a/test/test.py +++ b/test/test.py @@ -1034,23 +1034,31 @@ def test_bool_obj_col(self): _pandas(df3, table_name='tbl1') def test_datetime64_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - pd.Timestamp('2019-01-01 00:00:00'), - pd.Timestamp('2019-01-01 00:00:01'), - pd.Timestamp('2019-01-01 00:00:02'), - pd.Timestamp('2019-01-01 00:00:03'), - pd.Timestamp('2019-01-01 00:00:04'), - pd.Timestamp('2019-01-01 00:00:05')], - dtype='datetime64[ns]')}) + df = pd.DataFrame({ + 'a': pd.Series([ + pd.Timestamp('2019-01-01 00:00:00'), + pd.Timestamp('2019-01-01 00:00:01'), + pd.Timestamp('2019-01-01 00:00:02'), + pd.Timestamp('2019-01-01 00:00:03'), + pd.Timestamp('2019-01-01 00:00:04'), + pd.Timestamp('2019-01-01 00:00:05'), + None, + float('nan'), + pd.NA], + dtype='datetime64[ns]'), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) buf = _pandas(df, table_name='tbl1') self.assertEqual( buf, - 'tbl1 a=1546300800000000t\n' + - 'tbl1 a=1546300801000000t\n' + - 'tbl1 a=1546300802000000t\n' + - 'tbl1 a=1546300803000000t\n' + - 'tbl1 a=1546300804000000t\n' + - 'tbl1 a=1546300805000000t\n') + 'tbl1 a=1546300800000000t,b="a"\n' + + 'tbl1 a=1546300801000000t,b="b"\n' + + 'tbl1 a=1546300802000000t,b="c"\n' + + 'tbl1 a=1546300803000000t,b="d"\n' + + 'tbl1 a=1546300804000000t,b="e"\n' + + 'tbl1 a=1546300805000000t,b="f"\n' + + 'tbl1 b="g"\n' + + 'tbl1 b="h"\n' + + 'tbl1 b="i"\n') df = pd.DataFrame({'a': pd.Series([ pd.Timestamp('1970-01-01 00:00:00'), @@ -1146,9 +1154,12 @@ def test_datetime64_numpy_at(self): pd.Timestamp('2019-01-01 00:00:02'), pd.Timestamp('2019-01-01 00:00:03'), pd.Timestamp('2019-01-01 00:00:04'), - pd.Timestamp('2019-01-01 00:00:05')], + pd.Timestamp('2019-01-01 00:00:05'), + float('nan'), + None, + pd.NaT], dtype='datetime64[ns]'), - 'b': [1, 2, 3, 4, 5, 6]}) + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) buf = _pandas(df, table_name='tbl1', at='a') self.assertEqual( buf, @@ -1157,7 +1168,10 @@ def test_datetime64_numpy_at(self): 'tbl1 b=3i 1546300802000000000\n' + 'tbl1 b=4i 1546300803000000000\n' + 'tbl1 b=5i 1546300804000000000\n' + - 'tbl1 b=6i 1546300805000000000\n') + 'tbl1 b=6i 1546300805000000000\n' + + 'tbl1 b=7i\n' + + 'tbl1 b=8i\n' + + 'tbl1 b=9i\n') df = pd.DataFrame({ 'a': pd.Series([ @@ -1169,7 +1183,7 @@ def test_datetime64_numpy_at(self): buf = _pandas(df, table_name='tbl1', at='a') self.assertEqual( buf, - 'tbl1 b=1i\n' + # Special case for "at_now". + 'tbl1 b=1i 0\n' + 'tbl1 b=2i 1000000000\n' + 'tbl1 b=3i 2000000000\n') @@ -1481,7 +1495,8 @@ def test_pyobj_int_col(self): self.assertEqual( _pandas( pd.DataFrame({ - 'a': pd.Series([1, 2, 3, None, float('nan'), pd.NA, 7], dtype='object'), + 'a': pd.Series([ + 1, 2, 3, None, float('nan'), pd.NA, 7], dtype='object'), 'b': [1, 2, 3, 4, 5, 6, 7]}), table_name='tbl1'), 'tbl1 a=1i,b=1i\n' + @@ -1504,7 +1519,9 @@ def test_pyobj_float_col(self): self.assertEqual( _pandas( pd.DataFrame({ - 'a': pd.Series([1.0, 2.0, 3.0, None, float('nan'), pd.NA, 7.0], dtype='object'), + 'a': pd.Series( + [1.0, 2.0, 3.0, None, float('nan'), pd.NA, 7.0], + dtype='object'), 'b': [1, 2, 3, 4, 5, 6, 7]}), table_name='tbl1'), 'tbl1 a=1.0,b=1i\n' + @@ -1649,7 +1666,6 @@ def test_all_nulls_pyobj_col(self): 'tbl1 b=3i\n') -# TODO: Test datetime64[ns] and datetime64[ns, tz] columns fully, including None values for `at` and `column_ts`. # TODO: Test all datatypes, but no rows. # TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. # TODO: Test all datatypes, but multiple row chunks. From 480343dcd4a74955a99c4328e07142465a896121 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 18:34:35 +0000 Subject: [PATCH 097/147] Tests for degenerate pandas dataframes. --- src/questdb/pandas_integration.pxi | 12 +++++++----- test/test.py | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 2c742e31..d66fb2f9 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -434,7 +434,7 @@ cdef object _pandas_may_import_deps(): _PYARROW = None -cdef object _check_is_pandas_dataframe(object data): +cdef object _pandas_check_is_dataframe(object data): if not isinstance(data, _PANDAS.DataFrame): raise TypeError( f'Bad argument `data`: Expected {_fqn(_PANDAS.DataFrame)}, ' + @@ -2112,10 +2112,14 @@ cdef void_int _pandas( cdef bint was_serializing_cell = False _pandas_may_import_deps() + _pandas_check_is_dataframe(data) + row_count = len(data) + col_count = len(data.columns) + if (col_count == 0) or (row_count == 0): + return 0 # Nothing to do. + try: qdb_pystr_buf_clear(b) - _check_is_pandas_dataframe(data) - col_count = len(data.columns) cols = col_t_arr_new(col_count) _pandas_resolve_args( data, @@ -2134,8 +2138,6 @@ cdef void_int _pandas( # Instead of clearing it (which would clear the headers' memory) # we will truncate (rewind) back to this position. str_buf_marker = qdb_pystr_buf_tell(b) - - row_count = len(data) line_sender_buffer_clear_marker(impl) # On error, undo all added lines. diff --git a/test/test.py b/test/test.py index 8070224c..05e23e15 100755 --- a/test/test.py +++ b/test/test.py @@ -525,6 +525,20 @@ def test_bad_at(self): _pandas(DF1, table_name='tbl1', at=1) with self.assertRaisesRegex(TypeError, '`at`.*object.*be a datetime'): _pandas(DF1, table_name='tbl1', at=-1) + + def test_empty_dataframe(self): + buf = _pandas(pd.DataFrame(), table_name='tbl1') + self.assertEqual(buf, '') + + def test_zero_row_dataframe(self): + buf = _pandas(pd.DataFrame(columns=['A', 'B']), table_name='tbl1') + self.assertEqual(buf, '') + + def test_zero_column_dataframe(self): + df = pd.DataFrame(index=[0, 1, 2]) + self.assertEqual(len(df), 3) + buf = _pandas(df, table_name='tbl1') + self.assertEqual(buf, '') def test_basic(self): buf = _pandas( @@ -1666,7 +1680,6 @@ def test_all_nulls_pyobj_col(self): 'tbl1 b=3i\n') -# TODO: Test all datatypes, but no rows. # TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. # TODO: Test all datatypes, but multiple row chunks. From b1f2ebf9d959a0f0e7b0797a5b533f3986cab4d6 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 2 Dec 2022 21:06:46 +0000 Subject: [PATCH 098/147] Informative message for row of nulls. --- src/questdb/pandas_integration.pxi | 9 +++++++++ test/test.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index d66fb2f9..76f1ba65 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -2202,6 +2202,15 @@ cdef void_int _pandas( f' at row index {row_index} (' + repr(data.iloc[row_index, col.orig_index]) + f'): {e} [dc={col.dispatch_code}]') from e + elif (isinstance(e, IngressError) and + (e.code == IngressErrorCode.InvalidApiCall)): + # TODO: This should be allowed by the database. + # It currently isn't so we have to raise an error. + raise IngressError( + IngressErrorCode.BadDataFrame, + f'Bad pandas row at index {row_index}: ' + + 'All values are nulls. '+ + 'Ensure at least one column is not null.') from e else: raise finally: diff --git a/test/test.py b/test/test.py index 05e23e15..0b473188 100755 --- a/test/test.py +++ b/test/test.py @@ -555,7 +555,7 @@ def test_basic(self): def test_row_of_nulls(self): df = pd.DataFrame({'a': ['a1', None, 'a3']}) with self.assertRaisesRegex( - qi.IngressError, 'State error: Bad call to `at`'): + qi.IngressError, 'Bad pandas row .*1: All values are nulls.'): _pandas(df, table_name='tbl1', symbols=['a']) def test_u8_numpy_col(self): From 98110074c6374663a69f58288661389557157aca Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Sat, 3 Dec 2022 15:49:12 +0000 Subject: [PATCH 099/147] Mandating pyarrow dependency for pandas functionality. --- ci/cibuildwheel.yaml | 7 +++ ci/run_tests_pipeline.yaml | 1 + src/questdb/pandas_integration.pxi | 83 +++++++++++------------------- 3 files changed, 37 insertions(+), 54 deletions(-) diff --git a/ci/cibuildwheel.yaml b/ci/cibuildwheel.yaml index f9662e0f..b8c8c460 100644 --- a/ci/cibuildwheel.yaml +++ b/ci/cibuildwheel.yaml @@ -71,6 +71,7 @@ stages: python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -88,6 +89,7 @@ stages: python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -107,6 +109,7 @@ stages: python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -126,6 +129,7 @@ stages: python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -145,6 +149,7 @@ stages: python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -164,6 +169,7 @@ stages: python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -181,6 +187,7 @@ stages: python3 -m pip install cibuildwheel==2.11.2 python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels diff --git a/ci/run_tests_pipeline.yaml b/ci/run_tests_pipeline.yaml index 1d2145b8..5f703bd8 100644 --- a/ci/run_tests_pipeline.yaml +++ b/ci/run_tests_pipeline.yaml @@ -32,6 +32,7 @@ stages: python3 -m pip install cython python3 -m pip install numpy python3 -m pip install pandas + python3 -m pip install pyarrow displayName: Installing Python dependencies - script: python3 proj.py build displayName: "Build" diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 76f1ba65..b463b38b 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -409,7 +409,15 @@ cdef object _pandas_may_import_deps(): global _NUMPY_OBJECT if _NUMPY is not None: return - import numpy + try: + import pandas + import numpy + import pyarrow + except ImportError as ie: + raise ImportError( + 'Missing dependencies: pandas, numpy and pyarrow must all be '+ + 'installed to use the `.pandas()` method. ' + + 'Run: `python3 -m pip install -U pandas numpy pyarrow`.') from ie _NUMPY = numpy _NUMPY_BOOL = type(_NUMPY.dtype('bool')) _NUMPY_UINT8 = type(_NUMPY.dtype('uint8')) @@ -424,14 +432,9 @@ cdef object _pandas_may_import_deps(): _NUMPY_FLOAT64 = type(_NUMPY.dtype('float64')) _NUMPY_DATETIME64_NS = type(_NUMPY.dtype('datetime64[ns]')) _NUMPY_OBJECT = type(_NUMPY.dtype('object')) - import pandas _PANDAS = pandas _PANDAS_NA = pandas.NA - try: - import pyarrow - _PYARROW = pyarrow - except ImportError: - _PYARROW = None + _PYARROW = pyarrow cdef object _pandas_check_is_dataframe(object data): @@ -742,18 +745,11 @@ cdef void_int _pandas_series_as_pybuf( cdef void_int _pandas_series_as_arrow( PandasCol pandas_col, - col_t* col, - col_source_t np_fallback, - str fallback_dtype=None) except -1: + col_t* col) except -1: cdef object array cdef list chunks cdef size_t n_chunks cdef size_t chunk_index - if _PYARROW is None: - col.source = np_fallback - _pandas_series_as_pybuf(pandas_col, col, fallback_dtype) - return 0 - array = _PYARROW.Array.from_pandas(pandas_col.series) if isinstance(array, _PYARROW.ChunkedArray): chunks = array.chunks @@ -783,10 +779,7 @@ cdef const char* _ARROW_FMT_SML_STR = "u" cdef void_int _pandas_category_series_as_arrow( PandasCol pandas_col, col_t* col) except -1: cdef const char* format - col.source = col_source_t.col_source_nulls # placeholder value. - _pandas_series_as_arrow(pandas_col, col, col_source_t.col_source_str_pyobj) - if col.source == col_source_t.col_source_str_pyobj: - return 0 # PyArrow wasn't imported. + _pandas_series_as_arrow(pandas_col, col) format = col.arrow_schema.format if strncmp(format, _ARROW_FMT_INT8, 1) == 0: col.source = col_source_t.col_source_str_i8_cat @@ -798,8 +791,8 @@ cdef void_int _pandas_category_series_as_arrow( raise IngressError( IngressErrorCode.BadDataFrame, f'Bad column {pandas_col.name!r}: ' + - 'Expected an arrow category index ' + - f'format, got {(format).decode("utf-8")!r}.') + 'Unsupported arrow category index type. ' + + f'Got {(format).decode("utf-8")!r}.') format = col.arrow_schema.dictionary.format if strncmp(format, _ARROW_FMT_SML_STR, 1) != 0: @@ -873,8 +866,7 @@ cdef void_int _pandas_resolve_source_and_buffers( _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.BooleanDtype): col.source = col_source_t.col_source_bool_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_bool_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT8): col.source = col_source_t.col_source_u8_numpy _pandas_series_as_pybuf(pandas_col, col) @@ -901,57 +893,44 @@ cdef void_int _pandas_resolve_source_and_buffers( _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt8Dtype): col.source = col_source_t.col_source_u8_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int8Dtype): col.source = col_source_t.col_source_i8_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt16Dtype): col.source = col_source_t.col_source_u16_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int16Dtype): col.source = col_source_t.col_source_i16_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt32Dtype): col.source = col_source_t.col_source_u32_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int32Dtype): col.source = col_source_t.col_source_i32_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt64Dtype): col.source = col_source_t.col_source_u64_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int64Dtype): col.source = col_source_t.col_source_i64_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_int_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_FLOAT32): col.source = col_source_t.col_source_f32_numpy - _pandas_series_as_pybuf( - pandas_col, col) + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_FLOAT64): col.source = col_source_t.col_source_f64_numpy - _pandas_series_as_pybuf( - pandas_col, col) + _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.Float32Dtype): col.source = col_source_t.col_source_f32_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_float_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Float64Dtype): col.source = col_source_t.col_source_f64_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_float_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.StringDtype): if dtype.storage == 'pyarrow': col.source = col_source_t.col_source_str_arrow - _pandas_series_as_arrow( - pandas_col, col, col_source_t.col_source_str_pyobj) + _pandas_series_as_arrow(pandas_col, col) elif dtype.storage == 'python': col.source = col_source_t.col_source_str_pyobj _pandas_series_as_pybuf(pandas_col, col) @@ -969,11 +948,7 @@ cdef void_int _pandas_resolve_source_and_buffers( elif (isinstance(dtype, _PANDAS.DatetimeTZDtype) and _pandas_is_supported_datetime(dtype)): col.source = col_source_t.col_source_dt64ns_tz_arrow - _pandas_series_as_arrow( - pandas_col, - col, - col_source_t.col_source_dt64ns_numpy, - 'datetime64[ns]') + _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_OBJECT): _pandas_series_sniff_pyobj(pandas_col, col) else: From c03c4ed43fefd1bb83fd8aa59e88ff0e17e9219c Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 5 Dec 2022 17:40:10 +0000 Subject: [PATCH 100/147] There's a chance this will fix CI. --- ci/cibuildwheel.yaml | 21 - ci/pip_install_deps.py | 65 ++ ci/run_tests_pipeline.yaml | 4 +- pyproject.toml | 5 +- src/questdb/pandas_integration.pxi | 7 +- test/test.py | 1275 +-------------------------- test/test_pandas.py | 1278 ++++++++++++++++++++++++++++ 7 files changed, 1367 insertions(+), 1288 deletions(-) create mode 100644 ci/pip_install_deps.py create mode 100644 test/test_pandas.py diff --git a/ci/cibuildwheel.yaml b/ci/cibuildwheel.yaml index b8c8c460..d6fa6c32 100644 --- a/ci/cibuildwheel.yaml +++ b/ci/cibuildwheel.yaml @@ -69,9 +69,6 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.2 - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -87,9 +84,6 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.2 - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -107,9 +101,6 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.2 - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -127,9 +118,6 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.2 - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -147,9 +135,6 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.2 - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -167,9 +152,6 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.2 - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels @@ -185,9 +167,6 @@ stages: set -o errexit python3 -m pip install --upgrade pip python3 -m pip install cibuildwheel==2.11.2 - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow displayName: Install dependencies - bash: cibuildwheel --output-dir wheelhouse . displayName: Build wheels diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py new file mode 100644 index 00000000..5a44c2de --- /dev/null +++ b/ci/pip_install_deps.py @@ -0,0 +1,65 @@ +import sys +import subprocess +import shlex +import textwrap +import platform + + +class UnsupportedDependency(Exception): + pass + + +def pip_install(package): + args = [ + sys.executable, + '-m', 'pip', 'install', + '--upgrade', + '--only-binary', ':all:', + package] + args_s = ' '.join(shlex.quote(arg) for arg in args) + sys.stderr.write(args_s + '\n') + res = subprocess.run( + args, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE) + if res.returncode == 0: + return + output = res.stdout.decode('utf-8') + if 'Could not find a version that satisfies the requirement' in output: + raise UnsupportedDependency(output) + else: + sys.stderr.write(output + '\n') + sys.exit(res.returncode) + + +def try_pip_install(package): + try: + pip_install(package) + except UnsupportedDependency as e: + msg = textwrap.indent(str(e), ' ' * 8) + sys.stderr.write(f' Ignored unsatisfiable dependency:\n{msg}\n') + + +def ensure_zoneinfo(): + try: + import zoneinfo + except ImportError: + pip_install('backports.zoneinfo[tzdata]') + from backports import zoneinfo + + +def main(): + ensure_zoneinfo() + try_pip_install('pandas') + try_pip_install('numpy') + try_pip_install('pyarrow') + + if platform.python_implementation() == 'CPython': + # We import the dependency we expect to have correctly installed. + import pandas + import numpy + import pyarrow + + +if __name__ == "__main__": + main() diff --git a/ci/run_tests_pipeline.yaml b/ci/run_tests_pipeline.yaml index 5f703bd8..65d0c4b9 100644 --- a/ci/run_tests_pipeline.yaml +++ b/ci/run_tests_pipeline.yaml @@ -30,9 +30,7 @@ stages: - script: python3 --version - script: | python3 -m pip install cython - python3 -m pip install numpy - python3 -m pip install pandas - python3 -m pip install pyarrow + python3 ci/pip_install_deps.py displayName: Installing Python dependencies - script: python3 proj.py build displayName: "Build" diff --git a/pyproject.toml b/pyproject.toml index 1903d979..c7cb32e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,10 +51,7 @@ requires = [ # See: https://cibuildwheel.readthedocs.io/en/stable/options/#configuration-file build-verbosity = "3" before-build = "python {project}/install_rust.py" -before-test = """ - python -m pip install numpy>=1.21.6 - python -m pip install pandas>=1.3.5 - """ +before-test = "python {project}/ci/pip_install_deps.py" test-command = "python {project}/test/test.py -v" skip = [ # No 32-bit musl C native tool chain for Rust. diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index b463b38b..2ea6104d 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -415,9 +415,10 @@ cdef object _pandas_may_import_deps(): import pyarrow except ImportError as ie: raise ImportError( - 'Missing dependencies: pandas, numpy and pyarrow must all be '+ - 'installed to use the `.pandas()` method. ' + - 'Run: `python3 -m pip install -U pandas numpy pyarrow`.') from ie + 'Missing dependencies: `pandas`, `numpy` and `pyarrow` must all ' + + 'be installed to use the `.pandas()` method. ' + + 'See: https://py-questdb-client.readthedocs.io/' + + 'en/latest/installation.html.') from ie _NUMPY = numpy _NUMPY_BOOL = type(_NUMPY.dtype('bool')) _NUMPY_UINT8 = type(_NUMPY.dtype('uint8')) diff --git a/test/test.py b/test/test.py index 0b473188..93a04c93 100755 --- a/test/test.py +++ b/test/test.py @@ -6,9 +6,6 @@ import unittest import datetime import time -import numpy as np -import pandas as pd -import zoneinfo import patch_path from mock_server import Server @@ -18,6 +15,24 @@ if os.environ.get('TEST_QUESTDB_INTEGRATION') == '1': from system_test import TestWithDatabase +try: + import pandas as pa + import numpy as np + import pyarrow as pa +except ImportError: + pa = None + + +if pa is not None: + from test_pandas import TestPandas +else: + class TestNoPandas(unittest.TestCase): + def test_no_pandas(self): + buf = qi.Buffer() + exp = 'Missing.*`pandas.*pyarrow`.*readthedocs.*installation.html.' + with self.assertRaisesRegex(ImportError, exp): + buf.pandas(None) + class TestBuffer(unittest.TestCase): def test_new(self): @@ -430,1260 +445,6 @@ def test_bad_init_args(self): qi.Sender(host='localhost', port=9009, max_name_len=-1) -def _pandas(*args, **kwargs): - buf = qi.Buffer() - buf.pandas(*args, **kwargs) - return str(buf) - - -DF1 = pd.DataFrame({ - 'A': [1.0, 2.0, 3.0], - 'B': [1, 2, 3], - 'C': [ - pd.Timestamp('20180310'), - pd.Timestamp('20180311'), - pd.Timestamp('20180312')], - 'D': [True, 'foo', 'bar']}) - - -DF2 = pd.DataFrame({ - 'T': ['t1', 't2', 't1'], - 'A': ['a1', 'a2', 'a3'], - 'B': ['b1', None, 'b3'], - 'C': pd.Series(['b1', None, 'b3'], dtype='string'), - 'D': pd.Series(['a1', 'a2', 'a3'], dtype='string'), - 'E': [1.0, 2.0, 3.0], - 'F': [1, 2, 3], - 'G': [ - pd.Timestamp('20180310'), - pd.Timestamp('20180311'), - pd.Timestamp('20180312')]}) - - -class TestPandas(unittest.TestCase): - def test_bad_dataframe(self): - with self.assertRaisesRegex(TypeError, 'Expected pandas'): - _pandas([]) - - def test_no_table_name(self): - with self.assertRaisesRegex(ValueError, 'Must specify at least one of'): - _pandas(DF1) - - def test_bad_table_name_type(self): - with self.assertRaisesRegex(TypeError, 'Must be str'): - _pandas(DF1, table_name=1.5) - - def test_invalid_table_name(self): - with self.assertRaisesRegex( - qi.IngressError, '`table_name`: Bad string "."'): - _pandas(DF1, table_name='.') - - def test_invalid_column_dtype(self): - with self.assertRaisesRegex(qi.IngressError, - '`table_name_col`: Bad dtype'): - _pandas(DF1, table_name_col='B') - with self.assertRaisesRegex(qi.IngressError, - '`table_name_col`: Bad dtype'): - _pandas(DF1, table_name_col=1) - with self.assertRaisesRegex(qi.IngressError, - '`table_name_col`: Bad dtype'): - _pandas(DF1, table_name_col=-3) - with self.assertRaisesRegex(IndexError, '`table_name_col`: -5 index'): - _pandas(DF1, table_name_col=-5) - - def test_bad_str_obj_col(self): - with self.assertRaisesRegex(qi.IngressError, - "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): - _pandas(DF1, table_name_col='D') - with self.assertRaisesRegex(qi.IngressError, - "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): - _pandas(DF1, table_name_col=3) - with self.assertRaisesRegex(qi.IngressError, - "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): - _pandas(DF1, table_name_col=-1) - - def test_bad_symbol(self): - with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): - _pandas(DF1, table_name='tbl1', symbols=0) - with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): - _pandas(DF1, table_name='tbl1', symbols={}) - with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): - _pandas(DF1, table_name='tbl1', symbols=None) - with self.assertRaisesRegex(qi.IngressError, - "`symbols`: Bad dtype `float64`.*'A'.*Must.*strings col"): - _pandas(DF1, table_name='tbl1', symbols=(0,)) - with self.assertRaisesRegex(qi.IngressError, - "`symbols`: Bad dtype `int64`.*'B'.*Must be a strings column."): - _pandas(DF1, table_name='tbl1', symbols=[1]) - - def test_bad_at(self): - with self.assertRaisesRegex(KeyError, '`at`.*2018.*not found in the'): - _pandas(DF1, table_name='tbl1', at='2018-03-10T00:00:00Z') - with self.assertRaisesRegex(TypeError, '`at`.*float64.*be a datetime'): - _pandas(DF1, table_name='tbl1', at='A') - with self.assertRaisesRegex(TypeError, '`at`.*int64.*be a datetime'): - _pandas(DF1, table_name='tbl1', at=1) - with self.assertRaisesRegex(TypeError, '`at`.*object.*be a datetime'): - _pandas(DF1, table_name='tbl1', at=-1) - - def test_empty_dataframe(self): - buf = _pandas(pd.DataFrame(), table_name='tbl1') - self.assertEqual(buf, '') - - def test_zero_row_dataframe(self): - buf = _pandas(pd.DataFrame(columns=['A', 'B']), table_name='tbl1') - self.assertEqual(buf, '') - - def test_zero_column_dataframe(self): - df = pd.DataFrame(index=[0, 1, 2]) - self.assertEqual(len(df), 3) - buf = _pandas(df, table_name='tbl1') - self.assertEqual(buf, '') - - def test_basic(self): - buf = _pandas( - DF2, - table_name_col='T', - symbols=['A', 'B', 'C', 'D'], - at=-1) - self.assertEqual( - buf, - 't1,A=a1,B=b1,C=b1,D=a1 E=1.0,F=1i 1520640000000000000\n' + - 't2,A=a2,D=a2 E=2.0,F=2i 1520726400000000000\n' + - 't1,A=a3,B=b3,C=b3,D=a3 E=3.0,F=3i 1520812800000000000\n') - - def test_row_of_nulls(self): - df = pd.DataFrame({'a': ['a1', None, 'a3']}) - with self.assertRaisesRegex( - qi.IngressError, 'Bad pandas row .*1: All values are nulls.'): - _pandas(df, table_name='tbl1', symbols=['a']) - - def test_u8_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - 0, - 255], # u8 max - dtype='uint8')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=0i\n' + - 'tbl1 a=255i\n') - - def test_i8_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - -128, # i8 min - 127, # i8 max - 0], dtype='int8')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=-128i\n' + - 'tbl1 a=127i\n' + - 'tbl1 a=0i\n') - - def test_u16_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - 0, - 65535], # u16 max - dtype='uint16')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=0i\n' + - 'tbl1 a=65535i\n') - - def test_i16_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - -32768, # i16 min - 32767, # i16 max - 0], dtype='int16')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=-32768i\n' + - 'tbl1 a=32767i\n' + - 'tbl1 a=0i\n') - - def test_u32_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - 0, - 4294967295], # u32 max - dtype='uint32')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=0i\n' + - 'tbl1 a=4294967295i\n') - - def test_i32_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - -2147483648, # i32 min - 0, - 2147483647], # i32 max - dtype='int32')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=-2147483648i\n' + - 'tbl1 a=0i\n' + - 'tbl1 a=2147483647i\n') - - def test_u64_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - 0, - 9223372036854775807], # i64 max - dtype='uint64')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=0i\n' + - 'tbl1 a=9223372036854775807i\n') - - buf = qi.Buffer() - buf.pandas(pd.DataFrame({'b': [.5, 1.0, 1.5]}), table_name='tbl2') - exp1 = ( - 'tbl2 b=0.5\n' + - 'tbl2 b=1.0\n' + - 'tbl2 b=1.5\n') - self.assertEqual( - str(buf), - exp1) - df2 = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - 0, - 9223372036854775808], # i64 max + 1 - dtype='uint64')}) - with self.assertRaisesRegex( - qi.IngressError, - 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): - buf.pandas(df2, table_name='tbl1') - - self.assertEqual( - str(buf), - exp1) # No partial write of `df2`. - - def test_i64_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - -9223372036854775808, # i64 min - 0, - 9223372036854775807], # i64 max - dtype='int64')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i\n' + - 'tbl1 a=2i\n' + - 'tbl1 a=3i\n' + - 'tbl1 a=-9223372036854775808i\n' + - 'tbl1 a=0i\n' + - 'tbl1 a=9223372036854775807i\n') - - def test_f32_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1.0, 2.0, 3.0, - 0.0, - float('inf'), - float('-inf'), - float('nan'), - 3.4028234663852886e38], # f32 max - dtype='float32')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1.0\n' + - 'tbl1 a=2.0\n' + - 'tbl1 a=3.0\n' + - 'tbl1 a=0.0\n' + - 'tbl1 a=Infinity\n' + - 'tbl1 a=-Infinity\n' + - 'tbl1 a=NaN\n' + - 'tbl1 a=3.4028234663852886e38\n') - - def test_f64_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 1.0, 2.0, 3.0, - 0.0, - float('inf'), - float('-inf'), - float('nan'), - 1.7976931348623157e308], # f64 max - dtype='float64')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1.0\n' + - 'tbl1 a=2.0\n' + - 'tbl1 a=3.0\n' + - 'tbl1 a=0.0\n' + - 'tbl1 a=Infinity\n' + - 'tbl1 a=-Infinity\n' + - 'tbl1 a=NaN\n' + - 'tbl1 a=1.7976931348623157e308\n') - - def test_u8_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - 0, - None, - 255], # u8 max - dtype=pd.UInt8Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=0i,b="d"\n' + - 'tbl1 b="e"\n' + - 'tbl1 a=255i,b="f"\n') - - def test_i8_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - -128, # i8 min - 0, - None, - 127], # i8 max - dtype=pd.Int8Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=-128i,b="d"\n' + - 'tbl1 a=0i,b="e"\n' + - 'tbl1 b="f"\n' + - 'tbl1 a=127i,b="g"\n') - - def test_u16_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - 0, - None, - 65535], # u16 max - dtype=pd.UInt16Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=0i,b="d"\n' + - 'tbl1 b="e"\n' + - 'tbl1 a=65535i,b="f"\n') - - def test_i16_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - -32768, # i16 min - 0, - None, - 32767], # i16 max - dtype=pd.Int16Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=-32768i,b="d"\n' + - 'tbl1 a=0i,b="e"\n' + - 'tbl1 b="f"\n' + - 'tbl1 a=32767i,b="g"\n') - - def test_u32_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - 0, - None, - 4294967295], # u32 max - dtype=pd.UInt32Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=0i,b="d"\n' + - 'tbl1 b="e"\n' + - 'tbl1 a=4294967295i,b="f"\n') - - def test_i32_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - -2147483648, # i32 min - 0, - None, - 2147483647], # i32 max - dtype=pd.Int32Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=-2147483648i,b="d"\n' + - 'tbl1 a=0i,b="e"\n' + - 'tbl1 b="f"\n' + - 'tbl1 a=2147483647i,b="g"\n') - - def test_u64_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - 0, - None, - 9223372036854775807], # i64 max - dtype=pd.UInt64Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=0i,b="d"\n' + - 'tbl1 b="e"\n' + - 'tbl1 a=9223372036854775807i,b="f"\n') - - df2 = pd.DataFrame({'a': pd.Series([ - 1, 2, 3, - 0, - 9223372036854775808], # i64 max + 1 - dtype=pd.UInt64Dtype())}) - with self.assertRaisesRegex( - qi.IngressError, - 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): - _pandas(df2, table_name='tbl1') - - def test_i64_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, - -9223372036854775808, # i64 min - 0, - None, - 9223372036854775807], # i64 max - dtype=pd.Int64Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1i,b="a"\n' + - 'tbl1 a=2i,b="b"\n' + - 'tbl1 a=3i,b="c"\n' + - 'tbl1 a=-9223372036854775808i,b="d"\n' + - 'tbl1 a=0i,b="e"\n' + - 'tbl1 b="f"\n' + - 'tbl1 a=9223372036854775807i,b="g"\n') - - def test_f32_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1.0, 2.0, 3.0, - 0.0, - float('inf'), - float('-inf'), - float('nan'), - 3.4028234663852886e38, # f32 max - None], - dtype=pd.Float32Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1.0,b="a"\n' + - 'tbl1 a=2.0,b="b"\n' + - 'tbl1 a=3.0,b="c"\n' + - 'tbl1 a=0.0,b="d"\n' + - 'tbl1 a=Infinity,b="e"\n' + - 'tbl1 a=-Infinity,b="f"\n' + - 'tbl1 b="g"\n' + # This one is wierd: `nan` gets 0 in the bitmask. - 'tbl1 a=3.4028234663852886e38,b="h"\n' + - 'tbl1 b="i"\n') - - def test_f64_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 1.0, 2.0, 3.0, - 0.0, - float('inf'), - float('-inf'), - float('nan'), - 1.7976931348623157e308, # f64 max - None], - dtype=pd.Float64Dtype()), - 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1.0,b="a"\n' + - 'tbl1 a=2.0,b="b"\n' + - 'tbl1 a=3.0,b="c"\n' + - 'tbl1 a=0.0,b="d"\n' + - 'tbl1 a=Infinity,b="e"\n' + - 'tbl1 a=-Infinity,b="f"\n' + - 'tbl1 b="g"\n' + # This one is wierd: `nan` gets 0 in the bitmask. - 'tbl1 a=1.7976931348623157e308,b="h"\n' + - 'tbl1 b="i"\n') - - def test_bool_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - True, False, False, - False, True, False], - dtype='bool')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=t\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n' + - 'tbl1 a=t\n' + - 'tbl1 a=f\n') - - def test_bool_arrow_col(self): - df = pd.DataFrame({'a': pd.Series([ - True, False, False, - False, True, False, - True, True, True, - False, False, False], - dtype='boolean')}) # Note `boolean` != `bool`. - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=t\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n' + - 'tbl1 a=t\n' + - 'tbl1 a=f\n' + - 'tbl1 a=t\n' + - 'tbl1 a=t\n' + - 'tbl1 a=t\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n') - - df2 = pd.DataFrame({'a': pd.Series([ - True, False, False, - None, True, False], - dtype='boolean')}) - with self.assertRaisesRegex( - qi.IngressError, - 'Failed.*at row index 3 .*.: .*insert null .*boolean col'): - _pandas(df2, table_name='tbl1') - - def test_bool_obj_col(self): - df = pd.DataFrame({'a': pd.Series([ - True, False, False, - False, True, False], - dtype='object')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=t\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n' + - 'tbl1 a=f\n' + - 'tbl1 a=t\n' + - 'tbl1 a=f\n') - - df2 = pd.DataFrame({'a': pd.Series([ - True, False, 'false'], - dtype='object')}) - with self.assertRaisesRegex( - qi.IngressError, - 'serialize .* column .a. .* 2 .*false.*bool'): - _pandas(df2, table_name='tbl1') - - df3 = pd.DataFrame({'a': pd.Series([ - None, True, False], - dtype='object')}) - with self.assertRaisesRegex( - qi.IngressError, - 'serialize.*\\(None\\): Cannot insert null.*boolean column'): - _pandas(df3, table_name='tbl1') - - def test_datetime64_numpy_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - pd.Timestamp('2019-01-01 00:00:00'), - pd.Timestamp('2019-01-01 00:00:01'), - pd.Timestamp('2019-01-01 00:00:02'), - pd.Timestamp('2019-01-01 00:00:03'), - pd.Timestamp('2019-01-01 00:00:04'), - pd.Timestamp('2019-01-01 00:00:05'), - None, - float('nan'), - pd.NA], - dtype='datetime64[ns]'), - 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=1546300800000000t,b="a"\n' + - 'tbl1 a=1546300801000000t,b="b"\n' + - 'tbl1 a=1546300802000000t,b="c"\n' + - 'tbl1 a=1546300803000000t,b="d"\n' + - 'tbl1 a=1546300804000000t,b="e"\n' + - 'tbl1 a=1546300805000000t,b="f"\n' + - 'tbl1 b="g"\n' + - 'tbl1 b="h"\n' + - 'tbl1 b="i"\n') - - df = pd.DataFrame({'a': pd.Series([ - pd.Timestamp('1970-01-01 00:00:00'), - pd.Timestamp('1970-01-01 00:00:01'), - pd.Timestamp('1970-01-01 00:00:02')])}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a=0t\n' + - 'tbl1 a=1000000t\n' + - 'tbl1 a=2000000t\n') - - def test_datetime64_tz_arrow_col(self): - tz = zoneinfo.ZoneInfo('America/New_York') - df = pd.DataFrame({ - 'a': [ - pd.Timestamp( - year=2019, month=1, day=1, - hour=0, minute=0, second=0, tz=tz), - pd.Timestamp( - year=2019, month=1, day=1, - hour=0, minute=0, second=1, tz=tz), - None, - pd.Timestamp( - year=2019, month=1, day=1, - hour=0, minute=0, second=3, tz=tz)], - 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) - buf = _pandas(df, table_name='tbl1', symbols=['b']) - self.assertEqual( - buf, - # Note how these are 5hr offset from `test_datetime64_numpy_col`. - 'tbl1,b=sym1 a=1546318800000000t\n' + - 'tbl1,b=sym2 a=1546318801000000t\n' + - 'tbl1,b=sym3\n' + - 'tbl1,b=sym4 a=1546318803000000t\n') - - # Not epoch 0. - df = pd.DataFrame({ - 'a': [ - pd.Timestamp( - year=1970, month=1, day=1, - hour=0, minute=0, second=0, tz=tz), - pd.Timestamp( - year=1970, month=1, day=1, - hour=0, minute=0, second=1, tz=tz), - pd.Timestamp( - year=1970, month=1, day=1, - hour=0, minute=0, second=2, tz=tz)], - 'b': ['sym1', 'sym2', 'sym3']}) - buf = _pandas(df, table_name='tbl1', symbols=['b']) - self.assertEqual( - buf, - # Note how these are 5hr offset from `test_datetime64_numpy_col`. - 'tbl1,b=sym1 a=18000000000t\n' + - 'tbl1,b=sym2 a=18001000000t\n' + - 'tbl1,b=sym3 a=18002000000t\n') - - # Actual epoch 0. - df = pd.DataFrame({ - 'a': [ - pd.Timestamp( - year=1969, month=12, day=31, - hour=19, minute=0, second=0, tz=tz), - pd.Timestamp( - year=1969, month=12, day=31, - hour=19, minute=0, second=1, tz=tz), - pd.Timestamp( - year=1969, month=12, day=31, - hour=19, minute=0, second=2, tz=tz)], - 'b': ['sym1', 'sym2', 'sym3']}) - buf = _pandas(df, table_name='tbl1', symbols=['b']) - self.assertEqual( - buf, - 'tbl1,b=sym1 a=0t\n' + - 'tbl1,b=sym2 a=1000000t\n' + - 'tbl1,b=sym3 a=2000000t\n') - - df2 = pd.DataFrame({ - 'a': [ - pd.Timestamp( - year=1900, month=1, day=1, - hour=0, minute=0, second=0, tz=tz)], - 'b': ['sym1']}) - with self.assertRaisesRegex( - qi.IngressError, "Failed.*'a'.*-2208970800000000 is negative."): - _pandas(df2, table_name='tbl1', symbols=['b']) - - def test_datetime64_numpy_at(self): - df = pd.DataFrame({ - 'a': pd.Series([ - pd.Timestamp('2019-01-01 00:00:00'), - pd.Timestamp('2019-01-01 00:00:01'), - pd.Timestamp('2019-01-01 00:00:02'), - pd.Timestamp('2019-01-01 00:00:03'), - pd.Timestamp('2019-01-01 00:00:04'), - pd.Timestamp('2019-01-01 00:00:05'), - float('nan'), - None, - pd.NaT], - dtype='datetime64[ns]'), - 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) - buf = _pandas(df, table_name='tbl1', at='a') - self.assertEqual( - buf, - 'tbl1 b=1i 1546300800000000000\n' + - 'tbl1 b=2i 1546300801000000000\n' + - 'tbl1 b=3i 1546300802000000000\n' + - 'tbl1 b=4i 1546300803000000000\n' + - 'tbl1 b=5i 1546300804000000000\n' + - 'tbl1 b=6i 1546300805000000000\n' + - 'tbl1 b=7i\n' + - 'tbl1 b=8i\n' + - 'tbl1 b=9i\n') - - df = pd.DataFrame({ - 'a': pd.Series([ - pd.Timestamp('1970-01-01 00:00:00'), - pd.Timestamp('1970-01-01 00:00:01'), - pd.Timestamp('1970-01-01 00:00:02')], - dtype='datetime64[ns]'), - 'b': [1, 2, 3]}) - buf = _pandas(df, table_name='tbl1', at='a') - self.assertEqual( - buf, - 'tbl1 b=1i 0\n' + - 'tbl1 b=2i 1000000000\n' + - 'tbl1 b=3i 2000000000\n') - - def test_datetime64_tz_arrow_at(self): - tz = zoneinfo.ZoneInfo('America/New_York') - df = pd.DataFrame({ - 'a': [ - pd.Timestamp( - year=2019, month=1, day=1, - hour=0, minute=0, second=0, tz=tz), - pd.Timestamp( - year=2019, month=1, day=1, - hour=0, minute=0, second=1, tz=tz), - None, - pd.Timestamp( - year=2019, month=1, day=1, - hour=0, minute=0, second=3, tz=tz)], - 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) - buf = _pandas(df, table_name='tbl1', symbols=['b'], at='a') - self.assertEqual( - buf, - # Note how these are 5hr offset from `test_datetime64_numpy_col`. - 'tbl1,b=sym1 1546318800000000000\n' + - 'tbl1,b=sym2 1546318801000000000\n' + - 'tbl1,b=sym3\n' + - 'tbl1,b=sym4 1546318803000000000\n') - - df2 = pd.DataFrame({ - 'a': [ - pd.Timestamp( - year=1900, month=1, day=1, - hour=0, minute=0, second=0, tz=tz)], - 'b': ['sym1']}) - with self.assertRaisesRegex( - qi.IngressError, "Failed.*'a'.*-2208970800000000000 is neg"): - _pandas(df2, table_name='tbl1', symbols=['b'], at='a') - - def _test_pyobjstr_table(self, dtype): - df = pd.DataFrame({ - '../bad col name/../it does not matter...': - pd.Series([ - 'a', # ASCII - 'b' * 127, # Max table name length. - 'q❤️p', # Mixed ASCII and UCS-2 - '嚜꓂', # UCS-2, 3 bytes for UTF-8. - '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype=dtype), - 'b': [1, 2, 3, 4, 5]}) - buf = _pandas(df, table_name_col=0) - self.assertEqual( - buf, - 'a b=1i\n' + - ('b' * 127) + ' b=2i\n' + - 'q❤️p b=3i\n' + - '嚜꓂ b=4i\n' + - '💩🦞 b=5i\n') - - with self.assertRaisesRegex( - qi.IngressError, "Too long"): - _pandas( - pd.DataFrame({'a': pd.Series(['b' * 128], dtype=dtype)}), - table_name_col='a') - - with self.assertRaisesRegex( - qi.IngressError, 'Failed.*Expected a table name, got a null.*'): - _pandas( - pd.DataFrame({ - '.': pd.Series(['x', None], dtype=dtype), - 'b': [1, 2]}), - table_name_col='.') - - with self.assertRaisesRegex( - qi.IngressError, 'Failed.*Expected a table name, got a null.*'): - _pandas( - pd.DataFrame({ - '.': pd.Series(['x', float('nan')], dtype=dtype), - 'b': [1, 2]}), - table_name_col='.') - - with self.assertRaisesRegex( - qi.IngressError, 'Failed.*Expected a table name, got a null.*'): - _pandas( - pd.DataFrame({ - '.': pd.Series(['x', pd.NA], dtype=dtype), - 'b': [1, 2]}), - table_name_col='.') - - with self.assertRaisesRegex( - qi.IngressError, "''.*must have a non-zero length"): - _pandas( - pd.DataFrame({ - '/': pd.Series([''], dtype=dtype), - 'b': [1]}), - table_name_col='/') - - with self.assertRaisesRegex( - qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): - _pandas( - pd.DataFrame({ - '/': pd.Series(['tab..1'], dtype=dtype), - 'b': [1]}), - table_name_col='/') - - def test_obj_str_table(self): - self._test_pyobjstr_table('object') - - with self.assertRaisesRegex( - qi.IngressError, 'table name .*got an object of type int'): - _pandas( - pd.DataFrame({ - '.': pd.Series(['x', 42], dtype='object'), - 'z': [1, 2]}), - table_name_col='.') - - def test_obj_string_table(self): - self._test_pyobjstr_table('string') - - self.assertEqual( - _pandas( - pd.DataFrame({ - '.': pd.Series(['x', 42], dtype='string'), - 'z': [1, 2]}), - table_name_col='.'), - 'x z=1i\n' + - '42 z=2i\n') - - def _test_pyobjstr_numpy_symbol(self, dtype): - df = pd.DataFrame({'a': pd.Series([ - 'a', # ASCII - 'q❤️p', # Mixed ASCII and UCS-2 - '❤️' * 1200, # Over the 1024 buffer prealloc. - 'Questo è un qualcosa', # Non-ASCII UCS-1 - 'щось', # UCS-2, 2 bytes for UTF-8. - '', # Empty string - '嚜꓂', # UCS-2, 3 bytes for UTF-8. - '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype=dtype)}) - buf = _pandas(df, table_name='tbl1', symbols=True) - self.assertEqual( - buf, - 'tbl1,a=a\n' + - 'tbl1,a=q❤️p\n' + - 'tbl1,a=' + ('❤️' * 1200) + '\n' + - 'tbl1,a=Questo\\ è\\ un\\ qualcosa\n' + - 'tbl1,a=щось\n' + - 'tbl1,a=\n' + - 'tbl1,a=嚜꓂\n' + - 'tbl1,a=💩🦞\n') - - for null_obj in (None, float('nan'), pd.NA): - self.assertEqual( - _pandas( - pd.DataFrame({ - 'x': pd.Series(['a', null_obj], dtype=dtype), - 'y': [1, 2]}), - table_name='tbl1', symbols=[0]), - 'tbl1,x=a y=1i\n' + - 'tbl1 y=2i\n') - - def test_obj_str_numpy_symbol(self): - self._test_pyobjstr_numpy_symbol('object') - - with self.assertRaisesRegex( - qi.IngressError, 'Expected a string, got an .* type int'): - _pandas( - pd.DataFrame({ - 'x': pd.Series(['x', 42], dtype='object'), - 'y': [1, 2]}), - table_name='tbl1', symbols=[0]) - - def test_obj_string_numpy_symbol(self): - self._test_pyobjstr_numpy_symbol('string') - - self.assertEqual( - _pandas( - pd.DataFrame({ - 'x': pd.Series(['x', 42], dtype='string'), - 'y': [1, 2]}), - table_name='tbl1', symbols=[0]), - 'tbl1,x=x y=1i\n' + - 'tbl1,x=42 y=2i\n') - - def test_str_numpy_col(self): - df = pd.DataFrame({'a': pd.Series([ - 'a', # ASCII - 'q❤️p', # Mixed ASCII and UCS-2 - '❤️' * 1200, # Over the 1024 buffer prealloc. - 'Questo è un qualcosa', # Non-ASCII UCS-1 - 'щось', # UCS-2, 2 bytes for UTF-8. - '', # Empty string - '嚜꓂', # UCS-2, 3 bytes for UTF-8. - '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype='str')}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 a="a"\n' + - 'tbl1 a="q❤️p"\n' + - 'tbl1 a="' + ('❤️' * 1200) + '"\n' + - 'tbl1 a="Questo è un qualcosa"\n' + - 'tbl1 a="щось"\n' + - 'tbl1 a=""\n' + - 'tbl1 a="嚜꓂"\n' + - 'tbl1 a="💩🦞"\n') - - def test_str_arrow_table(self): - df = pd.DataFrame({ - '../bad col name/../it does not matter...': pd.Series([ - 'a', # ASCII - 'b' * 127, # Max table name length. - 'q❤️p', # Mixed ASCII and UCS-2 - '嚜꓂', # UCS-2, 3 bytes for UTF-8. - '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype='string[pyarrow]'), - 'b': [1, 2, 3, 4, 5]}) - buf = _pandas(df, table_name_col=0) - self.assertEqual( - buf, - 'a b=1i\n' + - ('b' * 127) + ' b=2i\n' + - 'q❤️p b=3i\n' + - '嚜꓂ b=4i\n' + - '💩🦞 b=5i\n') - - with self.assertRaisesRegex( - qi.IngressError, "Too long"): - _pandas( - pd.DataFrame({ - 'a': pd.Series(['b' * 128], dtype='string[pyarrow]')}), - table_name_col='a') - - with self.assertRaisesRegex( - qi.IngressError, "Failed .*.*Table name cannot be null"): - _pandas( - pd.DataFrame({ - '.': pd.Series(['x', None], dtype='string[pyarrow]'), - 'b': [1, 2]}), - table_name_col='.') - - with self.assertRaisesRegex( - qi.IngressError, "''.*must have a non-zero length"): - _pandas( - pd.DataFrame({ - '/': pd.Series([''], dtype='string[pyarrow]')}), - table_name_col='/') - - with self.assertRaisesRegex( - qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): - _pandas( - pd.DataFrame({ - '/': pd.Series(['tab..1'], dtype='string[pyarrow]')}), - table_name_col='/') - - def test_str_arrow_symbol(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 'a', # ASCII - 'q❤️p', # Mixed ASCII and UCS-2 - '❤️' * 1200, # Over the 1024 buffer prealloc. - 'Questo è un qualcosa', # Non-ASCII UCS-1 - 'щось', # UCS-2, 2 bytes for UTF-8. - '', # Empty string - None, - '嚜꓂', # UCS-2, 3 bytes for UTF-8. - '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype='string[pyarrow]'), - 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) - buf = _pandas(df, table_name='tbl1', symbols=True) - self.assertEqual( - buf, - 'tbl1,a=a b=1i\n' + - 'tbl1,a=q❤️p b=2i\n' + - 'tbl1,a=' + ('❤️' * 1200) + ' b=3i\n' + - 'tbl1,a=Questo\\ è\\ un\\ qualcosa b=4i\n' + - 'tbl1,a=щось b=5i\n' + - 'tbl1,a= b=6i\n' + - 'tbl1 b=7i\n' + - 'tbl1,a=嚜꓂ b=8i\n' + - 'tbl1,a=💩🦞 b=9i\n') - - def test_str_arrow_col(self): - df = pd.DataFrame({ - 'a': pd.Series([ - 'a', # ASCII - 'q❤️p', # Mixed ASCII and UCS-2 - '❤️' * 1200, # Over the 1024 buffer prealloc. - 'Questo è un qualcosa', # Non-ASCII UCS-1 - 'щось', # UCS-2, 2 bytes for UTF-8. - '', # Empty string - None, - '嚜꓂', # UCS-2, 3 bytes for UTF-8. - '💩🦞'], # UCS-4, 4 bytes for UTF-8. - dtype='string[pyarrow]'), - 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) - buf = _pandas(df, table_name='tbl1', symbols=False) - self.assertEqual( - buf, - 'tbl1 a="a",b=1i\n' + - 'tbl1 a="q❤️p",b=2i\n' + - 'tbl1 a="' + ('❤️' * 1200) + '",b=3i\n' + - 'tbl1 a="Questo è un qualcosa",b=4i\n' + - 'tbl1 a="щось",b=5i\n' + - 'tbl1 a="",b=6i\n' + - 'tbl1 b=7i\n' + - 'tbl1 a="嚜꓂",b=8i\n' + - 'tbl1 a="💩🦞",b=9i\n') - - def test_pyobj_int_col(self): - self.assertEqual( - _pandas( - pd.DataFrame({ - 'a': pd.Series([ - 1, 2, 3, None, float('nan'), pd.NA, 7], dtype='object'), - 'b': [1, 2, 3, 4, 5, 6, 7]}), - table_name='tbl1'), - 'tbl1 a=1i,b=1i\n' + - 'tbl1 a=2i,b=2i\n' + - 'tbl1 a=3i,b=3i\n' + - 'tbl1 b=4i\n' + - 'tbl1 b=5i\n' + - 'tbl1 b=6i\n' + - 'tbl1 a=7i,b=7i\n') - - with self.assertRaisesRegex( - qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\\."): - _pandas( - pd.DataFrame({ - 'a': pd.Series([1, 'STRING'], dtype='object'), - 'b': [1, 2]}), - table_name='tbl1') - - def test_pyobj_float_col(self): - self.assertEqual( - _pandas( - pd.DataFrame({ - 'a': pd.Series( - [1.0, 2.0, 3.0, None, float('nan'), pd.NA, 7.0], - dtype='object'), - 'b': [1, 2, 3, 4, 5, 6, 7]}), - table_name='tbl1'), - 'tbl1 a=1.0,b=1i\n' + - 'tbl1 a=2.0,b=2i\n' + - 'tbl1 a=3.0,b=3i\n' + - 'tbl1 b=4i\n' + - 'tbl1 a=NaN,b=5i\n' + - 'tbl1 b=6i\n' + - 'tbl1 a=7.0,b=7i\n') - - with self.assertRaisesRegex( - qi.IngressError, "1 \\('STRING'\\): .*type float, got.*str\\."): - _pandas( - pd.DataFrame({ - 'a': pd.Series([1.0, 'STRING'], dtype='object'), - 'b': [1, 2]}), - table_name='tbl1') - - def test_bad_category(self): - # We only support string categories - # (unless anyone asks for additional ones). - # We want to test others are rejected. - with self.assertRaisesRegex( - qi.IngressError, "Bad column 'a'.*got a category of .*int64"): - _pandas( - pd.DataFrame({'a': pd.Series([1, 2, 3, 2], dtype='category')}), - table_name='tbl1') - - def _test_cat_table(self, count): - slist = [f's{i}' for i in range(count)] - - df = pd.DataFrame({ - 'a': pd.Series(slist, dtype='category'), - 'b': list(range(len(slist)))}) - - buf = _pandas(df, table_name_col=0) - exp = ''.join( - f'{s} b={i}i\n' - for i, s in enumerate(slist)) - self.assertEqual(buf, exp) - - slist[2] = None - df2 = pd.DataFrame({ - 'a': pd.Series(slist, dtype='category'), - 'b': list(range(len(slist)))}) - with self.assertRaisesRegex( - qi.IngressError, 'Table name cannot be null'): - _pandas(df2, table_name_col=0) - - def test_cat_i8_table(self): - self._test_cat_table(30) - self._test_cat_table(127) - - def test_cat_i16_table(self): - self._test_cat_table(128) - self._test_cat_table(4000) - self._test_cat_table(32767) - - def test_cat_i32_table(self): - self._test_cat_table(32768) - self._test_cat_table(40000) - - def _test_cat_symbol(self, count): - slist = [f's{i}' for i in range(count)] - - df = pd.DataFrame({ - 'a': pd.Series(slist, dtype='category'), - 'b': list(range(len(slist)))}) - - buf = _pandas(df, table_name='tbl1', symbols=True) - exp = ''.join( - f'tbl1,a={s} b={i}i\n' - for i, s in enumerate(slist)) - self.assertEqual(buf, exp) - - slist[2] = None - df2 = pd.DataFrame({ - 'a': pd.Series(slist, dtype='category'), - 'b': list(range(len(slist)))}) - - exp2 = exp.replace('tbl1,a=s2 b=2i\n', 'tbl1 b=2i\n') - buf2 = _pandas(df2, table_name='tbl1', symbols=True) - self.assertEqual(buf2, exp2) - - def test_cat_i8_symbol(self): - self._test_cat_symbol(30) - self._test_cat_symbol(127) - - def test_cat_i16_symbol(self): - self._test_cat_symbol(128) - self._test_cat_symbol(4000) - self._test_cat_symbol(32767) - - def test_cat_i32_symbol(self): - self._test_cat_symbol(32768) - self._test_cat_symbol(40000) - - def _test_cat_str(self, count): - slist = [f's{i}' for i in range(count)] - - df = pd.DataFrame({ - 'a': pd.Series(slist, dtype='category'), - 'b': list(range(len(slist)))}) - - buf = _pandas(df, table_name='tbl1', symbols=False) - exp = ''.join( - f'tbl1 a="{s}",b={i}i\n' - for i, s in enumerate(slist)) - self.assertEqual(buf, exp) - - slist[2] = None - df2 = pd.DataFrame({ - 'a': pd.Series(slist, dtype='category'), - 'b': list(range(len(slist)))}) - - exp2 = exp.replace('tbl1 a="s2",b=2i\n', 'tbl1 b=2i\n') - buf2 = _pandas(df2, table_name='tbl1', symbols=False) - self.assertEqual(buf2, exp2) - - def test_cat_i8_str(self): - self._test_cat_str(30) - self._test_cat_str(127) - - def test_cat_i16_str(self): - self._test_cat_str(128) - self._test_cat_str(4000) - self._test_cat_str(32767) - - def test_cat_i32_str(self): - self._test_cat_str(32768) - self._test_cat_str(40000) - - def test_all_nulls_pyobj_col(self): - df = pd.DataFrame({ - 'a': [None, pd.NA, float('nan')], - 'b': [1, 2, 3]}) - buf = _pandas(df, table_name='tbl1') - self.assertEqual( - buf, - 'tbl1 b=1i\n' + - 'tbl1 b=2i\n' + - 'tbl1 b=3i\n') - - -# TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. -# TODO: Test all datatypes, but multiple row chunks. - - if __name__ == '__main__': if os.environ.get('TEST_QUESTDB_PROFILE') == '1': import cProfile diff --git a/test/test_pandas.py b/test/test_pandas.py new file mode 100644 index 00000000..1164fd0e --- /dev/null +++ b/test/test_pandas.py @@ -0,0 +1,1278 @@ +#!/usr/bin/env python3 + +import sys +import os +sys.dont_write_bytecode = True +import unittest + +try: + import zoneinfo +except ImportError: + import backports.zoneinfo as zoneinfo + +import patch_path + +import questdb.ingress as qi +import pandas as pd + + +def _pandas(*args, **kwargs): + buf = qi.Buffer() + buf.pandas(*args, **kwargs) + return str(buf) + + +DF1 = pd.DataFrame({ + 'A': [1.0, 2.0, 3.0], + 'B': [1, 2, 3], + 'C': [ + pd.Timestamp('20180310'), + pd.Timestamp('20180311'), + pd.Timestamp('20180312')], + 'D': [True, 'foo', 'bar']}) + + +DF2 = pd.DataFrame({ + 'T': ['t1', 't2', 't1'], + 'A': ['a1', 'a2', 'a3'], + 'B': ['b1', None, 'b3'], + 'C': pd.Series(['b1', None, 'b3'], dtype='string'), + 'D': pd.Series(['a1', 'a2', 'a3'], dtype='string'), + 'E': [1.0, 2.0, 3.0], + 'F': [1, 2, 3], + 'G': [ + pd.Timestamp('20180310'), + pd.Timestamp('20180311'), + pd.Timestamp('20180312')]}) + + +class TestPandas(unittest.TestCase): + def test_bad_dataframe(self): + with self.assertRaisesRegex(TypeError, 'Expected pandas'): + _pandas([]) + + def test_no_table_name(self): + with self.assertRaisesRegex(ValueError, 'Must specify at least one of'): + _pandas(DF1) + + def test_bad_table_name_type(self): + with self.assertRaisesRegex(TypeError, 'Must be str'): + _pandas(DF1, table_name=1.5) + + def test_invalid_table_name(self): + with self.assertRaisesRegex( + qi.IngressError, '`table_name`: Bad string "."'): + _pandas(DF1, table_name='.') + + def test_invalid_column_dtype(self): + with self.assertRaisesRegex(qi.IngressError, + '`table_name_col`: Bad dtype'): + _pandas(DF1, table_name_col='B') + with self.assertRaisesRegex(qi.IngressError, + '`table_name_col`: Bad dtype'): + _pandas(DF1, table_name_col=1) + with self.assertRaisesRegex(qi.IngressError, + '`table_name_col`: Bad dtype'): + _pandas(DF1, table_name_col=-3) + with self.assertRaisesRegex(IndexError, '`table_name_col`: -5 index'): + _pandas(DF1, table_name_col=-5) + + def test_bad_str_obj_col(self): + with self.assertRaisesRegex(qi.IngressError, + "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): + _pandas(DF1, table_name_col='D') + with self.assertRaisesRegex(qi.IngressError, + "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): + _pandas(DF1, table_name_col=3) + with self.assertRaisesRegex(qi.IngressError, + "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): + _pandas(DF1, table_name_col=-1) + + def test_bad_symbol(self): + with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + _pandas(DF1, table_name='tbl1', symbols=0) + with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + _pandas(DF1, table_name='tbl1', symbols={}) + with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + _pandas(DF1, table_name='tbl1', symbols=None) + with self.assertRaisesRegex(qi.IngressError, + "`symbols`: Bad dtype `float64`.*'A'.*Must.*strings col"): + _pandas(DF1, table_name='tbl1', symbols=(0,)) + with self.assertRaisesRegex(qi.IngressError, + "`symbols`: Bad dtype `int64`.*'B'.*Must be a strings column."): + _pandas(DF1, table_name='tbl1', symbols=[1]) + + def test_bad_at(self): + with self.assertRaisesRegex(KeyError, '`at`.*2018.*not found in the'): + _pandas(DF1, table_name='tbl1', at='2018-03-10T00:00:00Z') + with self.assertRaisesRegex(TypeError, '`at`.*float64.*be a datetime'): + _pandas(DF1, table_name='tbl1', at='A') + with self.assertRaisesRegex(TypeError, '`at`.*int64.*be a datetime'): + _pandas(DF1, table_name='tbl1', at=1) + with self.assertRaisesRegex(TypeError, '`at`.*object.*be a datetime'): + _pandas(DF1, table_name='tbl1', at=-1) + + def test_empty_dataframe(self): + buf = _pandas(pd.DataFrame(), table_name='tbl1') + self.assertEqual(buf, '') + + def test_zero_row_dataframe(self): + buf = _pandas(pd.DataFrame(columns=['A', 'B']), table_name='tbl1') + self.assertEqual(buf, '') + + def test_zero_column_dataframe(self): + df = pd.DataFrame(index=[0, 1, 2]) + self.assertEqual(len(df), 3) + buf = _pandas(df, table_name='tbl1') + self.assertEqual(buf, '') + + def test_basic(self): + buf = _pandas( + DF2, + table_name_col='T', + symbols=['A', 'B', 'C', 'D'], + at=-1) + self.assertEqual( + buf, + 't1,A=a1,B=b1,C=b1,D=a1 E=1.0,F=1i 1520640000000000000\n' + + 't2,A=a2,D=a2 E=2.0,F=2i 1520726400000000000\n' + + 't1,A=a3,B=b3,C=b3,D=a3 E=3.0,F=3i 1520812800000000000\n') + + def test_row_of_nulls(self): + df = pd.DataFrame({'a': ['a1', None, 'a3']}) + with self.assertRaisesRegex( + qi.IngressError, 'Bad pandas row .*1: All values are nulls.'): + _pandas(df, table_name='tbl1', symbols=['a']) + + def test_u8_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 255], # u8 max + dtype='uint8')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=255i\n') + + def test_i8_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -128, # i8 min + 127, # i8 max + 0], dtype='int8')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-128i\n' + + 'tbl1 a=127i\n' + + 'tbl1 a=0i\n') + + def test_u16_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 65535], # u16 max + dtype='uint16')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=65535i\n') + + def test_i16_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -32768, # i16 min + 32767, # i16 max + 0], dtype='int16')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-32768i\n' + + 'tbl1 a=32767i\n' + + 'tbl1 a=0i\n') + + def test_u32_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 4294967295], # u32 max + dtype='uint32')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=4294967295i\n') + + def test_i32_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -2147483648, # i32 min + 0, + 2147483647], # i32 max + dtype='int32')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-2147483648i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=2147483647i\n') + + def test_u64_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 9223372036854775807], # i64 max + dtype='uint64')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=9223372036854775807i\n') + + buf = qi.Buffer() + buf.pandas(pd.DataFrame({'b': [.5, 1.0, 1.5]}), table_name='tbl2') + exp1 = ( + 'tbl2 b=0.5\n' + + 'tbl2 b=1.0\n' + + 'tbl2 b=1.5\n') + self.assertEqual( + str(buf), + exp1) + df2 = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 9223372036854775808], # i64 max + 1 + dtype='uint64')}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): + buf.pandas(df2, table_name='tbl1') + + self.assertEqual( + str(buf), + exp1) # No partial write of `df2`. + + def test_i64_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + -9223372036854775808, # i64 min + 0, + 9223372036854775807], # i64 max + dtype='int64')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i\n' + + 'tbl1 a=2i\n' + + 'tbl1 a=3i\n' + + 'tbl1 a=-9223372036854775808i\n' + + 'tbl1 a=0i\n' + + 'tbl1 a=9223372036854775807i\n') + + def test_f32_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 3.4028234663852886e38], # f32 max + dtype='float32')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0\n' + + 'tbl1 a=2.0\n' + + 'tbl1 a=3.0\n' + + 'tbl1 a=0.0\n' + + 'tbl1 a=Infinity\n' + + 'tbl1 a=-Infinity\n' + + 'tbl1 a=NaN\n' + + 'tbl1 a=3.4028234663852886e38\n') + + def test_f64_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 1.7976931348623157e308], # f64 max + dtype='float64')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0\n' + + 'tbl1 a=2.0\n' + + 'tbl1 a=3.0\n' + + 'tbl1 a=0.0\n' + + 'tbl1 a=Infinity\n' + + 'tbl1 a=-Infinity\n' + + 'tbl1 a=NaN\n' + + 'tbl1 a=1.7976931348623157e308\n') + + def test_u8_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 255], # u8 max + dtype=pd.UInt8Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=255i,b="f"\n') + + def test_i8_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -128, # i8 min + 0, + None, + 127], # i8 max + dtype=pd.Int8Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-128i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=127i,b="g"\n') + + def test_u16_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 65535], # u16 max + dtype=pd.UInt16Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=65535i,b="f"\n') + + def test_i16_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -32768, # i16 min + 0, + None, + 32767], # i16 max + dtype=pd.Int16Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-32768i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=32767i,b="g"\n') + + def test_u32_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 4294967295], # u32 max + dtype=pd.UInt32Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=4294967295i,b="f"\n') + + def test_i32_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -2147483648, # i32 min + 0, + None, + 2147483647], # i32 max + dtype=pd.Int32Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-2147483648i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=2147483647i,b="g"\n') + + def test_u64_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + 0, + None, + 9223372036854775807], # i64 max + dtype=pd.UInt64Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=0i,b="d"\n' + + 'tbl1 b="e"\n' + + 'tbl1 a=9223372036854775807i,b="f"\n') + + df2 = pd.DataFrame({'a': pd.Series([ + 1, 2, 3, + 0, + 9223372036854775808], # i64 max + 1 + dtype=pd.UInt64Dtype())}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): + _pandas(df2, table_name='tbl1') + + def test_i64_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, + -9223372036854775808, # i64 min + 0, + None, + 9223372036854775807], # i64 max + dtype=pd.Int64Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n' + + 'tbl1 a=-9223372036854775808i,b="d"\n' + + 'tbl1 a=0i,b="e"\n' + + 'tbl1 b="f"\n' + + 'tbl1 a=9223372036854775807i,b="g"\n') + + def test_f32_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 3.4028234663852886e38, # f32 max + None], + dtype=pd.Float32Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0,b="a"\n' + + 'tbl1 a=2.0,b="b"\n' + + 'tbl1 a=3.0,b="c"\n' + + 'tbl1 a=0.0,b="d"\n' + + 'tbl1 a=Infinity,b="e"\n' + + 'tbl1 a=-Infinity,b="f"\n' + + 'tbl1 b="g"\n' + # This one is wierd: `nan` gets 0 in the bitmask. + 'tbl1 a=3.4028234663852886e38,b="h"\n' + + 'tbl1 b="i"\n') + + def test_f64_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 1.0, 2.0, 3.0, + 0.0, + float('inf'), + float('-inf'), + float('nan'), + 1.7976931348623157e308, # f64 max + None], + dtype=pd.Float64Dtype()), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1.0,b="a"\n' + + 'tbl1 a=2.0,b="b"\n' + + 'tbl1 a=3.0,b="c"\n' + + 'tbl1 a=0.0,b="d"\n' + + 'tbl1 a=Infinity,b="e"\n' + + 'tbl1 a=-Infinity,b="f"\n' + + 'tbl1 b="g"\n' + # This one is wierd: `nan` gets 0 in the bitmask. + 'tbl1 a=1.7976931348623157e308,b="h"\n' + + 'tbl1 b="i"\n') + + def test_bool_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + True, False, False, + False, True, False], + dtype='bool')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n') + + def test_bool_arrow_col(self): + df = pd.DataFrame({'a': pd.Series([ + True, False, False, + False, True, False, + True, True, True, + False, False, False], + dtype='boolean')}) # Note `boolean` != `bool`. + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=t\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n') + + df2 = pd.DataFrame({'a': pd.Series([ + True, False, False, + None, True, False], + dtype='boolean')}) + with self.assertRaisesRegex( + qi.IngressError, + 'Failed.*at row index 3 .*.: .*insert null .*boolean col'): + _pandas(df2, table_name='tbl1') + + def test_bool_obj_col(self): + df = pd.DataFrame({'a': pd.Series([ + True, False, False, + False, True, False], + dtype='object')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=t\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=f\n' + + 'tbl1 a=t\n' + + 'tbl1 a=f\n') + + df2 = pd.DataFrame({'a': pd.Series([ + True, False, 'false'], + dtype='object')}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize .* column .a. .* 2 .*false.*bool'): + _pandas(df2, table_name='tbl1') + + df3 = pd.DataFrame({'a': pd.Series([ + None, True, False], + dtype='object')}) + with self.assertRaisesRegex( + qi.IngressError, + 'serialize.*\\(None\\): Cannot insert null.*boolean column'): + _pandas(df3, table_name='tbl1') + + def test_datetime64_numpy_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + pd.Timestamp('2019-01-01 00:00:00'), + pd.Timestamp('2019-01-01 00:00:01'), + pd.Timestamp('2019-01-01 00:00:02'), + pd.Timestamp('2019-01-01 00:00:03'), + pd.Timestamp('2019-01-01 00:00:04'), + pd.Timestamp('2019-01-01 00:00:05'), + None, + float('nan'), + pd.NA], + dtype='datetime64[ns]'), + 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1546300800000000t,b="a"\n' + + 'tbl1 a=1546300801000000t,b="b"\n' + + 'tbl1 a=1546300802000000t,b="c"\n' + + 'tbl1 a=1546300803000000t,b="d"\n' + + 'tbl1 a=1546300804000000t,b="e"\n' + + 'tbl1 a=1546300805000000t,b="f"\n' + + 'tbl1 b="g"\n' + + 'tbl1 b="h"\n' + + 'tbl1 b="i"\n') + + df = pd.DataFrame({'a': pd.Series([ + pd.Timestamp('1970-01-01 00:00:00'), + pd.Timestamp('1970-01-01 00:00:01'), + pd.Timestamp('1970-01-01 00:00:02')])}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=0t\n' + + 'tbl1 a=1000000t\n' + + 'tbl1 a=2000000t\n') + + def test_datetime64_tz_arrow_col(self): + tz = zoneinfo.ZoneInfo('America/New_York') + df = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=0, tz=tz), + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=1, tz=tz), + None, + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=3, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) + buf = _pandas(df, table_name='tbl1', symbols=['b']) + self.assertEqual( + buf, + # Note how these are 5hr offset from `test_datetime64_numpy_col`. + 'tbl1,b=sym1 a=1546318800000000t\n' + + 'tbl1,b=sym2 a=1546318801000000t\n' + + 'tbl1,b=sym3\n' + + 'tbl1,b=sym4 a=1546318803000000t\n') + + # Not epoch 0. + df = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1970, month=1, day=1, + hour=0, minute=0, second=0, tz=tz), + pd.Timestamp( + year=1970, month=1, day=1, + hour=0, minute=0, second=1, tz=tz), + pd.Timestamp( + year=1970, month=1, day=1, + hour=0, minute=0, second=2, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3']}) + buf = _pandas(df, table_name='tbl1', symbols=['b']) + self.assertEqual( + buf, + # Note how these are 5hr offset from `test_datetime64_numpy_col`. + 'tbl1,b=sym1 a=18000000000t\n' + + 'tbl1,b=sym2 a=18001000000t\n' + + 'tbl1,b=sym3 a=18002000000t\n') + + # Actual epoch 0. + df = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1969, month=12, day=31, + hour=19, minute=0, second=0, tz=tz), + pd.Timestamp( + year=1969, month=12, day=31, + hour=19, minute=0, second=1, tz=tz), + pd.Timestamp( + year=1969, month=12, day=31, + hour=19, minute=0, second=2, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3']}) + buf = _pandas(df, table_name='tbl1', symbols=['b']) + self.assertEqual( + buf, + 'tbl1,b=sym1 a=0t\n' + + 'tbl1,b=sym2 a=1000000t\n' + + 'tbl1,b=sym3 a=2000000t\n') + + df2 = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1900, month=1, day=1, + hour=0, minute=0, second=0, tz=tz)], + 'b': ['sym1']}) + with self.assertRaisesRegex( + qi.IngressError, "Failed.*'a'.*-2208970800000000 is negative."): + _pandas(df2, table_name='tbl1', symbols=['b']) + + def test_datetime64_numpy_at(self): + df = pd.DataFrame({ + 'a': pd.Series([ + pd.Timestamp('2019-01-01 00:00:00'), + pd.Timestamp('2019-01-01 00:00:01'), + pd.Timestamp('2019-01-01 00:00:02'), + pd.Timestamp('2019-01-01 00:00:03'), + pd.Timestamp('2019-01-01 00:00:04'), + pd.Timestamp('2019-01-01 00:00:05'), + float('nan'), + None, + pd.NaT], + dtype='datetime64[ns]'), + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) + buf = _pandas(df, table_name='tbl1', at='a') + self.assertEqual( + buf, + 'tbl1 b=1i 1546300800000000000\n' + + 'tbl1 b=2i 1546300801000000000\n' + + 'tbl1 b=3i 1546300802000000000\n' + + 'tbl1 b=4i 1546300803000000000\n' + + 'tbl1 b=5i 1546300804000000000\n' + + 'tbl1 b=6i 1546300805000000000\n' + + 'tbl1 b=7i\n' + + 'tbl1 b=8i\n' + + 'tbl1 b=9i\n') + + df = pd.DataFrame({ + 'a': pd.Series([ + pd.Timestamp('1970-01-01 00:00:00'), + pd.Timestamp('1970-01-01 00:00:01'), + pd.Timestamp('1970-01-01 00:00:02')], + dtype='datetime64[ns]'), + 'b': [1, 2, 3]}) + buf = _pandas(df, table_name='tbl1', at='a') + self.assertEqual( + buf, + 'tbl1 b=1i 0\n' + + 'tbl1 b=2i 1000000000\n' + + 'tbl1 b=3i 2000000000\n') + + def test_datetime64_tz_arrow_at(self): + tz = zoneinfo.ZoneInfo('America/New_York') + df = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=0, tz=tz), + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=1, tz=tz), + None, + pd.Timestamp( + year=2019, month=1, day=1, + hour=0, minute=0, second=3, tz=tz)], + 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) + buf = _pandas(df, table_name='tbl1', symbols=['b'], at='a') + self.assertEqual( + buf, + # Note how these are 5hr offset from `test_datetime64_numpy_col`. + 'tbl1,b=sym1 1546318800000000000\n' + + 'tbl1,b=sym2 1546318801000000000\n' + + 'tbl1,b=sym3\n' + + 'tbl1,b=sym4 1546318803000000000\n') + + df2 = pd.DataFrame({ + 'a': [ + pd.Timestamp( + year=1900, month=1, day=1, + hour=0, minute=0, second=0, tz=tz)], + 'b': ['sym1']}) + with self.assertRaisesRegex( + qi.IngressError, "Failed.*'a'.*-2208970800000000000 is neg"): + _pandas(df2, table_name='tbl1', symbols=['b'], at='a') + + def _test_pyobjstr_table(self, dtype): + df = pd.DataFrame({ + '../bad col name/../it does not matter...': + pd.Series([ + 'a', # ASCII + 'b' * 127, # Max table name length. + 'q❤️p', # Mixed ASCII and UCS-2 + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype=dtype), + 'b': [1, 2, 3, 4, 5]}) + buf = _pandas(df, table_name_col=0) + self.assertEqual( + buf, + 'a b=1i\n' + + ('b' * 127) + ' b=2i\n' + + 'q❤️p b=3i\n' + + '嚜꓂ b=4i\n' + + '💩🦞 b=5i\n') + + with self.assertRaisesRegex( + qi.IngressError, "Too long"): + _pandas( + pd.DataFrame({'a': pd.Series(['b' * 128], dtype=dtype)}), + table_name_col='a') + + with self.assertRaisesRegex( + qi.IngressError, 'Failed.*Expected a table name, got a null.*'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', None], dtype=dtype), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, 'Failed.*Expected a table name, got a null.*'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', float('nan')], dtype=dtype), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, 'Failed.*Expected a table name, got a null.*'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', pd.NA], dtype=dtype), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, "''.*must have a non-zero length"): + _pandas( + pd.DataFrame({ + '/': pd.Series([''], dtype=dtype), + 'b': [1]}), + table_name_col='/') + + with self.assertRaisesRegex( + qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): + _pandas( + pd.DataFrame({ + '/': pd.Series(['tab..1'], dtype=dtype), + 'b': [1]}), + table_name_col='/') + + def test_obj_str_table(self): + self._test_pyobjstr_table('object') + + with self.assertRaisesRegex( + qi.IngressError, 'table name .*got an object of type int'): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', 42], dtype='object'), + 'z': [1, 2]}), + table_name_col='.') + + def test_obj_string_table(self): + self._test_pyobjstr_table('string') + + self.assertEqual( + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', 42], dtype='string'), + 'z': [1, 2]}), + table_name_col='.'), + 'x z=1i\n' + + '42 z=2i\n') + + def _test_pyobjstr_numpy_symbol(self, dtype): + df = pd.DataFrame({'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype=dtype)}) + buf = _pandas(df, table_name='tbl1', symbols=True) + self.assertEqual( + buf, + 'tbl1,a=a\n' + + 'tbl1,a=q❤️p\n' + + 'tbl1,a=' + ('❤️' * 1200) + '\n' + + 'tbl1,a=Questo\\ è\\ un\\ qualcosa\n' + + 'tbl1,a=щось\n' + + 'tbl1,a=\n' + + 'tbl1,a=嚜꓂\n' + + 'tbl1,a=💩🦞\n') + + for null_obj in (None, float('nan'), pd.NA): + self.assertEqual( + _pandas( + pd.DataFrame({ + 'x': pd.Series(['a', null_obj], dtype=dtype), + 'y': [1, 2]}), + table_name='tbl1', symbols=[0]), + 'tbl1,x=a y=1i\n' + + 'tbl1 y=2i\n') + + def test_obj_str_numpy_symbol(self): + self._test_pyobjstr_numpy_symbol('object') + + with self.assertRaisesRegex( + qi.IngressError, 'Expected a string, got an .* type int'): + _pandas( + pd.DataFrame({ + 'x': pd.Series(['x', 42], dtype='object'), + 'y': [1, 2]}), + table_name='tbl1', symbols=[0]) + + def test_obj_string_numpy_symbol(self): + self._test_pyobjstr_numpy_symbol('string') + + self.assertEqual( + _pandas( + pd.DataFrame({ + 'x': pd.Series(['x', 42], dtype='string'), + 'y': [1, 2]}), + table_name='tbl1', symbols=[0]), + 'tbl1,x=x y=1i\n' + + 'tbl1,x=42 y=2i\n') + + def test_str_numpy_col(self): + df = pd.DataFrame({'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='str')}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a="a"\n' + + 'tbl1 a="q❤️p"\n' + + 'tbl1 a="' + ('❤️' * 1200) + '"\n' + + 'tbl1 a="Questo è un qualcosa"\n' + + 'tbl1 a="щось"\n' + + 'tbl1 a=""\n' + + 'tbl1 a="嚜꓂"\n' + + 'tbl1 a="💩🦞"\n') + + def test_str_arrow_table(self): + df = pd.DataFrame({ + '../bad col name/../it does not matter...': pd.Series([ + 'a', # ASCII + 'b' * 127, # Max table name length. + 'q❤️p', # Mixed ASCII and UCS-2 + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='string[pyarrow]'), + 'b': [1, 2, 3, 4, 5]}) + buf = _pandas(df, table_name_col=0) + self.assertEqual( + buf, + 'a b=1i\n' + + ('b' * 127) + ' b=2i\n' + + 'q❤️p b=3i\n' + + '嚜꓂ b=4i\n' + + '💩🦞 b=5i\n') + + with self.assertRaisesRegex( + qi.IngressError, "Too long"): + _pandas( + pd.DataFrame({ + 'a': pd.Series(['b' * 128], dtype='string[pyarrow]')}), + table_name_col='a') + + with self.assertRaisesRegex( + qi.IngressError, "Failed .*.*Table name cannot be null"): + _pandas( + pd.DataFrame({ + '.': pd.Series(['x', None], dtype='string[pyarrow]'), + 'b': [1, 2]}), + table_name_col='.') + + with self.assertRaisesRegex( + qi.IngressError, "''.*must have a non-zero length"): + _pandas( + pd.DataFrame({ + '/': pd.Series([''], dtype='string[pyarrow]')}), + table_name_col='/') + + with self.assertRaisesRegex( + qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): + _pandas( + pd.DataFrame({ + '/': pd.Series(['tab..1'], dtype='string[pyarrow]')}), + table_name_col='/') + + def test_str_arrow_symbol(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + None, + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='string[pyarrow]'), + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) + buf = _pandas(df, table_name='tbl1', symbols=True) + self.assertEqual( + buf, + 'tbl1,a=a b=1i\n' + + 'tbl1,a=q❤️p b=2i\n' + + 'tbl1,a=' + ('❤️' * 1200) + ' b=3i\n' + + 'tbl1,a=Questo\\ è\\ un\\ qualcosa b=4i\n' + + 'tbl1,a=щось b=5i\n' + + 'tbl1,a= b=6i\n' + + 'tbl1 b=7i\n' + + 'tbl1,a=嚜꓂ b=8i\n' + + 'tbl1,a=💩🦞 b=9i\n') + + def test_str_arrow_col(self): + df = pd.DataFrame({ + 'a': pd.Series([ + 'a', # ASCII + 'q❤️p', # Mixed ASCII and UCS-2 + '❤️' * 1200, # Over the 1024 buffer prealloc. + 'Questo è un qualcosa', # Non-ASCII UCS-1 + 'щось', # UCS-2, 2 bytes for UTF-8. + '', # Empty string + None, + '嚜꓂', # UCS-2, 3 bytes for UTF-8. + '💩🦞'], # UCS-4, 4 bytes for UTF-8. + dtype='string[pyarrow]'), + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) + buf = _pandas(df, table_name='tbl1', symbols=False) + self.assertEqual( + buf, + 'tbl1 a="a",b=1i\n' + + 'tbl1 a="q❤️p",b=2i\n' + + 'tbl1 a="' + ('❤️' * 1200) + '",b=3i\n' + + 'tbl1 a="Questo è un qualcosa",b=4i\n' + + 'tbl1 a="щось",b=5i\n' + + 'tbl1 a="",b=6i\n' + + 'tbl1 b=7i\n' + + 'tbl1 a="嚜꓂",b=8i\n' + + 'tbl1 a="💩🦞",b=9i\n') + + def test_pyobj_int_col(self): + self.assertEqual( + _pandas( + pd.DataFrame({ + 'a': pd.Series([ + 1, 2, 3, None, float('nan'), pd.NA, 7], dtype='object'), + 'b': [1, 2, 3, 4, 5, 6, 7]}), + table_name='tbl1'), + 'tbl1 a=1i,b=1i\n' + + 'tbl1 a=2i,b=2i\n' + + 'tbl1 a=3i,b=3i\n' + + 'tbl1 b=4i\n' + + 'tbl1 b=5i\n' + + 'tbl1 b=6i\n' + + 'tbl1 a=7i,b=7i\n') + + with self.assertRaisesRegex( + qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\\."): + _pandas( + pd.DataFrame({ + 'a': pd.Series([1, 'STRING'], dtype='object'), + 'b': [1, 2]}), + table_name='tbl1') + + def test_pyobj_float_col(self): + self.assertEqual( + _pandas( + pd.DataFrame({ + 'a': pd.Series( + [1.0, 2.0, 3.0, None, float('nan'), pd.NA, 7.0], + dtype='object'), + 'b': [1, 2, 3, 4, 5, 6, 7]}), + table_name='tbl1'), + 'tbl1 a=1.0,b=1i\n' + + 'tbl1 a=2.0,b=2i\n' + + 'tbl1 a=3.0,b=3i\n' + + 'tbl1 b=4i\n' + + 'tbl1 a=NaN,b=5i\n' + + 'tbl1 b=6i\n' + + 'tbl1 a=7.0,b=7i\n') + + with self.assertRaisesRegex( + qi.IngressError, "1 \\('STRING'\\): .*type float, got.*str\\."): + _pandas( + pd.DataFrame({ + 'a': pd.Series([1.0, 'STRING'], dtype='object'), + 'b': [1, 2]}), + table_name='tbl1') + + def test_bad_category(self): + # We only support string categories + # (unless anyone asks for additional ones). + # We want to test others are rejected. + with self.assertRaisesRegex( + qi.IngressError, "Bad column 'a'.*got a category of .*int64"): + _pandas( + pd.DataFrame({'a': pd.Series([1, 2, 3, 2], dtype='category')}), + table_name='tbl1') + + def _test_cat_table(self, count): + slist = [f's{i}' for i in range(count)] + + df = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + buf = _pandas(df, table_name_col=0) + exp = ''.join( + f'{s} b={i}i\n' + for i, s in enumerate(slist)) + self.assertEqual(buf, exp) + + slist[2] = None + df2 = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + with self.assertRaisesRegex( + qi.IngressError, 'Table name cannot be null'): + _pandas(df2, table_name_col=0) + + def test_cat_i8_table(self): + self._test_cat_table(30) + self._test_cat_table(127) + + def test_cat_i16_table(self): + self._test_cat_table(128) + self._test_cat_table(4000) + self._test_cat_table(32767) + + def test_cat_i32_table(self): + self._test_cat_table(32768) + self._test_cat_table(40000) + + def _test_cat_symbol(self, count): + slist = [f's{i}' for i in range(count)] + + df = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + buf = _pandas(df, table_name='tbl1', symbols=True) + exp = ''.join( + f'tbl1,a={s} b={i}i\n' + for i, s in enumerate(slist)) + self.assertEqual(buf, exp) + + slist[2] = None + df2 = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + exp2 = exp.replace('tbl1,a=s2 b=2i\n', 'tbl1 b=2i\n') + buf2 = _pandas(df2, table_name='tbl1', symbols=True) + self.assertEqual(buf2, exp2) + + def test_cat_i8_symbol(self): + self._test_cat_symbol(30) + self._test_cat_symbol(127) + + def test_cat_i16_symbol(self): + self._test_cat_symbol(128) + self._test_cat_symbol(4000) + self._test_cat_symbol(32767) + + def test_cat_i32_symbol(self): + self._test_cat_symbol(32768) + self._test_cat_symbol(40000) + + def _test_cat_str(self, count): + slist = [f's{i}' for i in range(count)] + + df = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + buf = _pandas(df, table_name='tbl1', symbols=False) + exp = ''.join( + f'tbl1 a="{s}",b={i}i\n' + for i, s in enumerate(slist)) + self.assertEqual(buf, exp) + + slist[2] = None + df2 = pd.DataFrame({ + 'a': pd.Series(slist, dtype='category'), + 'b': list(range(len(slist)))}) + + exp2 = exp.replace('tbl1 a="s2",b=2i\n', 'tbl1 b=2i\n') + buf2 = _pandas(df2, table_name='tbl1', symbols=False) + self.assertEqual(buf2, exp2) + + def test_cat_i8_str(self): + self._test_cat_str(30) + self._test_cat_str(127) + + def test_cat_i16_str(self): + self._test_cat_str(128) + self._test_cat_str(4000) + self._test_cat_str(32767) + + def test_cat_i32_str(self): + self._test_cat_str(32768) + self._test_cat_str(40000) + + def test_all_nulls_pyobj_col(self): + df = pd.DataFrame({ + 'a': [None, pd.NA, float('nan')], + 'b': [1, 2, 3]}) + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 b=1i\n' + + 'tbl1 b=2i\n' + + 'tbl1 b=3i\n') + + +# TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. +# TODO: Test all datatypes, but multiple row chunks. + + +if __name__ == '__main__': + if os.environ.get('TEST_QUESTDB_PROFILE') == '1': + import cProfile + cProfile.run('unittest.main()', sort='cumtime') + else: + unittest.main() From b1a4dc7f153b43a4374f8a219160c8b169224559 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 5 Dec 2022 17:57:24 +0000 Subject: [PATCH 101/147] Second attempt to fix up the CI. --- ci/pip_install_deps.py | 7 +++++-- src/questdb/ingress.pyx | 17 ++++++++++------- src/questdb/pandas_integration.pxi | 3 +-- test/test.py | 2 +- ...est_pandas.py => test_pandas_integration.py} | 0 5 files changed, 17 insertions(+), 12 deletions(-) rename test/{test_pandas.py => test_pandas_integration.py} (100%) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index 5a44c2de..ebf8ee67 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -44,18 +44,21 @@ def ensure_zoneinfo(): try: import zoneinfo except ImportError: - pip_install('backports.zoneinfo[tzdata]') + pip_install('backports.zoneinfo') from backports import zoneinfo def main(): ensure_zoneinfo() + if platform.system() == 'Windows': + pip_install('tzdata') # for zoneinfo + try_pip_install('pandas') try_pip_install('numpy') try_pip_install('pyarrow') if platform.python_implementation() == 'CPython': - # We import the dependency we expect to have correctly installed. + # We import the dependencies we expect to have correctly installed. import pandas import numpy import pyarrow diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index d3483b2f..286c3d0f 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1037,16 +1037,19 @@ cdef class Buffer: *, table_name: Optional[str] = None, table_name_col: Union[None, int, str] = None, - symbols: Union[ - Literal['auto'], bool, List[int], List[str]] = 'auto', - at: Union[None, int, str, TimestampNanos, datetime] = None, - sort: bool = True): + symbols: Union[str, bool, List[int], List[str]] = 'auto', + at: Union[None, int, str, TimestampNanos, datetime] = None): """ Add a pandas DataFrame to the buffer. """ - # See https://cython.readthedocs.io/en/latest/src/userguide/ - # numpy_tutorial.html#numpy-tutorial - _pandas(self._impl, self._b, data, table_name, table_name_col, symbols, at, sort) + _pandas( + self._impl, + self._b, + data, + table_name, + table_name_col, + symbols, + at) _FLUSH_FMT = ('{} - See https://py-questdb-client.readthedocs.io/en/' diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 2ea6104d..e02173fb 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -2070,8 +2070,7 @@ cdef void_int _pandas( object table_name, object table_name_col, object symbols, - object at, - bint sort) except -1: + object at) except -1: cdef size_t col_count cdef line_sender_table_name c_table_name cdef int64_t at_value = _AT_IS_SET_BY_COLUMN diff --git a/test/test.py b/test/test.py index 93a04c93..6b205664 100755 --- a/test/test.py +++ b/test/test.py @@ -24,7 +24,7 @@ if pa is not None: - from test_pandas import TestPandas + from test_pandas_integration import TestPandas else: class TestNoPandas(unittest.TestCase): def test_no_pandas(self): diff --git a/test/test_pandas.py b/test/test_pandas_integration.py similarity index 100% rename from test/test_pandas.py rename to test/test_pandas_integration.py From 8b3e45d7f2d54aa97b1425038704fd33444aece7 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 5 Dec 2022 18:05:45 +0000 Subject: [PATCH 102/147] Third attempt to fix up the CI. --- src/questdb/ingress.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 286c3d0f..3d48fdff 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -61,7 +61,7 @@ include "pandas_integration.pxi" from enum import Enum from typing import List, Tuple, Dict, Union, Any, Optional, Callable, \ - Iterable, Literal + Iterable import pathlib import sys From 15330b01ec427946d429b5a11e5a897c997a15ea Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 5 Dec 2022 18:25:04 +0000 Subject: [PATCH 103/147] Reduced stack size in case of errors to aid legibility. --- src/questdb/pandas_integration.pxi | 37 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index e02173fb..00ff0674 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -985,24 +985,6 @@ cdef void _pandas_init_cursor(col_t* col): col.cursor.offset = col.cursor.chunk.offset -cdef void_int _pandas_resolve_col( - qdb_pystr_buf* b, - size_t index, - PandasCol pandas_col, - col_t* col) except -1: - # The target is resolved in stages: - # * We first assign all columns to be fields. - # * Then, depending on argument parsing some/none of the columns - # obtain a meta-target of "table", "symbol" or "at". - # * Finally, based on the source, any remaining "meta_target_field" - # columns are converted to the appropriate target. - # See: _pandas_resolve_col_targets_and_dc(..). - col.meta_target = meta_target_t.meta_target_field - col.orig_index = index # We will sort columns later. - _pandas_resolve_source_and_buffers(pandas_col, col) - _pandas_init_cursor(col) - - cdef void_int _pandas_resolve_cols( qdb_pystr_buf* b, list pandas_cols, @@ -1010,11 +992,28 @@ cdef void_int _pandas_resolve_cols( bint* any_cols_need_gil_out) except -1: cdef size_t index cdef size_t len_pandas_cols = len(pandas_cols) + cdef PandasCol pandas_col cdef col_t* col any_cols_need_gil_out[0] = False for index in range(len_pandas_cols): + pandas_col = pandas_cols[index] col = &cols.d[index] - _pandas_resolve_col(b, index, pandas_cols[index], col) + + # The target is resolved in stages: + # * We first assign all column `.meta_target`s to be fields. + # * Then, depending on argument parsing some/none of the columns + # obtain a meta-target of "table", "symbol" or "at". + # * Finally, based on the source, any remaining "meta_target_field" + # columns are converted to the appropriate target. + # See: _pandas_resolve_col_targets_and_dc(..). + col.meta_target = meta_target_t.meta_target_field + + # We will sort columns later. The index will be used to achieve a stable + # sort among columns with the same `.meta_target`. + col.orig_index = index + + _pandas_resolve_source_and_buffers(pandas_col, col) + _pandas_init_cursor(col) if col_source_needs_gil(col.source): any_cols_need_gil_out[0] = True From cee6d4bf871d89b69a2b7ab3dfe85cd75ae146e6 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 5 Dec 2022 18:58:27 +0000 Subject: [PATCH 104/147] Fourth attempt to fix up the CI. --- ci/pip_install_deps.py | 16 +++++++++----- test/test_pandas_integration.py | 39 +++++++++++++++++---------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index ebf8ee67..9fb6fd76 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -40,18 +40,22 @@ def try_pip_install(package): sys.stderr.write(f' Ignored unsatisfiable dependency:\n{msg}\n') -def ensure_zoneinfo(): +def ensure_timezone(): try: import zoneinfo except ImportError: - pip_install('backports.zoneinfo') - from backports import zoneinfo + pip_install('pytz') def main(): - ensure_zoneinfo() - if platform.system() == 'Windows': - pip_install('tzdata') # for zoneinfo + ensure_timezone() + + try: + import zoneinfo + if platform.system() == 'Windows': + pip_install('tzdata') # for zoneinfo + except ImportError: + pass # We're using `pytz` instead. try_pip_install('pandas') try_pip_install('numpy') diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index 1164fd0e..134632b7 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -7,8 +7,10 @@ try: import zoneinfo + _TZ = zoneinfo.ZoneInfo('America/New_York') except ImportError: - import backports.zoneinfo as zoneinfo + import pytz + _TZ = pytz.timezone('America/New_York') import patch_path @@ -672,19 +674,18 @@ def test_datetime64_numpy_col(self): 'tbl1 a=2000000t\n') def test_datetime64_tz_arrow_col(self): - tz = zoneinfo.ZoneInfo('America/New_York') df = pd.DataFrame({ 'a': [ pd.Timestamp( year=2019, month=1, day=1, - hour=0, minute=0, second=0, tz=tz), + hour=0, minute=0, second=0, tz=_TZ), pd.Timestamp( year=2019, month=1, day=1, - hour=0, minute=0, second=1, tz=tz), + hour=0, minute=0, second=1, tz=_TZ), None, pd.Timestamp( year=2019, month=1, day=1, - hour=0, minute=0, second=3, tz=tz)], + hour=0, minute=0, second=3, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) buf = _pandas(df, table_name='tbl1', symbols=['b']) self.assertEqual( @@ -700,13 +701,13 @@ def test_datetime64_tz_arrow_col(self): 'a': [ pd.Timestamp( year=1970, month=1, day=1, - hour=0, minute=0, second=0, tz=tz), + hour=0, minute=0, second=0, tz=_TZ), pd.Timestamp( year=1970, month=1, day=1, - hour=0, minute=0, second=1, tz=tz), + hour=0, minute=0, second=1, tz=_TZ), pd.Timestamp( year=1970, month=1, day=1, - hour=0, minute=0, second=2, tz=tz)], + hour=0, minute=0, second=2, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3']}) buf = _pandas(df, table_name='tbl1', symbols=['b']) self.assertEqual( @@ -721,13 +722,13 @@ def test_datetime64_tz_arrow_col(self): 'a': [ pd.Timestamp( year=1969, month=12, day=31, - hour=19, minute=0, second=0, tz=tz), + hour=19, minute=0, second=0, tz=_TZ), pd.Timestamp( year=1969, month=12, day=31, - hour=19, minute=0, second=1, tz=tz), + hour=19, minute=0, second=1, tz=_TZ), pd.Timestamp( year=1969, month=12, day=31, - hour=19, minute=0, second=2, tz=tz)], + hour=19, minute=0, second=2, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3']}) buf = _pandas(df, table_name='tbl1', symbols=['b']) self.assertEqual( @@ -740,11 +741,12 @@ def test_datetime64_tz_arrow_col(self): 'a': [ pd.Timestamp( year=1900, month=1, day=1, - hour=0, minute=0, second=0, tz=tz)], + hour=0, minute=0, second=0, tz=_TZ)], 'b': ['sym1']}) with self.assertRaisesRegex( - qi.IngressError, "Failed.*'a'.*-2208970800000000 is negative."): + qi.IngressError, "Failed.*'a'.*-220897.* is negative."): _pandas(df2, table_name='tbl1', symbols=['b']) + return ############################################################### def test_datetime64_numpy_at(self): df = pd.DataFrame({ @@ -788,19 +790,18 @@ def test_datetime64_numpy_at(self): 'tbl1 b=3i 2000000000\n') def test_datetime64_tz_arrow_at(self): - tz = zoneinfo.ZoneInfo('America/New_York') df = pd.DataFrame({ 'a': [ pd.Timestamp( year=2019, month=1, day=1, - hour=0, minute=0, second=0, tz=tz), + hour=0, minute=0, second=0, tz=_TZ), pd.Timestamp( year=2019, month=1, day=1, - hour=0, minute=0, second=1, tz=tz), + hour=0, minute=0, second=1, tz=_TZ), None, pd.Timestamp( year=2019, month=1, day=1, - hour=0, minute=0, second=3, tz=tz)], + hour=0, minute=0, second=3, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) buf = _pandas(df, table_name='tbl1', symbols=['b'], at='a') self.assertEqual( @@ -815,10 +816,10 @@ def test_datetime64_tz_arrow_at(self): 'a': [ pd.Timestamp( year=1900, month=1, day=1, - hour=0, minute=0, second=0, tz=tz)], + hour=0, minute=0, second=0, tz=_TZ)], 'b': ['sym1']}) with self.assertRaisesRegex( - qi.IngressError, "Failed.*'a'.*-2208970800000000000 is neg"): + qi.IngressError, "Failed.*'a'.*-220897.* is neg"): _pandas(df2, table_name='tbl1', symbols=['b'], at='a') def _test_pyobjstr_table(self, dtype): From 5668b575764d8b0cbf203c575d9d2e217481954a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 5 Dec 2022 21:21:14 +0000 Subject: [PATCH 105/147] Fifth attempt to fix up the CI. --- ci/pip_install_deps.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index 9fb6fd76..41b04f3c 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -46,10 +46,6 @@ def ensure_timezone(): except ImportError: pip_install('pytz') - -def main(): - ensure_timezone() - try: import zoneinfo if platform.system() == 'Windows': @@ -57,11 +53,15 @@ def main(): except ImportError: pass # We're using `pytz` instead. + +def main(): + ensure_timezone() try_pip_install('pandas') try_pip_install('numpy') try_pip_install('pyarrow') - if platform.python_implementation() == 'CPython': + is_64bits = sys.maxsize > 2**32 + if is_64bits and (platform.python_implementation() == 'CPython'): # We import the dependencies we expect to have correctly installed. import pandas import numpy From 77a612cc8b7160a6dccf8668a217089d9424a78b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 5 Dec 2022 21:31:54 +0000 Subject: [PATCH 106/147] Sixth attempt to fix up the CI. --- ci/pip_install_deps.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index 41b04f3c..43b17696 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -60,9 +60,13 @@ def main(): try_pip_install('numpy') try_pip_install('pyarrow') + on_linux_is_glibc = ( + (not platform.system() == 'Linux') or + (platform.libc_ver()[0] == 'glibc')) is_64bits = sys.maxsize > 2**32 - if is_64bits and (platform.python_implementation() == 'CPython'): - # We import the dependencies we expect to have correctly installed. + is_cpython = platform.python_implementation() == 'CPython' + if on_linux_is_glibc and is_64bits and is_cpython: + # Ensure that we've managed to install the expected dependencies. import pandas import numpy import pyarrow From 57ae0b8773c007579ac595193cbe6a5a06293123 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 6 Dec 2022 19:05:28 +0000 Subject: [PATCH 107/147] Progress on API docs. --- ci/pip_install_deps.py | 7 +- src/questdb/ingress.pyx | 321 ++++++++++++++++---------------- test/test_pandas_integration.py | 2 + 3 files changed, 160 insertions(+), 170 deletions(-) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index 43b17696..e37050d8 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -41,17 +41,12 @@ def try_pip_install(package): def ensure_timezone(): - try: - import zoneinfo - except ImportError: - pip_install('pytz') - try: import zoneinfo if platform.system() == 'Windows': pip_install('tzdata') # for zoneinfo except ImportError: - pass # We're using `pytz` instead. + pip_install('pytz') def main(): diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 3d48fdff..4c69578c 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -867,170 +867,6 @@ cdef class Buffer: self._row(table_name, symbols, columns, at) return self - # def tabular( - # self, - # table_name: str, - # data: Iterable[Iterable[Union[ - # bool, int, float, str, - # TimestampMicros, TimestampNanos, datetime]]], - # *, - # header: Optional[List[Optional[str]]]=None, - # symbols: Union[bool, List[int]]=False, - # at: Union[None, TimestampNanos, datetime]=None): - # """ - # Add multiple rows as an iterable of iterables (e.g. list of lists) to - # the buffer. - - # **Data and header** - - # The ``data`` argument specifies rows which must all be for the same - # table. Column names are provided as the ``header``. - - # .. code-block:: python - - # buffer.tabular( - # 'table_name', - # [[True, 123, 3.14, 'xyz'], - # [False, 456, 6.28, 'abc'], - # [True, 789, 9.87, 'def']], - # header=['col1', 'col2', 'col3', 'col4']) - - # **Designated Timestamp Column** - - # QuestDB supports a special `designated timestamp - # `_ column that it - # uses to sort the rows by timestamp. - - # If the data section contains the same number of columns as the header, - # then the designated is going to be - # assigned by the server, unless specified for all columns the `at` - # argument as either an integer wrapped in a ``TimestampNanos`` object - # representing nanoseconds since unix epoch (1970-01-01 00:00:00 UTC) or - # as a ``datetime.datetime`` object. - - # .. code-block:: python - - # buffer.tabular( - # 'table_name', - # [[True, None, 3.14, 'xyz'], - # [False, 123, 6.28, 'abc'], - # [True, 456, 9.87, 'def']], - # header=['col1', 'col2', 'col3', 'col4'], - # at=datetime.datetime.utcnow()) - - # # or ... - # # at=TimestampNanos(1657386397157631000)) - - # If the rows need different `designated timestamp - # `_ values across - # different rows, you can provide them as an additional unlabeled column. - # An unlabled column is one that has its name set to ``None``. - - # .. code-block:: python - - # ts1 = datetime.datetime.utcnow() - # ts2 = ( - # datetime.datetime.utcnow() + - # datetime.timedelta(microseconds=1)) - # buffer.tabular( - # 'table_name', - # [[True, 123, ts1], - # [False, 456, ts2]], - # header=['col1', 'col2', None]) - - # Like the ``at`` argument, the designated timestamp column may also be - # specified as ``TimestampNanos`` objects. - - # .. code-block:: python - - # buffer.tabular( - # 'table_name', - # [[True, 123, TimestampNanos(1657386397157630000)], - # [False, 456, TimestampNanos(1657386397157631000)]], - # header=['col1', 'col2', None]) - - # The designated timestamp column may appear anywhere positionally. - - # .. code-block:: python - - # ts1 = datetime.datetime.utcnow() - # ts2 = ( - # datetime.datetime.utcnow() + - # datetime.timedelta(microseconds=1)) - # buffer.tabular( - # 'table_name', - # [[1000, ts1, 123], - # [2000, ts2, 456]], - # header=['col1', None, 'col2']) - - # **Other timestamp columns** - - # Other columns may also contain timestamps. These columns can take - # ``datetime.datetime`` objects or ``TimestampMicros`` (*not nanos*) - # objects. - - # .. code-block:: python - - # ts1 = datetime.datetime.utcnow() - # ts2 = ( - # datetime.datetime.utcnow() + - # datetime.timedelta(microseconds=1)) - # buffer.tabular( - # 'table_name', - # [[1000, ts1, 123], - # [2000, ts2, 456]], - # header=['col1', 'col2', 'col3'], - # at=datetime.datetime.utcnow()) - - # **Symbol Columns** - - # QuestDB can represent strings via the ``STRING`` or ``SYMBOL`` types. - - # If all the columns of type ``str`` are to be treated as ``STRING``, then - # specify ``symbols=False`` (default - see exaples above). - - # If all need to be treated as ``SYMBOL`` specify ``symbols=True``. - - # .. code-block:: python - - # buffer.tabular( - # 'table_name', - # [['abc', 123, 3.14, 'xyz'], - # ['def', 456, None, 'abc'], - # ['ghi', 789, 9.87, 'def']], - # header=['col1', 'col2', 'col3', 'col4'], - # symbols=True) # `col1` and `col4` are SYMBOL columns. - - # Whilst if only a select few are to be treated as ``SYMBOL``, specify a - # list of column indices to the ``symbols`` arg. - - # .. code-block:: python - - # buffer.tabular( - # 'table_name', - # [['abc', 123, 3.14, 'xyz'], - # ['def', 456, 6.28, 'abc'], - # ['ghi', 789, 9.87, 'def']], - # header=['col1', 'col2', 'col3', 'col4'], - # symbols=[0]) # `col1` is SYMBOL; 'col4' is STRING. - - # Alternatively, you can specify a list of symbol column names. - - # .. code-block:: python - - # buffer.tabular( - # 'table_name', - # [['abc', 123, 3.14, 'xyz'], - # ['def', 456, 6.28, 'abc'], - # ['ghi', 789, 9.87, 'def']], - # header=['col1', 'col2', 'col3', 'col4'], - # symbols=['col1']) # `col1` is SYMBOL; 'col4' is STRING. - - # Note that column indices are 0-based and negative indices are counted - # from the end. - # """ - # raise ValueError('nyi') - def pandas( self, data, # : pd.DataFrame @@ -1041,7 +877,114 @@ cdef class Buffer: at: Union[None, int, str, TimestampNanos, datetime] = None): """ Add a pandas DataFrame to the buffer. + + Also see the :func:`Sender.pandas` method if you're + not using the buffer explicitly. It supports the same parameters + and also supports auto-flushing. + + This feature requires the ``pandas``, ``numpy` and ``pyarrow`` + package to be installed. + + :param data: The pandas DataFrame to serialize to the buffer. + :type data: pandas.DataFrame + + :param table_name: The name of the table to which the rows belong. + + If ``None``, the table name is taken from the ``table_name_col`` + parameter. If both ``table_name`` and ``table_name_col`` are + ``None``, the table name is taken from the DataFrame's ``.name``. + :type table_name: str or None + + :param table_name_col: The name or index of the column in the DataFrame + that contains the table name. + + If ``None``, the table name is taken + from the ``table_name`` parameter. If both ``table_name`` and + ``table_name_col`` are ``None``, the table name is taken from the + DataFrame's ``.name``. + + If ``table_name_col`` is an integer, it is interpreted as the index + of the column starting from ``0``. The index of the column can be + negative, in which case it is interpreted as an offset from the end + of the DataFrame. E.g. ``-1`` is the last column. + :type table_name_col: str or int or None + + :param symbols: The columns to be serialized as symbols. + + If ``'auto'`` (default), all columns of dtype ``'categorical'`` are + serialized as symbols. If ``True``, all ``str`` columns are + serialized as symbols. If ``False``, no columns are serialized as + symbols. + + The list of symbols can also be specified explicitly as a ``list`` + of column names (``str``) or indices (``int``). Integer indices + start at ``0`` and can be negative, offset from the end of the + DataFrame. E.g. ``-1`` is the last column. + + Only columns containing strings can be serialized as symbols. + + :type symbols: str or bool or list of str or list of int + + :param at: The designated timestamp of the rows. + + You can specify a single value for all rows or column name or index. + If ``None``, timestamp is assigned by the server for all rows. + If ``datetime``, the timestamp is converted to nanoseconds. + A ``datetime`` object is assumed to be in the UTC timezone unless + one is specified explicitly (so call ``datetime.utcnow()`` instead + of ``datetime.now()`` for the current timestamp). + To pass in a timestamp explicity as an integer use the + ``TimestampNanos`` wrapper type. + + To specify a different timestamp for each row, pass in a column name + (``str``) or index (``int``, 0-based index, negative index + supported): In this case, the column needs to be of dtype + ``datetime64[ns]`` (assumed to be in the UTC timezone) or + ``datetime64[ns, tz]``. When a timezone is specified in the column, + it is converted to UTC automatically. + + A timestamp column can also contain ``None`` values. The server will + assign the current timestamp to those rows. + Note that the timestamp is always converted to nanoseconds and in + the UTC timezone. Timezone information is dropped before sending. + :type at: TimestampNanos, datetime.datetime, int or str or None + + **Note**: It is an error to specify both ``table_name`` and + ``table_name_col``. + + **Note**: The "index" column of the DataFrame is never serialized, + even if it is named. + + Example: + + .. code-block:: python + + import pandas as pd + import questdb.ingress as qi + + buf = qi.Buffer() + # ... + + df = pd.DataFrame({ + 'location': ['London', 'Managua', 'London'], + 'temperature': [24.5, 35.0, 25.5], + 'humidity': [0.5, 0.6, 0.45], + 'ts': pd.date_range('2021-07-01', periods=3)}) + buf.pandas(df, table_name='weather', at='ts', symbols=['location']) + + # ... + sender.flush(buf) + + ILP / Pandas Datatype Mappings: + + +------------------+------------------+-----------------+ + | ILP Datatype | Pandas ``dtype`` | Nulls Allowed | + +==================+==================+=================+ + | ``SYMBOL`` | ``'object'`` column containing ``str`` | Yes | + +------------------+------------------+-----------------+ + """ + # TODO: Continue docs, examples and datatype mappings _pandas( self._impl, self._b, @@ -1400,6 +1343,56 @@ cdef class Sender: """ self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) + def pandas( + self, + data, # : pd.DataFrame + *, + table_name: Optional[str] = None, + table_name_col: Union[None, int, str] = None, + symbols: Union[str, bool, List[int], List[str]] = 'auto', + at: Union[None, int, str, TimestampNanos, datetime] = None): + """ + Write a Pandas DataFrame to the internal buffer. + + Example: + + .. code-block:: python + + import pandas as pd + import questdb.ingress as qi + + df = pd.DataFrame({ + 'car': pd.Categorical(['Nic 42', 'Eddi', 'Nic 42', 'Eddi']), + 'position': [1, 2, 1, 2], + 'speed': [89.3, 98.2, 3, 4], + 'lat_gforce': [0.1, -0.2, -0.6, 0.4], + 'accelleration': [0.1, -0.2, 0.6, 4.4], + 'tyre_pressure': [2.6, 2.5, 2.6, 2.5], + 'ts': [ + pd.Timestamp('2022-08-09 13:56:00'), + pd.Timestamp('2022-08-09 13:56:01'), + pd.Timestamp('2022-08-09 13:56:02'), + pd.Timestamp('2022-08-09 13:56:03')]}) + + with qi.Sender('localhost', 9000) as sender: + sender.pandas(df, table_name='race_metrics', at='ts') + + This method builds on top of the :func:`Buffer.pandas` method. + See its documentation for details on arguments. + + Additionally, this method also supports auto-flushing the buffer + as specified in the ``Sender``'s ``auto_flush`` constructor argument. + + In case of data errors with auto-flushing enabled, some of the rows + may have been transmitted to the server already. + """ + self._buffer.pandas( + data, + table_name=table_name, + table_name_col=table_name_col, + symbols=symbols, + at=at) + cpdef flush(self, Buffer buffer=None, bint clear=True): """ If called with no arguments, immediately flushes the internal buffer. diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index 134632b7..00bdba36 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -1269,6 +1269,8 @@ def test_all_nulls_pyobj_col(self): # TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. # TODO: Test all datatypes, but multiple row chunks. +# TODO: Test datetime `at` argument with timezone. +# TODO: Test `df.name = 'foo'` if __name__ == '__main__': From a2763f9d36d7954dc2c8d0acee139bd93bba2e16 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 7 Dec 2022 13:23:01 +0000 Subject: [PATCH 108/147] Found and fixed a memory leak. --- src/questdb/pandas_integration.pxi | 4 +++ test/test_pandas_leaks.py | 43 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/test_pandas_leaks.py diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 00ff0674..09acadbe 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -329,6 +329,10 @@ cdef void col_t_release(col_t* col): if col.arrow_schema.release != NULL: col.arrow_schema.release(&col.arrow_schema) + free(col.chunks.chunks) + col.chunks.chunks = NULL + col.chunks.n_chunks = 0 + # Calloc'd array of col_t. cdef struct col_t_arr: diff --git a/test/test_pandas_leaks.py b/test/test_pandas_leaks.py new file mode 100644 index 00000000..af36911d --- /dev/null +++ b/test/test_pandas_leaks.py @@ -0,0 +1,43 @@ +import patch_path +patch_path.patch() + +import pandas as pd +import questdb.ingress as qi + +import os, psutil +process = psutil.Process(os.getpid()) + +def get_rss(): + return process.memory_info().rss + + +def serialize_and_cleanup(): + # qi.Buffer().row( + # 'table_name', + # symbols={'x': 'a', 'y': 'b'}, + # columns={'a': 1, 'b': 2, 'c': 3}) + df = pd.DataFrame({ + 'a': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + 'b': [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], + 'c': [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]}) + qi.Buffer().pandas(df, table_name='test') + + +def main(): + warmup_count = 0 + for n in range(1000000): + if n % 1000 == 0: + print(f'[iter: {n:09}, RSS: {get_rss():010}]') + if n > warmup_count: + before = get_rss() + serialize_and_cleanup() + if n > warmup_count: + after = get_rss() + if after != before: + msg = f'RSS changed from {before} to {after} after {n} iters' + print(msg) + + +if __name__ == '__main__': + main() + \ No newline at end of file From 960cd743b164544fa3fba7dc1d2f236543f47d45 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 7 Dec 2022 18:17:45 +0000 Subject: [PATCH 109/147] More fuzzing. --- .gitignore | 3 + proj.py | 30 +++++ setup.py | 33 ++++- test/test_pandas_integration_fuzz.py | 187 +++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 4 deletions(-) create mode 100644 test/test_pandas_integration_fuzz.py diff --git a/.gitignore b/.gitignore index 81a8bad3..1c747ac6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ rustup-init.exe perf.data* perf/*.svg +# Atheris Crash/OOM and other files +fuzz-artifact/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/proj.py b/proj.py index d48631eb..6eb84c3f 100755 --- a/proj.py +++ b/proj.py @@ -66,6 +66,12 @@ def build(): _run('python3', 'setup.py', 'build_ext', '--inplace') +@command +def build_fuzzing(): + _run('python3', 'setup.py', 'build_ext', '--inplace', + env={'TEST_QUESTDB_FUZZING': '1'}) + + @command def test(all=False, patch_path='1', *args): _run('cargo', 'test', cwd=PROJ_ROOT / 'pystr-to-utf8') @@ -76,6 +82,30 @@ def test(all=False, patch_path='1', *args): env=env) +@command +def test_fuzzing(*args): + import atheris + import pathlib + lib_path = pathlib.Path(atheris.path()) / 'asan_with_fuzzer.so' + if not lib_path.exists(): + sys.stderr.write(f'WARNING: {lib_path} not found\n') + sys.exit(42) + ld_preload = os.environ.get('LD_PRELOAD', '') + if ld_preload: + ld_preload += ':' + ld_preload += str(lib_path) + cmd = [ + 'python3', + 'test/test_pandas_integration_fuzz.py'] + list(args) + if not args: + cmd.extend([ + '-detect_leaks=0', + '-rss_limit_mb=32768', + '-artifact_prefix=fuzz-artifact/', + '-create_missing_dirs=1']) + _run(*cmd, env={'LD_PRELOAD': ld_preload}) + + @command def benchmark(*args): env = {'TEST_QUESTDB_PATCH_PATH': '1'} diff --git a/setup.py b/setup.py index 0b4cff6c..f871e695 100755 --- a/setup.py +++ b/setup.py @@ -21,6 +21,15 @@ WIN_32BIT_CARGO_TARGET = 'i686-pc-windows-msvc' +INSTRUMENT_FUZZING = False +if os.environ.get('TEST_QUESTDB_FUZZING') == '1': + INSTRUMENT_FUZZING = True + ORIG_CC = os.environ.get('CC') + os.environ['CC'] = "clang" + ORIG_CXX = os.environ.get('CXX') + os.environ['CXX'] = "clang++" + + def ingress_extension(): lib_prefix = '' lib_suffix = '' @@ -42,8 +51,12 @@ def ingress_extension(): else: questdb_client_lib_dir = questdb_rs_ffi_dir / 'target' / 'release' pystr_to_utf8_lib_dir = pystr_to_utf8_dir / 'target' / 'release' - extra_compile_args.append('-flto') - extra_link_args.append('-flto') + if INSTRUMENT_FUZZING: + extra_compile_args.append('-fsanitize=fuzzer-no-link') + extra_link_args.append('-fsanitize=fuzzer-no-link') + else: + extra_compile_args.append('-flto') + extra_link_args.append('-flto') if PLATFORM == 'darwin': lib_prefix = 'lib' @@ -114,13 +127,25 @@ def cargo_build(): if PLATFORM == 'win32' and MODE == '32bit': cargo_args.append(f'--target={WIN_32BIT_CARGO_TARGET}') + env = os.environ.copy() + if INSTRUMENT_FUZZING: + if ORIG_CC is not None: + env['CC'] = ORIG_CC + else: + del env['CC'] + if ORIG_CXX is not None: + env['CXX'] = ORIG_CXX + else: + del env['CXX'] subprocess.check_call( cargo_args, - cwd=str(PROJ_ROOT / 'c-questdb-client' / 'questdb-rs-ffi')) + cwd=str(PROJ_ROOT / 'c-questdb-client' / 'questdb-rs-ffi'), + env=env) subprocess.check_call( cargo_args, - cwd=str(PROJ_ROOT / 'pystr-to-utf8')) + cwd=str(PROJ_ROOT / 'pystr-to-utf8'), + env=env) class questdb_build_ext(build_ext): diff --git a/test/test_pandas_integration_fuzz.py b/test/test_pandas_integration_fuzz.py new file mode 100644 index 00000000..c9e00c98 --- /dev/null +++ b/test/test_pandas_integration_fuzz.py @@ -0,0 +1,187 @@ +""" +# On Linux, ensure `clang` is installed. +pyenv shell 3.10 +./proj clean +./proj build_fuzzing +./proj test_fuzzing +""" + +import sys +import struct +import patch_path +patch_path.patch() +from random import Random +import numpy as np +import pandas as pd +import pyarrow as pa +import re +import atheris + + +with atheris.instrument_imports(): + import questdb.ingress as qi + + +@atheris.instrument_func +def get_test_alphabet(): + include_ranges = [ + (0x0021, 0x0021), + (0x0023, 0x0026), + (0x0028, 0x007E), + (0x00A1, 0x00AC), + (0x00AE, 0x00FF), + (0x0100, 0x017F), + (0x0180, 0x024F), + (0x2C60, 0x2C7F), + (0x16A0, 0x16F0), + (0x0370, 0x0377), + (0x037A, 0x037E), + (0x0384, 0x038A), + (0x038C, 0x038C)] + return [ + chr(code_point) + for current_range in include_ranges + for code_point in range(current_range[0], current_range[1] + 1)] + + +TEST_ALPHABET = get_test_alphabet() + + +def get_random_unicode(rand, length, none_val_prob=0): + """ + Adapted from https://stackoverflow.com/questions/1477294 + """ + if none_val_prob and (rand.random() < none_val_prob): + return None + return ''.join(rand.choice(TEST_ALPHABET) for _ in range(length)) + + +class TooMany(Exception): + pass + + +class IllegalConstruct(Exception): + pass + + +@atheris.instrument_func +def gen_string_series(rand, n_rows, none_val_prob, length, dtype): + series_n_rows = n_rows + if dtype == 'categorical': + series_n_rows //= 4 + data = [ + get_random_unicode(rand, length, none_val_prob) + for _ in range(series_n_rows)] + if dtype == 'categorical': + data = data * 6 + data = data[:n_rows] + rand.shuffle(data) + return pd.Series(data, dtype=dtype) + + +@atheris.instrument_func +def gen_series_pyobj_str(rand, n_rows, none_val_prob): + return gen_string_series(rand, n_rows, none_val_prob, 6, 'object') + + +series_generators = [ + # gen_series_i8, + # gen_series_i16, + gen_series_pyobj_str] + + + +@atheris.instrument_func +def parse_input_bytes(input_bytes): + fdp = atheris.FuzzedDataProvider(input_bytes) + rand_seed = fdp.ConsumeUInt(1) + none_val_prob = fdp.ConsumeProbability() + table_name_type = fdp.ConsumeIntInRange(0, 4) + table_name_len = fdp.ConsumeIntInRange(1, 32) + n_cols = fdp.ConsumeIntInRange(10, 40) + col_generators = [ + series_generators[fdp.ConsumeIntInRange(0, len(series_generators) - 1)] + for _ in range(n_cols)] + n_rows = fdp.ConsumeIntInRange(10, 5000) + rand = Random(rand_seed) + series_list = [] + col_name = lambda: f'{get_random_unicode(rand, 4)}_{len(series_list)}' + table_name = None + table_name_col = None + symbols = 'auto' + at = None + if table_name_type == 0: + table_name = get_random_unicode(rand, table_name_len) + else: + table_name_col = col_name() + dtype = { + 1: 'object', + 2: 'string', + 3: 'string[pyarrow]', + 4: 'category'}[table_name_type] + series = gen_string_series(rand, n_rows, 0, table_name_len, dtype) + series_list.append((table_name_col, series)) + + for index in range(n_cols): + name = col_name() + series = col_generators[index](rand, n_rows, none_val_prob) + series_list.append((name, series)) + rand.shuffle(series_list) + series = dict([ + (name, series) + for name, series in series_list]) + df = pd.DataFrame(series) + return df, table_name, table_name_col, symbols, at + + +@atheris.instrument_func +def test_pandas(input_bytes): + # print(f'input_bytes: {input_bytes}') + try: + params = parse_input_bytes(input_bytes) + except (TooMany, IllegalConstruct): + return + df, table_name, table_name_col, symbols, at = params + + try: + BUF = qi.Buffer() + BUF.clear() + try: + BUF.pandas( + df, + table_name=table_name, + table_name_col=table_name_col, + symbols=symbols, + at=at) + except Exception as e: + if isinstance(e, (qi.IngressError)): + msg = str(e) + if 'Bad argument `table_name`' in msg: + return + if re.search(r'Failed .*Bad string.*', msg): + return + if re.search(r'Bad string .*: Column names', msg): + return + if 'Ensure at least one column is not null.' in msg: + return + raise e + except: + print('>>>>>>>>>') + print(f'input_bytes: {input_bytes!r}') + print(f'df: {df}') + print(f'table_name: {table_name}') + print(f'table_name_col: {table_name_col}') + print(f'symbols: {symbols}') + print(f'at: {at}') + print('<<<<<<<<<') + raise + + +def main(): + args = list(sys.argv) + atheris.Setup(args, test_pandas) + atheris.Fuzz() + + +if __name__ == "__main__": + main() From 5998a1c9ddefa66dd17b039fd3ab93dea710fa7a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 8 Dec 2022 12:33:49 +0000 Subject: [PATCH 110/147] Added support from taking the table name from the df.index.name, renamed 'data' to 'df' in code. --- src/questdb/ingress.pyx | 17 +++--- src/questdb/pandas_integration.pxi | 86 +++++++++++++++------------- test/test_pandas_integration.py | 34 ++++++++++- test/test_pandas_integration_fuzz.py | 37 ++++++------ 4 files changed, 107 insertions(+), 67 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 4c69578c..130075a6 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -869,7 +869,7 @@ cdef class Buffer: def pandas( self, - data, # : pd.DataFrame + df, # : pd.DataFrame *, table_name: Optional[str] = None, table_name_col: Union[None, int, str] = None, @@ -885,14 +885,15 @@ cdef class Buffer: This feature requires the ``pandas``, ``numpy` and ``pyarrow`` package to be installed. - :param data: The pandas DataFrame to serialize to the buffer. - :type data: pandas.DataFrame + :param df: The pandas DataFrame to serialize to the buffer. + :type df: pandas.DataFrame :param table_name: The name of the table to which the rows belong. If ``None``, the table name is taken from the ``table_name_col`` parameter. If both ``table_name`` and ``table_name_col`` are - ``None``, the table name is taken from the DataFrame's ``.name``. + ``None``, the table name is taken from the DataFrame's index + name (``df.index.name`` attribute). :type table_name: str or None :param table_name_col: The name or index of the column in the DataFrame @@ -901,7 +902,7 @@ cdef class Buffer: If ``None``, the table name is taken from the ``table_name`` parameter. If both ``table_name`` and ``table_name_col`` are ``None``, the table name is taken from the - DataFrame's ``.name``. + DataFrame's index name (``df.index.name`` attribute). If ``table_name_col`` is an integer, it is interpreted as the index of the column starting from ``0``. The index of the column can be @@ -988,7 +989,7 @@ cdef class Buffer: _pandas( self._impl, self._b, - data, + df, table_name, table_name_col, symbols, @@ -1345,7 +1346,7 @@ cdef class Sender: def pandas( self, - data, # : pd.DataFrame + df, # : pd.DataFrame *, table_name: Optional[str] = None, table_name_col: Union[None, int, str] = None, @@ -1387,7 +1388,7 @@ cdef class Sender: may have been transmitted to the server already. """ self._buffer.pandas( - data, + df, table_name=table_name, table_name_col=table_name_col, symbols=symbols, diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 09acadbe..bf88b46b 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -442,16 +442,16 @@ cdef object _pandas_may_import_deps(): _PYARROW = pyarrow -cdef object _pandas_check_is_dataframe(object data): - if not isinstance(data, _PANDAS.DataFrame): +cdef object _pandas_check_is_dataframe(object df): + if not isinstance(df, _PANDAS.DataFrame): raise TypeError( - f'Bad argument `data`: Expected {_fqn(_PANDAS.DataFrame)}, ' + - f'not an object of type {_fqn(type(data))}.') + f'Bad argument `df`: Expected {_fqn(_PANDAS.DataFrame)}, ' + + f'not an object of type {_fqn(type(df))}.') cdef ssize_t _pandas_resolve_table_name( qdb_pystr_buf* b, - object data, + object df, list pandas_cols, col_t_arr* cols, object table_name, @@ -459,18 +459,9 @@ cdef ssize_t _pandas_resolve_table_name( size_t col_count, line_sender_table_name* name_out) except -2: """ - Return a tuple-pair of: - * int column index - * object - - If the column index is -1, then `name_out` is set and either the returned - object is None or a bytes object to track ownership of data in `name_out`. - - Alternatively, if the returned column index > 0, then `name_out` is not set - and the column index relates to which pandas column contains the table name - on a per-row basis. In such case, the object is always None. + Resolve the table name string or column. - This method validates input and may raise. + Returns -1 if the table name is a string, otherwise the column index. """ cdef size_t col_index = 0 cdef PandasCol pandas_col @@ -491,7 +482,7 @@ cdef ssize_t _pandas_resolve_table_name( raise TypeError('Bad argument `table_name`: Must be str.') elif table_name_col is not None: if isinstance(table_name_col, str): - _pandas_get_loc(data, table_name_col, 'table_name_col', &col_index) + _pandas_get_loc(df, table_name_col, 'table_name_col', &col_index) elif isinstance(table_name_col, int): _bind_col_index( 'table_name_col', table_name_col, col_count, &col_index) @@ -509,9 +500,25 @@ cdef ssize_t _pandas_resolve_table_name( name_out.len = 0 name_out.buf = NULL return col_index + elif df.index.name: + if not isinstance(df.index.name, str): + raise IngressError( + IngressErrorCode.BadDataFrame, + 'Bad dataframe index name as table name: Expected str, ' + + f'not an object of type {_fqn(type(df.index.name))}.') + + # If the index has a name, use that as the table name. + try: + str_to_table_name_copy(b, df.index.name, name_out) + return -1 # Magic value for "no column index". + except IngressError as ie: + raise IngressError( + IngressErrorCode.BadDataFrame, + f'Bad dataframe index name as table name: {ie}') else: raise ValueError( - 'Must specify at least one of `table_name` or `table_name_col`.') + 'Must specify at least one of `table_name` or `table_name_col`, ' + + 'or set the dataframe index name (df.index.name = \'tbl_name\').') cdef void_int _bind_col_index( @@ -569,7 +576,7 @@ cdef class PandasCol: cdef void_int _pandas_resolve_symbols( - object data, + object df, list pandas_cols, col_t_arr* cols, ssize_t table_name_col, @@ -602,7 +609,7 @@ cdef void_int _pandas_resolve_symbols( 'of column names (str) or indices (int).') for symbol in symbols: if isinstance(symbol, str): - _pandas_get_loc(data, symbol, 'symbols', &col_index) + _pandas_get_loc(df, symbol, 'symbols', &col_index) elif isinstance(symbol, int): _bind_col_index('symbol', symbol, cols.size, &col_index) else: @@ -616,7 +623,7 @@ cdef void_int _pandas_resolve_symbols( if (at_col >= 0) and (col_index == at_col): raise ValueError( f'Bad argument `symbols`: Cannot use the `at` column ' + - f'({data.columns[at_col]!r}) as a symbol column.') + f'({df.columns[at_col]!r}) as a symbol column.') pandas_col = pandas_cols[col_index] col = &cols.d[col_index] _pandas_check_column_is_str( @@ -627,13 +634,13 @@ cdef void_int _pandas_resolve_symbols( cdef void_int _pandas_get_loc( - object data, str col_name, str arg_name, + object df, str col_name, str arg_name, size_t* col_index_out) except -1: """ Return the column index for `col_name`. """ try: - col_index_out[0] = data.columns.get_loc(col_name) + col_index_out[0] = df.columns.get_loc(col_name) except KeyError: raise KeyError( f'Bad argument `{arg_name}`: ' + @@ -658,7 +665,7 @@ cdef object _pandas_is_supported_datetime(object dtype): cdef ssize_t _pandas_resolve_at( - object data, + object df, col_t_arr* cols, object at, size_t col_count, @@ -676,7 +683,7 @@ cdef ssize_t _pandas_resolve_at( at_value_out[0] = datetime_to_nanos(at) return -1 elif isinstance(at, str): - _pandas_get_loc(data, at, 'at', &col_index) + _pandas_get_loc(df, at, 'at', &col_index) elif isinstance(at, int): _bind_col_index('at', at, col_count, &col_index) else: @@ -684,7 +691,7 @@ cdef ssize_t _pandas_resolve_at( f'Bad argument `at`: Unsupported type {_fqn(type(at))}. ' + 'Must be one of: None, TimestampNanos, datetime, ' + 'int (column index), str (colum name)') - dtype = data.dtypes[col_index] + dtype = df.dtypes[col_index] if _pandas_is_supported_datetime(dtype): at_value_out[0] = _AT_IS_SET_BY_COLUMN col = &cols.d[col_index] @@ -1059,7 +1066,7 @@ cdef int _pandas_compare_cols(const void* lhs, const void* rhs) nogil: cdef void_int _pandas_resolve_args( - object data, + object df, object table_name, object table_name_col, object symbols, @@ -1074,21 +1081,20 @@ cdef void_int _pandas_resolve_args( cdef ssize_t at_col cdef list pandas_cols = [ - PandasCol(name, data.dtypes[index], series) - for index, (name, series) in enumerate(data.items())] + PandasCol(name, df.dtypes[index], series) + for index, (name, series) in enumerate(df.items())] _pandas_resolve_cols(b, pandas_cols, cols, any_cols_need_gil_out) name_col = _pandas_resolve_table_name( b, - data, + df, pandas_cols, cols, table_name, table_name_col, col_count, c_table_name_out) - at_col = _pandas_resolve_at(data, cols, at, col_count, at_value_out) - _pandas_resolve_symbols( - data, pandas_cols, cols, name_col, at_col, symbols) + at_col = _pandas_resolve_at(df, cols, at, col_count, at_value_out) + _pandas_resolve_symbols(df, pandas_cols, cols, name_col, at_col, symbols) _pandas_resolve_cols_target_name_and_dc(b, pandas_cols, cols) qsort(cols.d, col_count, sizeof(col_t), _pandas_compare_cols) @@ -2069,7 +2075,7 @@ cdef size_t _CELL_GIL_BLIP_INTERVAL = 40000 cdef void_int _pandas( line_sender_buffer* impl, qdb_pystr_buf* b, - object data, + object df, object table_name, object table_name_col, object symbols, @@ -2090,9 +2096,9 @@ cdef void_int _pandas( cdef bint was_serializing_cell = False _pandas_may_import_deps() - _pandas_check_is_dataframe(data) - row_count = len(data) - col_count = len(data.columns) + _pandas_check_is_dataframe(df) + row_count = len(df) + col_count = len(df.columns) if (col_count == 0) or (row_count == 0): return 0 # Nothing to do. @@ -2100,7 +2106,7 @@ cdef void_int _pandas( qdb_pystr_buf_clear(b) cols = col_t_arr_new(col_count) _pandas_resolve_args( - data, + df, table_name, table_name_col, symbols, @@ -2176,9 +2182,9 @@ cdef void_int _pandas( raise IngressError( IngressErrorCode.BadDataFrame, 'Failed to serialize value of column ' + - repr(data.columns[col.orig_index]) + + repr(df.columns[col.orig_index]) + f' at row index {row_index} (' + - repr(data.iloc[row_index, col.orig_index]) + + repr(df.iloc[row_index, col.orig_index]) + f'): {e} [dc={col.dispatch_code}]') from e elif (isinstance(e, IngressError) and (e.code == IngressErrorCode.InvalidApiCall)): diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index 00bdba36..594a6f8f 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -140,6 +140,37 @@ def test_basic(self): 't2,A=a2,D=a2 E=2.0,F=2i 1520726400000000000\n' + 't1,A=a3,B=b3,C=b3,D=a3 E=3.0,F=3i 1520812800000000000\n') + def test_named_dataframe(self): + df = pd.DataFrame({ + 'a': [1, 2, 3], + 'b': ['a', 'b', 'c']}) + df.index.name = 'table_name' + buf = _pandas(df) + self.assertEqual( + buf, + 'table_name a=1i,b="a"\n' + + 'table_name a=2i,b="b"\n' + + 'table_name a=3i,b="c"\n') + + buf = _pandas(df, table_name='tbl1') + self.assertEqual( + buf, + 'tbl1 a=1i,b="a"\n' + + 'tbl1 a=2i,b="b"\n' + + 'tbl1 a=3i,b="c"\n') + + buf = _pandas(df, table_name_col='b') + self.assertEqual( + buf, + 'a a=1i\n' + + 'b a=2i\n' + + 'c a=3i\n') + + df.index.name = 42 # bad type, not str + with self.assertRaisesRegex(qi.IngressError, + 'Bad dataframe index name as table.*: Expected str, not.*int.'): + _pandas(df) + def test_row_of_nulls(self): df = pd.DataFrame({'a': ['a1', None, 'a3']}) with self.assertRaisesRegex( @@ -1266,11 +1297,8 @@ def test_all_nulls_pyobj_col(self): 'tbl1 b=2i\n' + 'tbl1 b=3i\n') - -# TODO: Test all datatypes, but one, two, 10 and 1000 rows. Include None, NA and NaN. # TODO: Test all datatypes, but multiple row chunks. # TODO: Test datetime `at` argument with timezone. -# TODO: Test `df.name = 'foo'` if __name__ == '__main__': diff --git a/test/test_pandas_integration_fuzz.py b/test/test_pandas_integration_fuzz.py index c9e00c98..18179922 100644 --- a/test/test_pandas_integration_fuzz.py +++ b/test/test_pandas_integration_fuzz.py @@ -10,8 +10,8 @@ import struct import patch_path patch_path.patch() -from random import Random import numpy as np +from numpy.random import Generator, PCG64 import pandas as pd import pyarrow as pa import re @@ -56,14 +56,6 @@ def get_random_unicode(rand, length, none_val_prob=0): return ''.join(rand.choice(TEST_ALPHABET) for _ in range(length)) -class TooMany(Exception): - pass - - -class IllegalConstruct(Exception): - pass - - @atheris.instrument_func def gen_string_series(rand, n_rows, none_val_prob, length, dtype): series_n_rows = n_rows @@ -79,14 +71,30 @@ def gen_string_series(rand, n_rows, none_val_prob, length, dtype): return pd.Series(data, dtype=dtype) +def gen_numpy_series(rand, n_rows, dtype): + return pd.Series( + rand.integers( + np.iinfo(dtype).min, + np.iinfo(dtype).max, + size=n_rows, + dtype=dtype)) + + +@atheris.instrument_func +def gen_series_i8_numpy(rand, n_rows, none_val_prob): + return gen_numpy_series(rand, n_rows, np.int8) + + @atheris.instrument_func def gen_series_pyobj_str(rand, n_rows, none_val_prob): return gen_string_series(rand, n_rows, none_val_prob, 6, 'object') +# TODO: Test all datatypes +# TODO: Include None, NA and NaN. series_generators = [ - # gen_series_i8, - # gen_series_i16, + gen_series_i8_numpy, + # gen_series_i16_numpy, gen_series_pyobj_str] @@ -103,7 +111,7 @@ def parse_input_bytes(input_bytes): series_generators[fdp.ConsumeIntInRange(0, len(series_generators) - 1)] for _ in range(n_cols)] n_rows = fdp.ConsumeIntInRange(10, 5000) - rand = Random(rand_seed) + rand = Generator(PCG64(rand_seed)) series_list = [] col_name = lambda: f'{get_random_unicode(rand, 4)}_{len(series_list)}' table_name = None @@ -137,10 +145,7 @@ def parse_input_bytes(input_bytes): @atheris.instrument_func def test_pandas(input_bytes): # print(f'input_bytes: {input_bytes}') - try: - params = parse_input_bytes(input_bytes) - except (TooMany, IllegalConstruct): - return + params = parse_input_bytes(input_bytes) df, table_name, table_name_col, symbols, at = params try: From be0407c13f1c81e308f99d9d113a55c512af6dc2 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 13 Dec 2022 04:45:54 +1300 Subject: [PATCH 111/147] General fixes and testcases for handling timestamps. --- src/questdb/ingress.pyx | 148 +++++++++++++++++++++-------- src/questdb/pandas_integration.pxi | 19 ++-- test/test.py | 48 ++++++++++ test/test_pandas_integration.py | 63 ++++++++++++ 4 files changed, 230 insertions(+), 48 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 130075a6..3616b06c 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -36,6 +36,7 @@ from libc.stdint cimport uint8_t, uint64_t, int64_t, uint32_t, uintptr_t, \ from libc.stdlib cimport malloc, calloc, realloc, free, abort, qsort from libc.string cimport strncmp, memset from libc.math cimport isnan +from libc.errno cimport errno from cpython.datetime cimport datetime from cpython.bool cimport bool from cpython.weakref cimport PyWeakref_NewRef, PyWeakref_GetObject @@ -66,6 +67,13 @@ import pathlib import sys +# For `get_time_now_ns` and `get_time_now_us` functions. +IF UNAME_SYSNAME == 'Windows': + import time +ELSE: + from posix.time cimport timespec, clock_gettime, CLOCK_REALTIME + + class IngressErrorCode(Enum): """Category of Error.""" CouldNotResolveAddr = line_sender_error_could_not_resolve_addr @@ -333,40 +341,70 @@ cdef int64_t datetime_to_nanos(datetime dt): (dt.microsecond * 1000)) +cdef int64_t get_time_now_us() except -1: + """ + Get the current time in microseconds. + """ + IF UNAME_SYSNAME == 'Windows': + return time.time_ns() // 1000 + ELSE: + cdef timespec ts + if clock_gettime(CLOCK_REALTIME, &ts) != 0: + raise OSError(errno, 'clock_gettime(CLOCK_REALTIME, &ts) failed') + return ts.tv_sec * 1000000 + ts.tv_nsec // 1000 + + +cdef int64_t get_time_now_ns() except -1: + """ + Get the current time in nanoseconds. + """ + IF UNAME_SYSNAME == 'Windows': + return time.time_ns() + ELSE: + cdef timespec ts + if clock_gettime(CLOCK_REALTIME, &ts) != 0: + raise OSError(errno, 'clock_gettime(CLOCK_REALTIME, &ts) failed') + return ts.tv_sec * 1000000000 + ts.tv_nsec + + cdef class TimestampMicros: """ - A timestamp in microseconds since the UNIX epoch. + A timestamp in microseconds since the UNIX epoch (UTC). - You may construct a ``TimestampMicros`` from an integer or a ``datetime``. + You may construct a ``TimestampMicros`` from an integer or a + ``datetime.datetime``, or simply call the :func:`TimestampMicros.now` + method. .. code-block:: python - # Can't be negative. - TimestampMicros(1657888365426838016) - - # Careful with the timezeone! - TimestampMicros.from_datetime(datetime.datetime.utcnow()) + # Recommended way to get the current timestamp. + TimestampMicros.now() - When constructing from a ``datetime``, you should take extra care - to ensure that the timezone is correct. + # The above is equivalent to: + TimestampMicros(time.time_ns() // 1000) - For example, ``datetime.now()`` implies the `local` timezone which - is probably not what you want. + # You can provide a numeric timestamp too. It can't be negative. + TimestampMicros(1657888365426838) - When constructing the ``datetime`` object explicity, you pass in the - timezone to use. + ``TimestampMicros`` can also be constructed from a ``datetime.datetime`` + object. .. code-block:: python TimestampMicros.from_datetime( - datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc)) + datetime.datetime.now(tz=datetime.timezone.utc)) + We recommend that when using ``datetime`` objects, you explicitly pass in + the timezone to use. This is because ``datetime`` objects without an + associated timezone are assumed to be in the local timezone and it is easy + to make mistakes (e.g. passing ``datetime.datetime.utcnow()`` is a likely + bug). """ cdef int64_t _value def __cinit__(self, value: int): if value < 0: - raise ValueError('value must positive integer.') + raise ValueError('value must be a positive integer.') self._value = value @classmethod @@ -378,46 +416,57 @@ cdef class TimestampMicros: raise TypeError('dt must be a datetime object.') return cls(datetime_to_micros(dt)) + @classmethod + def now(cls): + """ + Construct a ``TimestampMicros`` from the current time as UTC. + """ + cdef int64_t value = get_time_now_us() + return cls(value) + @property def value(self) -> int: - """Number of microseconds.""" + """Number of microseconds (Unix epoch timestamp, UTC).""" return self._value cdef class TimestampNanos: """ - A timestamp in nanoseconds since the UNIX epoch. + A timestamp in nanoseconds since the UNIX epoch (UTC). - You may construct a ``TimestampNanos`` from an integer or a ``datetime``. + You may construct a ``TimestampNanos`` from an integer or a + ``datetime.datetime``, or simply call the :func:`TimestampNanos.now` + method. .. code-block:: python - # Can't be negative. - TimestampNanos(1657888365426838016) - - # Careful with the timezeone! - TimestampNanos.from_datetime(datetime.datetime.utcnow()) + # Recommended way to get the current timestamp. + TimestampNanos.now() - When constructing from a ``datetime``, you should take extra care - to ensure that the timezone is correct. + # The above is equivalent to: + TimestampNanos(time.time_ns()) - For example, ``datetime.now()`` implies the `local` timezone which - is probably not what you want. + # You can provide a numeric timestamp too. It can't be negative. + TimestampNanos(1657888365426838016) - When constructing the ``datetime`` object explicity, you pass in the - timezone to use. + ``TimestampNanos`` can also be constructed from a ``datetime`` object. .. code-block:: python - TimestampMicros.from_datetime( - datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc)) + TimestampNanos.from_datetime( + datetime.datetime.now(tz=datetime.timezone.utc)) + We recommend that when using ``datetime`` objects, you explicitly pass in + the timezone to use. This is because ``datetime`` objects without an + associated timezone are assumed to be in the local timezone and it is easy + to make mistakes (e.g. passing ``datetime.datetime.utcnow()`` is a likely + bug). """ cdef int64_t _value def __cinit__(self, value: int): if value < 0: - raise ValueError('value must positive integer.') + raise ValueError('value must be a positive integer.') self._value = value @classmethod @@ -429,9 +478,17 @@ cdef class TimestampNanos: raise TypeError('dt must be a datetime object.') return cls(datetime_to_nanos(dt)) + @classmethod + def now(cls): + """ + Construct a ``TimestampNanos`` from the current time as UTC. + """ + cdef int64_t value = get_time_now_ns() + return cls(value) + @property def value(self) -> int: - """Number of nanoseconds.""" + """Number of nanoseconds (Unix epoch timestamp, UTC).""" return self._value @@ -811,7 +868,7 @@ cdef class Buffer: columns={ 'temperature': 24.5, 'humidity': 0.5}, - at=datetime.datetime.utcnow()) + at=datetime.datetime.now(tz=datetime.timezone.utc)) Python strings passed as values to ``symbols`` are going to be encoded @@ -930,24 +987,31 @@ cdef class Buffer: You can specify a single value for all rows or column name or index. If ``None``, timestamp is assigned by the server for all rows. - If ``datetime``, the timestamp is converted to nanoseconds. - A ``datetime`` object is assumed to be in the UTC timezone unless - one is specified explicitly (so call ``datetime.utcnow()`` instead - of ``datetime.now()`` for the current timestamp). To pass in a timestamp explicity as an integer use the - ``TimestampNanos`` wrapper type. + ``TimestampNanos`` wrapper type. To get the current timestamp, + use ``TimestampNanos.now()``. + When passing a ``datetime.datetime`` object, the timestamp is + converted to nanoseconds. + A ``datetime`` object is assumed to be in the local timezone unless + one is specified explicitly (so call + ``datetime.datetime.now(tz=datetime.timezone.utc)`` instead + of ``datetime.datetime.utcnow()`` for the current timestamp to + avoid bugs). To specify a different timestamp for each row, pass in a column name (``str``) or index (``int``, 0-based index, negative index supported): In this case, the column needs to be of dtype - ``datetime64[ns]`` (assumed to be in the UTC timezone) or + ``datetime64[ns]`` (assumed to be in the **UTC timezone** and not + local, due to differences in Pandas and Python datetime handling) or ``datetime64[ns, tz]``. When a timezone is specified in the column, it is converted to UTC automatically. A timestamp column can also contain ``None`` values. The server will assign the current timestamp to those rows. - Note that the timestamp is always converted to nanoseconds and in - the UTC timezone. Timezone information is dropped before sending. + + **Note**: All timestamps are always converted to nanoseconds and in + the UTC timezone. Timezone information is dropped before sending and + QuestDB will not store any timezone information. :type at: TimestampNanos, datetime.datetime, int or str or None **Note**: It is an error to specify both ``table_name`` and diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index bf88b46b..fee64cfa 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -647,8 +647,9 @@ cdef void_int _pandas_get_loc( f'Column {col_name!r} not found in the dataframe.') -# The -1 value is safe to use as a sentinel because the TimestampNanos type -# already validates that the value is >= 0. +# The values -2 and -1 are safe to use as a sentinel because the TimestampNanos +# type already validates that the value is >= 0. +cdef int64_t _AT_IS_SERVER_NOW = -2 cdef int64_t _AT_IS_SET_BY_COLUMN = -1 @@ -673,13 +674,19 @@ cdef ssize_t _pandas_resolve_at( cdef size_t col_index cdef object dtype cdef PandasCol pandas_col + cdef TimestampNanos at_nanos if at is None: - at_value_out[0] = 0 # Special value for `at_now`. + at_value_out[0] = _AT_IS_SERVER_NOW return -1 elif isinstance(at, TimestampNanos): - at_value_out[0] = at._value + at_nanos = at + at_value_out[0] = at_nanos._value return -1 elif isinstance(at, datetime): + if at.timestamp() < 0: + raise ValueError( + 'Bad argument `at`: Cannot use a datetime before the ' + + 'Unix epoch (1970-01-01 00:00:00).') at_value_out[0] = datetime_to_nanos(at) return -1 elif isinstance(at, str): @@ -2165,11 +2172,11 @@ cdef void_int _pandas( was_serializing_cell = False # Fixed "at" value (not from a column). - if at_value == 0: + if at_value == _AT_IS_SERVER_NOW: if not line_sender_buffer_at_now(impl, &err): _ensure_has_gil(&gs) raise c_err_to_py(err) - elif at_value > 0: + elif at_value >= 0: if not line_sender_buffer_at(impl, at_value, &err): _ensure_has_gil(&gs) raise c_err_to_py(err) diff --git a/test/test.py b/test/test.py index 6b205664..5e395fb4 100755 --- a/test/test.py +++ b/test/test.py @@ -445,6 +445,54 @@ def test_bad_init_args(self): qi.Sender(host='localhost', port=9009, max_name_len=-1) +class TestBases: + class Timestamp(unittest.TestCase): + def test_from_int(self): + ns = 1670857929778202000 + num = ns // self.ns_scale + ts = self.timestamp_cls(num) + self.assertEqual(ts.value, num) + + ts0 = self.timestamp_cls(0) + self.assertEqual(ts0.value, 0) + + with self.assertRaisesRegex(ValueError, 'value must be a positive'): + self.timestamp_cls(-1) + + def test_from_datetime(self): + utc = datetime.timezone.utc + + dt1 = datetime.datetime(2022, 1, 1, 12, 0, 0, 0, tzinfo=utc) + ts1 = self.timestamp_cls.from_datetime(dt1) + self.assertEqual(ts1.value, 1641038400000000000 // self.ns_scale) + self.assertEqual( + ts1.value, + int(dt1.timestamp() * 1000000000 // self.ns_scale)) + + dt2 = datetime.datetime(1970, 1, 1, tzinfo=utc) + ts2 = self.timestamp_cls.from_datetime(dt2) + self.assertEqual(ts2.value, 0) + + with self.assertRaisesRegex(ValueError, 'value must be a positive'): + self.timestamp_cls.from_datetime( + datetime.datetime(1969, 12, 31, tzinfo=utc)) + + dt_naive = datetime.datetime(2022, 1, 1, 12, 0, 0, 0, + tzinfo=utc).astimezone(None).replace(tzinfo=None) + ts3 = self.timestamp_cls.from_datetime(dt_naive) + self.assertEqual(ts3.value, 1641038400000000000 // self.ns_scale) + + +class TestTimestampMicros(TestBases.Timestamp): + timestamp_cls = qi.TimestampMicros + ns_scale = 1000 + + +class TestTimestampNanos(TestBases.Timestamp): + timestamp_cls = qi.TimestampNanos + ns_scale = 1 + + if __name__ == '__main__': if os.environ.get('TEST_QUESTDB_PROFILE') == '1': import cProfile diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index 594a6f8f..0bb57df6 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -4,6 +4,7 @@ import os sys.dont_write_bytecode = True import unittest +import datetime as dt try: import zoneinfo @@ -171,6 +172,68 @@ def test_named_dataframe(self): 'Bad dataframe index name as table.*: Expected str, not.*int.'): _pandas(df) + def test_at_good(self): + df = pd.DataFrame({ + 'a': [1, 2, 3], + 'b': ['a', 'b', 'c']}) + df.index.name = 'test_at_good' + with self.assertRaisesRegex(KeyError, + 'Bad argument `at`: Column .2018-03.* not found .* dataframe.'): + _pandas(df, at='2018-03-10T00:00:00Z') + + # Same timestamp, specified in various ways. + t1_setup = dt.datetime(2018, 3, 10, 0, 0, 0, tzinfo=dt.timezone.utc) + t1 = t1_setup.astimezone(tz=None).replace(tzinfo=None) # naive, local + t2 = dt.datetime(2018, 3, 10, 0, 0, 0, tzinfo=dt.timezone.utc) + t3 = dt.datetime(2018, 3, 9, 19, 0, 0, tzinfo=_TZ) + t4 = qi.TimestampNanos(1520640000000000000) + t5 = qi.TimestampNanos.from_datetime(t1) + t6 = qi.TimestampNanos.from_datetime(t2) + t7 = qi.TimestampNanos.from_datetime(t3) + timestamps = [t1, t2, t3, t4, t5, t6, t7] + for ts in timestamps: + buf = _pandas(df, table_name='tbl1', at=ts) + self.assertEqual( + buf, + 'tbl1 a=1i,b="a" 1520640000000000000\n' + + 'tbl1 a=2i,b="b" 1520640000000000000\n' + + 'tbl1 a=3i,b="c" 1520640000000000000\n') + + def test_at_neg(self): + n1 = dt.datetime(1965, 1, 1, 0, 0, 0, tzinfo=dt.timezone.utc) + n2 = dt.datetime(1965, 1, 1, 0, 0, 0, tzinfo=_TZ) + n3 = dt.datetime(1965, 1, 1, 0, 0, 0) + neg_timestamps = [n1, n2, n3] + for ts in neg_timestamps: + with self.assertRaisesRegex(ValueError, + 'Bad.*`at`: Cannot .* before the Unix epoch .1970-01-01.*'): + _pandas(DF2, at=ts, table_name='test_at_neg') + + def test_at_ts_0(self): + df = pd.DataFrame({ + 'a': [1, 2, 3], + 'b': ['a', 'b', 'c']}) + df.index.name = 'test_at_ts_0' + + # Epoch 0, specified in various ways. + e1_setup = dt.datetime(1970, 1, 1, 0, 0, 0, tzinfo=dt.timezone.utc) + e1 = e1_setup.astimezone(tz=None).replace(tzinfo=None) # naive, local + e2 = dt.datetime(1970, 1, 1, 0, 0, 0, tzinfo=dt.timezone.utc) + e3 = dt.datetime(1969, 12, 31, 19, 0, 0, tzinfo=_TZ) + e4 = qi.TimestampNanos(0) + e5 = qi.TimestampNanos.from_datetime(e1) + e6 = qi.TimestampNanos.from_datetime(e2) + e7 = qi.TimestampNanos.from_datetime(e3) + edge_timestamps = [e1, e2, e3, e4, e5, e6, e7] + + for ts in edge_timestamps: + buf = _pandas(df, table_name='tbl1', at=ts) + self.assertEqual( + buf, + 'tbl1 a=1i,b="a" 0\n' + + 'tbl1 a=2i,b="b" 0\n' + + 'tbl1 a=3i,b="c" 0\n') + def test_row_of_nulls(self): df = pd.DataFrame({'a': ['a1', None, 'a3']}) with self.assertRaisesRegex( From 24ee3cd0dc82f89ef26dd20e6c9c2c4436f38f7c Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 12 Dec 2022 17:02:11 +0000 Subject: [PATCH 112/147] Should fix tests in CI. --- test/test_pandas_integration.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index 0bb57df6..59bf5180 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -6,9 +6,13 @@ import unittest import datetime as dt +BROKEN_TIMEZONES = True + try: import zoneinfo _TZ = zoneinfo.ZoneInfo('America/New_York') + # PyTz backup data (which we rely on) isn't accurate for epoch-0 testing. + BROKEN_TIMEZONES = os.name == 'nt' except ImportError: import pytz _TZ = pytz.timezone('America/New_York') @@ -172,6 +176,7 @@ def test_named_dataframe(self): 'Bad dataframe index name as table.*: Expected str, not.*int.'): _pandas(df) + @unittest.skipIf(BROKEN_TIMEZONES, 'requires accurate timezones') def test_at_good(self): df = pd.DataFrame({ 'a': [1, 2, 3], @@ -209,6 +214,7 @@ def test_at_neg(self): 'Bad.*`at`: Cannot .* before the Unix epoch .1970-01-01.*'): _pandas(DF2, at=ts, table_name='test_at_neg') + @unittest.skipIf(BROKEN_TIMEZONES, 'requires accurate timezones') def test_at_ts_0(self): df = pd.DataFrame({ 'a': [1, 2, 3], From e8d8daab1098d582363943851dca7d7843e4c251 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 12 Dec 2022 17:23:03 +0000 Subject: [PATCH 113/147] Extra testing of 'TimestampXXX.now()' and hopefully fixing CI. --- test/test.py | 7 +++++++ test/test_pandas_integration.py | 1 + 2 files changed, 8 insertions(+) diff --git a/test/test.py b/test/test.py index 5e395fb4..28678612 100755 --- a/test/test.py +++ b/test/test.py @@ -482,6 +482,13 @@ def test_from_datetime(self): ts3 = self.timestamp_cls.from_datetime(dt_naive) self.assertEqual(ts3.value, 1641038400000000000 // self.ns_scale) + def test_now(self): + expected = time.time_ns() // self.ns_scale + actual = self.timestamp_cls.now().value + delta = abs(expected - actual) + one_sec = 1000000000 // self.ns_scale + self.assertLess(delta, one_sec) + class TestTimestampMicros(TestBases.Timestamp): timestamp_cls = qi.TimestampMicros diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index 59bf5180..92b9c17c 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -204,6 +204,7 @@ def test_at_good(self): 'tbl1 a=2i,b="b" 1520640000000000000\n' + 'tbl1 a=3i,b="c" 1520640000000000000\n') + @unittest.skipIf(BROKEN_TIMEZONES, 'requires accurate timezones') def test_at_neg(self): n1 = dt.datetime(1965, 1, 1, 0, 0, 0, tzinfo=dt.timezone.utc) n2 = dt.datetime(1965, 1, 1, 0, 0, 0, tzinfo=_TZ) From 5f8e8eef6b00d6023e8db64d287afb8508408707 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 12 Dec 2022 17:31:50 +0000 Subject: [PATCH 114/147] CI fixup attempt. --- test/test.py | 9 +++++++++ test/test_pandas_integration.py | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/test/test.py b/test/test.py index 28678612..7c51ad80 100755 --- a/test/test.py +++ b/test/test.py @@ -10,6 +10,15 @@ import patch_path from mock_server import Server + +BROKEN_TIMEZONES = True +try: + import zoneinfo + BROKEN_TIMEZONES = os.name == 'nt' +except ImportError: + pass + + import questdb.ingress as qi if os.environ.get('TEST_QUESTDB_INTEGRATION') == '1': diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index 92b9c17c..d0d1ff0b 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -11,7 +11,6 @@ try: import zoneinfo _TZ = zoneinfo.ZoneInfo('America/New_York') - # PyTz backup data (which we rely on) isn't accurate for epoch-0 testing. BROKEN_TIMEZONES = os.name == 'nt' except ImportError: import pytz From 6b77da9e6b0209404cc9c33bb7169ac55fc89b37 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 12 Dec 2022 22:29:04 +0000 Subject: [PATCH 115/147] Fixing broken 32-bit binaries. --- src/questdb/ingress.pyx | 19 +++++++++++++++++-- test/test.py | 8 -------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 3616b06c..7b8c1403 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -341,6 +341,10 @@ cdef int64_t datetime_to_nanos(datetime dt): (dt.microsecond * 1000)) +cdef int64_t _US_SEC = 1000000 +cdef int64_t _NS_US = 1000 + + cdef int64_t get_time_now_us() except -1: """ Get the current time in microseconds. @@ -348,10 +352,14 @@ cdef int64_t get_time_now_us() except -1: IF UNAME_SYSNAME == 'Windows': return time.time_ns() // 1000 ELSE: + # Note: Y2K38 bug on 32-bit systems, but we don't care. cdef timespec ts if clock_gettime(CLOCK_REALTIME, &ts) != 0: raise OSError(errno, 'clock_gettime(CLOCK_REALTIME, &ts) failed') - return ts.tv_sec * 1000000 + ts.tv_nsec // 1000 + return (ts.tv_sec) * _US_SEC + (ts.tv_nsec) // _NS_US + + +cdef int64_t _NS_SEC = 1000000000 cdef int64_t get_time_now_ns() except -1: @@ -361,10 +369,11 @@ cdef int64_t get_time_now_ns() except -1: IF UNAME_SYSNAME == 'Windows': return time.time_ns() ELSE: + # Note: Y2K38 bug on 32-bit systems, but we don't care. cdef timespec ts if clock_gettime(CLOCK_REALTIME, &ts) != 0: raise OSError(errno, 'clock_gettime(CLOCK_REALTIME, &ts) failed') - return ts.tv_sec * 1000000000 + ts.tv_nsec + return (ts.tv_sec) * _NS_SEC + (ts.tv_nsec) cdef class TimestampMicros: @@ -429,6 +438,9 @@ cdef class TimestampMicros: """Number of microseconds (Unix epoch timestamp, UTC).""" return self._value + def __repr__(self): + return f'TimestampMicros.({self._value})' + cdef class TimestampNanos: """ @@ -491,6 +503,9 @@ cdef class TimestampNanos: """Number of nanoseconds (Unix epoch timestamp, UTC).""" return self._value + def __repr__(self): + return f'TimestampNanos({self.value})' + cdef class Sender cdef class Buffer diff --git a/test/test.py b/test/test.py index 7c51ad80..3116cd4c 100755 --- a/test/test.py +++ b/test/test.py @@ -11,14 +11,6 @@ from mock_server import Server -BROKEN_TIMEZONES = True -try: - import zoneinfo - BROKEN_TIMEZONES = os.name == 'nt' -except ImportError: - pass - - import questdb.ingress as qi if os.environ.get('TEST_QUESTDB_INTEGRATION') == '1': From aaf7e954de04786e6ffb89c36c63ec39f0cb1226 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 13 Dec 2022 13:55:31 +0000 Subject: [PATCH 116/147] Slimmed down 'col_t' type. --- src/questdb/ingress.pyx | 6 +- src/questdb/pandas_integration.pxi | 190 +++++++++++++++-------------- 2 files changed, 103 insertions(+), 93 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 7b8c1403..a4f7e8eb 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -769,7 +769,7 @@ cdef class Buffer: 'TimestampMicros', 'datetime.datetime')) raise TypeError( - f'Unsupported type: {type(value)}. Must be one of: {valid}') + f'Unsupported type: {_fqn(type(value))}. Must be one of: {valid}') cdef inline void_int _may_trigger_row_complete(self) except -1: cdef line_sender_error* err = NULL @@ -804,7 +804,7 @@ cdef class Buffer: self._at_dt(ts) else: raise TypeError( - f'Unsupported type: {type(ts)}. Must be one of: ' + + f'Unsupported type: {_fqn(type(ts))}. Must be one of: ' + 'TimestampNanos, datetime, None') cdef void_int _row( @@ -1321,7 +1321,7 @@ cdef class Sender: else: raise TypeError( 'tls must be a bool, a path or string pointing to CA file ' - f'or "insecure_skip_verify", not {type(tls)}') + f'or "insecure_skip_verify", not {_fqn(type(tls))}') if read_timeout is not None: line_sender_opts_read_timeout(self._opts, read_timeout) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index fee64cfa..5f6b25fb 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -294,17 +294,21 @@ cdef enum meta_target_t: meta_target_at = col_target_t.col_target_at -cdef struct col_t: - meta_target_t meta_target +cdef struct col_setup_t: + col_chunks_t chunks size_t orig_index - line_sender_column_name name Py_buffer pybuf ArrowSchema arrow_schema # Schema of first chunk. - col_chunks_t chunks - col_cursor_t cursor col_source_t source + meta_target_t meta_target col_target_t target + + +cdef struct col_t: col_dispatch_code_t dispatch_code # source + target. Determines serializer. + line_sender_column_name name + col_cursor_t cursor + col_setup_t* setup # Grouping to reduce size of struct. cdef void col_t_release(col_t* col): @@ -317,21 +321,24 @@ cdef void col_t_release(col_t* col): cdef size_t chunk_index cdef ArrowArray* chunk - if Py_buffer_obj_is_set(&col.pybuf): - PyBuffer_Release(&col.pybuf) # Note: Sets `col.pybuf.obj` to NULL. + if Py_buffer_obj_is_set(&col.setup.pybuf): + PyBuffer_Release(&col.setup.pybuf) # Note: Sets `col.pybuf.obj` to NULL. - for chunk_index in range(col.chunks.n_chunks): - chunk = &col.chunks.chunks[chunk_index] + for chunk_index in range(col.setup.chunks.n_chunks): + chunk = &col.setup.chunks.chunks[chunk_index] if chunk.release != NULL: chunk.release(chunk) memset(chunk, 0, sizeof(ArrowArray)) - if col.arrow_schema.release != NULL: - col.arrow_schema.release(&col.arrow_schema) + if col.setup.arrow_schema.release != NULL: + col.setup.arrow_schema.release(&col.setup.arrow_schema) + + free(col.setup.chunks.chunks) + col.setup.chunks.chunks = NULL + col.setup.chunks.n_chunks = 0 - free(col.chunks.chunks) - col.chunks.chunks = NULL - col.chunks.n_chunks = 0 + free(col.setup) + col.setup = NULL # Calloc'd array of col_t. @@ -349,8 +356,11 @@ cdef col_t_arr col_t_arr_blank(): cdef col_t_arr col_t_arr_new(size_t size): cdef col_t_arr arr + cdef size_t index arr.size = size arr.d = calloc(size, sizeof(col_t)) + for index in range(size): + arr.d[index].setup = calloc(1, sizeof(col_setup_t)) return arr @@ -495,8 +505,8 @@ cdef ssize_t _pandas_resolve_table_name( _pandas_check_column_is_str( 'Bad argument `table_name_col`: ', pandas_col, - col.source) - col.meta_target = meta_target_t.meta_target_table + col.setup.source) + col.setup.meta_target = meta_target_t.meta_target_table name_out.len = 0 name_out.buf = NULL return col_index @@ -590,18 +600,18 @@ cdef void_int _pandas_resolve_symbols( for col_index in range(cols.size): pandas_col = pandas_cols[col_index] col = &cols.d[col_index] - if col.meta_target == meta_target_t.meta_target_field: + if col.setup.meta_target == meta_target_t.meta_target_field: if isinstance(pandas_col.dtype, _PANDAS.CategoricalDtype): - col.meta_target = meta_target_t.meta_target_symbol + col.setup.meta_target = meta_target_t.meta_target_symbol elif symbols is False: pass elif symbols is True: for col_index in range(cols.size): col = &cols.d[col_index] - if col.source in _STR_SOURCES: + if col.setup.source in _STR_SOURCES: pandas_col = pandas_cols[col_index] - if col.meta_target == meta_target_t.meta_target_field: - col.meta_target = meta_target_t.meta_target_symbol + if col.setup.meta_target == meta_target_t.meta_target_field: + col.setup.meta_target = meta_target_t.meta_target_symbol else: if not isinstance(symbols, (tuple, list)): raise TypeError( @@ -629,8 +639,8 @@ cdef void_int _pandas_resolve_symbols( _pandas_check_column_is_str( 'Bad argument `symbols`: ', pandas_col, - col.source) - col.meta_target = meta_target_t.meta_target_symbol + col.setup.source) + col.setup.meta_target = meta_target_t.meta_target_symbol cdef void_int _pandas_get_loc( @@ -702,7 +712,7 @@ cdef ssize_t _pandas_resolve_at( if _pandas_is_supported_datetime(dtype): at_value_out[0] = _AT_IS_SET_BY_COLUMN col = &cols.d[col_index] - col.meta_target = meta_target_t.meta_target_at + col.setup.meta_target = meta_target_t.meta_target_at return col_index else: raise TypeError( @@ -712,11 +722,11 @@ cdef ssize_t _pandas_resolve_at( cdef void_int _pandas_alloc_chunks( size_t n_chunks, col_t* col) except -1: - col.chunks.n_chunks = n_chunks - col.chunks.chunks = calloc( - col.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. + col.setup.chunks.n_chunks = n_chunks + col.setup.chunks.chunks = calloc( + col.setup.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. sizeof(ArrowArray)) - if col.chunks.chunks == NULL: + if col.setup.chunks.chunks == NULL: raise MemoryError() @@ -738,25 +748,25 @@ cdef void_int _pandas_series_as_pybuf( try: # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. - get_buf_ret = PyObject_GetBuffer(nparr, &col.pybuf, PyBUF_SIMPLE) + get_buf_ret = PyObject_GetBuffer(nparr, &col.setup.pybuf, PyBUF_SIMPLE) except BufferError as be: raise TypeError( f'Bad column {pandas_col.name!r}: Expected a buffer, got ' + f'{pandas_col.series!r} ({_fqn(type(pandas_col.series))})') from be _pandas_alloc_chunks(1, col) - mapped = &col.chunks.chunks[0] + mapped = &col.setup.chunks.chunks[0] # Total number of elements. mapped.length = ( - col.pybuf.len // col.pybuf.itemsize) + col.setup.pybuf.len // col.setup.pybuf.itemsize) mapped.null_count = 0 mapped.offset = 0 mapped.n_buffers = 2 mapped.n_children = 0 mapped.buffers = calloc(2, sizeof(const void*)) mapped.buffers[0] = NULL - mapped.buffers[1] = col.pybuf.buf + mapped.buffers[1] = col.setup.pybuf.buf mapped.children = NULL mapped.dictionary = NULL mapped.release = _pandas_free_mapped_arrow # to cleanup allocated array. @@ -782,11 +792,11 @@ cdef void_int _pandas_series_as_arrow( array = chunks[chunk_index] if chunk_index == 0: chunks[chunk_index]._export_to_c( - &col.chunks.chunks[chunk_index], - &col.arrow_schema) + &col.setup.chunks.chunks[chunk_index], + &col.setup.arrow_schema) else: chunks[chunk_index]._export_to_c( - &col.chunks.chunks[chunk_index]) + &col.setup.chunks.chunks[chunk_index]) cdef const char* _ARROW_FMT_INT8 = "c" @@ -799,13 +809,13 @@ cdef void_int _pandas_category_series_as_arrow( PandasCol pandas_col, col_t* col) except -1: cdef const char* format _pandas_series_as_arrow(pandas_col, col) - format = col.arrow_schema.format + format = col.setup.arrow_schema.format if strncmp(format, _ARROW_FMT_INT8, 1) == 0: - col.source = col_source_t.col_source_str_i8_cat + col.setup.source = col_source_t.col_source_str_i8_cat elif strncmp(format, _ARROW_FMT_INT16, 1) == 0: - col.source = col_source_t.col_source_str_i16_cat + col.setup.source = col_source_t.col_source_str_i16_cat elif strncmp(format, _ARROW_FMT_INT32, 1) == 0: - col.source = col_source_t.col_source_str_i32_cat + col.setup.source = col_source_t.col_source_str_i32_cat else: raise IngressError( IngressErrorCode.BadDataFrame, @@ -813,7 +823,7 @@ cdef void_int _pandas_category_series_as_arrow( 'Unsupported arrow category index type. ' + f'Got {(format).decode("utf-8")!r}.') - format = col.arrow_schema.dictionary.format + format = col.setup.arrow_schema.dictionary.format if strncmp(format, _ARROW_FMT_SML_STR, 1) != 0: raise IngressError( IngressErrorCode.BadDataFrame, @@ -845,18 +855,18 @@ cdef void_int _pandas_series_sniff_pyobj( cdef PyObject** obj_arr cdef PyObject* obj _pandas_series_as_pybuf(pandas_col, col) - obj_arr = (col.pybuf.buf) + obj_arr = (col.setup.pybuf.buf) for el_index in range(n_elements): obj = obj_arr[el_index] if not _pandas_is_null_pyobj(obj): if PyBool_Check(obj): - col.source = col_source_t.col_source_bool_pyobj + col.setup.source = col_source_t.col_source_bool_pyobj elif PyLong_CheckExact(obj): - col.source = col_source_t.col_source_int_pyobj + col.setup.source = col_source_t.col_source_int_pyobj elif PyFloat_CheckExact(obj): - col.source = col_source_t.col_source_float_pyobj + col.setup.source = col_source_t.col_source_float_pyobj elif PyUnicode_CheckExact(obj): - col.source = col_source_t.col_source_str_pyobj + col.setup.source = col_source_t.col_source_str_pyobj elif PyBytes_CheckExact(obj): raise IngressError( IngressErrorCode.BadDataFrame, @@ -874,84 +884,84 @@ cdef void_int _pandas_series_sniff_pyobj( # We haven't returned yet, so we've hit an object column that # exclusively has null values. We will just skip this column. - col.source = col_source_t.col_source_nulls + col.setup.source = col_source_t.col_source_nulls cdef void_int _pandas_resolve_source_and_buffers( PandasCol pandas_col, col_t* col) except -1: cdef object dtype = pandas_col.dtype if isinstance(dtype, _NUMPY_BOOL): - col.source = col_source_t.col_source_bool_numpy + col.setup.source = col_source_t.col_source_bool_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.BooleanDtype): - col.source = col_source_t.col_source_bool_arrow + col.setup.source = col_source_t.col_source_bool_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT8): - col.source = col_source_t.col_source_u8_numpy + col.setup.source = col_source_t.col_source_u8_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT8): - col.source = col_source_t.col_source_i8_numpy + col.setup.source = col_source_t.col_source_i8_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT16): - col.source = col_source_t.col_source_u16_numpy + col.setup.source = col_source_t.col_source_u16_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT16): - col.source = col_source_t.col_source_i16_numpy + col.setup.source = col_source_t.col_source_i16_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT32): - col.source = col_source_t.col_source_u32_numpy + col.setup.source = col_source_t.col_source_u32_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT32): - col.source = col_source_t.col_source_i32_numpy + col.setup.source = col_source_t.col_source_i32_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT64): - col.source = col_source_t.col_source_u64_numpy + col.setup.source = col_source_t.col_source_u64_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT64): - col.source = col_source_t.col_source_i64_numpy + col.setup.source = col_source_t.col_source_i64_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt8Dtype): - col.source = col_source_t.col_source_u8_arrow + col.setup.source = col_source_t.col_source_u8_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int8Dtype): - col.source = col_source_t.col_source_i8_arrow + col.setup.source = col_source_t.col_source_i8_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt16Dtype): - col.source = col_source_t.col_source_u16_arrow + col.setup.source = col_source_t.col_source_u16_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int16Dtype): - col.source = col_source_t.col_source_i16_arrow + col.setup.source = col_source_t.col_source_i16_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt32Dtype): - col.source = col_source_t.col_source_u32_arrow + col.setup.source = col_source_t.col_source_u32_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int32Dtype): - col.source = col_source_t.col_source_i32_arrow + col.setup.source = col_source_t.col_source_i32_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt64Dtype): - col.source = col_source_t.col_source_u64_arrow + col.setup.source = col_source_t.col_source_u64_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int64Dtype): - col.source = col_source_t.col_source_i64_arrow + col.setup.source = col_source_t.col_source_i64_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_FLOAT32): - col.source = col_source_t.col_source_f32_numpy + col.setup.source = col_source_t.col_source_f32_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_FLOAT64): - col.source = col_source_t.col_source_f64_numpy + col.setup.source = col_source_t.col_source_f64_numpy _pandas_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.Float32Dtype): - col.source = col_source_t.col_source_f32_arrow + col.setup.source = col_source_t.col_source_f32_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Float64Dtype): - col.source = col_source_t.col_source_f64_arrow + col.setup.source = col_source_t.col_source_f64_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.StringDtype): if dtype.storage == 'pyarrow': - col.source = col_source_t.col_source_str_arrow + col.setup.source = col_source_t.col_source_str_arrow _pandas_series_as_arrow(pandas_col, col) elif dtype.storage == 'python': - col.source = col_source_t.col_source_str_pyobj + col.setup.source = col_source_t.col_source_str_pyobj _pandas_series_as_pybuf(pandas_col, col) else: raise IngressError( @@ -962,11 +972,11 @@ cdef void_int _pandas_resolve_source_and_buffers( _pandas_category_series_as_arrow(pandas_col, col) elif (isinstance(dtype, _NUMPY_DATETIME64_NS) and _pandas_is_supported_datetime(dtype)): - col.source = col_source_t.col_source_dt64ns_numpy + col.setup.source = col_source_t.col_source_dt64ns_numpy _pandas_series_as_pybuf(pandas_col, col) elif (isinstance(dtype, _PANDAS.DatetimeTZDtype) and _pandas_is_supported_datetime(dtype)): - col.source = col_source_t.col_source_dt64ns_tz_arrow + col.setup.source = col_source_t.col_source_dt64ns_tz_arrow _pandas_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_OBJECT): _pandas_series_sniff_pyobj(pandas_col, col) @@ -982,23 +992,23 @@ cdef void_int _pandas_resolve_target( PandasCol pandas_col, col_t* col) except -1: cdef col_target_t target cdef set target_sources - if col.meta_target in _DIRECT_META_TARGETS: - col.target = col.meta_target + if col.setup.meta_target in _DIRECT_META_TARGETS: + col.setup.target = col.setup.meta_target return 0 for target in _FIELD_TARGETS: target_sources = _TARGET_TO_SOURCES[target] - if col.source in target_sources: - col.target = target + if col.setup.source in target_sources: + col.setup.target = target return 0 raise IngressError( IngressErrorCode.BadDataFrame, - f'Could not map column source type (code {col.source} for ' + + f'Could not map column source type (code {col.setup.source} for ' + f'column {pandas_col.name!r} ' + f' ({pandas_col.dtype}) to any ILP type.') cdef void _pandas_init_cursor(col_t* col): - col.cursor.chunk = col.chunks.chunks + col.cursor.chunk = col.setup.chunks.chunks col.cursor.chunk_index = 0 col.cursor.offset = col.cursor.chunk.offset @@ -1024,15 +1034,15 @@ cdef void_int _pandas_resolve_cols( # * Finally, based on the source, any remaining "meta_target_field" # columns are converted to the appropriate target. # See: _pandas_resolve_col_targets_and_dc(..). - col.meta_target = meta_target_t.meta_target_field + col.setup.meta_target = meta_target_t.meta_target_field # We will sort columns later. The index will be used to achieve a stable # sort among columns with the same `.meta_target`. - col.orig_index = index + col.setup.orig_index = index _pandas_resolve_source_and_buffers(pandas_col, col) _pandas_init_cursor(col) - if col_source_needs_gil(col.source): + if col_source_needs_gil(col.setup.source): any_cols_need_gil_out[0] = True @@ -1047,29 +1057,29 @@ cdef void_int _pandas_resolve_cols_target_name_and_dc( col = &cols.d[index] pandas_col = pandas_cols[index] _pandas_resolve_target(pandas_col, col) - if col.source not in _TARGET_TO_SOURCES[col.target]: + if col.setup.source not in _TARGET_TO_SOURCES[col.setup.target]: raise ValueError( f'Bad value: Column {pandas_col.name!r} ' + f'({pandas_col.dtype}) is not ' + - f'supported as a {_TARGET_NAMES[col.target]} column.') + f'supported as a {_TARGET_NAMES[col.setup.target]} column.') col.dispatch_code = ( - col.source + col.target) + col.setup.source + col.setup.target) # Since we don't need to send the column names for 'table' and # 'at' columns, we don't need to validate and encode them as # column names. This allows unsupported names for these columns. - if ((col.meta_target != meta_target_t.meta_target_table) and - (col.meta_target != meta_target_t.meta_target_at)): + if ((col.setup.meta_target != meta_target_t.meta_target_table) and + (col.setup.meta_target != meta_target_t.meta_target_at)): str_to_column_name_copy(b, pandas_col.name, &col.name) cdef int _pandas_compare_cols(const void* lhs, const void* rhs) nogil: cdef col_t* lhs_col = lhs cdef col_t* rhs_col = rhs - cdef int source_diff = lhs_col.meta_target - rhs_col.meta_target + cdef int source_diff = lhs_col.setup.meta_target - rhs_col.setup.meta_target if source_diff != 0: return source_diff - return lhs_col.orig_index - rhs_col.orig_index + return lhs_col.setup.orig_index - rhs_col.setup.orig_index cdef void_int _pandas_resolve_args( @@ -2189,9 +2199,9 @@ cdef void_int _pandas( raise IngressError( IngressErrorCode.BadDataFrame, 'Failed to serialize value of column ' + - repr(df.columns[col.orig_index]) + + repr(df.columns[col.setup.orig_index]) + f' at row index {row_index} (' + - repr(df.iloc[row_index, col.orig_index]) + + repr(df.iloc[row_index, col.setup.orig_index]) + f'): {e} [dc={col.dispatch_code}]') from e elif (isinstance(e, IngressError) and (e.code == IngressErrorCode.InvalidApiCall)): From b9b2081b5815945b70178b410fde4af871972980 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 13 Dec 2022 15:29:57 +0000 Subject: [PATCH 117/147] Implemented (but not yet tested) pandas auto-flush logic. Also releasing GIL in general 'sender.flush' logic. --- src/questdb/ingress.pyx | 71 ++++-- src/questdb/pandas_integration.pxi | 345 ++++++++++++++++------------- 2 files changed, 241 insertions(+), 175 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index a4f7e8eb..8fde2f3a 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -74,6 +74,24 @@ ELSE: from posix.time cimport timespec, clock_gettime, CLOCK_REALTIME +cdef bint _has_gil(PyThreadState** gs): + return gs[0] == NULL + + +cdef bint _ensure_doesnt_have_gil(PyThreadState** gs): + """Returns True if previously had the GIL, False otherwise.""" + if _has_gil(gs): + gs[0] = PyEval_SaveThread() + return True + return False + + +cdef void _ensure_has_gil(PyThreadState** gs): + if not _has_gil(gs): + PyEval_RestoreThread(gs[0]) + gs[0] = NULL + + class IngressErrorCode(Enum): """Category of Error.""" CouldNotResolveAddr = line_sender_error_could_not_resolve_addr @@ -1066,6 +1084,7 @@ cdef class Buffer: """ # TODO: Continue docs, examples and datatype mappings _pandas( + auto_flush_blank(), self._impl, self._b, df, @@ -1466,12 +1485,19 @@ cdef class Sender: In case of data errors with auto-flushing enabled, some of the rows may have been transmitted to the server already. """ - self._buffer.pandas( + cdef auto_flush_t af = auto_flush_blank() + if self._auto_flush_enabled: + af.sender = self._impl + af.watermark = self._auto_flush_watermark + _pandas( + af, + self._buffer._impl, + self._buffer._b, df, - table_name=table_name, - table_name_col=table_name_col, - symbols=symbols, - at=at) + table_name, + table_name_col, + symbols, + at) cpdef flush(self, Buffer buffer=None, bint clear=True): """ @@ -1493,12 +1519,16 @@ cdef class Sender: Note that ``clear=False`` is only supported if ``buffer`` is also specified. """ + cdef line_sender* sender = self._impl + cdef line_sender_error* err = NULL + cdef line_sender_buffer* c_buf = NULL + cdef PyThreadState* gs = NULL # GIL state. NULL means we have the GIL. + cdef bint ok = False + if buffer is None and not clear: raise ValueError('The internal buffer must always be cleared.') - cdef line_sender_error* err = NULL - cdef line_sender_buffer* c_buf = NULL - if self._impl == NULL: + if sender == NULL: raise IngressError( IngressErrorCode.InvalidApiCall, 'flush() can\'t be called: Not connected.') @@ -1509,20 +1539,21 @@ cdef class Sender: if line_sender_buffer_size(c_buf) == 0: return - try: - if clear: - if not line_sender_flush(self._impl, c_buf, &err): - raise c_err_to_py_fmt(err, _FLUSH_FMT) - else: - if not line_sender_flush_and_keep(self._impl, c_buf, &err): - raise c_err_to_py_fmt(err, _FLUSH_FMT) - except: - # Prevent a follow-up call to `.close(flush=True)` (as is usually - # called from `__exit__`) to raise after the sender entered an error - # state following a failed call to `.flush()`. + # We might be blocking on IO, so temporarily release the GIL. + _ensure_doesnt_have_gil(&gs) + if clear: + ok = line_sender_flush(sender, c_buf, &err) + else: + ok = line_sender_flush_and_keep(sender, c_buf, &err) + _ensure_has_gil(&gs) + if not ok: if c_buf == self._buffer._impl: + # Prevent a follow-up call to `.close(flush=True)` (as is + # usually called from `__exit__`) to raise after the sender + # entered an error state following a failed call to `.flush()`. + # Note: In this case `clear` is always `True`. line_sender_buffer_clear(c_buf) - raise + raise c_err_to_py_fmt(err, _FLUSH_FMT) cdef _close(self): self._buffer = None diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index 5f6b25fb..f7412a9d 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -1,5 +1,17 @@ # See: pandas_integration.md for technical overview. +cdef struct auto_flush_t: + line_sender* sender + size_t watermark + + +cdef auto_flush_t auto_flush_blank(): + cdef auto_flush_t af + af.sender = NULL + af.watermark = 0 + return af + + cdef struct col_chunks_t: size_t n_chunks ArrowArray* chunks # We calloc `n_chunks + 1` of these. @@ -322,7 +334,7 @@ cdef void col_t_release(col_t* col): cdef ArrowArray* chunk if Py_buffer_obj_is_set(&col.setup.pybuf): - PyBuffer_Release(&col.setup.pybuf) # Note: Sets `col.pybuf.obj` to NULL. + PyBuffer_Release(&col.setup.pybuf) # Note: Sets `.pybuf.obj` to NULL. for chunk_index in range(col.setup.chunks.n_chunks): chunk = &col.setup.chunks.chunks[chunk_index] @@ -1116,12 +1128,6 @@ cdef void_int _pandas_resolve_args( qsort(cols.d, col_count, sizeof(col_t), _pandas_compare_cols) -cdef void _ensure_has_gil(PyThreadState** gs): - if gs[0] != NULL: - PyEval_RestoreThread(gs[0]) - gs[0] = NULL - - cdef inline bint _pandas_arrow_get_bool(col_cursor_t* cursor): return ( (cursor.chunk.buffers[1])[cursor.offset // 8] & @@ -1224,7 +1230,7 @@ cdef inline void_int _pandas_cell_str_pyobj_to_utf8( cdef void_int _pandas_serialize_cell_table__str_pyobj( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL @@ -1239,12 +1245,12 @@ cdef void_int _pandas_serialize_cell_table__str_pyobj( 'Expected a table name (str object), ' + f'got an object of type {_fqn(type(cell))}.') str_to_table_name(b, cell, &c_table_name) - if not line_sender_buffer_table(impl, c_table_name, &err): + if not line_sender_buffer_table(ls_buf, c_table_name, &err): raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_table__str_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1256,7 +1262,7 @@ cdef void_int _pandas_serialize_cell_table__str_arrow( if not line_sender_table_name_init(&c_table_name, c_len, buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) - if not line_sender_buffer_table(impl, c_table_name, &err): + if not line_sender_buffer_table(ls_buf, c_table_name, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: @@ -1265,7 +1271,7 @@ cdef void_int _pandas_serialize_cell_table__str_arrow( cdef void_int _pandas_serialize_cell_table__str_i8_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1277,7 +1283,7 @@ cdef void_int _pandas_serialize_cell_table__str_i8_cat( if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) - if not line_sender_buffer_table(impl, c_table_name, &err): + if not line_sender_buffer_table(ls_buf, c_table_name, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: @@ -1286,7 +1292,7 @@ cdef void_int _pandas_serialize_cell_table__str_i8_cat( cdef void_int _pandas_serialize_cell_table__str_i16_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1298,7 +1304,7 @@ cdef void_int _pandas_serialize_cell_table__str_i16_cat( if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) - if not line_sender_buffer_table(impl, c_table_name, &err): + if not line_sender_buffer_table(ls_buf, c_table_name, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: @@ -1307,7 +1313,7 @@ cdef void_int _pandas_serialize_cell_table__str_i16_cat( cdef void_int _pandas_serialize_cell_table__str_i32_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1319,7 +1325,7 @@ cdef void_int _pandas_serialize_cell_table__str_i32_cat( if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) - if not line_sender_buffer_table(impl, c_table_name, &err): + if not line_sender_buffer_table(ls_buf, c_table_name, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: @@ -1328,71 +1334,71 @@ cdef void_int _pandas_serialize_cell_table__str_i32_cat( cdef void_int _pandas_serialize_cell_symbol__str_pyobj( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 _pandas_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) - if valid and not line_sender_buffer_symbol(impl, col.name, utf8, &err): + if valid and not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i8_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i16_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_symbol__str_i32_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_symbol(impl, col.name, utf8, &err): + if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL @@ -1400,7 +1406,7 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( cdef PyObject* cell = access[col.cursor.offset] if PyBool_Check(cell): if not line_sender_buffer_column_bool( - impl, col.name, cell == Py_True, &err): + ls_buf, col.name, cell == Py_True, &err): raise c_err_to_py(err) elif _pandas_is_null_pyobj(cell): raise ValueError('Cannot insert null values into a boolean column.') @@ -1411,20 +1417,20 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint8_t* access = col.cursor.chunk.buffers[1] cdef uint8_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_bool(impl, col.name, not not cell, &err): + if not line_sender_buffer_column_bool(ls_buf, col.name, not not cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1433,7 +1439,7 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( cdef bint value if valid: value = _pandas_arrow_get_bool(&col.cursor) - if not line_sender_buffer_column_bool(impl, col.name, value, &err): + if not line_sender_buffer_column_bool(ls_buf, col.name, value, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: @@ -1442,7 +1448,7 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL @@ -1451,7 +1457,7 @@ cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( cdef int64_t value if PyLong_CheckExact(cell): value = PyLong_AsLongLong(cell) - if not line_sender_buffer_column_i64(impl, col.name, value, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, value, &err): raise c_err_to_py(err) elif _pandas_is_null_pyobj(cell): pass @@ -1462,85 +1468,85 @@ cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( cdef void_int _pandas_serialize_cell_column_i64__u8_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint8_t* access = col.cursor.chunk.buffers[1] cdef uint8_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i8_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int8_t* access = col.cursor.chunk.buffers[1] cdef int8_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u16_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint16_t* access = col.cursor.chunk.buffers[1] cdef uint16_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i16_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int16_t* access = col.cursor.chunk.buffers[1] cdef int16_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u32_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef uint32_t* access = col.cursor.chunk.buffers[1] cdef uint32_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i32_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int32_t* access = col.cursor.chunk.buffers[1] cdef int32_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u64_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1550,26 +1556,26 @@ cdef void_int _pandas_serialize_cell_column_i64__u64_numpy( if cell > INT64_MAX: _ensure_has_gil(gs) raise OverflowError('uint64 value too large for int64 column type.') - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__i64_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] - if not line_sender_buffer_column_i64(impl, col.name, cell, &err): + if not line_sender_buffer_column_i64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1579,7 +1585,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1588,7 +1594,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1598,7 +1604,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1607,7 +1613,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1617,7 +1623,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1626,7 +1632,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1636,7 +1642,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1645,7 +1651,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1655,7 +1661,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1664,7 +1670,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1674,7 +1680,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1683,7 +1689,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1698,7 +1704,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( _ensure_has_gil(gs) raise OverflowError('uint64 value too large for int64 column type.') if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, cell, &err): @@ -1707,7 +1713,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1717,7 +1723,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_i64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1726,7 +1732,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL @@ -1735,7 +1741,7 @@ cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( cdef double value if PyFloat_CheckExact(cell): value = PyFloat_AS_DOUBLE(cell) - if not line_sender_buffer_column_f64(impl, col.name, value, &err): + if not line_sender_buffer_column_f64(ls_buf, col.name, value, &err): raise c_err_to_py(err) elif _pandas_is_null_pyobj(cell): pass @@ -1746,7 +1752,7 @@ cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1754,26 +1760,26 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( # Note: This is the C `float` type, not the Python `float` type. cdef float* access = col.cursor.chunk.buffers[1] cdef float cell = access[col.cursor.offset] - if not line_sender_buffer_column_f64(impl, col.name, cell, &err): + if not line_sender_buffer_column_f64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__f64_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef double* access = col.cursor.chunk.buffers[1] cdef double cell = access[col.cursor.offset] - if not line_sender_buffer_column_f64(impl, col.name, cell, &err): + if not line_sender_buffer_column_f64(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1783,7 +1789,7 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_f64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1792,7 +1798,7 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1802,7 +1808,7 @@ cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( if valid: access = col.cursor.chunk.buffers[1] if not line_sender_buffer_column_f64( - impl, + ls_buf, col.name, access[col.cursor.offset], &err): @@ -1811,71 +1817,72 @@ cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( cdef void_int _pandas_serialize_cell_column_str__str_pyobj( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 _pandas_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) - if valid and not line_sender_buffer_column_str(impl, col.name, utf8, &err): + if valid and not line_sender_buffer_column_str( + ls_buf, col.name, utf8, &err): raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i8_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i16_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_str__str_i32_cat( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): - if not line_sender_buffer_column_str(impl, col.name, utf8, &err): + if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1884,13 +1891,13 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( cdef int64_t cell = access[col.cursor.offset] if cell != _NAT: cell //= 1000 # Convert from nanoseconds to microseconds. - if not line_sender_buffer_column_ts(impl, col.name, cell, &err): + if not line_sender_buffer_column_ts(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1902,13 +1909,13 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( access = col.cursor.chunk.buffers[1] cell = access[col.cursor.offset] cell //= 1000 # Convert from nanoseconds to microseconds. - if not line_sender_buffer_column_ts(impl, col.name, cell, &err): + if not line_sender_buffer_column_ts(ls_buf, col.name, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1916,18 +1923,18 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( cdef int64_t* access = col.cursor.chunk.buffers[1] cdef int64_t cell = access[col.cursor.offset] if cell == _NAT: - if not line_sender_buffer_at_now(impl, &err): + if not line_sender_buffer_at_now(ls_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: - # Note: impl will validate against negative numbers. - if not line_sender_buffer_at(impl, cell, &err): + # Note: ls_buf will validate against negative numbers. + if not line_sender_buffer_at(ls_buf, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1938,18 +1945,18 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( if valid: access = col.cursor.chunk.buffers[1] cell = access[col.cursor.offset] - # Note: impl will validate against negative numbers. - if not line_sender_buffer_at(impl, cell, &err): + # Note: ls_buf will validate against negative numbers. + if not line_sender_buffer_at(ls_buf, cell, &err): _ensure_has_gil(gs) raise c_err_to_py(err) else: - if not line_sender_buffer_at_now(impl, &err): + if not line_sender_buffer_at_now(ls_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) cdef void_int _pandas_serialize_cell( - line_sender_buffer* impl, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: @@ -1959,93 +1966,93 @@ cdef void_int _pandas_serialize_cell( if dc == col_dispatch_code_t.col_dispatch_code_skip_nulls: pass # We skip a null column. Nothing to do. elif dc == col_dispatch_code_t.col_dispatch_code_table__str_pyobj: - _pandas_serialize_cell_table__str_pyobj(impl, b, col) + _pandas_serialize_cell_table__str_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_arrow: - _pandas_serialize_cell_table__str_arrow(impl, b, col, gs) + _pandas_serialize_cell_table__str_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i8_cat: - _pandas_serialize_cell_table__str_i8_cat(impl, b, col, gs) + _pandas_serialize_cell_table__str_i8_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i16_cat: - _pandas_serialize_cell_table__str_i16_cat(impl, b, col, gs) + _pandas_serialize_cell_table__str_i16_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i32_cat: - _pandas_serialize_cell_table__str_i32_cat(impl, b, col, gs) + _pandas_serialize_cell_table__str_i32_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_pyobj: - _pandas_serialize_cell_symbol__str_pyobj(impl, b, col) + _pandas_serialize_cell_symbol__str_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_arrow: - _pandas_serialize_cell_symbol__str_arrow(impl, b, col, gs) + _pandas_serialize_cell_symbol__str_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i8_cat: - _pandas_serialize_cell_symbol__str_i8_cat(impl, b, col, gs) + _pandas_serialize_cell_symbol__str_i8_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i16_cat: - _pandas_serialize_cell_symbol__str_i16_cat(impl, b, col, gs) + _pandas_serialize_cell_symbol__str_i16_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i32_cat: - _pandas_serialize_cell_symbol__str_i32_cat(impl, b, col, gs) + _pandas_serialize_cell_symbol__str_i32_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_pyobj: - _pandas_serialize_cell_column_bool__bool_pyobj(impl, b, col) + _pandas_serialize_cell_column_bool__bool_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_numpy: - _pandas_serialize_cell_column_bool__bool_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_bool__bool_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_arrow: - _pandas_serialize_cell_column_bool__bool_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_bool__bool_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__int_pyobj: - _pandas_serialize_cell_column_i64__int_pyobj(impl, b, col) + _pandas_serialize_cell_column_i64__int_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_numpy: - _pandas_serialize_cell_column_i64__u8_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u8_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_numpy: - _pandas_serialize_cell_column_i64__i8_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i8_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_numpy: - _pandas_serialize_cell_column_i64__u16_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u16_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_numpy: - _pandas_serialize_cell_column_i64__i16_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i16_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_numpy: - _pandas_serialize_cell_column_i64__u32_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u32_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_numpy: - _pandas_serialize_cell_column_i64__i32_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i32_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_numpy: - _pandas_serialize_cell_column_i64__u64_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u64_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_numpy: - _pandas_serialize_cell_column_i64__i64_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i64_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_arrow: - _pandas_serialize_cell_column_i64__u8_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u8_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_arrow: - _pandas_serialize_cell_column_i64__i8_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i8_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_arrow: - _pandas_serialize_cell_column_i64__u16_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u16_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_arrow: - _pandas_serialize_cell_column_i64__i16_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i16_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_arrow: - _pandas_serialize_cell_column_i64__u32_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u32_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_arrow: - _pandas_serialize_cell_column_i64__i32_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i32_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_arrow: - _pandas_serialize_cell_column_i64__u64_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__u64_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_arrow: - _pandas_serialize_cell_column_i64__i64_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_i64__i64_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__float_pyobj: - _pandas_serialize_cell_column_f64__float_pyobj(impl, b, col) + _pandas_serialize_cell_column_f64__float_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_numpy: - _pandas_serialize_cell_column_f64__f32_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_f64__f32_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_numpy: - _pandas_serialize_cell_column_f64__f64_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_f64__f64_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_arrow: - _pandas_serialize_cell_column_f64__f32_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_f64__f32_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_arrow: - _pandas_serialize_cell_column_f64__f64_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_f64__f64_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_pyobj: - _pandas_serialize_cell_column_str__str_pyobj(impl, b, col) + _pandas_serialize_cell_column_str__str_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_arrow: - _pandas_serialize_cell_column_str__str_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_str__str_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i8_cat: - _pandas_serialize_cell_column_str__str_i8_cat(impl, b, col, gs) + _pandas_serialize_cell_column_str__str_i8_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i16_cat: - _pandas_serialize_cell_column_str__str_i16_cat(impl, b, col, gs) + _pandas_serialize_cell_column_str__str_i16_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i32_cat: - _pandas_serialize_cell_column_str__str_i32_cat(impl, b, col, gs) + _pandas_serialize_cell_column_str__str_i32_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_numpy: - _pandas_serialize_cell_column_ts__dt64ns_numpy(impl, b, col, gs) + _pandas_serialize_cell_column_ts__dt64ns_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_arrow: - _pandas_serialize_cell_column_ts__dt64ns_tz_arrow(impl, b, col, gs) + _pandas_serialize_cell_column_ts__dt64ns_tz_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_numpy: - _pandas_serialize_cell_at_dt64ns_numpy(impl, b, col, gs) + _pandas_serialize_cell_at_dt64ns_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_tz_arrow: - _pandas_serialize_cell_at_dt64ns_tz_arrow(impl, b, col, gs) + _pandas_serialize_cell_at_dt64ns_tz_arrow(ls_buf, b, col, gs) else: _ensure_has_gil(gs) raise RuntimeError(f"Unknown column dispatch code: {dc}") @@ -2079,6 +2086,30 @@ cdef void _pandas_col_advance(col_t* col): ((not new_chunk) * cursor.offset)) +cdef void_int _pandas_handle_auto_flush( + auto_flush_t af, + line_sender_buffer* ls_buf, + PyThreadState** gs) except -1: + cdef line_sender_error* err = NULL + if (af.sender == NULL) or (line_sender_buffer_size(ls_buf) < af.watermark): + return 0 + + # Always temporarily release GIL during a flush. + had_gil = _ensure_doesnt_have_gil(gs) + if not line_sender_flush(af.sender, ls_buf, &err): + _ensure_has_gil(gs) + raise c_err_to_py(err) + + # Flushing will have cleared the marker: We need to set it again. + if not line_sender_buffer_set_marker(ls_buf, &err): + _ensure_has_gil(gs) + raise c_err_to_py(err) + + # Re-acquire GIL if we previously had it. + if had_gil: + _ensure_has_gil(gs) + + # Every how many cells to release and re-acquire the Python GIL. # # We've done some perf testing with some mixed column dtypes. @@ -2090,7 +2121,8 @@ cdef size_t _CELL_GIL_BLIP_INTERVAL = 40000 cdef void_int _pandas( - line_sender_buffer* impl, + auto_flush_t af, + line_sender_buffer* ls_buf, qdb_pystr_buf* b, object df, object table_name, @@ -2110,6 +2142,7 @@ cdef void_int _pandas( cdef col_t* col cdef size_t row_gil_blip_interval cdef PyThreadState* gs = NULL # GIL state. NULL means we have the GIL. + cdef bint had_gil cdef bint was_serializing_cell = False _pandas_may_import_deps() @@ -2139,10 +2172,10 @@ cdef void_int _pandas( # Instead of clearing it (which would clear the headers' memory) # we will truncate (rewind) back to this position. str_buf_marker = qdb_pystr_buf_tell(b) - line_sender_buffer_clear_marker(impl) + line_sender_buffer_clear_marker(ls_buf) # On error, undo all added lines. - if not line_sender_buffer_set_marker(impl, &err): + if not line_sender_buffer_set_marker(ls_buf, &err): raise c_err_to_py(err) row_gil_blip_interval = _CELL_GIL_BLIP_INTERVAL // col_count @@ -2153,7 +2186,7 @@ cdef void_int _pandas( # Also we can't have any other `try` blocks between here and the # `finally` block. if not any_cols_need_gil: - gs = PyEval_SaveThread() + _ensure_doesnt_have_gil(&gs) for row_index in range(row_count): if (gs == NULL) and (row_index % row_gil_blip_interval == 0): @@ -2161,14 +2194,14 @@ cdef void_int _pandas( # This is to allow other python threads to run. # If we hold the GIL for too long, we can starve other # threads, for example timing out network activity. - gs = PyEval_SaveThread() + _ensure_doesnt_have_gil(&gs) _ensure_has_gil(&gs) qdb_pystr_buf_truncate(b, str_buf_marker) # Table-name from `table_name` arg in Python. if c_table_name.buf != NULL: - if not line_sender_buffer_table(impl, c_table_name, &err): + if not line_sender_buffer_table(ls_buf, c_table_name, &err): _ensure_has_gil(&gs) raise c_err_to_py(err) @@ -2177,22 +2210,24 @@ cdef void_int _pandas( was_serializing_cell = True for col_index in range(col_count): col = &cols.d[col_index] - _pandas_serialize_cell(impl, b, col, &gs) # may raise + _pandas_serialize_cell(ls_buf, b, col, &gs) # may raise _pandas_col_advance(col) was_serializing_cell = False # Fixed "at" value (not from a column). if at_value == _AT_IS_SERVER_NOW: - if not line_sender_buffer_at_now(impl, &err): + if not line_sender_buffer_at_now(ls_buf, &err): _ensure_has_gil(&gs) raise c_err_to_py(err) elif at_value >= 0: - if not line_sender_buffer_at(impl, at_value, &err): + if not line_sender_buffer_at(ls_buf, at_value, &err): _ensure_has_gil(&gs) raise c_err_to_py(err) + + _pandas_handle_auto_flush(af, ls_buf, &gs) except Exception as e: # It would be an internal bug for this to raise. - if not line_sender_buffer_rewind_to_marker(impl, &err): + if not line_sender_buffer_rewind_to_marker(ls_buf, &err): raise c_err_to_py(err) if was_serializing_cell: @@ -2216,6 +2251,6 @@ cdef void_int _pandas( raise finally: _ensure_has_gil(&gs) # Note: We need the GIL for cleanup. - line_sender_buffer_clear_marker(impl) + line_sender_buffer_clear_marker(ls_buf) col_t_arr_release(&cols) qdb_pystr_buf_clear(b) From dcccabd6c12eb5be00dcb7d54ba853ee68567e9f Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 13 Dec 2022 15:40:14 +0000 Subject: [PATCH 118/147] Tweak to pandas auto-flush logic. --- src/questdb/pandas_integration.pxi | 1 + 1 file changed, 1 insertion(+) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index f7412a9d..bc56e4ab 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -2097,6 +2097,7 @@ cdef void_int _pandas_handle_auto_flush( # Always temporarily release GIL during a flush. had_gil = _ensure_doesnt_have_gil(gs) if not line_sender_flush(af.sender, ls_buf, &err): + line_sender_buffer_clear(ls_buf) # To avoid double-flush in __exit__. _ensure_has_gil(gs) raise c_err_to_py(err) From 98a549676741ac3326b077f3123c15a2389a7256 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 13 Dec 2022 16:03:42 +0000 Subject: [PATCH 119/147] Basic pandas end-to-end test. --- test/system_test.py | 46 +++++++++++++++++++++++++++++++++++++++++++++ test/test.py | 10 +++++----- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/test/system_test.py b/test/system_test.py index 900fff03..f86224c7 100755 --- a/test/system_test.py +++ b/test/system_test.py @@ -12,6 +12,14 @@ from fixture import QuestDbFixture, install_questdb, CA_PATH, AUTH +try: + import pandas as pd + import numpy + import pyarrow +except ImportError: + pd = None + + import questdb.ingress as qi @@ -123,6 +131,44 @@ def test_auth_tls_ca(self): def test_auth_tls_ca_str(self): self._test_scenario(self.qdb_auth, AUTH, str(CA_PATH)) + @unittest.skipIf(pd is None, 'pandas not installed') + def test_basic_pandas(self): + port = self.qdb_plain.line_tcp_port + pending = None + table_name = uuid.uuid4().hex + df = pd.DataFrame({ + 'col_a': [1, 2, 3], + 'col_b': ['a', 'b', 'c'], + 'col_c': [True, False, True], + 'col_d': [1.5, 2.5, 3.5], + 'col_e': pd.Categorical(['A', 'B', 'C']), + 'col_f': [ + numpy.datetime64('2021-01-01'), + numpy.datetime64('2021-01-02'), + numpy.datetime64('2021-01-03')]}) + df.index.name = table_name + with qi.Sender('localhost', port) as sender: + sender.pandas(df) + pending = str(sender) + + resp = self.qdb_plain.retry_check_table( + table_name, min_rows=3, log_ctx=pending) + exp_columns = [ + {'name': 'col_e', 'type': 'SYMBOL'}, + {'name': 'col_a', 'type': 'LONG'}, + {'name': 'col_b', 'type': 'STRING'}, + {'name': 'col_c', 'type': 'BOOLEAN'}, + {'name': 'col_d', 'type': 'DOUBLE'}, + {'name': 'col_f', 'type': 'TIMESTAMP'}, + {'name': 'timestamp', 'type': 'TIMESTAMP'}] + self.assertEqual(resp['columns'], exp_columns) + + exp_dataset = [ # Comparison excludes timestamp column. + ['A', 1, 'a', True, 1.5, '2021-01-01T00:00:00.000000Z'], + ['B', 2, 'b', False, 2.5, '2021-01-02T00:00:00.000000Z'], + ['C', 3, 'c', True, 3.5, '2021-01-03T00:00:00.000000Z']] + scrubbed_dataset = [row[:-1] for row in resp['dataset']] + self.assertEqual(scrubbed_dataset, exp_dataset) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/test.py b/test/test.py index 3116cd4c..c913913b 100755 --- a/test/test.py +++ b/test/test.py @@ -17,14 +17,14 @@ from system_test import TestWithDatabase try: - import pandas as pa - import numpy as np - import pyarrow as pa + import pandas as pd + import numpy + import pyarrow except ImportError: - pa = None + pd = None -if pa is not None: +if pd is not None: from test_pandas_integration import TestPandas else: class TestNoPandas(unittest.TestCase): From 02d49dde2731eb3f7d842e85d13e007f0e841ae2 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 13 Dec 2022 18:43:08 +0000 Subject: [PATCH 120/147] Tests (and bugfixes) for panda's auto-flush. --- src/questdb/pandas_integration.pxi | 31 ++++++++++++------- test/system_test.py | 2 +- test/test.py | 49 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/pandas_integration.pxi index bc56e4ab..9b9175a1 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/pandas_integration.pxi @@ -2090,26 +2090,35 @@ cdef void_int _pandas_handle_auto_flush( auto_flush_t af, line_sender_buffer* ls_buf, PyThreadState** gs) except -1: - cdef line_sender_error* err = NULL + cdef line_sender_error* flush_err + cdef line_sender_error* marker_err + cdef bint flush_ok + cdef bint marker_ok if (af.sender == NULL) or (line_sender_buffer_size(ls_buf) < af.watermark): return 0 # Always temporarily release GIL during a flush. had_gil = _ensure_doesnt_have_gil(gs) - if not line_sender_flush(af.sender, ls_buf, &err): - line_sender_buffer_clear(ls_buf) # To avoid double-flush in __exit__. - _ensure_has_gil(gs) - raise c_err_to_py(err) + flush_ok = line_sender_flush(af.sender, ls_buf, &flush_err) + if not flush_ok: + # To avoid flush reattempt on Sender.__exit__. + line_sender_buffer_clear(ls_buf) - # Flushing will have cleared the marker: We need to set it again. - if not line_sender_buffer_set_marker(ls_buf, &err): - _ensure_has_gil(gs) - raise c_err_to_py(err) + # Flushing will have cleared the marker: We need to set it again + # We need this also on error due to our error handling logic which will + # try to rewind the buffer on error and fail if the marker is unset. + marker_ok = line_sender_buffer_set_marker(ls_buf, &marker_err) - # Re-acquire GIL if we previously had it. - if had_gil: + if had_gil or (not flush_ok) or (not marker_ok): _ensure_has_gil(gs) + if not flush_ok: + raise c_err_to_py_fmt(flush_err, _FLUSH_FMT) + + # The flush error takes precedence over the marker error. + if not marker_ok: + raise c_err_to_py(marker_err) + # Every how many cells to release and re-acquire the Python GIL. # diff --git a/test/system_test.py b/test/system_test.py index f86224c7..3f3c530e 100755 --- a/test/system_test.py +++ b/test/system_test.py @@ -131,7 +131,7 @@ def test_auth_tls_ca(self): def test_auth_tls_ca_str(self): self._test_scenario(self.qdb_auth, AUTH, str(CA_PATH)) - @unittest.skipIf(pd is None, 'pandas not installed') + @unittest.skipIf(not pd, 'pandas not installed') def test_basic_pandas(self): port = self.qdb_plain.line_tcp_port pending = None diff --git a/test/test.py b/test/test.py index c913913b..be3f76ae 100755 --- a/test/test.py +++ b/test/test.py @@ -415,6 +415,55 @@ def test_dont_flush_on_exception(self): msgs = server.recv() self.assertEqual(msgs, []) + @unittest.skipIf(not pd, 'pandas not installed') + def test_pandas(self): + with Server() as server: + with qi.Sender('localhost', server.port) as sender: + server.accept() + df = pd.DataFrame({'a': [1, 2], 'b': [3.0, 4.0]}) + sender.pandas(df, table_name='tbl1') + msgs = server.recv() + self.assertEqual( + msgs, + [b'tbl1 a=1i,b=3.0', + b'tbl1 a=2i,b=4.0']) + + @unittest.skipIf(not pd, 'pandas not installed') + def test_pandas_auto_flush(self): + with Server() as server: + # An auto-flush size of 20 bytes is enough to auto-flush the first + # row, but not the second. + with qi.Sender('localhost', server.port, auto_flush=20) as sender: + server.accept() + df = pd.DataFrame({'a': [100000, 2], 'b': [3.0, 4.0]}) + sender.pandas(df, table_name='tbl1') + msgs = server.recv() + self.assertEqual( + msgs, + [b'tbl1 a=100000i,b=3.0']) + + # The second row is still pending send. + self.assertEqual(len(sender), 16) + + # So we give it some more data and we should see it flush. + sender.row('tbl1', columns={'a': 3, 'b': 5.0}) + msgs = server.recv() + self.assertEqual( + msgs, + [b'tbl1 a=2i,b=4.0', + b'tbl1 a=3i,b=5.0']) + + self.assertEqual(len(sender), 0) + + # We can now disconnect the server and see auto flush failing. + server.close() + + exp_err = 'Could not flush buffer.* - See https' + with self.assertRaisesRegex(qi.IngressError, exp_err): + for _ in range(1000): + time.sleep(0.01) + sender.pandas(df.head(1), table_name='tbl1') + def test_new_buffer(self): sender = qi.Sender( host='localhost', From 1801f10721c6237cd9f9a8677a41abf9d444ec52 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 14 Dec 2022 13:51:48 +0000 Subject: [PATCH 121/147] Pandas API docs. --- src/questdb/ingress.pyx | 131 ++++++++++++++++++++++++++++++-- test/test_pandas_integration.py | 2 + 2 files changed, 126 insertions(+), 7 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 8fde2f3a..77e8b3e6 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1073,16 +1073,133 @@ cdef class Buffer: # ... sender.flush(buf) - ILP / Pandas Datatype Mappings: + **Pandas to ILP datatype mappings** - +------------------+------------------+-----------------+ - | ILP Datatype | Pandas ``dtype`` | Nulls Allowed | - +==================+==================+=================+ - | ``SYMBOL`` | ``'object'`` column containing ``str`` | Yes | - +------------------+------------------+-----------------+ + .. seealso:: https://questdb.io/docs/reference/api/ilp/columnset-types/ + .. list-table:: Pandas Mappings + :header-rows: 1 + + * - Pandas ``dtype`` + - Nulls + - ILP Datatype + * - ``'bool'`` + - N + - ``BOOLEAN`` + * - ``'boolean'`` + - N **α** + - ``BOOLEAN`` + * - ``'object'`` (``bool`` objects) + - N **α** + - ``BOOLEAN`` + * - ``'uint8'`` + - N + - ``INTEGER`` + * - ``'int8'`` + - N + - ``INTEGER`` + * - ``'uint16'`` + - N + - ``INTEGER`` + * - ``'int16'`` + - N + - ``INTEGER`` + * - ``'uint32'`` + - N + - ``INTEGER`` + * - ``'int32'`` + - N + - ``INTEGER`` + * - ``'uint64'`` + - N + - ``INTEGER`` **β** + * - ``'int64'`` + - N + - ``INTEGER`` + * - ``'UInt8'`` + - Y + - ``INTEGER`` + * - ``'Int8'`` + - Y + - ``INTEGER`` + * - ``'UInt16'`` + - Y + - ``INTEGER`` + * - ``'Int16'`` + - Y + - ``INTEGER`` + * - ``'UInt32'`` + - Y + - ``INTEGER`` + * - ``'Int32'`` + - Y + - ``INTEGER`` + * - ``'UInt64'`` + - Y + - ``INTEGER`` **β** + * - ``'Int64'`` + - Y + - ``INTEGER`` + * - ``'object'`` (``int`` objects) + - Y + - ``INTEGER`` **β** + * - ``'float32'`` **γ** + - Y (``NaN``) + - ``FLOAT`` + * - ``'float64'`` + - Y (``NaN``) + - ``FLOAT`` + * - ``'object'`` (``float`` objects) + - Y (``NaN``) + - ``FLOAT`` + * - ``'string'`` (``str`` objects) + - Y + - ``STRING`` (default), ``SYMBOL`` via ``symbols`` arg. **δ** + * - ``'string[pyarrow]'`` + - Y + - ``STRING`` (default), ``SYMBOL`` via ``symbols`` arg. **δ** + * - ``'category'`` (``str`` objects) **ε** + - Y + - ``SYMBOL`` (default), ``STRING`` via ``symbols`` arg. **δ** + * - ``'object'`` (``str`` objects) + - Y + - ``STRING`` (default), ``SYMBOL`` via ``symbols`` arg. **δ** + * - ``'datetime64[ns]'`` + - Y + - ``TIMESTAMP`` **ζ** + * - ``'datetime64[ns, tz]'`` + - Y + - ``TIMESTAMP`` **ζ** + + .. note:: + + * **α**: Note some pandas dtypes allow nulls (e.g. ``'boolean'``), + where the QuestDB database does not. + + * **β**: The valid range for integer values is -2^63 to 2^63-1. + Any ``'uint64'``, ``'UInt64'`` or python ``int`` object values + outside this range will raise an error during serialization. + + * **γ**: Upcast to 64-bit float during serialization. + + * **δ**: Columns containing strings can also be used to specify the + table name. See ``table_name_col``. + + * **ε**: We only support categories containing strings. If the + category contains non-string values, an error will be raised. + + * **ζ**: We don't support datetimes with precisions other than + nanoseconds. The designated timestamp column (see ``at`` + parameter) maintains the nanosecond precision, whilst values + stored as columns have their precision truncated to microseconds. + All dates are sent as UTC and any additional timezone information + is dropped. If no timezone is specified, we follow + the pandas convention of assuming the timezone is UTC. + Date times before 1970-01-01 00:00:00 UTC are not supported. + If a datetime value is specified as ``None`` (``NaT``), it is + interpreted as the current time set by the server on receipt of + message. """ - # TODO: Continue docs, examples and datatype mappings _pandas( auto_flush_blank(), self._impl, diff --git a/test/test_pandas_integration.py b/test/test_pandas_integration.py index d0d1ff0b..83330286 100644 --- a/test/test_pandas_integration.py +++ b/test/test_pandas_integration.py @@ -1216,6 +1216,8 @@ def test_pyobj_int_col(self): 'b': [1, 2]}), table_name='tbl1') + # TODO test ints outside of int64 range + def test_pyobj_float_col(self): self.assertEqual( _pandas( From 45aa14b72caf04704e5dd47b36a0e76f93a83954 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 14 Dec 2022 16:11:17 +0000 Subject: [PATCH 122/147] Renamed '.pandas()' to '.dataframe()'. --- proj.py | 2 +- .../{pandas_integration.md => dataframe.md} | 0 .../{pandas_integration.pxi => dataframe.pxi} | 458 +++++++++--------- src/questdb/ingress.pyx | 19 +- test/benchmark.py | 18 +- test/system_test.py | 4 +- test/test.py | 14 +- ...andas_integration.py => test_dataframe.py} | 242 ++++----- ...gration_fuzz.py => test_dataframe_fuzz.py} | 6 +- ...andas_leaks.py => test_dataframe_leaks.py} | 2 +- 10 files changed, 383 insertions(+), 382 deletions(-) rename src/questdb/{pandas_integration.md => dataframe.md} (100%) rename src/questdb/{pandas_integration.pxi => dataframe.pxi} (84%) rename test/{test_pandas_integration.py => test_dataframe.py} (89%) rename test/{test_pandas_integration_fuzz.py => test_dataframe_fuzz.py} (98%) rename test/{test_pandas_leaks.py => test_dataframe_leaks.py} (95%) diff --git a/proj.py b/proj.py index 6eb84c3f..875ebe1f 100755 --- a/proj.py +++ b/proj.py @@ -96,7 +96,7 @@ def test_fuzzing(*args): ld_preload += str(lib_path) cmd = [ 'python3', - 'test/test_pandas_integration_fuzz.py'] + list(args) + 'test/test_dataframe_fuzz.py'] + list(args) if not args: cmd.extend([ '-detect_leaks=0', diff --git a/src/questdb/pandas_integration.md b/src/questdb/dataframe.md similarity index 100% rename from src/questdb/pandas_integration.md rename to src/questdb/dataframe.md diff --git a/src/questdb/pandas_integration.pxi b/src/questdb/dataframe.pxi similarity index 84% rename from src/questdb/pandas_integration.pxi rename to src/questdb/dataframe.pxi index 9b9175a1..ee6050bd 100644 --- a/src/questdb/pandas_integration.pxi +++ b/src/questdb/dataframe.pxi @@ -1,4 +1,4 @@ -# See: pandas_integration.md for technical overview. +# See: dataframe.md for technical overview. cdef struct auto_flush_t: line_sender* sender @@ -407,7 +407,7 @@ cdef object _PYARROW = None # module object, if available or None cdef int64_t _NAT = INT64_MIN # pandas NaT -cdef object _pandas_may_import_deps(): +cdef object _dataframe_may_import_deps(): """" Lazily import module dependencies on first use to avoid startup overhead. @@ -442,7 +442,7 @@ cdef object _pandas_may_import_deps(): except ImportError as ie: raise ImportError( 'Missing dependencies: `pandas`, `numpy` and `pyarrow` must all ' + - 'be installed to use the `.pandas()` method. ' + + 'be installed to use the `.dataframe()` method. ' + 'See: https://py-questdb-client.readthedocs.io/' + 'en/latest/installation.html.') from ie _NUMPY = numpy @@ -464,14 +464,14 @@ cdef object _pandas_may_import_deps(): _PYARROW = pyarrow -cdef object _pandas_check_is_dataframe(object df): +cdef object _dataframe_check_is_dataframe(object df): if not isinstance(df, _PANDAS.DataFrame): raise TypeError( f'Bad argument `df`: Expected {_fqn(_PANDAS.DataFrame)}, ' + f'not an object of type {_fqn(type(df))}.') -cdef ssize_t _pandas_resolve_table_name( +cdef ssize_t _dataframe_resolve_table_name( qdb_pystr_buf* b, object df, list pandas_cols, @@ -504,7 +504,7 @@ cdef ssize_t _pandas_resolve_table_name( raise TypeError('Bad argument `table_name`: Must be str.') elif table_name_col is not None: if isinstance(table_name_col, str): - _pandas_get_loc(df, table_name_col, 'table_name_col', &col_index) + _dataframe_get_loc(df, table_name_col, 'table_name_col', &col_index) elif isinstance(table_name_col, int): _bind_col_index( 'table_name_col', table_name_col, col_count, &col_index) @@ -514,7 +514,7 @@ cdef ssize_t _pandas_resolve_table_name( 'must be a column name (str) or index (int).') pandas_col = pandas_cols[col_index] col = &cols.d[col_index] - _pandas_check_column_is_str( + _dataframe_check_column_is_str( 'Bad argument `table_name_col`: ', pandas_col, col.setup.source) @@ -565,7 +565,7 @@ cdef void_int _bind_col_index( col_index[0] = col_num -cdef void_int _pandas_check_column_is_str( +cdef void_int _dataframe_check_column_is_str( str err_msg_prefix, PandasCol pandas_col, col_source_t source) except -1: @@ -582,7 +582,7 @@ cdef void_int _pandas_check_column_is_str( @cython.internal cdef class PandasCol: - """Python object representing a column whilst parsing .pandas arguments.""" + """Python object representing a column to parse .dataframe() arguments.""" cdef str name cdef object dtype cdef object series @@ -597,7 +597,7 @@ cdef class PandasCol: self.series = series -cdef void_int _pandas_resolve_symbols( +cdef void_int _dataframe_resolve_symbols( object df, list pandas_cols, col_t_arr* cols, @@ -631,7 +631,7 @@ cdef void_int _pandas_resolve_symbols( 'of column names (str) or indices (int).') for symbol in symbols: if isinstance(symbol, str): - _pandas_get_loc(df, symbol, 'symbols', &col_index) + _dataframe_get_loc(df, symbol, 'symbols', &col_index) elif isinstance(symbol, int): _bind_col_index('symbol', symbol, cols.size, &col_index) else: @@ -648,14 +648,14 @@ cdef void_int _pandas_resolve_symbols( f'({df.columns[at_col]!r}) as a symbol column.') pandas_col = pandas_cols[col_index] col = &cols.d[col_index] - _pandas_check_column_is_str( + _dataframe_check_column_is_str( 'Bad argument `symbols`: ', pandas_col, col.setup.source) col.setup.meta_target = meta_target_t.meta_target_symbol -cdef void_int _pandas_get_loc( +cdef void_int _dataframe_get_loc( object df, str col_name, str arg_name, size_t* col_index_out) except -1: """ @@ -678,7 +678,7 @@ cdef int64_t _AT_IS_SET_BY_COLUMN = -1 cdef str _SUPPORTED_DATETIMES = 'datetime64[ns] or datetime64[ns, tz]' -cdef object _pandas_is_supported_datetime(object dtype): +cdef object _dataframe_is_supported_datetime(object dtype): if (isinstance(dtype, _NUMPY_DATETIME64_NS) and (str(dtype) == 'datetime64[ns]')): return True @@ -687,7 +687,7 @@ cdef object _pandas_is_supported_datetime(object dtype): return False -cdef ssize_t _pandas_resolve_at( +cdef ssize_t _dataframe_resolve_at( object df, col_t_arr* cols, object at, @@ -712,7 +712,7 @@ cdef ssize_t _pandas_resolve_at( at_value_out[0] = datetime_to_nanos(at) return -1 elif isinstance(at, str): - _pandas_get_loc(df, at, 'at', &col_index) + _dataframe_get_loc(df, at, 'at', &col_index) elif isinstance(at, int): _bind_col_index('at', at, col_count, &col_index) else: @@ -721,7 +721,7 @@ cdef ssize_t _pandas_resolve_at( 'Must be one of: None, TimestampNanos, datetime, ' + 'int (column index), str (colum name)') dtype = df.dtypes[col_index] - if _pandas_is_supported_datetime(dtype): + if _dataframe_is_supported_datetime(dtype): at_value_out[0] = _AT_IS_SET_BY_COLUMN col = &cols.d[col_index] col.setup.meta_target = meta_target_t.meta_target_at @@ -732,23 +732,23 @@ cdef ssize_t _pandas_resolve_at( f'for the {at!r} column: Must be a {_SUPPORTED_DATETIMES} column.') -cdef void_int _pandas_alloc_chunks( +cdef void_int _dataframe_alloc_chunks( size_t n_chunks, col_t* col) except -1: col.setup.chunks.n_chunks = n_chunks col.setup.chunks.chunks = calloc( - col.setup.chunks.n_chunks + 1, # See `_pandas_col_advance` on why +1. + col.setup.chunks.n_chunks + 1, # See `_dataframe_col_advance` on why +1. sizeof(ArrowArray)) if col.setup.chunks.chunks == NULL: raise MemoryError() -cdef void _pandas_free_mapped_arrow(ArrowArray* arr): +cdef void _dataframe_free_mapped_arrow(ArrowArray* arr): free(arr.buffers) arr.buffers = NULL arr.release = NULL -cdef void_int _pandas_series_as_pybuf( +cdef void_int _dataframe_series_as_pybuf( PandasCol pandas_col, col_t* col, str fallback_dtype=None) except -1: cdef object nparr = pandas_col.series.to_numpy(dtype=fallback_dtype) cdef ArrowArray* mapped @@ -766,7 +766,7 @@ cdef void_int _pandas_series_as_pybuf( raise TypeError( f'Bad column {pandas_col.name!r}: Expected a buffer, got ' + f'{pandas_col.series!r} ({_fqn(type(pandas_col.series))})') from be - _pandas_alloc_chunks(1, col) + _dataframe_alloc_chunks(1, col) mapped = &col.setup.chunks.chunks[0] # Total number of elements. @@ -781,10 +781,10 @@ cdef void_int _pandas_series_as_pybuf( mapped.buffers[1] = col.setup.pybuf.buf mapped.children = NULL mapped.dictionary = NULL - mapped.release = _pandas_free_mapped_arrow # to cleanup allocated array. + mapped.release = _dataframe_free_mapped_arrow # to cleanup allocated array. -cdef void_int _pandas_series_as_arrow( +cdef void_int _dataframe_series_as_arrow( PandasCol pandas_col, col_t* col) except -1: cdef object array @@ -798,7 +798,7 @@ cdef void_int _pandas_series_as_arrow( chunks = [array] n_chunks = len(chunks) - _pandas_alloc_chunks(n_chunks, col) + _dataframe_alloc_chunks(n_chunks, col) for chunk_index in range(n_chunks): array = chunks[chunk_index] @@ -817,10 +817,10 @@ cdef const char* _ARROW_FMT_INT32 = "i" cdef const char* _ARROW_FMT_SML_STR = "u" -cdef void_int _pandas_category_series_as_arrow( +cdef void_int _dataframe_category_series_as_arrow( PandasCol pandas_col, col_t* col) except -1: cdef const char* format - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) format = col.setup.arrow_schema.format if strncmp(format, _ARROW_FMT_INT8, 1) == 0: col.setup.source = col_source_t.col_source_str_i8_cat @@ -844,18 +844,18 @@ cdef void_int _pandas_category_series_as_arrow( f'got a category of {pandas_col.series.dtype.categories.dtype}.') -cdef inline bint _pandas_is_float_nan(PyObject* obj): +cdef inline bint _dataframe_is_float_nan(PyObject* obj): return PyFloat_CheckExact(obj) and isnan(PyFloat_AS_DOUBLE(obj)) -cdef inline bint _pandas_is_null_pyobj(PyObject* obj): +cdef inline bint _dataframe_is_null_pyobj(PyObject* obj): return ( (obj == Py_None) or (obj == _PANDAS_NA) or - _pandas_is_float_nan(obj)) + _dataframe_is_float_nan(obj)) -cdef void_int _pandas_series_sniff_pyobj( +cdef void_int _dataframe_series_sniff_pyobj( PandasCol pandas_col, col_t* col) except -1: """ Deduct the type of the object column. @@ -866,11 +866,11 @@ cdef void_int _pandas_series_sniff_pyobj( cdef size_t n_elements = len(pandas_col.series) cdef PyObject** obj_arr cdef PyObject* obj - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) obj_arr = (col.setup.pybuf.buf) for el_index in range(n_elements): obj = obj_arr[el_index] - if not _pandas_is_null_pyobj(obj): + if not _dataframe_is_null_pyobj(obj): if PyBool_Check(obj): col.setup.source = col_source_t.col_source_bool_pyobj elif PyLong_CheckExact(obj): @@ -899,99 +899,99 @@ cdef void_int _pandas_series_sniff_pyobj( col.setup.source = col_source_t.col_source_nulls -cdef void_int _pandas_resolve_source_and_buffers( +cdef void_int _dataframe_resolve_source_and_buffers( PandasCol pandas_col, col_t* col) except -1: cdef object dtype = pandas_col.dtype if isinstance(dtype, _NUMPY_BOOL): col.setup.source = col_source_t.col_source_bool_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.BooleanDtype): col.setup.source = col_source_t.col_source_bool_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT8): col.setup.source = col_source_t.col_source_u8_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT8): col.setup.source = col_source_t.col_source_i8_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT16): col.setup.source = col_source_t.col_source_u16_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT16): col.setup.source = col_source_t.col_source_i16_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT32): col.setup.source = col_source_t.col_source_u32_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT32): col.setup.source = col_source_t.col_source_i32_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_UINT64): col.setup.source = col_source_t.col_source_u64_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_INT64): col.setup.source = col_source_t.col_source_i64_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt8Dtype): col.setup.source = col_source_t.col_source_u8_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int8Dtype): col.setup.source = col_source_t.col_source_i8_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt16Dtype): col.setup.source = col_source_t.col_source_u16_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int16Dtype): col.setup.source = col_source_t.col_source_i16_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt32Dtype): col.setup.source = col_source_t.col_source_u32_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int32Dtype): col.setup.source = col_source_t.col_source_i32_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.UInt64Dtype): col.setup.source = col_source_t.col_source_u64_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Int64Dtype): col.setup.source = col_source_t.col_source_i64_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_FLOAT32): col.setup.source = col_source_t.col_source_f32_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _NUMPY_FLOAT64): col.setup.source = col_source_t.col_source_f64_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif isinstance(dtype, _PANDAS.Float32Dtype): col.setup.source = col_source_t.col_source_f32_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.Float64Dtype): col.setup.source = col_source_t.col_source_f64_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _PANDAS.StringDtype): if dtype.storage == 'pyarrow': col.setup.source = col_source_t.col_source_str_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif dtype.storage == 'python': col.setup.source = col_source_t.col_source_str_pyobj - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) else: raise IngressError( IngressErrorCode.BadDataFrame, f'Unknown string dtype storage: f{dtype.storage} ' + f'for column {pandas_col.name} of dtype {dtype}.') elif isinstance(dtype, _PANDAS.CategoricalDtype): - _pandas_category_series_as_arrow(pandas_col, col) + _dataframe_category_series_as_arrow(pandas_col, col) elif (isinstance(dtype, _NUMPY_DATETIME64_NS) and - _pandas_is_supported_datetime(dtype)): + _dataframe_is_supported_datetime(dtype)): col.setup.source = col_source_t.col_source_dt64ns_numpy - _pandas_series_as_pybuf(pandas_col, col) + _dataframe_series_as_pybuf(pandas_col, col) elif (isinstance(dtype, _PANDAS.DatetimeTZDtype) and - _pandas_is_supported_datetime(dtype)): + _dataframe_is_supported_datetime(dtype)): col.setup.source = col_source_t.col_source_dt64ns_tz_arrow - _pandas_series_as_arrow(pandas_col, col) + _dataframe_series_as_arrow(pandas_col, col) elif isinstance(dtype, _NUMPY_OBJECT): - _pandas_series_sniff_pyobj(pandas_col, col) + _dataframe_series_sniff_pyobj(pandas_col, col) else: raise IngressError( IngressErrorCode.BadDataFrame, @@ -1000,7 +1000,7 @@ cdef void_int _pandas_resolve_source_and_buffers( 'https://github.com/questdb/py-questdb-client/issues.') -cdef void_int _pandas_resolve_target( +cdef void_int _dataframe_resolve_target( PandasCol pandas_col, col_t* col) except -1: cdef col_target_t target cdef set target_sources @@ -1019,23 +1019,23 @@ cdef void_int _pandas_resolve_target( f' ({pandas_col.dtype}) to any ILP type.') -cdef void _pandas_init_cursor(col_t* col): +cdef void _dataframe_init_cursor(col_t* col): col.cursor.chunk = col.setup.chunks.chunks col.cursor.chunk_index = 0 col.cursor.offset = col.cursor.chunk.offset -cdef void_int _pandas_resolve_cols( +cdef void_int _dataframe_resolve_cols( qdb_pystr_buf* b, list pandas_cols, col_t_arr* cols, bint* any_cols_need_gil_out) except -1: cdef size_t index - cdef size_t len_pandas_cols = len(pandas_cols) + cdef size_t len_dataframe_cols = len(pandas_cols) cdef PandasCol pandas_col cdef col_t* col any_cols_need_gil_out[0] = False - for index in range(len_pandas_cols): + for index in range(len_dataframe_cols): pandas_col = pandas_cols[index] col = &cols.d[index] @@ -1045,20 +1045,20 @@ cdef void_int _pandas_resolve_cols( # obtain a meta-target of "table", "symbol" or "at". # * Finally, based on the source, any remaining "meta_target_field" # columns are converted to the appropriate target. - # See: _pandas_resolve_col_targets_and_dc(..). + # See: _dataframe_resolve_col_targets_and_dc(..). col.setup.meta_target = meta_target_t.meta_target_field # We will sort columns later. The index will be used to achieve a stable # sort among columns with the same `.meta_target`. col.setup.orig_index = index - _pandas_resolve_source_and_buffers(pandas_col, col) - _pandas_init_cursor(col) + _dataframe_resolve_source_and_buffers(pandas_col, col) + _dataframe_init_cursor(col) if col_source_needs_gil(col.setup.source): any_cols_need_gil_out[0] = True -cdef void_int _pandas_resolve_cols_target_name_and_dc( +cdef void_int _dataframe_resolve_cols_target_name_and_dc( qdb_pystr_buf* b, list pandas_cols, col_t_arr* cols) except -1: @@ -1068,7 +1068,7 @@ cdef void_int _pandas_resolve_cols_target_name_and_dc( for index in range(cols.size): col = &cols.d[index] pandas_col = pandas_cols[index] - _pandas_resolve_target(pandas_col, col) + _dataframe_resolve_target(pandas_col, col) if col.setup.source not in _TARGET_TO_SOURCES[col.setup.target]: raise ValueError( f'Bad value: Column {pandas_col.name!r} ' + @@ -1085,7 +1085,7 @@ cdef void_int _pandas_resolve_cols_target_name_and_dc( str_to_column_name_copy(b, pandas_col.name, &col.name) -cdef int _pandas_compare_cols(const void* lhs, const void* rhs) nogil: +cdef int _dataframe_compare_cols(const void* lhs, const void* rhs) nogil: cdef col_t* lhs_col = lhs cdef col_t* rhs_col = rhs cdef int source_diff = lhs_col.setup.meta_target - rhs_col.setup.meta_target @@ -1094,7 +1094,7 @@ cdef int _pandas_compare_cols(const void* lhs, const void* rhs) nogil: return lhs_col.setup.orig_index - rhs_col.setup.orig_index -cdef void_int _pandas_resolve_args( +cdef void_int _dataframe_resolve_args( object df, object table_name, object table_name_col, @@ -1112,8 +1112,8 @@ cdef void_int _pandas_resolve_args( cdef list pandas_cols = [ PandasCol(name, df.dtypes[index], series) for index, (name, series) in enumerate(df.items())] - _pandas_resolve_cols(b, pandas_cols, cols, any_cols_need_gil_out) - name_col = _pandas_resolve_table_name( + _dataframe_resolve_cols(b, pandas_cols, cols, any_cols_need_gil_out) + name_col = _dataframe_resolve_table_name( b, df, pandas_cols, @@ -1122,19 +1122,19 @@ cdef void_int _pandas_resolve_args( table_name_col, col_count, c_table_name_out) - at_col = _pandas_resolve_at(df, cols, at, col_count, at_value_out) - _pandas_resolve_symbols(df, pandas_cols, cols, name_col, at_col, symbols) - _pandas_resolve_cols_target_name_and_dc(b, pandas_cols, cols) - qsort(cols.d, col_count, sizeof(col_t), _pandas_compare_cols) + at_col = _dataframe_resolve_at(df, cols, at, col_count, at_value_out) + _dataframe_resolve_symbols(df, pandas_cols, cols, name_col, at_col, symbols) + _dataframe_resolve_cols_target_name_and_dc(b, pandas_cols, cols) + qsort(cols.d, col_count, sizeof(col_t), _dataframe_compare_cols) -cdef inline bint _pandas_arrow_get_bool(col_cursor_t* cursor): +cdef inline bint _dataframe_arrow_get_bool(col_cursor_t* cursor): return ( (cursor.chunk.buffers[1])[cursor.offset // 8] & (1 << (cursor.offset % 8))) -cdef inline bint _pandas_arrow_is_valid(col_cursor_t* cursor): +cdef inline bint _dataframe_arrow_is_valid(col_cursor_t* cursor): """Check if the value is set according to the validity bitmap.""" return ( cursor.chunk.null_count == 0 or @@ -1143,7 +1143,7 @@ cdef inline bint _pandas_arrow_is_valid(col_cursor_t* cursor): (1 << (cursor.offset % 8)))) -cdef inline void _pandas_arrow_get_cat_value( +cdef inline void _dataframe_arrow_get_cat_value( col_cursor_t* cursor, size_t key, size_t* len_out, @@ -1158,50 +1158,50 @@ cdef inline void _pandas_arrow_get_cat_value( buf_out[0] = &value_char_access[value_begin] -cdef inline bint _pandas_arrow_get_cat_i8( +cdef inline bint _dataframe_arrow_get_cat_i8( col_cursor_t* cursor, size_t* len_out, const char** buf_out): - cdef bint valid = _pandas_arrow_is_valid(cursor) + cdef bint valid = _dataframe_arrow_is_valid(cursor) cdef int8_t* key_access cdef int8_t key if valid: key_access = cursor.chunk.buffers[1] key = key_access[cursor.offset] - _pandas_arrow_get_cat_value(cursor, key, len_out, buf_out) + _dataframe_arrow_get_cat_value(cursor, key, len_out, buf_out) return valid -cdef inline bint _pandas_arrow_get_cat_i16( +cdef inline bint _dataframe_arrow_get_cat_i16( col_cursor_t* cursor, size_t* len_out, const char** buf_out): - cdef bint valid = _pandas_arrow_is_valid(cursor) + cdef bint valid = _dataframe_arrow_is_valid(cursor) cdef int16_t* key_access cdef int16_t key if valid: key_access = cursor.chunk.buffers[1] key = key_access[cursor.offset] - _pandas_arrow_get_cat_value(cursor, key, len_out, buf_out) + _dataframe_arrow_get_cat_value(cursor, key, len_out, buf_out) return valid -cdef inline bint _pandas_arrow_get_cat_i32( +cdef inline bint _dataframe_arrow_get_cat_i32( col_cursor_t* cursor, size_t* len_out, const char** buf_out): - cdef bint valid = _pandas_arrow_is_valid(cursor) + cdef bint valid = _dataframe_arrow_is_valid(cursor) cdef int32_t* key_access cdef int32_t key if valid: key_access = cursor.chunk.buffers[1] key = key_access[cursor.offset] - _pandas_arrow_get_cat_value(cursor, key, len_out, buf_out) + _dataframe_arrow_get_cat_value(cursor, key, len_out, buf_out) return valid -cdef inline bint _pandas_arrow_str( +cdef inline bint _dataframe_arrow_str( col_cursor_t* cursor, size_t* len_out, const char** buf_out): cdef int32_t* index_access cdef uint8_t* char_access cdef int32_t begin - cdef bint valid = _pandas_arrow_is_valid(cursor) + cdef bint valid = _dataframe_arrow_is_valid(cursor) if valid: index_access = cursor.chunk.buffers[1] char_access = cursor.chunk.buffers[2] @@ -1211,7 +1211,7 @@ cdef inline bint _pandas_arrow_str( return valid -cdef inline void_int _pandas_cell_str_pyobj_to_utf8( +cdef inline void_int _dataframe_cell_str_pyobj_to_utf8( qdb_pystr_buf* b, col_cursor_t* cursor, bint* valid_out, @@ -1221,7 +1221,7 @@ cdef inline void_int _pandas_cell_str_pyobj_to_utf8( if PyUnicode_CheckExact(cell): str_to_utf8(b, cell, utf8_out) valid_out[0] = True - elif _pandas_is_null_pyobj(cell): + elif _dataframe_is_null_pyobj(cell): valid_out[0] = False else: raise ValueError( @@ -1229,7 +1229,7 @@ cdef inline void_int _pandas_cell_str_pyobj_to_utf8( f'got an object of type {_fqn(type(cell))}.') -cdef void_int _pandas_serialize_cell_table__str_pyobj( +cdef void_int _dataframe_serialize_cell_table__str_pyobj( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: @@ -1238,7 +1238,7 @@ cdef void_int _pandas_serialize_cell_table__str_pyobj( cdef PyObject* cell = access[col.cursor.offset] cdef line_sender_table_name c_table_name if not PyUnicode_CheckExact(cell): - if _pandas_is_null_pyobj(cell): + if _dataframe_is_null_pyobj(cell): raise ValueError('Expected a table name, got a null value') else: raise ValueError( @@ -1249,7 +1249,7 @@ cdef void_int _pandas_serialize_cell_table__str_pyobj( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_table__str_arrow( +cdef void_int _dataframe_serialize_cell_table__str_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1258,7 +1258,7 @@ cdef void_int _pandas_serialize_cell_table__str_arrow( cdef size_t c_len cdef const char* buf cdef line_sender_table_name c_table_name - if _pandas_arrow_str(&col.cursor, &c_len, &buf): + if _dataframe_arrow_str(&col.cursor, &c_len, &buf): if not line_sender_table_name_init(&c_table_name, c_len, buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1270,7 +1270,7 @@ cdef void_int _pandas_serialize_cell_table__str_arrow( raise ValueError('Table name cannot be null') -cdef void_int _pandas_serialize_cell_table__str_i8_cat( +cdef void_int _dataframe_serialize_cell_table__str_i8_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1279,7 +1279,7 @@ cdef void_int _pandas_serialize_cell_table__str_i8_cat( cdef size_t c_len cdef const char* c_buf cdef line_sender_table_name c_table_name - if _pandas_arrow_get_cat_i8(&col.cursor, &c_len, &c_buf): + if _dataframe_arrow_get_cat_i8(&col.cursor, &c_len, &c_buf): if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1291,7 +1291,7 @@ cdef void_int _pandas_serialize_cell_table__str_i8_cat( raise ValueError('Table name cannot be null') -cdef void_int _pandas_serialize_cell_table__str_i16_cat( +cdef void_int _dataframe_serialize_cell_table__str_i16_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1300,7 +1300,7 @@ cdef void_int _pandas_serialize_cell_table__str_i16_cat( cdef size_t c_len cdef const char* c_buf cdef line_sender_table_name c_table_name - if _pandas_arrow_get_cat_i16(&col.cursor, &c_len, &c_buf): + if _dataframe_arrow_get_cat_i16(&col.cursor, &c_len, &c_buf): if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1312,7 +1312,7 @@ cdef void_int _pandas_serialize_cell_table__str_i16_cat( raise ValueError('Table name cannot be null') -cdef void_int _pandas_serialize_cell_table__str_i32_cat( +cdef void_int _dataframe_serialize_cell_table__str_i32_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1321,7 +1321,7 @@ cdef void_int _pandas_serialize_cell_table__str_i32_cat( cdef size_t c_len cdef const char* c_buf cdef line_sender_table_name c_table_name - if _pandas_arrow_get_cat_i32(&col.cursor, &c_len, &c_buf): + if _dataframe_arrow_get_cat_i32(&col.cursor, &c_len, &c_buf): if not line_sender_table_name_init(&c_table_name, c_len, c_buf, &err): _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1333,71 +1333,71 @@ cdef void_int _pandas_serialize_cell_table__str_i32_cat( raise ValueError('Table name cannot be null') -cdef void_int _pandas_serialize_cell_symbol__str_pyobj( +cdef void_int _dataframe_serialize_cell_symbol__str_pyobj( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 - _pandas_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) + _dataframe_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) if valid and not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_symbol__str_arrow( +cdef void_int _dataframe_serialize_cell_symbol__str_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_str(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_symbol__str_i8_cat( +cdef void_int _dataframe_serialize_cell_symbol__str_i8_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_symbol__str_i16_cat( +cdef void_int _dataframe_serialize_cell_symbol__str_i16_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_symbol__str_i32_cat( +cdef void_int _dataframe_serialize_cell_symbol__str_i32_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_symbol(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( +cdef void_int _dataframe_serialize_cell_column_bool__bool_pyobj( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: @@ -1408,7 +1408,7 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( if not line_sender_buffer_column_bool( ls_buf, col.name, cell == Py_True, &err): raise c_err_to_py(err) - elif _pandas_is_null_pyobj(cell): + elif _dataframe_is_null_pyobj(cell): raise ValueError('Cannot insert null values into a boolean column.') else: raise ValueError( @@ -1416,7 +1416,7 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_pyobj( _fqn(type(cell)) + '.') -cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( +cdef void_int _dataframe_serialize_cell_column_bool__bool_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1429,16 +1429,16 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( +cdef void_int _dataframe_serialize_cell_column_bool__bool_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef bint value if valid: - value = _pandas_arrow_get_bool(&col.cursor) + value = _dataframe_arrow_get_bool(&col.cursor) if not line_sender_buffer_column_bool(ls_buf, col.name, value, &err): _ensure_has_gil(gs) raise c_err_to_py(err) @@ -1447,7 +1447,7 @@ cdef void_int _pandas_serialize_cell_column_bool__bool_arrow( raise ValueError('Cannot insert null values into a boolean column.') -cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( +cdef void_int _dataframe_serialize_cell_column_i64__int_pyobj( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: @@ -1459,7 +1459,7 @@ cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( value = PyLong_AsLongLong(cell) if not line_sender_buffer_column_i64(ls_buf, col.name, value, &err): raise c_err_to_py(err) - elif _pandas_is_null_pyobj(cell): + elif _dataframe_is_null_pyobj(cell): pass else: raise ValueError( @@ -1467,7 +1467,7 @@ cdef void_int _pandas_serialize_cell_column_i64__int_pyobj( _fqn(type(cell)) + '.') -cdef void_int _pandas_serialize_cell_column_i64__u8_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__u8_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1480,7 +1480,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u8_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i8_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__i8_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1493,7 +1493,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i8_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__u16_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__u16_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1506,7 +1506,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u16_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i16_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__i16_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1519,7 +1519,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i16_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__u32_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__u32_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1532,7 +1532,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u32_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i32_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__i32_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1545,7 +1545,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i32_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__u64_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__u64_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1561,7 +1561,7 @@ cdef void_int _pandas_serialize_cell_column_i64__u64_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i64_numpy( +cdef void_int _dataframe_serialize_cell_column_i64__i64_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1574,13 +1574,13 @@ cdef void_int _pandas_serialize_cell_column_i64__i64_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__u8_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef uint8_t* access if valid: access = col.cursor.chunk.buffers[1] @@ -1593,13 +1593,13 @@ cdef void_int _pandas_serialize_cell_column_i64__u8_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__i8_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef int8_t* access if valid: access = col.cursor.chunk.buffers[1] @@ -1612,13 +1612,13 @@ cdef void_int _pandas_serialize_cell_column_i64__i8_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__u16_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef uint16_t* access if valid: access = col.cursor.chunk.buffers[1] @@ -1631,13 +1631,13 @@ cdef void_int _pandas_serialize_cell_column_i64__u16_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__i16_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef int16_t* access if valid: access = col.cursor.chunk.buffers[1] @@ -1650,13 +1650,13 @@ cdef void_int _pandas_serialize_cell_column_i64__i16_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__u32_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef uint32_t* access if valid: access = col.cursor.chunk.buffers[1] @@ -1669,13 +1669,13 @@ cdef void_int _pandas_serialize_cell_column_i64__u32_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__i32_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef int32_t* access if valid: access = col.cursor.chunk.buffers[1] @@ -1688,13 +1688,13 @@ cdef void_int _pandas_serialize_cell_column_i64__i32_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__u64_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef uint64_t* access cdef uint64_t cell if valid: @@ -1712,13 +1712,13 @@ cdef void_int _pandas_serialize_cell_column_i64__u64_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( +cdef void_int _dataframe_serialize_cell_column_i64__i64_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef int64_t* access if valid: access = col.cursor.chunk.buffers[1] @@ -1731,7 +1731,7 @@ cdef void_int _pandas_serialize_cell_column_i64__i64_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( +cdef void_int _dataframe_serialize_cell_column_f64__float_pyobj( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: @@ -1743,7 +1743,7 @@ cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( value = PyFloat_AS_DOUBLE(cell) if not line_sender_buffer_column_f64(ls_buf, col.name, value, &err): raise c_err_to_py(err) - elif _pandas_is_null_pyobj(cell): + elif _dataframe_is_null_pyobj(cell): pass else: raise ValueError( @@ -1751,7 +1751,7 @@ cdef void_int _pandas_serialize_cell_column_f64__float_pyobj( _fqn(type(cell)) + '.') -cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( +cdef void_int _dataframe_serialize_cell_column_f64__f32_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1765,7 +1765,7 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_f64__f64_numpy( +cdef void_int _dataframe_serialize_cell_column_f64__f64_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1778,13 +1778,13 @@ cdef void_int _pandas_serialize_cell_column_f64__f64_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( +cdef void_int _dataframe_serialize_cell_column_f64__f32_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef float* access if valid: access = col.cursor.chunk.buffers[1] @@ -1797,13 +1797,13 @@ cdef void_int _pandas_serialize_cell_column_f64__f32_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( +cdef void_int _dataframe_serialize_cell_column_f64__f64_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef double* access if valid: access = col.cursor.chunk.buffers[1] @@ -1816,72 +1816,72 @@ cdef void_int _pandas_serialize_cell_column_f64__f64_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_str__str_pyobj( +cdef void_int _dataframe_serialize_cell_column_str__str_pyobj( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col) except -1: cdef line_sender_error* err = NULL cdef bint valid = False cdef line_sender_utf8 utf8 - _pandas_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) + _dataframe_cell_str_pyobj_to_utf8(b, &col.cursor, &valid, &utf8) if valid and not line_sender_buffer_column_str( ls_buf, col.name, utf8, &err): raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_str__str_arrow( +cdef void_int _dataframe_serialize_cell_column_str__str_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_str(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_str(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_str__str_i8_cat( +cdef void_int _dataframe_serialize_cell_column_str__str_i8_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_get_cat_i8(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_str__str_i16_cat( +cdef void_int _dataframe_serialize_cell_column_str__str_i16_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_get_cat_i16(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_str__str_i32_cat( +cdef void_int _dataframe_serialize_cell_column_str__str_i32_cat( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL cdef line_sender_utf8 utf8 - if _pandas_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): + if _dataframe_arrow_get_cat_i32(&col.cursor, &utf8.len, &utf8.buf): if not line_sender_buffer_column_str(ls_buf, col.name, utf8, &err): _ensure_has_gil(gs) raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( +cdef void_int _dataframe_serialize_cell_column_ts__dt64ns_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1896,13 +1896,13 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( +cdef void_int _dataframe_serialize_cell_column_ts__dt64ns_tz_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef int64_t cell cdef int64_t* access if valid: @@ -1914,7 +1914,7 @@ cdef void_int _pandas_serialize_cell_column_ts__dt64ns_tz_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( +cdef void_int _dataframe_serialize_cell_at_dt64ns_numpy( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1933,13 +1933,13 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_numpy( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( +cdef void_int _dataframe_serialize_cell_at_dt64ns_tz_arrow( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, PyThreadState** gs) except -1: cdef line_sender_error* err = NULL - cdef bint valid = _pandas_arrow_is_valid(&col.cursor) + cdef bint valid = _dataframe_arrow_is_valid(&col.cursor) cdef int64_t* access cdef int64_t cell if valid: @@ -1955,7 +1955,7 @@ cdef void_int _pandas_serialize_cell_at_dt64ns_tz_arrow( raise c_err_to_py(err) -cdef void_int _pandas_serialize_cell( +cdef void_int _dataframe_serialize_cell( line_sender_buffer* ls_buf, qdb_pystr_buf* b, col_t* col, @@ -1966,93 +1966,93 @@ cdef void_int _pandas_serialize_cell( if dc == col_dispatch_code_t.col_dispatch_code_skip_nulls: pass # We skip a null column. Nothing to do. elif dc == col_dispatch_code_t.col_dispatch_code_table__str_pyobj: - _pandas_serialize_cell_table__str_pyobj(ls_buf, b, col) + _dataframe_serialize_cell_table__str_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_arrow: - _pandas_serialize_cell_table__str_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_table__str_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i8_cat: - _pandas_serialize_cell_table__str_i8_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_table__str_i8_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i16_cat: - _pandas_serialize_cell_table__str_i16_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_table__str_i16_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_table__str_i32_cat: - _pandas_serialize_cell_table__str_i32_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_table__str_i32_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_pyobj: - _pandas_serialize_cell_symbol__str_pyobj(ls_buf, b, col) + _dataframe_serialize_cell_symbol__str_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_arrow: - _pandas_serialize_cell_symbol__str_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_symbol__str_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i8_cat: - _pandas_serialize_cell_symbol__str_i8_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_symbol__str_i8_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i16_cat: - _pandas_serialize_cell_symbol__str_i16_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_symbol__str_i16_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_symbol__str_i32_cat: - _pandas_serialize_cell_symbol__str_i32_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_symbol__str_i32_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_pyobj: - _pandas_serialize_cell_column_bool__bool_pyobj(ls_buf, b, col) + _dataframe_serialize_cell_column_bool__bool_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_numpy: - _pandas_serialize_cell_column_bool__bool_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_bool__bool_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_bool__bool_arrow: - _pandas_serialize_cell_column_bool__bool_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_bool__bool_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__int_pyobj: - _pandas_serialize_cell_column_i64__int_pyobj(ls_buf, b, col) + _dataframe_serialize_cell_column_i64__int_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_numpy: - _pandas_serialize_cell_column_i64__u8_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u8_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_numpy: - _pandas_serialize_cell_column_i64__i8_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i8_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_numpy: - _pandas_serialize_cell_column_i64__u16_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u16_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_numpy: - _pandas_serialize_cell_column_i64__i16_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i16_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_numpy: - _pandas_serialize_cell_column_i64__u32_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u32_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_numpy: - _pandas_serialize_cell_column_i64__i32_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i32_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_numpy: - _pandas_serialize_cell_column_i64__u64_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u64_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_numpy: - _pandas_serialize_cell_column_i64__i64_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i64_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u8_arrow: - _pandas_serialize_cell_column_i64__u8_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u8_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i8_arrow: - _pandas_serialize_cell_column_i64__i8_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i8_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u16_arrow: - _pandas_serialize_cell_column_i64__u16_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u16_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i16_arrow: - _pandas_serialize_cell_column_i64__i16_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i16_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u32_arrow: - _pandas_serialize_cell_column_i64__u32_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u32_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i32_arrow: - _pandas_serialize_cell_column_i64__i32_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i32_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__u64_arrow: - _pandas_serialize_cell_column_i64__u64_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__u64_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_i64__i64_arrow: - _pandas_serialize_cell_column_i64__i64_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_i64__i64_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__float_pyobj: - _pandas_serialize_cell_column_f64__float_pyobj(ls_buf, b, col) + _dataframe_serialize_cell_column_f64__float_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_numpy: - _pandas_serialize_cell_column_f64__f32_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_f64__f32_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_numpy: - _pandas_serialize_cell_column_f64__f64_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_f64__f64_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f32_arrow: - _pandas_serialize_cell_column_f64__f32_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_f64__f32_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_f64__f64_arrow: - _pandas_serialize_cell_column_f64__f64_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_f64__f64_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_pyobj: - _pandas_serialize_cell_column_str__str_pyobj(ls_buf, b, col) + _dataframe_serialize_cell_column_str__str_pyobj(ls_buf, b, col) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_arrow: - _pandas_serialize_cell_column_str__str_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_str__str_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i8_cat: - _pandas_serialize_cell_column_str__str_i8_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_str__str_i8_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i16_cat: - _pandas_serialize_cell_column_str__str_i16_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_str__str_i16_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_str__str_i32_cat: - _pandas_serialize_cell_column_str__str_i32_cat(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_str__str_i32_cat(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_numpy: - _pandas_serialize_cell_column_ts__dt64ns_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_ts__dt64ns_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_column_ts__dt64ns_tz_arrow: - _pandas_serialize_cell_column_ts__dt64ns_tz_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_column_ts__dt64ns_tz_arrow(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_numpy: - _pandas_serialize_cell_at_dt64ns_numpy(ls_buf, b, col, gs) + _dataframe_serialize_cell_at_dt64ns_numpy(ls_buf, b, col, gs) elif dc == col_dispatch_code_t.col_dispatch_code_at__dt64ns_tz_arrow: - _pandas_serialize_cell_at_dt64ns_tz_arrow(ls_buf, b, col, gs) + _dataframe_serialize_cell_at_dt64ns_tz_arrow(ls_buf, b, col, gs) else: _ensure_has_gil(gs) raise RuntimeError(f"Unknown column dispatch code: {dc}") @@ -2060,7 +2060,7 @@ cdef void_int _pandas_serialize_cell( # Don't add complex conditions above! -cdef void _pandas_col_advance(col_t* col): +cdef void _dataframe_col_advance(col_t* col): # Branchless version of: # cdef bint new_chunk = cursor.offset == cursor.chunk.length # if new_chunk == 0: @@ -2086,7 +2086,7 @@ cdef void _pandas_col_advance(col_t* col): ((not new_chunk) * cursor.offset)) -cdef void_int _pandas_handle_auto_flush( +cdef void_int _dataframe_handle_auto_flush( auto_flush_t af, line_sender_buffer* ls_buf, PyThreadState** gs) except -1: @@ -2130,7 +2130,7 @@ cdef void_int _pandas_handle_auto_flush( cdef size_t _CELL_GIL_BLIP_INTERVAL = 40000 -cdef void_int _pandas( +cdef void_int _dataframe( auto_flush_t af, line_sender_buffer* ls_buf, qdb_pystr_buf* b, @@ -2155,8 +2155,8 @@ cdef void_int _pandas( cdef bint had_gil cdef bint was_serializing_cell = False - _pandas_may_import_deps() - _pandas_check_is_dataframe(df) + _dataframe_may_import_deps() + _dataframe_check_is_dataframe(df) row_count = len(df) col_count = len(df.columns) if (col_count == 0) or (row_count == 0): @@ -2165,7 +2165,7 @@ cdef void_int _pandas( try: qdb_pystr_buf_clear(b) cols = col_t_arr_new(col_count) - _pandas_resolve_args( + _dataframe_resolve_args( df, table_name, table_name_col, @@ -2220,8 +2220,8 @@ cdef void_int _pandas( was_serializing_cell = True for col_index in range(col_count): col = &cols.d[col_index] - _pandas_serialize_cell(ls_buf, b, col, &gs) # may raise - _pandas_col_advance(col) + _dataframe_serialize_cell(ls_buf, b, col, &gs) # may raise + _dataframe_col_advance(col) was_serializing_cell = False # Fixed "at" value (not from a column). @@ -2234,7 +2234,7 @@ cdef void_int _pandas( _ensure_has_gil(&gs) raise c_err_to_py(err) - _pandas_handle_auto_flush(af, ls_buf, &gs) + _dataframe_handle_auto_flush(af, ls_buf, &gs) except Exception as e: # It would be an internal bug for this to raise. if not line_sender_buffer_rewind_to_marker(ls_buf, &err): @@ -2254,7 +2254,7 @@ cdef void_int _pandas( # It currently isn't so we have to raise an error. raise IngressError( IngressErrorCode.BadDataFrame, - f'Bad pandas row at index {row_index}: ' + + f'Bad dataframe row at index {row_index}: ' + 'All values are nulls. '+ 'Ensure at least one column is not null.') from e else: diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 77e8b3e6..c3d9356a 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -57,7 +57,7 @@ from .ingress_helper cimport * ctypedef int void_int import cython -include "pandas_integration.pxi" +include "dataframe.pxi" from enum import Enum @@ -957,7 +957,7 @@ cdef class Buffer: self._row(table_name, symbols, columns, at) return self - def pandas( + def dataframe( self, df, # : pd.DataFrame *, @@ -968,7 +968,7 @@ cdef class Buffer: """ Add a pandas DataFrame to the buffer. - Also see the :func:`Sender.pandas` method if you're + Also see the :func:`Sender.dataframe` method if you're not using the buffer explicitly. It supports the same parameters and also supports auto-flushing. @@ -1068,7 +1068,8 @@ cdef class Buffer: 'temperature': [24.5, 35.0, 25.5], 'humidity': [0.5, 0.6, 0.45], 'ts': pd.date_range('2021-07-01', periods=3)}) - buf.pandas(df, table_name='weather', at='ts', symbols=['location']) + buf.dataframe( + df, table_name='weather', at='ts', symbols=['location']) # ... sender.flush(buf) @@ -1200,7 +1201,7 @@ cdef class Buffer: interpreted as the current time set by the server on receipt of message. """ - _pandas( + _dataframe( auto_flush_blank(), self._impl, self._b, @@ -1559,7 +1560,7 @@ cdef class Sender: """ self._buffer.row(table_name, symbols=symbols, columns=columns, at=at) - def pandas( + def dataframe( self, df, # : pd.DataFrame *, @@ -1591,9 +1592,9 @@ cdef class Sender: pd.Timestamp('2022-08-09 13:56:03')]}) with qi.Sender('localhost', 9000) as sender: - sender.pandas(df, table_name='race_metrics', at='ts') + sender.dataframe(df, table_name='race_metrics', at='ts') - This method builds on top of the :func:`Buffer.pandas` method. + This method builds on top of the :func:`Buffer.dataframe` method. See its documentation for details on arguments. Additionally, this method also supports auto-flushing the buffer @@ -1606,7 +1607,7 @@ cdef class Sender: if self._auto_flush_enabled: af.sender = self._impl af.watermark = self._auto_flush_watermark - _pandas( + _dataframe( af, self._buffer._impl, self._buffer._b, diff --git a/test/benchmark.py b/test/benchmark.py index d9eff5d4..066298dd 100644 --- a/test/benchmark.py +++ b/test/benchmark.py @@ -25,12 +25,12 @@ def test_pystr_i64_10m(self): buf = qi.Buffer() # Warm up and pre-size buffer - buf.pandas(df, table_name='tbl1', symbols=True) + buf.dataframe(df, table_name='tbl1', symbols=True) buf.clear() # Run t0 = time.monotonic() - buf.pandas(df, table_name='tbl1', symbols=True) + buf.dataframe(df, table_name='tbl1', symbols=True) t1 = time.monotonic() print(f'Time: {t1 - t0}, size: {len(buf)}') @@ -51,12 +51,12 @@ def test_mixed_10m(self): buf = qi.Buffer() # Warm up and pre-size buffer - buf.pandas(df, table_name='tbl1', symbols=True) + buf.dataframe(df, table_name='tbl1', symbols=True) buf.clear() # Run t0 = time.monotonic() - buf.pandas(df, table_name='tbl1', symbols=True) + buf.dataframe(df, table_name='tbl1', symbols=True) t1 = time.monotonic() print(f'Time: {t1 - t0}, size: {len(buf)}') @@ -75,12 +75,12 @@ def test_string_escaping_10m(self): buf = qi.Buffer() # Warm up and pre-size buffer - buf.pandas(df, table_name='tbl1', symbols=True) + buf.dataframe(df, table_name='tbl1', symbols=True) buf.clear() # Run t0 = time.monotonic() - buf.pandas(df, table_name='tbl1', symbols=True) + buf.dataframe(df, table_name='tbl1', symbols=True) t1 = time.monotonic() print(f'Time: {t1 - t0}, size: {len(buf)}') @@ -107,12 +107,12 @@ def test_string_encoding_10m(self): buf = qi.Buffer() # Warm up and pre-size buffer - buf.pandas(df, table_name='tbl1', symbols=False) + buf.dataframe(df, table_name='tbl1', symbols=False) buf.clear() # Run t0 = time.monotonic() - buf.pandas(df, table_name='tbl1', symbols=False) + buf.dataframe(df, table_name='tbl1', symbols=False) t1 = time.monotonic() print(f'Time: {t1 - t0}, size: {len(buf)}') @@ -132,7 +132,7 @@ def _test_gil_release_10m(self, threads): def benchmark_run(buf): t0 = time.monotonic() - buf.pandas(df, table_name='tbl1', symbols=True) + buf.dataframe(df, table_name='tbl1', symbols=True) t1 = time.monotonic() return buf, (t0, t1) diff --git a/test/system_test.py b/test/system_test.py index 3f3c530e..e0eb7d5a 100755 --- a/test/system_test.py +++ b/test/system_test.py @@ -132,7 +132,7 @@ def test_auth_tls_ca_str(self): self._test_scenario(self.qdb_auth, AUTH, str(CA_PATH)) @unittest.skipIf(not pd, 'pandas not installed') - def test_basic_pandas(self): + def test_basic_dataframe(self): port = self.qdb_plain.line_tcp_port pending = None table_name = uuid.uuid4().hex @@ -148,7 +148,7 @@ def test_basic_pandas(self): numpy.datetime64('2021-01-03')]}) df.index.name = table_name with qi.Sender('localhost', port) as sender: - sender.pandas(df) + sender.dataframe(df) pending = str(sender) resp = self.qdb_plain.retry_check_table( diff --git a/test/test.py b/test/test.py index be3f76ae..136f91f1 100755 --- a/test/test.py +++ b/test/test.py @@ -25,14 +25,14 @@ if pd is not None: - from test_pandas_integration import TestPandas + from test_dataframe import TestPandas else: class TestNoPandas(unittest.TestCase): def test_no_pandas(self): buf = qi.Buffer() exp = 'Missing.*`pandas.*pyarrow`.*readthedocs.*installation.html.' with self.assertRaisesRegex(ImportError, exp): - buf.pandas(None) + buf.dataframe(None) class TestBuffer(unittest.TestCase): @@ -416,12 +416,12 @@ def test_dont_flush_on_exception(self): self.assertEqual(msgs, []) @unittest.skipIf(not pd, 'pandas not installed') - def test_pandas(self): + def test_dataframe(self): with Server() as server: with qi.Sender('localhost', server.port) as sender: server.accept() df = pd.DataFrame({'a': [1, 2], 'b': [3.0, 4.0]}) - sender.pandas(df, table_name='tbl1') + sender.dataframe(df, table_name='tbl1') msgs = server.recv() self.assertEqual( msgs, @@ -429,14 +429,14 @@ def test_pandas(self): b'tbl1 a=2i,b=4.0']) @unittest.skipIf(not pd, 'pandas not installed') - def test_pandas_auto_flush(self): + def test_dataframe_auto_flush(self): with Server() as server: # An auto-flush size of 20 bytes is enough to auto-flush the first # row, but not the second. with qi.Sender('localhost', server.port, auto_flush=20) as sender: server.accept() df = pd.DataFrame({'a': [100000, 2], 'b': [3.0, 4.0]}) - sender.pandas(df, table_name='tbl1') + sender.dataframe(df, table_name='tbl1') msgs = server.recv() self.assertEqual( msgs, @@ -462,7 +462,7 @@ def test_pandas_auto_flush(self): with self.assertRaisesRegex(qi.IngressError, exp_err): for _ in range(1000): time.sleep(0.01) - sender.pandas(df.head(1), table_name='tbl1') + sender.dataframe(df.head(1), table_name='tbl1') def test_new_buffer(self): sender = qi.Sender( diff --git a/test/test_pandas_integration.py b/test/test_dataframe.py similarity index 89% rename from test/test_pandas_integration.py rename to test/test_dataframe.py index 83330286..1902fe69 100644 --- a/test/test_pandas_integration.py +++ b/test/test_dataframe.py @@ -22,9 +22,9 @@ import pandas as pd -def _pandas(*args, **kwargs): +def _dataframe(*args, **kwargs): buf = qi.Buffer() - buf.pandas(*args, **kwargs) + buf.dataframe(*args, **kwargs) return str(buf) @@ -55,85 +55,85 @@ def _pandas(*args, **kwargs): class TestPandas(unittest.TestCase): def test_bad_dataframe(self): with self.assertRaisesRegex(TypeError, 'Expected pandas'): - _pandas([]) + _dataframe([]) def test_no_table_name(self): with self.assertRaisesRegex(ValueError, 'Must specify at least one of'): - _pandas(DF1) + _dataframe(DF1) def test_bad_table_name_type(self): with self.assertRaisesRegex(TypeError, 'Must be str'): - _pandas(DF1, table_name=1.5) + _dataframe(DF1, table_name=1.5) def test_invalid_table_name(self): with self.assertRaisesRegex( qi.IngressError, '`table_name`: Bad string "."'): - _pandas(DF1, table_name='.') + _dataframe(DF1, table_name='.') def test_invalid_column_dtype(self): with self.assertRaisesRegex(qi.IngressError, '`table_name_col`: Bad dtype'): - _pandas(DF1, table_name_col='B') + _dataframe(DF1, table_name_col='B') with self.assertRaisesRegex(qi.IngressError, '`table_name_col`: Bad dtype'): - _pandas(DF1, table_name_col=1) + _dataframe(DF1, table_name_col=1) with self.assertRaisesRegex(qi.IngressError, '`table_name_col`: Bad dtype'): - _pandas(DF1, table_name_col=-3) + _dataframe(DF1, table_name_col=-3) with self.assertRaisesRegex(IndexError, '`table_name_col`: -5 index'): - _pandas(DF1, table_name_col=-5) + _dataframe(DF1, table_name_col=-5) def test_bad_str_obj_col(self): with self.assertRaisesRegex(qi.IngressError, "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): - _pandas(DF1, table_name_col='D') + _dataframe(DF1, table_name_col='D') with self.assertRaisesRegex(qi.IngressError, "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): - _pandas(DF1, table_name_col=3) + _dataframe(DF1, table_name_col=3) with self.assertRaisesRegex(qi.IngressError, "`table_name_col`: Bad.*`object`.*bool.*'D'.*Must.*strings"): - _pandas(DF1, table_name_col=-1) + _dataframe(DF1, table_name_col=-1) def test_bad_symbol(self): with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): - _pandas(DF1, table_name='tbl1', symbols=0) + _dataframe(DF1, table_name='tbl1', symbols=0) with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): - _pandas(DF1, table_name='tbl1', symbols={}) + _dataframe(DF1, table_name='tbl1', symbols={}) with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): - _pandas(DF1, table_name='tbl1', symbols=None) + _dataframe(DF1, table_name='tbl1', symbols=None) with self.assertRaisesRegex(qi.IngressError, "`symbols`: Bad dtype `float64`.*'A'.*Must.*strings col"): - _pandas(DF1, table_name='tbl1', symbols=(0,)) + _dataframe(DF1, table_name='tbl1', symbols=(0,)) with self.assertRaisesRegex(qi.IngressError, "`symbols`: Bad dtype `int64`.*'B'.*Must be a strings column."): - _pandas(DF1, table_name='tbl1', symbols=[1]) + _dataframe(DF1, table_name='tbl1', symbols=[1]) def test_bad_at(self): with self.assertRaisesRegex(KeyError, '`at`.*2018.*not found in the'): - _pandas(DF1, table_name='tbl1', at='2018-03-10T00:00:00Z') + _dataframe(DF1, table_name='tbl1', at='2018-03-10T00:00:00Z') with self.assertRaisesRegex(TypeError, '`at`.*float64.*be a datetime'): - _pandas(DF1, table_name='tbl1', at='A') + _dataframe(DF1, table_name='tbl1', at='A') with self.assertRaisesRegex(TypeError, '`at`.*int64.*be a datetime'): - _pandas(DF1, table_name='tbl1', at=1) + _dataframe(DF1, table_name='tbl1', at=1) with self.assertRaisesRegex(TypeError, '`at`.*object.*be a datetime'): - _pandas(DF1, table_name='tbl1', at=-1) + _dataframe(DF1, table_name='tbl1', at=-1) def test_empty_dataframe(self): - buf = _pandas(pd.DataFrame(), table_name='tbl1') + buf = _dataframe(pd.DataFrame(), table_name='tbl1') self.assertEqual(buf, '') def test_zero_row_dataframe(self): - buf = _pandas(pd.DataFrame(columns=['A', 'B']), table_name='tbl1') + buf = _dataframe(pd.DataFrame(columns=['A', 'B']), table_name='tbl1') self.assertEqual(buf, '') def test_zero_column_dataframe(self): df = pd.DataFrame(index=[0, 1, 2]) self.assertEqual(len(df), 3) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual(buf, '') - + def test_basic(self): - buf = _pandas( + buf = _dataframe( DF2, table_name_col='T', symbols=['A', 'B', 'C', 'D'], @@ -149,21 +149,21 @@ def test_named_dataframe(self): 'a': [1, 2, 3], 'b': ['a', 'b', 'c']}) df.index.name = 'table_name' - buf = _pandas(df) + buf = _dataframe(df) self.assertEqual( buf, 'table_name a=1i,b="a"\n' + 'table_name a=2i,b="b"\n' + 'table_name a=3i,b="c"\n') - - buf = _pandas(df, table_name='tbl1') + + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + 'tbl1 a=2i,b="b"\n' + 'tbl1 a=3i,b="c"\n') - buf = _pandas(df, table_name_col='b') + buf = _dataframe(df, table_name_col='b') self.assertEqual( buf, 'a a=1i\n' + @@ -173,7 +173,7 @@ def test_named_dataframe(self): df.index.name = 42 # bad type, not str with self.assertRaisesRegex(qi.IngressError, 'Bad dataframe index name as table.*: Expected str, not.*int.'): - _pandas(df) + _dataframe(df) @unittest.skipIf(BROKEN_TIMEZONES, 'requires accurate timezones') def test_at_good(self): @@ -183,7 +183,7 @@ def test_at_good(self): df.index.name = 'test_at_good' with self.assertRaisesRegex(KeyError, 'Bad argument `at`: Column .2018-03.* not found .* dataframe.'): - _pandas(df, at='2018-03-10T00:00:00Z') + _dataframe(df, at='2018-03-10T00:00:00Z') # Same timestamp, specified in various ways. t1_setup = dt.datetime(2018, 3, 10, 0, 0, 0, tzinfo=dt.timezone.utc) @@ -196,7 +196,7 @@ def test_at_good(self): t7 = qi.TimestampNanos.from_datetime(t3) timestamps = [t1, t2, t3, t4, t5, t6, t7] for ts in timestamps: - buf = _pandas(df, table_name='tbl1', at=ts) + buf = _dataframe(df, table_name='tbl1', at=ts) self.assertEqual( buf, 'tbl1 a=1i,b="a" 1520640000000000000\n' + @@ -212,7 +212,7 @@ def test_at_neg(self): for ts in neg_timestamps: with self.assertRaisesRegex(ValueError, 'Bad.*`at`: Cannot .* before the Unix epoch .1970-01-01.*'): - _pandas(DF2, at=ts, table_name='test_at_neg') + _dataframe(DF2, at=ts, table_name='test_at_neg') @unittest.skipIf(BROKEN_TIMEZONES, 'requires accurate timezones') def test_at_ts_0(self): @@ -233,7 +233,7 @@ def test_at_ts_0(self): edge_timestamps = [e1, e2, e3, e4, e5, e6, e7] for ts in edge_timestamps: - buf = _pandas(df, table_name='tbl1', at=ts) + buf = _dataframe(df, table_name='tbl1', at=ts) self.assertEqual( buf, 'tbl1 a=1i,b="a" 0\n' + @@ -243,8 +243,8 @@ def test_at_ts_0(self): def test_row_of_nulls(self): df = pd.DataFrame({'a': ['a1', None, 'a3']}) with self.assertRaisesRegex( - qi.IngressError, 'Bad pandas row .*1: All values are nulls.'): - _pandas(df, table_name='tbl1', symbols=['a']) + qi.IngressError, 'Bad dataframe row.*1: All values are nulls.'): + _dataframe(df, table_name='tbl1', symbols=['a']) def test_u8_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ @@ -252,7 +252,7 @@ def test_u8_numpy_col(self): 0, 255], # u8 max dtype='uint8')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -267,7 +267,7 @@ def test_i8_numpy_col(self): -128, # i8 min 127, # i8 max 0], dtype='int8')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -283,7 +283,7 @@ def test_u16_numpy_col(self): 0, 65535], # u16 max dtype='uint16')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -298,7 +298,7 @@ def test_i16_numpy_col(self): -32768, # i16 min 32767, # i16 max 0], dtype='int16')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -314,7 +314,7 @@ def test_u32_numpy_col(self): 0, 4294967295], # u32 max dtype='uint32')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -330,7 +330,7 @@ def test_i32_numpy_col(self): 0, 2147483647], # i32 max dtype='int32')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -346,7 +346,7 @@ def test_u64_numpy_col(self): 0, 9223372036854775807], # i64 max dtype='uint64')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -356,7 +356,7 @@ def test_u64_numpy_col(self): 'tbl1 a=9223372036854775807i\n') buf = qi.Buffer() - buf.pandas(pd.DataFrame({'b': [.5, 1.0, 1.5]}), table_name='tbl2') + buf.dataframe(pd.DataFrame({'b': [.5, 1.0, 1.5]}), table_name='tbl2') exp1 = ( 'tbl2 b=0.5\n' + 'tbl2 b=1.0\n' + @@ -372,7 +372,7 @@ def test_u64_numpy_col(self): with self.assertRaisesRegex( qi.IngressError, 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): - buf.pandas(df2, table_name='tbl1') + buf.dataframe(df2, table_name='tbl1') self.assertEqual( str(buf), @@ -385,7 +385,7 @@ def test_i64_numpy_col(self): 0, 9223372036854775807], # i64 max dtype='int64')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i\n' + @@ -394,7 +394,7 @@ def test_i64_numpy_col(self): 'tbl1 a=-9223372036854775808i\n' + 'tbl1 a=0i\n' + 'tbl1 a=9223372036854775807i\n') - + def test_f32_numpy_col(self): df = pd.DataFrame({'a': pd.Series([ 1.0, 2.0, 3.0, @@ -404,7 +404,7 @@ def test_f32_numpy_col(self): float('nan'), 3.4028234663852886e38], # f32 max dtype='float32')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1.0\n' + @@ -425,7 +425,7 @@ def test_f64_numpy_col(self): float('nan'), 1.7976931348623157e308], # f64 max dtype='float64')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1.0\n' + @@ -446,7 +446,7 @@ def test_u8_arrow_col(self): 255], # u8 max dtype=pd.UInt8Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -455,7 +455,7 @@ def test_u8_arrow_col(self): 'tbl1 a=0i,b="d"\n' + 'tbl1 b="e"\n' + 'tbl1 a=255i,b="f"\n') - + def test_i8_arrow_col(self): df = pd.DataFrame({ 'a': pd.Series([ @@ -466,7 +466,7 @@ def test_i8_arrow_col(self): 127], # i8 max dtype=pd.Int8Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -486,7 +486,7 @@ def test_u16_arrow_col(self): 65535], # u16 max dtype=pd.UInt16Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -506,7 +506,7 @@ def test_i16_arrow_col(self): 32767], # i16 max dtype=pd.Int16Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -526,7 +526,7 @@ def test_u32_arrow_col(self): 4294967295], # u32 max dtype=pd.UInt32Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -546,7 +546,7 @@ def test_i32_arrow_col(self): 2147483647], # i32 max dtype=pd.Int32Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -566,7 +566,7 @@ def test_u64_arrow_col(self): 9223372036854775807], # i64 max dtype=pd.UInt64Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -584,7 +584,7 @@ def test_u64_arrow_col(self): with self.assertRaisesRegex( qi.IngressError, 'serialize .* column .a. .* 4 .9223372036854775808.*int64'): - _pandas(df2, table_name='tbl1') + _dataframe(df2, table_name='tbl1') def test_i64_arrow_col(self): df = pd.DataFrame({ @@ -596,7 +596,7 @@ def test_i64_arrow_col(self): 9223372036854775807], # i64 max dtype=pd.Int64Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1i,b="a"\n' + @@ -619,7 +619,7 @@ def test_f32_arrow_col(self): None], dtype=pd.Float32Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1.0,b="a"\n' + @@ -644,7 +644,7 @@ def test_f64_arrow_col(self): None], dtype=pd.Float64Dtype()), 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1.0,b="a"\n' + @@ -662,7 +662,7 @@ def test_bool_numpy_col(self): True, False, False, False, True, False], dtype='bool')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=t\n' + @@ -679,7 +679,7 @@ def test_bool_arrow_col(self): True, True, True, False, False, False], dtype='boolean')}) # Note `boolean` != `bool`. - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=t\n' + @@ -694,7 +694,7 @@ def test_bool_arrow_col(self): 'tbl1 a=f\n' + 'tbl1 a=f\n' + 'tbl1 a=f\n') - + df2 = pd.DataFrame({'a': pd.Series([ True, False, False, None, True, False], @@ -702,14 +702,14 @@ def test_bool_arrow_col(self): with self.assertRaisesRegex( qi.IngressError, 'Failed.*at row index 3 .*.: .*insert null .*boolean col'): - _pandas(df2, table_name='tbl1') + _dataframe(df2, table_name='tbl1') def test_bool_obj_col(self): df = pd.DataFrame({'a': pd.Series([ True, False, False, False, True, False], dtype='object')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=t\n' + @@ -718,14 +718,14 @@ def test_bool_obj_col(self): 'tbl1 a=f\n' + 'tbl1 a=t\n' + 'tbl1 a=f\n') - + df2 = pd.DataFrame({'a': pd.Series([ True, False, 'false'], dtype='object')}) with self.assertRaisesRegex( qi.IngressError, 'serialize .* column .a. .* 2 .*false.*bool'): - _pandas(df2, table_name='tbl1') + _dataframe(df2, table_name='tbl1') df3 = pd.DataFrame({'a': pd.Series([ None, True, False], @@ -733,7 +733,7 @@ def test_bool_obj_col(self): with self.assertRaisesRegex( qi.IngressError, 'serialize.*\\(None\\): Cannot insert null.*boolean column'): - _pandas(df3, table_name='tbl1') + _dataframe(df3, table_name='tbl1') def test_datetime64_numpy_col(self): df = pd.DataFrame({ @@ -749,7 +749,7 @@ def test_datetime64_numpy_col(self): pd.NA], dtype='datetime64[ns]'), 'b': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=1546300800000000t,b="a"\n' + @@ -766,7 +766,7 @@ def test_datetime64_numpy_col(self): pd.Timestamp('1970-01-01 00:00:00'), pd.Timestamp('1970-01-01 00:00:01'), pd.Timestamp('1970-01-01 00:00:02')])}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a=0t\n' + @@ -787,7 +787,7 @@ def test_datetime64_tz_arrow_col(self): year=2019, month=1, day=1, hour=0, minute=0, second=3, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) - buf = _pandas(df, table_name='tbl1', symbols=['b']) + buf = _dataframe(df, table_name='tbl1', symbols=['b']) self.assertEqual( buf, # Note how these are 5hr offset from `test_datetime64_numpy_col`. @@ -809,7 +809,7 @@ def test_datetime64_tz_arrow_col(self): year=1970, month=1, day=1, hour=0, minute=0, second=2, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3']}) - buf = _pandas(df, table_name='tbl1', symbols=['b']) + buf = _dataframe(df, table_name='tbl1', symbols=['b']) self.assertEqual( buf, # Note how these are 5hr offset from `test_datetime64_numpy_col`. @@ -830,7 +830,7 @@ def test_datetime64_tz_arrow_col(self): year=1969, month=12, day=31, hour=19, minute=0, second=2, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3']}) - buf = _pandas(df, table_name='tbl1', symbols=['b']) + buf = _dataframe(df, table_name='tbl1', symbols=['b']) self.assertEqual( buf, 'tbl1,b=sym1 a=0t\n' + @@ -845,7 +845,7 @@ def test_datetime64_tz_arrow_col(self): 'b': ['sym1']}) with self.assertRaisesRegex( qi.IngressError, "Failed.*'a'.*-220897.* is negative."): - _pandas(df2, table_name='tbl1', symbols=['b']) + _dataframe(df2, table_name='tbl1', symbols=['b']) return ############################################################### def test_datetime64_numpy_at(self): @@ -862,7 +862,7 @@ def test_datetime64_numpy_at(self): pd.NaT], dtype='datetime64[ns]'), 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) - buf = _pandas(df, table_name='tbl1', at='a') + buf = _dataframe(df, table_name='tbl1', at='a') self.assertEqual( buf, 'tbl1 b=1i 1546300800000000000\n' + @@ -882,7 +882,7 @@ def test_datetime64_numpy_at(self): pd.Timestamp('1970-01-01 00:00:02')], dtype='datetime64[ns]'), 'b': [1, 2, 3]}) - buf = _pandas(df, table_name='tbl1', at='a') + buf = _dataframe(df, table_name='tbl1', at='a') self.assertEqual( buf, 'tbl1 b=1i 0\n' + @@ -903,7 +903,7 @@ def test_datetime64_tz_arrow_at(self): year=2019, month=1, day=1, hour=0, minute=0, second=3, tz=_TZ)], 'b': ['sym1', 'sym2', 'sym3', 'sym4']}) - buf = _pandas(df, table_name='tbl1', symbols=['b'], at='a') + buf = _dataframe(df, table_name='tbl1', symbols=['b'], at='a') self.assertEqual( buf, # Note how these are 5hr offset from `test_datetime64_numpy_col`. @@ -920,7 +920,7 @@ def test_datetime64_tz_arrow_at(self): 'b': ['sym1']}) with self.assertRaisesRegex( qi.IngressError, "Failed.*'a'.*-220897.* is neg"): - _pandas(df2, table_name='tbl1', symbols=['b'], at='a') + _dataframe(df2, table_name='tbl1', symbols=['b'], at='a') def _test_pyobjstr_table(self, dtype): df = pd.DataFrame({ @@ -933,7 +933,7 @@ def _test_pyobjstr_table(self, dtype): '💩🦞'], # UCS-4, 4 bytes for UTF-8. dtype=dtype), 'b': [1, 2, 3, 4, 5]}) - buf = _pandas(df, table_name_col=0) + buf = _dataframe(df, table_name_col=0) self.assertEqual( buf, 'a b=1i\n' + @@ -944,13 +944,13 @@ def _test_pyobjstr_table(self, dtype): with self.assertRaisesRegex( qi.IngressError, "Too long"): - _pandas( + _dataframe( pd.DataFrame({'a': pd.Series(['b' * 128], dtype=dtype)}), table_name_col='a') with self.assertRaisesRegex( qi.IngressError, 'Failed.*Expected a table name, got a null.*'): - _pandas( + _dataframe( pd.DataFrame({ '.': pd.Series(['x', None], dtype=dtype), 'b': [1, 2]}), @@ -958,7 +958,7 @@ def _test_pyobjstr_table(self, dtype): with self.assertRaisesRegex( qi.IngressError, 'Failed.*Expected a table name, got a null.*'): - _pandas( + _dataframe( pd.DataFrame({ '.': pd.Series(['x', float('nan')], dtype=dtype), 'b': [1, 2]}), @@ -966,7 +966,7 @@ def _test_pyobjstr_table(self, dtype): with self.assertRaisesRegex( qi.IngressError, 'Failed.*Expected a table name, got a null.*'): - _pandas( + _dataframe( pd.DataFrame({ '.': pd.Series(['x', pd.NA], dtype=dtype), 'b': [1, 2]}), @@ -974,7 +974,7 @@ def _test_pyobjstr_table(self, dtype): with self.assertRaisesRegex( qi.IngressError, "''.*must have a non-zero length"): - _pandas( + _dataframe( pd.DataFrame({ '/': pd.Series([''], dtype=dtype), 'b': [1]}), @@ -982,7 +982,7 @@ def _test_pyobjstr_table(self, dtype): with self.assertRaisesRegex( qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): - _pandas( + _dataframe( pd.DataFrame({ '/': pd.Series(['tab..1'], dtype=dtype), 'b': [1]}), @@ -993,7 +993,7 @@ def test_obj_str_table(self): with self.assertRaisesRegex( qi.IngressError, 'table name .*got an object of type int'): - _pandas( + _dataframe( pd.DataFrame({ '.': pd.Series(['x', 42], dtype='object'), 'z': [1, 2]}), @@ -1003,7 +1003,7 @@ def test_obj_string_table(self): self._test_pyobjstr_table('string') self.assertEqual( - _pandas( + _dataframe( pd.DataFrame({ '.': pd.Series(['x', 42], dtype='string'), 'z': [1, 2]}), @@ -1022,7 +1022,7 @@ def _test_pyobjstr_numpy_symbol(self, dtype): '嚜꓂', # UCS-2, 3 bytes for UTF-8. '💩🦞'], # UCS-4, 4 bytes for UTF-8. dtype=dtype)}) - buf = _pandas(df, table_name='tbl1', symbols=True) + buf = _dataframe(df, table_name='tbl1', symbols=True) self.assertEqual( buf, 'tbl1,a=a\n' + @@ -1036,7 +1036,7 @@ def _test_pyobjstr_numpy_symbol(self, dtype): for null_obj in (None, float('nan'), pd.NA): self.assertEqual( - _pandas( + _dataframe( pd.DataFrame({ 'x': pd.Series(['a', null_obj], dtype=dtype), 'y': [1, 2]}), @@ -1049,7 +1049,7 @@ def test_obj_str_numpy_symbol(self): with self.assertRaisesRegex( qi.IngressError, 'Expected a string, got an .* type int'): - _pandas( + _dataframe( pd.DataFrame({ 'x': pd.Series(['x', 42], dtype='object'), 'y': [1, 2]}), @@ -1059,7 +1059,7 @@ def test_obj_string_numpy_symbol(self): self._test_pyobjstr_numpy_symbol('string') self.assertEqual( - _pandas( + _dataframe( pd.DataFrame({ 'x': pd.Series(['x', 42], dtype='string'), 'y': [1, 2]}), @@ -1078,7 +1078,7 @@ def test_str_numpy_col(self): '嚜꓂', # UCS-2, 3 bytes for UTF-8. '💩🦞'], # UCS-4, 4 bytes for UTF-8. dtype='str')}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 a="a"\n' + @@ -1100,7 +1100,7 @@ def test_str_arrow_table(self): '💩🦞'], # UCS-4, 4 bytes for UTF-8. dtype='string[pyarrow]'), 'b': [1, 2, 3, 4, 5]}) - buf = _pandas(df, table_name_col=0) + buf = _dataframe(df, table_name_col=0) self.assertEqual( buf, 'a b=1i\n' + @@ -1111,14 +1111,14 @@ def test_str_arrow_table(self): with self.assertRaisesRegex( qi.IngressError, "Too long"): - _pandas( + _dataframe( pd.DataFrame({ 'a': pd.Series(['b' * 128], dtype='string[pyarrow]')}), table_name_col='a') with self.assertRaisesRegex( qi.IngressError, "Failed .*.*Table name cannot be null"): - _pandas( + _dataframe( pd.DataFrame({ '.': pd.Series(['x', None], dtype='string[pyarrow]'), 'b': [1, 2]}), @@ -1126,14 +1126,14 @@ def test_str_arrow_table(self): with self.assertRaisesRegex( qi.IngressError, "''.*must have a non-zero length"): - _pandas( + _dataframe( pd.DataFrame({ '/': pd.Series([''], dtype='string[pyarrow]')}), table_name_col='/') with self.assertRaisesRegex( qi.IngressError, "'tab..1'.*invalid dot `\\.` at position 4"): - _pandas( + _dataframe( pd.DataFrame({ '/': pd.Series(['tab..1'], dtype='string[pyarrow]')}), table_name_col='/') @@ -1152,7 +1152,7 @@ def test_str_arrow_symbol(self): '💩🦞'], # UCS-4, 4 bytes for UTF-8. dtype='string[pyarrow]'), 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) - buf = _pandas(df, table_name='tbl1', symbols=True) + buf = _dataframe(df, table_name='tbl1', symbols=True) self.assertEqual( buf, 'tbl1,a=a b=1i\n' + @@ -1179,7 +1179,7 @@ def test_str_arrow_col(self): '💩🦞'], # UCS-4, 4 bytes for UTF-8. dtype='string[pyarrow]'), 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) - buf = _pandas(df, table_name='tbl1', symbols=False) + buf = _dataframe(df, table_name='tbl1', symbols=False) self.assertEqual( buf, 'tbl1 a="a",b=1i\n' + @@ -1194,7 +1194,7 @@ def test_str_arrow_col(self): def test_pyobj_int_col(self): self.assertEqual( - _pandas( + _dataframe( pd.DataFrame({ 'a': pd.Series([ 1, 2, 3, None, float('nan'), pd.NA, 7], dtype='object'), @@ -1207,10 +1207,10 @@ def test_pyobj_int_col(self): 'tbl1 b=5i\n' + 'tbl1 b=6i\n' + 'tbl1 a=7i,b=7i\n') - + with self.assertRaisesRegex( qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\\."): - _pandas( + _dataframe( pd.DataFrame({ 'a': pd.Series([1, 'STRING'], dtype='object'), 'b': [1, 2]}), @@ -1220,7 +1220,7 @@ def test_pyobj_int_col(self): def test_pyobj_float_col(self): self.assertEqual( - _pandas( + _dataframe( pd.DataFrame({ 'a': pd.Series( [1.0, 2.0, 3.0, None, float('nan'), pd.NA, 7.0], @@ -1237,7 +1237,7 @@ def test_pyobj_float_col(self): with self.assertRaisesRegex( qi.IngressError, "1 \\('STRING'\\): .*type float, got.*str\\."): - _pandas( + _dataframe( pd.DataFrame({ 'a': pd.Series([1.0, 'STRING'], dtype='object'), 'b': [1, 2]}), @@ -1249,7 +1249,7 @@ def test_bad_category(self): # We want to test others are rejected. with self.assertRaisesRegex( qi.IngressError, "Bad column 'a'.*got a category of .*int64"): - _pandas( + _dataframe( pd.DataFrame({'a': pd.Series([1, 2, 3, 2], dtype='category')}), table_name='tbl1') @@ -1259,20 +1259,20 @@ def _test_cat_table(self, count): df = pd.DataFrame({ 'a': pd.Series(slist, dtype='category'), 'b': list(range(len(slist)))}) - - buf = _pandas(df, table_name_col=0) + + buf = _dataframe(df, table_name_col=0) exp = ''.join( f'{s} b={i}i\n' for i, s in enumerate(slist)) self.assertEqual(buf, exp) - + slist[2] = None df2 = pd.DataFrame({ 'a': pd.Series(slist, dtype='category'), 'b': list(range(len(slist)))}) with self.assertRaisesRegex( qi.IngressError, 'Table name cannot be null'): - _pandas(df2, table_name_col=0) + _dataframe(df2, table_name_col=0) def test_cat_i8_table(self): self._test_cat_table(30) @@ -1293,20 +1293,20 @@ def _test_cat_symbol(self, count): df = pd.DataFrame({ 'a': pd.Series(slist, dtype='category'), 'b': list(range(len(slist)))}) - - buf = _pandas(df, table_name='tbl1', symbols=True) + + buf = _dataframe(df, table_name='tbl1', symbols=True) exp = ''.join( f'tbl1,a={s} b={i}i\n' for i, s in enumerate(slist)) self.assertEqual(buf, exp) - + slist[2] = None df2 = pd.DataFrame({ 'a': pd.Series(slist, dtype='category'), 'b': list(range(len(slist)))}) exp2 = exp.replace('tbl1,a=s2 b=2i\n', 'tbl1 b=2i\n') - buf2 = _pandas(df2, table_name='tbl1', symbols=True) + buf2 = _dataframe(df2, table_name='tbl1', symbols=True) self.assertEqual(buf2, exp2) def test_cat_i8_symbol(self): @@ -1328,20 +1328,20 @@ def _test_cat_str(self, count): df = pd.DataFrame({ 'a': pd.Series(slist, dtype='category'), 'b': list(range(len(slist)))}) - - buf = _pandas(df, table_name='tbl1', symbols=False) + + buf = _dataframe(df, table_name='tbl1', symbols=False) exp = ''.join( f'tbl1 a="{s}",b={i}i\n' for i, s in enumerate(slist)) self.assertEqual(buf, exp) - + slist[2] = None df2 = pd.DataFrame({ 'a': pd.Series(slist, dtype='category'), 'b': list(range(len(slist)))}) exp2 = exp.replace('tbl1 a="s2",b=2i\n', 'tbl1 b=2i\n') - buf2 = _pandas(df2, table_name='tbl1', symbols=False) + buf2 = _dataframe(df2, table_name='tbl1', symbols=False) self.assertEqual(buf2, exp2) def test_cat_i8_str(self): @@ -1361,7 +1361,7 @@ def test_all_nulls_pyobj_col(self): df = pd.DataFrame({ 'a': [None, pd.NA, float('nan')], 'b': [1, 2, 3]}) - buf = _pandas(df, table_name='tbl1') + buf = _dataframe(df, table_name='tbl1') self.assertEqual( buf, 'tbl1 b=1i\n' + diff --git a/test/test_pandas_integration_fuzz.py b/test/test_dataframe_fuzz.py similarity index 98% rename from test/test_pandas_integration_fuzz.py rename to test/test_dataframe_fuzz.py index 18179922..991c5d9e 100644 --- a/test/test_pandas_integration_fuzz.py +++ b/test/test_dataframe_fuzz.py @@ -143,7 +143,7 @@ def parse_input_bytes(input_bytes): @atheris.instrument_func -def test_pandas(input_bytes): +def test_dataframe(input_bytes): # print(f'input_bytes: {input_bytes}') params = parse_input_bytes(input_bytes) df, table_name, table_name_col, symbols, at = params @@ -152,7 +152,7 @@ def test_pandas(input_bytes): BUF = qi.Buffer() BUF.clear() try: - BUF.pandas( + BUF.dataframe( df, table_name=table_name, table_name_col=table_name_col, @@ -184,7 +184,7 @@ def test_pandas(input_bytes): def main(): args = list(sys.argv) - atheris.Setup(args, test_pandas) + atheris.Setup(args, test_dataframe) atheris.Fuzz() diff --git a/test/test_pandas_leaks.py b/test/test_dataframe_leaks.py similarity index 95% rename from test/test_pandas_leaks.py rename to test/test_dataframe_leaks.py index af36911d..2f33313c 100644 --- a/test/test_pandas_leaks.py +++ b/test/test_dataframe_leaks.py @@ -20,7 +20,7 @@ def serialize_and_cleanup(): 'a': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], 'b': [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 'c': [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]}) - qi.Buffer().pandas(df, table_name='test') + qi.Buffer().dataframe(df, table_name='test') def main(): From ada3ac8400000f3158bc496d0fa17c4286879e33 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 11:16:33 +0000 Subject: [PATCH 123/147] Int object int64 bounds check tests. --- TODO.rst | 8 -------- test/test_dataframe.py | 24 ++++++++++++++++++++---- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/TODO.rst b/TODO.rst index 25ac8898..cb07d6f6 100644 --- a/TODO.rst +++ b/TODO.rst @@ -17,11 +17,3 @@ Docs * **[MEDIUM]** Examples should be tested as part of the unit tests (as they are in the C client). This is to ensure they don't "bit rot" as the code changes. - -Development -=========== - -* **[HIGH]** Implement ``tabular()`` API in the buffer. - -* **[MEDIUM]** Implement ``pandas()`` API in the buffer. - *This can probably wait for a future release.* \ No newline at end of file diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 1902fe69..d269bb22 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -1193,12 +1193,17 @@ def test_str_arrow_col(self): 'tbl1 a="💩🦞",b=9i\n') def test_pyobj_int_col(self): + int64_min = -2**63 + int64_max = 2**63 - 1 self.assertEqual( _dataframe( pd.DataFrame({ 'a': pd.Series([ - 1, 2, 3, None, float('nan'), pd.NA, 7], dtype='object'), - 'b': [1, 2, 3, 4, 5, 6, 7]}), + 1, 2, 3, None, float('nan'), pd.NA, 7, + 0, + int64_min, + int64_max], dtype='object'), + 'b': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}), table_name='tbl1'), 'tbl1 a=1i,b=1i\n' + 'tbl1 a=2i,b=2i\n' + @@ -1206,7 +1211,10 @@ def test_pyobj_int_col(self): 'tbl1 b=4i\n' + 'tbl1 b=5i\n' + 'tbl1 b=6i\n' + - 'tbl1 a=7i,b=7i\n') + 'tbl1 a=7i,b=7i\n' + + 'tbl1 a=0i,b=8i\n' + + 'tbl1 a=' + str(int64_min) + 'i,b=9i\n' + + 'tbl1 a=' + str(int64_max) + 'i,b=10i\n') with self.assertRaisesRegex( qi.IngressError, "1 \\('STRING'\\): .*type int, got.*str\\."): @@ -1216,7 +1224,15 @@ def test_pyobj_int_col(self): 'b': [1, 2]}), table_name='tbl1') - # TODO test ints outside of int64 range + out_of_range = [int64_min - 1, int64_max + 1] + for num in out_of_range: + with self.assertRaisesRegex( + qi.IngressError, "index 1 .*922337203685477.*int too big"): + _dataframe( + pd.DataFrame({ + 'a': pd.Series([1, num], dtype='object'), + 'b': [1, 2]}), + table_name='tbl1') def test_pyobj_float_col(self): self.assertEqual( From 89c50b4e4e81c859b162bc314f6650b251312833 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 12:31:36 +0000 Subject: [PATCH 124/147] Test strided numpy array with zero-copy into pandas. --- test/test_dataframe.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index d269bb22..8b25ae89 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -20,6 +20,7 @@ import questdb.ingress as qi import pandas as pd +import numpy as np def _dataframe(*args, **kwargs): @@ -1384,6 +1385,28 @@ def test_all_nulls_pyobj_col(self): 'tbl1 b=2i\n' + 'tbl1 b=3i\n') + def test_strided_numpy_column(self): + two_d = np.array([ + [1, 10], + [2, 20], + [3, 30]]) + col2 = two_d[:, 1] + col2.flags['WRITEABLE'] = False + + # Checking our test case setup. + mv = memoryview(col2) + self.assertEqual(mv.contiguous, False) + self.assertEqual(mv.strides, (16,)) + + df = pd.DataFrame(col2, copy=False) + df.columns = ['a'] + + with self.assertRaisesRegex( + ValueError, 'not.*contiguous'): + _dataframe(df, table_name='tbl1') + + + # TODO: Test all datatypes, but multiple row chunks. # TODO: Test datetime `at` argument with timezone. From 64f14fa4e41a14edf24b30e87c919c95a9f2099d Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 12:41:07 +0000 Subject: [PATCH 125/147] Serializing subset of dataframe rows. --- test/test_dataframe.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 8b25ae89..5e6cf606 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -1405,6 +1405,20 @@ def test_strided_numpy_column(self): ValueError, 'not.*contiguous'): _dataframe(df, table_name='tbl1') + def test_serializing_in_chunks(self): + df = pd.DataFrame({ + 'a': pd.Series(np.arange(30), dtype='int64'), + 'b': pd.Series(np.arange(30), dtype='Int64')}) + parts = [ + df.iloc[:10], + df.iloc[10:20], + df.iloc[20:]] + for index, part in enumerate(parts): + buf = _dataframe(part, table_name='tbl1') + exp = ''.join( + f'tbl1 a={i}i,b={i}i\n' + for i in range(index * 10, (index + 1) * 10)) + self.assertEqual(buf, exp) # TODO: Test all datatypes, but multiple row chunks. From def3887805b2077225790425f5d0a3aef5f257ab Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 15:42:44 +0000 Subject: [PATCH 126/147] Improved error messaging. --- src/questdb/dataframe.pxi | 8 ++++++-- test/test_dataframe.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/questdb/dataframe.pxi b/src/questdb/dataframe.pxi index ee6050bd..63ff92c5 100644 --- a/src/questdb/dataframe.pxi +++ b/src/questdb/dataframe.pxi @@ -761,9 +761,13 @@ cdef void_int _dataframe_series_as_pybuf( # Note! We don't need to support numpy strides since Pandas doesn't. # Also note that this guarantees a 1D buffer. get_buf_ret = PyObject_GetBuffer(nparr, &col.setup.pybuf, PyBUF_SIMPLE) - + except ValueError as ve: + raise IngressError( + IngressErrorCode.BadDataFrame, + f'Bad column {pandas_col.name!r}: {ve}') from ve except BufferError as be: - raise TypeError( + raise IngressError( + IngressErrorCode.BadDataFrame, f'Bad column {pandas_col.name!r}: Expected a buffer, got ' + f'{pandas_col.series!r} ({_fqn(type(pandas_col.series))})') from be _dataframe_alloc_chunks(1, col) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 5e6cf606..bb5a5e60 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -1402,7 +1402,7 @@ def test_strided_numpy_column(self): df.columns = ['a'] with self.assertRaisesRegex( - ValueError, 'not.*contiguous'): + qi.IngressError, "Bad column 'a': .*not.*contiguous"): _dataframe(df, table_name='tbl1') def test_serializing_in_chunks(self): From 81d6cb8df0927a4f4c0eaa382573b92435db32a5 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 17:16:48 +0000 Subject: [PATCH 127/147] Testing chunked arrow arrays. --- src/questdb/dataframe.pxi | 2 +- test/test_dataframe.py | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/questdb/dataframe.pxi b/src/questdb/dataframe.pxi index 63ff92c5..d5ad3728 100644 --- a/src/questdb/dataframe.pxi +++ b/src/questdb/dataframe.pxi @@ -999,7 +999,7 @@ cdef void_int _dataframe_resolve_source_and_buffers( else: raise IngressError( IngressErrorCode.BadDataFrame, - f'Unsupported dtype {dtype} for column {pandas_col.name}. ' + + f'Unsupported dtype {dtype} for column {pandas_col.name!r}. ' + 'Raise an issue if you think it should be supported: ' + 'https://github.com/questdb/py-questdb-client/issues.') diff --git a/test/test_dataframe.py b/test/test_dataframe.py index bb5a5e60..4eb5e5c7 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -21,6 +21,7 @@ import questdb.ingress as qi import pandas as pd import numpy as np +import pyarrow as pa def _dataframe(*args, **kwargs): @@ -1420,6 +1421,51 @@ def test_serializing_in_chunks(self): for i in range(index * 10, (index + 1) * 10)) self.assertEqual(buf, exp) + def test_arrow_chunked_array(self): + # We build a table with chunked arrow arrays as columns. + chunks_a = [ + pa.array([1, 2, 3], type=pa.int16()), + pa.array([4, 5, 6], type=pa.int16()), + pa.array([], type=pa.int16()), + pa.array([7, 8, 9], type=pa.int16())] + chunked_a = pa.chunked_array(chunks_a) + chunks_b = [ + pa.array([10, 20], type=pa.int32()), + pa.array([], type=pa.int32()), + pa.array([30, 40, 50, 60], type=pa.int32()), + pa.array([70, 80, 90], type=pa.int32())] + chunked_b = pa.chunked_array(chunks_b) + arr_tab = pa.Table.from_arrays([chunked_a, chunked_b], names=['a', 'b']) + + # NOTE! + # This does *not* preserve the chunking of the arrow arrays. + df = arr_tab.to_pandas() + buf = _dataframe(df, table_name='tbl1') + exp = ( + 'tbl1 a=1i,b=10i\n' + + 'tbl1 a=2i,b=20i\n' + + 'tbl1 a=3i,b=30i\n' + + 'tbl1 a=4i,b=40i\n' + + 'tbl1 a=5i,b=50i\n' + + 'tbl1 a=6i,b=60i\n' + + 'tbl1 a=7i,b=70i\n' + + 'tbl1 a=8i,b=80i\n' + + 'tbl1 a=9i,b=90i\n') + self.assertEqual(buf, exp) + + # To preserve the chunking we need to use a special pandas type: + pandarrow_a = pd.array(chunked_a, dtype='int16[pyarrow]') + pandarrow_b = pd.array(chunked_b, dtype='int32[pyarrow]') + df = pd.DataFrame({'a': pandarrow_a, 'b': pandarrow_b}) + + # Note that this dtype is experimental (currently), + # so we don't support it yet.. but we have everything in place should we + # need to, so - as for now - we just test that we raise a nice error. + with self.assertRaisesRegex( + qi.IngressError, + "Unsupported dtype int16\[pyarrow\] for column 'a'.*github"): + _dataframe(df, table_name='tbl1') + # TODO: Test all datatypes, but multiple row chunks. # TODO: Test datetime `at` argument with timezone. From 83a937ab71968237aa7fbeaa11760894aca56bf0 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 17:18:37 +0000 Subject: [PATCH 128/147] Removed completed TODOs --- ci/run_tests_pipeline.yaml | 4 ---- test/test_dataframe.py | 4 ---- 2 files changed, 8 deletions(-) diff --git a/ci/run_tests_pipeline.yaml b/ci/run_tests_pipeline.yaml index 65d0c4b9..84f62c7e 100644 --- a/ci/run_tests_pipeline.yaml +++ b/ci/run_tests_pipeline.yaml @@ -38,7 +38,3 @@ stages: displayName: "Test" env: JAVA_HOME: $(JAVA_HOME_11_X64) - -# TODO: Add tests with and tests without installing `pyarrow` as it's -# an optional dependency (that can't always be installed). -# The tests without to test the fallback logic. diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 4eb5e5c7..f7ddf422 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -1467,10 +1467,6 @@ def test_arrow_chunked_array(self): _dataframe(df, table_name='tbl1') -# TODO: Test all datatypes, but multiple row chunks. -# TODO: Test datetime `at` argument with timezone. - - if __name__ == '__main__': if os.environ.get('TEST_QUESTDB_PROFILE') == '1': import cProfile From 712ec1dac4e4f0fffaec15195e82546c9166e747 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 18:12:16 +0000 Subject: [PATCH 129/147] Hopefully fixing CI. --- test/test_dataframe.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index f7ddf422..8408278a 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -5,6 +5,9 @@ sys.dont_write_bytecode = True import unittest import datetime as dt +import functools +import tempfile +import pathlib BROKEN_TIMEZONES = True @@ -54,6 +57,14 @@ def _dataframe(*args, **kwargs): pd.Timestamp('20180312')]}) +def with_tmp_dir(func): + @functools.wraps(func) + def wrapper(self, *args, **kwargs): + with tempfile.TemporaryDirectory(prefix='py-questdb-client_') as tmpdir: + return func(self, *args, pathlib.Path(tmpdir), **kwargs) + return wrapper + + class TestPandas(unittest.TestCase): def test_bad_dataframe(self): with self.assertRaisesRegex(TypeError, 'Expected pandas'): @@ -1390,7 +1401,7 @@ def test_strided_numpy_column(self): two_d = np.array([ [1, 10], [2, 20], - [3, 30]]) + [3, 30]], dtype='int64') col2 = two_d[:, 1] col2.flags['WRITEABLE'] = False @@ -1453,6 +1464,10 @@ def test_arrow_chunked_array(self): 'tbl1 a=9i,b=90i\n') self.assertEqual(buf, exp) + if getattr(pd, 'ArrowDtype') is None: + # We don't have pandas ArrowDtype, so we can't test the rest. + return + # To preserve the chunking we need to use a special pandas type: pandarrow_a = pd.array(chunked_a, dtype='int16[pyarrow]') pandarrow_b = pd.array(chunked_b, dtype='int32[pyarrow]') @@ -1466,6 +1481,10 @@ def test_arrow_chunked_array(self): "Unsupported dtype int16\[pyarrow\] for column 'a'.*github"): _dataframe(df, table_name='tbl1') + @with_tmp_dir + def test_parquet(self, tmpdir): + print(tmpdir) + if __name__ == '__main__': if os.environ.get('TEST_QUESTDB_PROFILE') == '1': From 88b043eb22f745d384198da22e754d9a4f019176 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 18:18:19 +0000 Subject: [PATCH 130/147] Dataframe API doc fixup. --- src/questdb/ingress.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index c3d9356a..18d1fc47 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1189,16 +1189,16 @@ cdef class Buffer: * **ε**: We only support categories containing strings. If the category contains non-string values, an error will be raised. - * **ζ**: We don't support datetimes with precisions other than - nanoseconds. The designated timestamp column (see ``at`` + * **ζ**: The '.dataframe()' method only supports datetimes with + nanosecond precision. The designated timestamp column (see ``at`` parameter) maintains the nanosecond precision, whilst values stored as columns have their precision truncated to microseconds. All dates are sent as UTC and any additional timezone information is dropped. If no timezone is specified, we follow the pandas convention of assuming the timezone is UTC. - Date times before 1970-01-01 00:00:00 UTC are not supported. + Datetimes before 1970-01-01 00:00:00 UTC are not supported. If a datetime value is specified as ``None`` (``NaT``), it is - interpreted as the current time set by the server on receipt of + interpreted as the current QuestDB server time set on receipt of message. """ _dataframe( From 58de10cc58495804a27f75bbb06c3c6eba7c153b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 15 Dec 2022 18:22:34 +0000 Subject: [PATCH 131/147] Fixing the CI --- test/test_dataframe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 8408278a..11a7e22f 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -1464,7 +1464,7 @@ def test_arrow_chunked_array(self): 'tbl1 a=9i,b=90i\n') self.assertEqual(buf, exp) - if getattr(pd, 'ArrowDtype') is None: + if not hasattr(pd, 'ArrowDtype'): # We don't have pandas ArrowDtype, so we can't test the rest. return From b461557d814d8791ace77f21b05eae714e009e12 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 16 Dec 2022 11:50:04 +0000 Subject: [PATCH 132/147] Parquet rountrip test. --- test/benchmark.py | 16 +++++++---- test/test_dataframe.py | 63 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/test/benchmark.py b/test/benchmark.py index 066298dd..fa62b514 100644 --- a/test/benchmark.py +++ b/test/benchmark.py @@ -13,6 +13,11 @@ import questdb.ingress as qi +def _tp(buf, t0, t1): + tp = len(buf) / (t1 - t0) / 1024 / 1024 + return f'{tp:.2f} MiB/s' + + class TestBenchmarkPandas(unittest.TestCase): def test_pystr_i64_10m(self): # This is a benchmark, not a test. @@ -32,7 +37,7 @@ def test_pystr_i64_10m(self): t0 = time.monotonic() buf.dataframe(df, table_name='tbl1', symbols=True) t1 = time.monotonic() - print(f'Time: {t1 - t0}, size: {len(buf)}') + print(f'Time: {t1 - t0}, size: {len(buf)}, tp: {_tp(buf, t0, t1)}') def test_mixed_10m(self): # This is a benchmark, not a test. @@ -58,7 +63,7 @@ def test_mixed_10m(self): t0 = time.monotonic() buf.dataframe(df, table_name='tbl1', symbols=True) t1 = time.monotonic() - print(f'Time: {t1 - t0}, size: {len(buf)}') + print(f'Time: {t1 - t0}, size: {len(buf)}, tp: {_tp(buf, t0, t1)}') def test_string_escaping_10m(self): count = 10_000_000 @@ -82,7 +87,7 @@ def test_string_escaping_10m(self): t0 = time.monotonic() buf.dataframe(df, table_name='tbl1', symbols=True) t1 = time.monotonic() - print(f'Time: {t1 - t0}, size: {len(buf)}') + print(f'Time: {t1 - t0}, size: {len(buf)}, tp: {_tp(buf, t0, t1)}') def test_string_encoding_10m(self): count = 10_000_000 @@ -114,7 +119,7 @@ def test_string_encoding_10m(self): t0 = time.monotonic() buf.dataframe(df, table_name='tbl1', symbols=False) t1 = time.monotonic() - print(f'Time: {t1 - t0}, size: {len(buf)}') + print(f'Time: {t1 - t0}, size: {len(buf)}, tp: {_tp(buf, t0, t1)}') def _test_gil_release_10m(self, threads): count = 10_000_000 @@ -167,7 +172,8 @@ def benchmark_run(buf): total_time += elapsed avg_time = total_time / len(results) print(f'Avg time: {avg_time}') - print(f'Wall time: {max_time - min_time}') + tp = (len(bufs[0]) * len(bufs)) / (max_time - min_time) / 1024 / 1024 + print(f'Wall time: {max_time - min_time}, tp: {tp:.2f} MiB/s') def test_gil_release_10m_1t(self): self._test_gil_release_10m(1) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 11a7e22f..0017590b 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -1482,8 +1482,67 @@ def test_arrow_chunked_array(self): _dataframe(df, table_name='tbl1') @with_tmp_dir - def test_parquet(self, tmpdir): - print(tmpdir) + def test_parquet_roundtrip(self, tmpdir): + pa_parquet_path = tmpdir / 'test_pa.parquet' + fp_parquet_path = tmpdir / 'test_fp.parquet' + df = pd.DataFrame({ + 's': pd.Categorical(['a', 'b', 'a', 'c', 'a']), + 'a': pd.Series([1, 2, 3, 4, 5], dtype='int16'), + 'b': pd.Series([10, 20, 30, None, 50], dtype='UInt8'), + 'c': [0.5, float('nan'), 2.5, 3.5, None]}) + df.to_parquet(pa_parquet_path, engine='pyarrow') + df.to_parquet(fp_parquet_path, engine='fastparquet') + pa2pa_df = pd.read_parquet(pa_parquet_path, engine='pyarrow') + pa2fp_df = pd.read_parquet(pa_parquet_path, engine='fastparquet') + fp2pa_df = pd.read_parquet(fp_parquet_path, engine='pyarrow') + fp2fp_df = pd.read_parquet(fp_parquet_path, engine='fastparquet') + + exp_dtypes = ['category', 'int16', 'UInt8', 'float64'] + self.assertEqual(list(df.dtypes), exp_dtypes) + + def df_eq(exp_df, deser_df, exp_dtypes): + self.assertEqual(list(deser_df.dtypes), exp_dtypes) + if not exp_df.equals(deser_df): + print('\nexp_df:') + print(exp_df) + print('\ndeser_df:') + print(deser_df) + self.assertTrue(exp_df.equals(deser_df)) + + # fastparquet doesn't roundtrip with pyarrow parquet properly. + # It decays categories to object and UInt8 to float64. + # We need to set up special case expected results for that. + fallback_exp_dtypes = [ + np.dtype('O'), + np.dtype('int16'), + np.dtype('float64'), + np.dtype('float64')] + fallback_df = df.astype({'s': 'object', 'b': 'float64'}) + + df_eq(df, pa2pa_df, exp_dtypes) + df_eq(df, pa2fp_df, exp_dtypes) + df_eq(fallback_df, fp2pa_df, fallback_exp_dtypes) + df_eq(df, fp2fp_df, exp_dtypes) + + exp = ( + 'tbl1,s=a a=1i,b=10i,c=0.5\n' + + 'tbl1,s=b a=2i,b=20i,c=NaN\n' + + 'tbl1,s=a a=3i,b=30i,c=2.5\n' + + 'tbl1,s=c a=4i,c=3.5\n' + + 'tbl1,s=a a=5i,b=50i,c=NaN\n') + + fallback_exp = ( + 'tbl1 s="a",a=1i,b=10.0,c=0.5\n' + + 'tbl1 s="b",a=2i,b=20.0,c=NaN\n' + + 'tbl1 s="a",a=3i,b=30.0,c=2.5\n' + + 'tbl1 s="c",a=4i,b=NaN,c=3.5\n' + + 'tbl1 s="a",a=5i,b=50.0,c=NaN\n') + + self.assertEqual(_dataframe(df, table_name='tbl1'), exp) + self.assertEqual(_dataframe(pa2pa_df, table_name='tbl1'), exp) + self.assertEqual(_dataframe(pa2fp_df, table_name='tbl1'), exp) + self.assertEqual(_dataframe(fp2pa_df, table_name='tbl1'), fallback_exp) + self.assertEqual(_dataframe(fp2fp_df, table_name='tbl1'), exp) if __name__ == '__main__': From 96254475bfa3052ed126ff425d582ce76422ae6b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 28 Dec 2022 15:01:24 +0000 Subject: [PATCH 133/147] Added missing libs in dev_requirements.txt --- ci/pip_install_deps.py | 2 ++ dev_requirements.txt | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index e37050d8..a613972f 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -54,6 +54,7 @@ def main(): try_pip_install('pandas') try_pip_install('numpy') try_pip_install('pyarrow') + try_pip_install('fastparquet') on_linux_is_glibc = ( (not platform.system() == 'Linux') or @@ -65,6 +66,7 @@ def main(): import pandas import numpy import pyarrow + import fastparquet if __name__ == "__main__": diff --git a/dev_requirements.txt b/dev_requirements.txt index 097910ca..c639c014 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -7,4 +7,6 @@ sphinx-rtd-theme>=1.0.0 twine>=4.0.1 bump2version>=1.0.1 pandas>=1.3.5 -numpy>=1.21.6 \ No newline at end of file +numpy>=1.21.6 +pyarrow>=10.0.1 +fastparquet>=2022.12.0 From 02da96bc15abdc05137bf55545c5db30d15a0445 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 28 Dec 2022 15:40:40 +0000 Subject: [PATCH 134/147] CI fixup (hopefully) --- ci/pip_install_deps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index a613972f..db67fdd6 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -51,10 +51,10 @@ def ensure_timezone(): def main(): ensure_timezone() + try_pip_install('fastparquet>=2022.12.0') try_pip_install('pandas') try_pip_install('numpy') try_pip_install('pyarrow') - try_pip_install('fastparquet') on_linux_is_glibc = ( (not platform.system() == 'Linux') or From e26f5fe2d0871ebe07d595deb904a8a88a8b346b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 28 Dec 2022 17:49:33 +0000 Subject: [PATCH 135/147] CI fixup (hopefully, again) --- ci/pip_install_deps.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci/pip_install_deps.py b/ci/pip_install_deps.py index db67fdd6..13e9f247 100644 --- a/ci/pip_install_deps.py +++ b/ci/pip_install_deps.py @@ -66,7 +66,8 @@ def main(): import pandas import numpy import pyarrow - import fastparquet + if sys.version_info >= (3, 8): + import fastparquet if __name__ == "__main__": From 6dd6cf6f87aceb5a83200f380e43ea03999288ba Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 28 Dec 2022 17:51:33 +0000 Subject: [PATCH 136/147] CI fixup (once more, with feeling) --- test/test_dataframe.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 0017590b..0c1b0976 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -26,6 +26,11 @@ import numpy as np import pyarrow as pa +try: + import fastparquet +except ImportError: + fastparquet = None + def _dataframe(*args, **kwargs): buf = qi.Buffer() @@ -1481,6 +1486,7 @@ def test_arrow_chunked_array(self): "Unsupported dtype int16\[pyarrow\] for column 'a'.*github"): _dataframe(df, table_name='tbl1') + @unittest.skipIf(not fastparquet, 'fastparquet not installed') @with_tmp_dir def test_parquet_roundtrip(self, tmpdir): pa_parquet_path = tmpdir / 'test_pa.parquet' From 67cedd93e022d5a835c3b661c282a0f41fb0959a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Thu, 29 Dec 2022 11:24:06 +0000 Subject: [PATCH 137/147] More examples. --- docs/examples.rst | 39 +++++++++++++++++++++++++++++++++++++ examples/pandas_advanced.py | 33 +++++++++++++++++++++++++++++++ examples/pandas_basic.py | 29 +++++++++++++++++++++++++++ proj.py | 6 ++++++ src/questdb/ingress.pyx | 2 +- 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 examples/pandas_advanced.py create mode 100644 examples/pandas_basic.py diff --git a/docs/examples.rst b/docs/examples.rst index a1a4409e..302d46dd 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -57,3 +57,42 @@ based on a timer if the auto-flushing logic was not triggered recently. .. literalinclude:: ../examples/random_data.py :language: python + +Inserting from Data Frames +========================== + +Pandas Basics +------------- + +The following example shows how to insert data from a Pandas DataFrame to the +``'trades'`` table. + +.. literalinclude:: ../examples/pandas_basic.py + :language: python + +For details on all options, see the +:func:`questdb.ingress.Buffer.dataframe` method. + + +``pd.Categorical`` and multiple tables +-------------------------------------- + +The next example shows some more advanced features inserting data from Pandas. + +* The data is sent to multiple tables. + +* It uses the ``pd.Categorical`` type to determine the table to insert and also + uses it for the sensor name. + +* Columns of type ``pd.Categorical`` are sent as ``SYMBOL`` types. + +* The ``at`` parameter is specified using a column index: -1 is the last column. + +.. literalinclude:: ../examples/pandas_advanced.py + :language: python + +After running this example, the rows will be split across the ``'humidity'``, +``'temp_c'`` and ``'voc_index'`` tables. + +For details on all options, see the +:func:`questdb.ingress.Buffer.dataframe` method. diff --git a/examples/pandas_advanced.py b/examples/pandas_advanced.py new file mode 100644 index 00000000..7b163cd4 --- /dev/null +++ b/examples/pandas_advanced.py @@ -0,0 +1,33 @@ +from questdb.ingress import Sender, IngressError + +import sys +import pandas as pd + + +def example(host: str = 'localhost', port: int = 9009): + df = pd.DataFrame({ + 'metric': pd.Categorical( + ['humidity', 'temp_c', 'voc_index', 'temp_c']), + 'sensor': pd.Categorical( + ['paris-01', 'london-02', 'london-01', 'paris-01']), + 'value': [ + 0.83, 22.62, 100.0, 23.62], + 'ts': [ + pd.Timestamp('2022-08-06 07:35:23.189062'), + pd.Timestamp('2022-08-06 07:35:23.189062'), + pd.Timestamp('2022-08-06 07:35:23.189062'), + pd.Timestamp('2022-08-06 07:35:23.189062')]}) + try: + with Sender(host, port) as sender: + sender.dataframe( + df, + table_name_col='metric', # Table name from 'metric' column. + symbols='auto', # Category columns as SYMBOL. (Default) + at=-1) # Last column contains the designated timestamps. + + except IngressError as e: + sys.stderr.write(f'Got error: {e}\n') + + +if __name__ == '__main__': + example() diff --git a/examples/pandas_basic.py b/examples/pandas_basic.py new file mode 100644 index 00000000..3c07d7fc --- /dev/null +++ b/examples/pandas_basic.py @@ -0,0 +1,29 @@ +from questdb.ingress import Sender, IngressError + +import sys +import pandas as pd + + +def example(host: str = 'localhost', port: int = 9009): + df = pd.DataFrame({ + 'pair': ['USDGBP', 'EURJPY'], + 'traded_price': [0.83, 142.62], + 'qty': [100, 400], + 'limit_price': [0.84, None], + 'timestamp': [ + pd.Timestamp('2022-08-06 07:35:23.189062', tz='UTC'), + pd.Timestamp('2022-08-06 07:35:23.189062', tz='UTC')]}) + try: + with Sender(host, port) as sender: + sender.dataframe( + df, + table_name='trades', # Table name to insert into. + symbols=['pair'], # Columns to be inserted as SYMBOL types. + at='timestamp') # Column containing the designated timestamps. + + except IngressError as e: + sys.stderr.write(f'Got error: {e}\n') + + +if __name__ == '__main__': + example() diff --git a/proj.py b/proj.py index 875ebe1f..c967cdfb 100755 --- a/proj.py +++ b/proj.py @@ -192,6 +192,12 @@ def repl(*args): _run('python3', env={'PYTHONPATH': str(PROJ_ROOT / 'src')}) +@command +def example(name, *args): + _run('python3', 'examples/' + name + '.py', *args, + env={'PYTHONPATH': str(PROJ_ROOT / 'src')}) + + @command def cw(*args): cibuildwheel(args) diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index 18d1fc47..e2545eb7 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -972,7 +972,7 @@ cdef class Buffer: not using the buffer explicitly. It supports the same parameters and also supports auto-flushing. - This feature requires the ``pandas``, ``numpy` and ``pyarrow`` + This feature requires the ``pandas``, ``numpy`` and ``pyarrow`` package to be installed. :param df: The pandas DataFrame to serialize to the buffer. From 0c7b6ef40f5ed3f7b19bec0565dde156e376f6e1 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Fri, 30 Dec 2022 16:54:24 +0000 Subject: [PATCH 138/147] Parquet data example. --- .gitignore | 3 +++ examples/pandas_parquet.py | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 examples/pandas_parquet.py diff --git a/.gitignore b/.gitignore index 1c747ac6..a3fa088f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ __pycache__/ *.py[cod] *$py.class +# Parquet files generated as part of example runs +*.parquet + # C extensions *.so diff --git a/examples/pandas_parquet.py b/examples/pandas_parquet.py new file mode 100644 index 00000000..3684cf50 --- /dev/null +++ b/examples/pandas_parquet.py @@ -0,0 +1,41 @@ +from questdb.ingress import Sender +import pandas as pd + + +def write_parquet_file(): + df = pd.DataFrame({ + 'company': pd.Categorical( + ['BP Pulse', 'Ubitricity', 'Source London', 'BP Pulse']), + 'location': pd.Categorical( + ['BP-5541', 'UB-3355', 'SL-0995', 'BP-6653']), + 'speed_kwh': pd.Categorical( + [50, 7, 7, 120]), + 'connector_type': pd.Categorical( + ['Type 2 & 2+CCS', 'Type 1 & 2', 'Type 1 & 2', 'Type 2 & 2+CCS']), + 'current_type': pd.Categorical( + ['dc', 'ac', 'ac', 'dc']), + 'price_pence': + [54, 34, 32, 59], + 'ts': [ + pd.Timestamp('2022-12-30 12:15:00'), + pd.Timestamp('2022-12-30 12:16:00'), + pd.Timestamp('2022-12-30 12:18:00'), + pd.Timestamp('2022-12-30 12:19:00')]}) + name = 'ev_chargers' + df.index.name = name # We set the dataframe's index name here! + filename = f'{name}.parquet' + df.to_parquet(filename) + return filename + + +def example(host: str = 'localhost', port: int = 9009): + filename = write_parquet_file() + + df = pd.read_parquet(filename) + with Sender(host, port) as sender: + # Note: Table name is set from the dataframe's index name. + sender.dataframe(df, at='ts') + + +if __name__ == '__main__': + example() From cd97af23f0040bd00ee00c2c167407a015fe36a8 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 2 Jan 2023 11:04:51 +0000 Subject: [PATCH 139/147] Updated parquet example, added to docs. --- docs/examples.rst | 28 +++++++++++++++++++++++----- examples/pandas_parquet.py | 8 +++++--- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/docs/examples.rst b/docs/examples.rst index 302d46dd..b9e01081 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -5,6 +5,9 @@ Examples Basics ====== +Row-by-row Insertion +-------------------- + The following example connects to the database and sends two rows (lines). The connection is unauthenticated and the data is sent at the end of the @@ -18,7 +21,7 @@ Here the :class:`questdb.ingress.Sender` is constructed with just ``host`` and Authentication and TLS -====================== +---------------------- Continuing from the previous example, the connection is authenticated and also uses TLS. @@ -31,7 +34,7 @@ and ``tls`` arguments. Explicit Buffers -================ +---------------- For more advanced use cases where the same messages need to be sent to multiple questdb instances or you want to decouple serialization and sending (as may be @@ -48,7 +51,7 @@ all data is sent. Ticking Random Data and Timer-based Flush -========================================= +----------------------------------------- The following example somewhat mimics the behavior of a loop in an application. @@ -58,8 +61,9 @@ based on a timer if the auto-flushing logic was not triggered recently. .. literalinclude:: ../examples/random_data.py :language: python -Inserting from Data Frames -========================== + +Data Frames +=========== Pandas Basics ------------- @@ -96,3 +100,17 @@ After running this example, the rows will be split across the ``'humidity'``, For details on all options, see the :func:`questdb.ingress.Buffer.dataframe` method. + +Loading Pandas from a Parquet File +---------------------------------- + +The following example shows how to load a Pandas DataFrame from a Parquet file. + +The example also relies on the dataframe's index name to determine the table +name. + +.. literalinclude:: ../examples/pandas_parquet.py + :language: python + +For details on all options, see the +:func:`questdb.ingress.Buffer.dataframe` method. diff --git a/examples/pandas_parquet.py b/examples/pandas_parquet.py index 3684cf50..0d3b315d 100644 --- a/examples/pandas_parquet.py +++ b/examples/pandas_parquet.py @@ -4,10 +4,10 @@ def write_parquet_file(): df = pd.DataFrame({ - 'company': pd.Categorical( - ['BP Pulse', 'Ubitricity', 'Source London', 'BP Pulse']), 'location': pd.Categorical( ['BP-5541', 'UB-3355', 'SL-0995', 'BP-6653']), + 'provider': pd.Categorical( + ['BP Pulse', 'Ubitricity', 'Source London', 'BP Pulse']), 'speed_kwh': pd.Categorical( [50, 7, 7, 120]), 'connector_type': pd.Categorical( @@ -16,6 +16,8 @@ def write_parquet_file(): ['dc', 'ac', 'ac', 'dc']), 'price_pence': [54, 34, 32, 59], + 'in_use': + [True, False, False, True], 'ts': [ pd.Timestamp('2022-12-30 12:15:00'), pd.Timestamp('2022-12-30 12:16:00'), @@ -33,7 +35,7 @@ def example(host: str = 'localhost', port: int = 9009): df = pd.read_parquet(filename) with Sender(host, port) as sender: - # Note: Table name is set from the dataframe's index name. + # Note: Table name is looked up from the dataframe's index name. sender.dataframe(df, at='ts') From ab69e9c916f56f57174b8abefcf876e69f5e5338 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 2 Jan 2023 11:17:04 +0000 Subject: [PATCH 140/147] Updated examples manifest to hint at more examples for Pandas dataframes. --- examples.manifest.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples.manifest.yaml b/examples.manifest.yaml index 9379adbf..75a1e3fb 100644 --- a/examples.manifest.yaml +++ b/examples.manifest.yaml @@ -5,6 +5,9 @@ Python client library [docs](https://py-questdb-client.readthedocs.io/en/latest/) and [repo](https://github.com/questdb/py-questdb-client). + See more [examples](https://py-questdb-client.readthedocs.io/en/latest/examples.html), + including ingesting data from Pandas dataframes. + ``` python3 -m pip install questdb ``` @@ -15,6 +18,9 @@ Python client library [docs](https://py-questdb-client.readthedocs.io/en/latest/) and [repo](https://github.com/questdb/py-questdb-client). + See more [examples](https://py-questdb-client.readthedocs.io/en/latest/examples.html), + including ingesting data from Pandas dataframes. + ``` python3 -m pip install questdb ``` From 3af8c8514f2acd3a6885bf3ae7e647fffa966366 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Mon, 2 Jan 2023 11:21:41 +0000 Subject: [PATCH 141/147] Disabled bytecode file gen for install_rust.py --- install_rust.py | 1 + 1 file changed, 1 insertion(+) diff --git a/install_rust.py b/install_rust.py index a0adacca..d0de3696 100644 --- a/install_rust.py +++ b/install_rust.py @@ -1,4 +1,5 @@ import sys +sys.dont_write_bytecode = True import os import subprocess import pathlib From 25d4e2bdc48b69ee7c5d1d8deb819c0be7b54e2b Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Tue, 3 Jan 2023 17:57:18 +0000 Subject: [PATCH 142/147] Updated CHANGELOG.rst --- CHANGELOG.rst | 60 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1015d247..0fe8b7a3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,9 +2,47 @@ Changelog ========= +1.1.0 (2023-01-04) +------------------ + +Features +~~~~~~~~ + +* High-performance ingestion of `Pandas `_ + dataframes into QuestDB via ILP. + We now support most Pandas column types. The logic is implemented in native + code and is orders of magnitude faster than iterating the dataframe + in Python and calling the ``Buffer.row()`` or ``Sender.row()`` methods: The + ``Buffer`` can be written from Pandas at hundreds of MiB/s per CPU core. + The new ``dataframe()`` method continues working with the ``auto_flush`` + feature. + See API documentation and examples for the new ``dataframe()`` method + available on both the ``Sender`` and ``Buffer`` classes. + +* New ``TimestampNanos.now()`` and ``TimestampMicros.now()`` methods. + *These are the new recommended way of getting the current timestamp.* + +* The Python GIL is now released during calls to ``Sender.flush()`` and when + ``auto_flush`` is triggered. This should improve throughput when using the + ``Sender`` from multiple threads. + +Errata +~~~~~~ + +* In previous releases the documentation for the ``from_datetime()`` methods of + the ``TimestampNanos`` and ``TimestampMicros`` types recommended calling + ``datetime.datetime.utcnow()`` to get the current timestamp. This is incorrect + as it will (confusinly) return object with the local timezone instead of UTC. + This documentation has been corrected and now recommends calling + ``datetime.datetime.now(tz=datetime.timezone.utc)`` or (more efficiently) the + new ``TimestampNanos.now()`` and ``TimestampMicros.now()`` methods. + 1.0.2 (2022-10-31) ------------------ +Features +~~~~~~~~ + * Support for Python 3.11. * Updated to version 2.1.1 of the ``c-questdb-client`` library: @@ -14,13 +52,20 @@ Changelog 1.0.1 (2022-08-16) ------------------ +Features +~~~~~~~~ + +* As a matter of convenience, the ``Buffer.row`` method can now take ``None`` column + values. This has the same semantics as skipping the column altogether. + Closes `#3 `_. + +Bugfixes +~~~~~~~~ + * Fixed a major bug where Python ``int`` and ``float`` types were handled with 32-bit instead of 64-bit precision. This caused certain ``int`` values to be rejected and other ``float`` values to be rounded incorrectly. Closes `#13 `_. -* As a matter of convenience, the ``Buffer.row`` method can now take ``None`` column - values. This has the same semantics as skipping the column altogether. - Closes `#3 `_. * Fixed a minor bug where an error auto-flush caused a second clean-up error. Closes `#4 `_. @@ -28,6 +73,9 @@ Changelog 1.0.0 (2022-07-15) ------------------ +Features +~~~~~~~~ + * First stable release. * Insert data into QuestDB via ILP. * Sender and Buffer APIs. @@ -38,6 +86,9 @@ Changelog 0.0.3 (2022-07-14) ------------------ +Features +~~~~~~~~ + * Initial set of features to connect to the database. * ``Buffer`` and ``Sender`` classes. * First release where ``pip install questdb`` should work. @@ -46,4 +97,7 @@ Changelog 0.0.1 (2022-07-08) ------------------ +Features +~~~~~~~~ + * First release on PyPI. From 39dc427d97ca2ab263ac39973cb5dede3ce49a47 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 4 Jan 2023 11:29:10 +0000 Subject: [PATCH 143/147] Minor error reporting bugfix. --- c-questdb-client | 2 +- src/questdb/dataframe.pxi | 18 +++++++++--------- test/test_dataframe.py | 6 ++++++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/c-questdb-client b/c-questdb-client index 7135c912..3ee23c87 160000 --- a/c-questdb-client +++ b/c-questdb-client @@ -1 +1 @@ -Subproject commit 7135c9127bedb823a4af5780f0d248f9a1bd89a2 +Subproject commit 3ee23c87e2887e6631fb66a81d3f7efa2d9fe09b diff --git a/src/questdb/dataframe.pxi b/src/questdb/dataframe.pxi index d5ad3728..f6e03b03 100644 --- a/src/questdb/dataframe.pxi +++ b/src/questdb/dataframe.pxi @@ -2244,15 +2244,7 @@ cdef void_int _dataframe( if not line_sender_buffer_rewind_to_marker(ls_buf, &err): raise c_err_to_py(err) - if was_serializing_cell: - raise IngressError( - IngressErrorCode.BadDataFrame, - 'Failed to serialize value of column ' + - repr(df.columns[col.setup.orig_index]) + - f' at row index {row_index} (' + - repr(df.iloc[row_index, col.setup.orig_index]) + - f'): {e} [dc={col.dispatch_code}]') from e - elif (isinstance(e, IngressError) and + if (isinstance(e, IngressError) and (e.code == IngressErrorCode.InvalidApiCall)): # TODO: This should be allowed by the database. # It currently isn't so we have to raise an error. @@ -2261,6 +2253,14 @@ cdef void_int _dataframe( f'Bad dataframe row at index {row_index}: ' + 'All values are nulls. '+ 'Ensure at least one column is not null.') from e + elif was_serializing_cell: + raise IngressError( + IngressErrorCode.BadDataFrame, + 'Failed to serialize value of column ' + + repr(df.columns[col.setup.orig_index]) + + f' at row index {row_index} (' + + repr(df.iloc[row_index, col.setup.orig_index]) + + f'): {e} [dc={col.dispatch_code}]') from e else: raise finally: diff --git a/test/test_dataframe.py b/test/test_dataframe.py index 0c1b0976..f904b6e3 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -258,6 +258,12 @@ def test_at_ts_0(self): 'tbl1 a=2i,b="b" 0\n' + 'tbl1 a=3i,b="c" 0\n') + def test_single_at_col(self): + df = pd.DataFrame({'timestamp': pd.to_datetime(['2023-01-01'])}) + with self.assertRaisesRegex(qi.IngressError, + 'Bad dataframe row at index 0: All values are nulls.'): + _dataframe(df, table_name='tbl1', at='timestamp') + def test_row_of_nulls(self): df = pd.DataFrame({'a': ['a1', None, 'a3']}) with self.assertRaisesRegex( From 7818149ae7772e7fb3fb2d071b23ec8878dc5880 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 4 Jan 2023 11:29:29 +0000 Subject: [PATCH 144/147] Improved docs. --- README.rst | 16 ++++++++++++++++ docs/installation.rst | 26 ++++++++++++++++++++++++-- src/questdb/ingress.pyx | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index ae0e4947..a5dc9469 100644 --- a/README.rst +++ b/README.rst @@ -34,6 +34,22 @@ The latest version of the library is 1.0.2. columns={'temperature': 20.0, 'humidity': 0.5}) sender.flush() +You can also send Pandas dataframes: + +.. code-block:: python + + import pandas as pd + from questdb.ingress import Sender + + df = pd.DataFrame({ + 'id': pd.Categorical(['toronto1', 'paris3']), + 'temperature': [20.0, 21.0], + 'humidity': [0.5, 0.6], + 'timestamp': pd.to_datetime(['2021-01-01', '2021-01-02'])'}) + + with Sender('localhost', 9009) as sender: + sender.dataframe(df, table_name='sensors') + Docs ==== diff --git a/docs/installation.rst b/docs/installation.rst index 0d926ffe..10397974 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -5,9 +5,9 @@ Installation The Python QuestDB client does not have any additional run-time dependencies and will run on any version of Python >= 3.7 on most platforms and architectures. -You can install it globally by running:: +You can install it (or updated it) globally by running:: - python3 -m pip install questdb + python3 -m pip install -U questdb Or, from within a virtual environment:: @@ -20,6 +20,15 @@ If you're using poetry, you can add ``questdb`` as a dependency:: poetry add questdb +Note that the :func:`questdb.ingress.Buffer.dataframe` and the +:func:`questdb.ingress.Sender.dataframe` methods also require the following +dependencies to be installed: + +* ``pandas`` +* ``pyarrow`` +* ``numpy`` + + Verifying the Installation ========================== @@ -34,3 +43,16 @@ following statements from a ``python3`` interactive shell: >>> str(buf) 'test,a=b\n' + +If you also want to check you can serialize from Pandas +(which requires additional dependencies): + +.. code-block:: python + + >>> import questdb.ingress + >>> import pandas as pd + >>> df = pd.DataFrame({'a': [1, 2]}) + >>> buf = questdb.ingress.Buffer() + >>> buf.dataframe(df, table_name='test') + >>> str(buf) + 'test a=1i\ntest a=2i\n' diff --git a/src/questdb/ingress.pyx b/src/questdb/ingress.pyx index e2545eb7..b676400c 100644 --- a/src/questdb/ingress.pyx +++ b/src/questdb/ingress.pyx @@ -1200,6 +1200,31 @@ cdef class Buffer: If a datetime value is specified as ``None`` (``NaT``), it is interpreted as the current QuestDB server time set on receipt of message. + + **Error Handling and Recovery** + + In case an exception is raised during dataframe serialization, the + buffer is left in its previous state. + The buffer remains in a valid state and can be used for further calls + even after an error. + + For clarification, as an example, if an invalid ``None`` + value appears at the 3rd row for a ``bool`` column, neither the 3rd nor + the preceding rows are added to the buffer. + + **Note**: This differs from the :func:`Sender.dataframe` method, which + modifies this guarantee due to its ``auto_flush`` logic. + + **Performance Considerations** + + The Python GIL is released during serialization if it is not needed. + If any column requires the GIL, the entire serialization is done whilst + holding the GIL. + + Column types that require the GIL are: + + * Columns of ``str``, ``float`` or ``int`` or ``float`` Python objects. + * The ``'string[python]'`` dtype. """ _dataframe( auto_flush_blank(), @@ -1599,6 +1624,11 @@ cdef class Sender: Additionally, this method also supports auto-flushing the buffer as specified in the ``Sender``'s ``auto_flush`` constructor argument. + Auto-flushing is implemented incrementally, meanting that when + calling ``sender.dataframe(df)`` with a large ``df``, the sender may + have sent some of the rows to the server already whist the rest of the + rows are going to be sent at the next auto-flush or next explicit call + to :func:`Sender.flush`. In case of data errors with auto-flushing enabled, some of the rows may have been transmitted to the server already. @@ -1636,6 +1666,8 @@ cdef class Sender: If ``False``, the flushed buffer is left in the internal buffer. Note that ``clear=False`` is only supported if ``buffer`` is also specified. + + The Python GIL is released during the network IO operation. """ cdef line_sender* sender = self._impl cdef line_sender_error* err = NULL From 46999e71f12371e1806ae38e00a7b37c8bcfeec6 Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 4 Jan 2023 12:08:28 +0000 Subject: [PATCH 145/147] Updated c-questdb-client dependency. --- c-questdb-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c-questdb-client b/c-questdb-client index 3ee23c87..ad3776ef 160000 --- a/c-questdb-client +++ b/c-questdb-client @@ -1 +1 @@ -Subproject commit 3ee23c87e2887e6631fb66a81d3f7efa2d9fe09b +Subproject commit ad3776efb057d09a86a83e15c0f39ae40d75485b From 32f3394268c60e72ed5e7827c5b93dd66a68ac5a Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 4 Jan 2023 12:52:47 +0000 Subject: [PATCH 146/147] Exception type tidy-up. --- src/questdb/dataframe.pxi | 19 ++++++++++++------- test/test_dataframe.py | 40 ++++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/questdb/dataframe.pxi b/src/questdb/dataframe.pxi index f6e03b03..62cfd365 100644 --- a/src/questdb/dataframe.pxi +++ b/src/questdb/dataframe.pxi @@ -466,7 +466,8 @@ cdef object _dataframe_may_import_deps(): cdef object _dataframe_check_is_dataframe(object df): if not isinstance(df, _PANDAS.DataFrame): - raise TypeError( + raise IngressError( + IngressErrorCode.InvalidApiCall, f'Bad argument `df`: Expected {_fqn(_PANDAS.DataFrame)}, ' + f'not an object of type {_fqn(type(df))}.') @@ -497,8 +498,7 @@ cdef ssize_t _dataframe_resolve_table_name( str_to_table_name_copy(b, table_name, name_out) return -1 # Magic value for "no column index". except IngressError as ie: - raise IngressError( - IngressErrorCode.BadDataFrame, + raise ValueError( f'Bad argument `table_name`: {ie}') else: raise TypeError('Bad argument `table_name`: Must be str.') @@ -524,8 +524,7 @@ cdef ssize_t _dataframe_resolve_table_name( return col_index elif df.index.name: if not isinstance(df.index.name, str): - raise IngressError( - IngressErrorCode.BadDataFrame, + raise TypeError( 'Bad dataframe index name as table name: Expected str, ' + f'not an object of type {_fqn(type(df.index.name))}.') @@ -534,8 +533,7 @@ cdef ssize_t _dataframe_resolve_table_name( str_to_table_name_copy(b, df.index.name, name_out) return -1 # Magic value for "no column index". except IngressError as ie: - raise IngressError( - IngressErrorCode.BadDataFrame, + raise ValueError( f'Bad dataframe index name as table name: {ie}') else: raise ValueError( @@ -2263,6 +2261,13 @@ cdef void_int _dataframe( f'): {e} [dc={col.dispatch_code}]') from e else: raise + except Exception as e: + if not isinstance(e, IngressError): + raise IngressError( + IngressErrorCode.InvalidApiCall, + str(e)) from e + else: + raise finally: _ensure_has_gil(&gs) # Note: We need the GIL for cleanup. line_sender_buffer_clear_marker(ls_buf) diff --git a/test/test_dataframe.py b/test/test_dataframe.py index f904b6e3..42e310c7 100644 --- a/test/test_dataframe.py +++ b/test/test_dataframe.py @@ -72,20 +72,22 @@ def wrapper(self, *args, **kwargs): class TestPandas(unittest.TestCase): def test_bad_dataframe(self): - with self.assertRaisesRegex(TypeError, 'Expected pandas'): + with self.assertRaisesRegex(qi.IngressError, + 'Expected pandas'): _dataframe([]) def test_no_table_name(self): - with self.assertRaisesRegex(ValueError, 'Must specify at least one of'): + with self.assertRaisesRegex(qi.IngressError, + 'Must specify at least one of'): _dataframe(DF1) def test_bad_table_name_type(self): - with self.assertRaisesRegex(TypeError, 'Must be str'): + with self.assertRaisesRegex(qi.IngressError, 'Must be str'): _dataframe(DF1, table_name=1.5) def test_invalid_table_name(self): - with self.assertRaisesRegex( - qi.IngressError, '`table_name`: Bad string "."'): + with self.assertRaisesRegex(qi.IngressError, + '`table_name`: Bad string "."'): _dataframe(DF1, table_name='.') def test_invalid_column_dtype(self): @@ -98,7 +100,8 @@ def test_invalid_column_dtype(self): with self.assertRaisesRegex(qi.IngressError, '`table_name_col`: Bad dtype'): _dataframe(DF1, table_name_col=-3) - with self.assertRaisesRegex(IndexError, '`table_name_col`: -5 index'): + with self.assertRaisesRegex(qi.IngressError, + '`table_name_col`: -5 index'): _dataframe(DF1, table_name_col=-5) def test_bad_str_obj_col(self): @@ -113,11 +116,14 @@ def test_bad_str_obj_col(self): _dataframe(DF1, table_name_col=-1) def test_bad_symbol(self): - with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + with self.assertRaisesRegex(qi.IngressError, + '`symbols`.*bool.*tuple.*list'): _dataframe(DF1, table_name='tbl1', symbols=0) - with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + with self.assertRaisesRegex(qi.IngressError, + '`symbols`.*bool.*tuple.*list'): _dataframe(DF1, table_name='tbl1', symbols={}) - with self.assertRaisesRegex(TypeError, '`symbols`.*bool.*tuple.*list'): + with self.assertRaisesRegex(qi.IngressError, + '`symbols`.*bool.*tuple.*list'): _dataframe(DF1, table_name='tbl1', symbols=None) with self.assertRaisesRegex(qi.IngressError, "`symbols`: Bad dtype `float64`.*'A'.*Must.*strings col"): @@ -127,13 +133,17 @@ def test_bad_symbol(self): _dataframe(DF1, table_name='tbl1', symbols=[1]) def test_bad_at(self): - with self.assertRaisesRegex(KeyError, '`at`.*2018.*not found in the'): + with self.assertRaisesRegex(qi.IngressError, + '`at`.*2018.*not found in the'): _dataframe(DF1, table_name='tbl1', at='2018-03-10T00:00:00Z') - with self.assertRaisesRegex(TypeError, '`at`.*float64.*be a datetime'): + with self.assertRaisesRegex(qi.IngressError, + '`at`.*float64.*be a datetime'): _dataframe(DF1, table_name='tbl1', at='A') - with self.assertRaisesRegex(TypeError, '`at`.*int64.*be a datetime'): + with self.assertRaisesRegex(qi.IngressError, + '`at`.*int64.*be a datetime'): _dataframe(DF1, table_name='tbl1', at=1) - with self.assertRaisesRegex(TypeError, '`at`.*object.*be a datetime'): + with self.assertRaisesRegex(qi.IngressError, + '`at`.*object.*be a datetime'): _dataframe(DF1, table_name='tbl1', at=-1) def test_empty_dataframe(self): @@ -199,7 +209,7 @@ def test_at_good(self): 'a': [1, 2, 3], 'b': ['a', 'b', 'c']}) df.index.name = 'test_at_good' - with self.assertRaisesRegex(KeyError, + with self.assertRaisesRegex(qi.IngressError, 'Bad argument `at`: Column .2018-03.* not found .* dataframe.'): _dataframe(df, at='2018-03-10T00:00:00Z') @@ -228,7 +238,7 @@ def test_at_neg(self): n3 = dt.datetime(1965, 1, 1, 0, 0, 0) neg_timestamps = [n1, n2, n3] for ts in neg_timestamps: - with self.assertRaisesRegex(ValueError, + with self.assertRaisesRegex(qi.IngressError, 'Bad.*`at`: Cannot .* before the Unix epoch .1970-01-01.*'): _dataframe(DF2, at=ts, table_name='test_at_neg') From 38eb3823ced2b099c475881f8ffc1ac6c412172f Mon Sep 17 00:00:00 2001 From: Adam Cimarosti Date: Wed, 4 Jan 2023 16:44:39 +0000 Subject: [PATCH 147/147] Fixed typos spotted during the code review. --- docs/installation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 10397974..7f450b3b 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -5,7 +5,7 @@ Installation The Python QuestDB client does not have any additional run-time dependencies and will run on any version of Python >= 3.7 on most platforms and architectures. -You can install it (or updated it) globally by running:: +You can install it (or update it) globally by running:: python3 -m pip install -U questdb @@ -44,7 +44,7 @@ following statements from a ``python3`` interactive shell: >>> str(buf) 'test,a=b\n' -If you also want to check you can serialize from Pandas +If you also want to if check you can serialize from Pandas (which requires additional dependencies): .. code-block:: python