/* Generated by Cython 3.0.12 */

/* BEGIN: Cython Metadata
{
    "distutils": {
        "name": "sQQideR.SQLBuilder",
        "sources": [
            "sQQideR/SQLBuilder.pyx"
        ]
    },
    "module_name": "sQQideR.SQLBuilder"
}
END: Cython Metadata */

#ifndef PY_SSIZE_T_CLEAN
#define PY_SSIZE_T_CLEAN
#endif /* PY_SSIZE_T_CLEAN */
#if defined(CYTHON_LIMITED_API) && 0
  #ifndef Py_LIMITED_API
    #if CYTHON_LIMITED_API+0 > 0x03030000
      #define Py_LIMITED_API CYTHON_LIMITED_API
    #else
      #define Py_LIMITED_API 0x03030000
    #endif
  #endif
#endif

#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 < 0x02070000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
    #error Cython requires Python 2.7+ or Python 3.3+.
#else
#if defined(CYTHON_LIMITED_API) && CYTHON_LIMITED_API
#define __PYX_EXTRA_ABI_MODULE_NAME "limited"
#else
#define __PYX_EXTRA_ABI_MODULE_NAME ""
#endif
#define CYTHON_ABI "3_0_12" __PYX_EXTRA_ABI_MODULE_NAME
#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI
#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."
#define CYTHON_HEX_VERSION 0x03000CF0
#define CYTHON_FUTURE_DIVISION 1
#include <stddef.h>
#ifndef offsetof
  #define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
#endif
#if !defined(_WIN32) && !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
  #define HAVE_LONG_LONG
#endif
#ifndef PY_LONG_LONG
  #define PY_LONG_LONG LONG_LONG
#endif
#ifndef Py_HUGE_VAL
  #define Py_HUGE_VAL HUGE_VAL
#endif
#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX
#if defined(GRAALVM_PYTHON)
  /* For very preliminary testing purposes. Most variables are set the same as PyPy.
     The existence of this section does not imply that anything works or is even tested */
  #define CYTHON_COMPILING_IN_PYPY 0
  #define CYTHON_COMPILING_IN_CPYTHON 0
  #define CYTHON_COMPILING_IN_LIMITED_API 0
  #define CYTHON_COMPILING_IN_GRAAL 1
  #define CYTHON_COMPILING_IN_NOGIL 0
  #undef CYTHON_USE_TYPE_SLOTS
  #define CYTHON_USE_TYPE_SLOTS 0
  #undef CYTHON_USE_TYPE_SPECS
  #define CYTHON_USE_TYPE_SPECS 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_GIL
  #define CYTHON_FAST_GIL 0
  #undef CYTHON_METH_FASTCALL
  #define CYTHON_METH_FASTCALL 0
  #undef CYTHON_FAST_PYCALL
  #define CYTHON_FAST_PYCALL 0
  #ifndef CYTHON_PEP487_INIT_SUBCLASS
    #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3)
  #endif
  #undef CYTHON_PEP489_MULTI_PHASE_INIT
  #define CYTHON_PEP489_MULTI_PHASE_INIT 1
  #undef CYTHON_USE_MODULE_STATE
  #define CYTHON_USE_MODULE_STATE 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
  #undef CYTHON_USE_FREELISTS
  #define CYTHON_USE_FREELISTS 0
#elif defined(PYPY_VERSION)
  #define CYTHON_COMPILING_IN_PYPY 1
  #define CYTHON_COMPILING_IN_CPYTHON 0
  #define CYTHON_COMPILING_IN_LIMITED_API 0
  #define CYTHON_COMPILING_IN_GRAAL 0
  #define CYTHON_COMPILING_IN_NOGIL 0
  #undef CYTHON_USE_TYPE_SLOTS
  #define CYTHON_USE_TYPE_SLOTS 0
  #ifndef CYTHON_USE_TYPE_SPECS
    #define CYTHON_USE_TYPE_SPECS 0
  #endif
  #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_GIL
  #define CYTHON_FAST_GIL 0
  #undef CYTHON_METH_FASTCALL
  #define CYTHON_METH_FASTCALL 0
  #undef CYTHON_FAST_PYCALL
  #define CYTHON_FAST_PYCALL 0
  #ifndef CYTHON_PEP487_INIT_SUBCLASS
    #define CYTHON_PEP487_INIT_SUBCLASS (PY_MAJOR_VERSION >= 3)
  #endif
  #if PY_VERSION_HEX < 0x03090000
    #undef CYTHON_PEP489_MULTI_PHASE_INIT
    #define CYTHON_PEP489_MULTI_PHASE_INIT 0
  #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT)
    #define CYTHON_PEP489_MULTI_PHASE_INIT 1
  #endif
  #undef CYTHON_USE_MODULE_STATE
  #define CYTHON_USE_MODULE_STATE 0
  #undef CYTHON_USE_TP_FINALIZE
  #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1 && PYPY_VERSION_NUM >= 0x07030C00)
  #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
  #undef CYTHON_USE_FREELISTS
  #define CYTHON_USE_FREELISTS 0
#elif defined(CYTHON_LIMITED_API)
  #ifdef Py_LIMITED_API
    #undef __PYX_LIMITED_VERSION_HEX
    #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API
  #endif
  #define CYTHON_COMPILING_IN_PYPY 0
  #define CYTHON_COMPILING_IN_CPYTHON 0
  #define CYTHON_COMPILING_IN_LIMITED_API 1
  #define CYTHON_COMPILING_IN_GRAAL 0
  #define CYTHON_COMPILING_IN_NOGIL 0
  #undef CYTHON_CLINE_IN_TRACEBACK
  #define CYTHON_CLINE_IN_TRACEBACK 0
  #undef CYTHON_USE_TYPE_SLOTS
  #define CYTHON_USE_TYPE_SLOTS 0
  #undef CYTHON_USE_TYPE_SPECS
  #define CYTHON_USE_TYPE_SPECS 1
  #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
  #undef CYTHON_USE_UNICODE_INTERNALS
  #define CYTHON_USE_UNICODE_INTERNALS 0
  #ifndef CYTHON_USE_UNICODE_WRITER
    #define CYTHON_USE_UNICODE_WRITER 0
  #endif
  #undef CYTHON_USE_PYLONG_INTERNALS
  #define CYTHON_USE_PYLONG_INTERNALS 0
  #ifndef CYTHON_AVOID_BORROWED_REFS
    #define CYTHON_AVOID_BORROWED_REFS 0
  #endif
  #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_GIL
  #define CYTHON_FAST_GIL 0
  #undef CYTHON_METH_FASTCALL
  #define CYTHON_METH_FASTCALL 0
  #undef CYTHON_FAST_PYCALL
  #define CYTHON_FAST_PYCALL 0
  #ifndef CYTHON_PEP487_INIT_SUBCLASS
    #define CYTHON_PEP487_INIT_SUBCLASS 1
  #endif
  #undef CYTHON_PEP489_MULTI_PHASE_INIT
  #define CYTHON_PEP489_MULTI_PHASE_INIT 0
  #undef CYTHON_USE_MODULE_STATE
  #define CYTHON_USE_MODULE_STATE 1
  #ifndef CYTHON_USE_TP_FINALIZE
    #define CYTHON_USE_TP_FINALIZE 0
  #endif
  #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
  #undef CYTHON_USE_FREELISTS
  #define CYTHON_USE_FREELISTS 0
#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL)
  #define CYTHON_COMPILING_IN_PYPY 0
  #define CYTHON_COMPILING_IN_CPYTHON 0
  #define CYTHON_COMPILING_IN_LIMITED_API 0
  #define CYTHON_COMPILING_IN_GRAAL 0
  #define CYTHON_COMPILING_IN_NOGIL 1
  #ifndef CYTHON_USE_TYPE_SLOTS
    #define CYTHON_USE_TYPE_SLOTS 1
  #endif
  #ifndef CYTHON_USE_TYPE_SPECS
    #define CYTHON_USE_TYPE_SPECS 0
  #endif
  #undef CYTHON_USE_PYTYPE_LOOKUP
  #define CYTHON_USE_PYTYPE_LOOKUP 0
  #ifndef CYTHON_USE_ASYNC_SLOTS
    #define CYTHON_USE_ASYNC_SLOTS 1
  #endif
  #ifndef CYTHON_USE_PYLONG_INTERNALS
    #define CYTHON_USE_PYLONG_INTERNALS 0
  #endif
  #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
  #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_GIL
  #define CYTHON_FAST_GIL 0
  #ifndef CYTHON_METH_FASTCALL
    #define CYTHON_METH_FASTCALL 1
  #endif
  #undef CYTHON_FAST_PYCALL
  #define CYTHON_FAST_PYCALL 0
  #ifndef CYTHON_PEP487_INIT_SUBCLASS
    #define CYTHON_PEP487_INIT_SUBCLASS 1
  #endif
  #ifndef CYTHON_PEP489_MULTI_PHASE_INIT
    #define CYTHON_PEP489_MULTI_PHASE_INIT 1
  #endif
  #ifndef CYTHON_USE_MODULE_STATE
    #define CYTHON_USE_MODULE_STATE 0
  #endif
  #ifndef CYTHON_USE_TP_FINALIZE
    #define CYTHON_USE_TP_FINALIZE 1
  #endif
  #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 1
  #endif
  #ifndef CYTHON_USE_FREELISTS
    #define CYTHON_USE_FREELISTS 0
  #endif
#else
  #define CYTHON_COMPILING_IN_PYPY 0
  #define CYTHON_COMPILING_IN_CPYTHON 1
  #define CYTHON_COMPILING_IN_LIMITED_API 0
  #define CYTHON_COMPILING_IN_GRAAL 0
  #define CYTHON_COMPILING_IN_NOGIL 0
  #ifndef CYTHON_USE_TYPE_SLOTS
    #define CYTHON_USE_TYPE_SLOTS 1
  #endif
  #ifndef CYTHON_USE_TYPE_SPECS
    #define CYTHON_USE_TYPE_SPECS 0
  #endif
  #ifndef 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
  #ifndef 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
  #ifndef CYTHON_FAST_THREAD_STATE
    #define CYTHON_FAST_THREAD_STATE 1
  #endif
  #ifndef CYTHON_FAST_GIL
    #define CYTHON_FAST_GIL (PY_MAJOR_VERSION < 3 || PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x030C00A6)
  #endif
  #ifndef CYTHON_METH_FASTCALL
    #define CYTHON_METH_FASTCALL (PY_VERSION_HEX >= 0x030700A1)
  #endif
  #ifndef CYTHON_FAST_PYCALL
    #define CYTHON_FAST_PYCALL 1
  #endif
  #ifndef CYTHON_PEP487_INIT_SUBCLASS
    #define CYTHON_PEP487_INIT_SUBCLASS 1
  #endif
  #if PY_VERSION_HEX < 0x03050000
    #undef CYTHON_PEP489_MULTI_PHASE_INIT
    #define CYTHON_PEP489_MULTI_PHASE_INIT 0
  #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT)
    #define CYTHON_PEP489_MULTI_PHASE_INIT 1
  #endif
  #ifndef CYTHON_USE_MODULE_STATE
    #define CYTHON_USE_MODULE_STATE 0
  #endif
  #if PY_VERSION_HEX < 0x030400a1
    #undef CYTHON_USE_TP_FINALIZE
    #define CYTHON_USE_TP_FINALIZE 0
  #elif !defined(CYTHON_USE_TP_FINALIZE)
    #define CYTHON_USE_TP_FINALIZE 1
  #endif
  #if PY_VERSION_HEX < 0x030600B1
    #undef CYTHON_USE_DICT_VERSIONS
    #define CYTHON_USE_DICT_VERSIONS 0
  #elif !defined(CYTHON_USE_DICT_VERSIONS)
    #define CYTHON_USE_DICT_VERSIONS  (PY_VERSION_HEX < 0x030C00A5)
  #endif
  #if PY_VERSION_HEX < 0x030700A3
    #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 1
  #endif
  #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC
    #define CYTHON_UPDATE_DESCRIPTOR_DOC 1
  #endif
  #ifndef CYTHON_USE_FREELISTS
    #define CYTHON_USE_FREELISTS 1
  #endif
#endif
#if !defined(CYTHON_FAST_PYCCALL)
#define CYTHON_FAST_PYCCALL  (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
#endif
#if !defined(CYTHON_VECTORCALL)
#define CYTHON_VECTORCALL  (CYTHON_FAST_PYCCALL && PY_VERSION_HEX >= 0x030800B1)
#endif
#define CYTHON_BACKPORT_VECTORCALL (CYTHON_METH_FASTCALL && PY_VERSION_HEX < 0x030800B1)
#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(__cplusplus)
    /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17
     * but leads to warnings with -pedantic, since it is a C++17 feature */
    #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
      #if __has_cpp_attribute(maybe_unused)
        #define CYTHON_UNUSED [[maybe_unused]]
      #endif
    #endif
  #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_UNUSED_VAR
#  if defined(__cplusplus)
     template<class T> void CYTHON_UNUSED_VAR( const T& ) { }
#  else
#    define CYTHON_UNUSED_VAR(x) (void)(x)
#  endif
#endif
#ifndef CYTHON_MAYBE_UNUSED_VAR
  #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x)
#endif
#ifndef CYTHON_NCP_UNUSED
# if CYTHON_COMPILING_IN_CPYTHON
#  define CYTHON_NCP_UNUSED
# else
#  define CYTHON_NCP_UNUSED CYTHON_UNUSED
# endif
#endif
#ifndef CYTHON_USE_CPP_STD_MOVE
  #if defined(__cplusplus) && (\
    __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600))
    #define CYTHON_USE_CPP_STD_MOVE 1
  #else
    #define CYTHON_USE_CPP_STD_MOVE 0
  #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 short    uint16_t;
            typedef unsigned int      uint32_t;
        #else
            typedef unsigned __int8   uint8_t;
            typedef unsigned __int16  uint16_t;
            typedef unsigned __int32  uint32_t;
        #endif
    #endif
    #if _MSC_VER < 1300
        #ifdef _WIN64
            typedef unsigned long long  __pyx_uintptr_t;
        #else
            typedef unsigned int        __pyx_uintptr_t;
        #endif
    #else
        #ifdef _WIN64
            typedef unsigned __int64    __pyx_uintptr_t;
        #else
            typedef unsigned __int32    __pyx_uintptr_t;
        #endif
    #endif
#else
    #include <stdint.h>
    typedef uintptr_t  __pyx_uintptr_t;
#endif
#ifndef CYTHON_FALLTHROUGH
  #if defined(__cplusplus)
    /* for clang __has_cpp_attribute(fallthrough) is true even before C++17
     * but leads to warnings with -pedantic, since it is a C++17 feature */
    #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
      #if __has_cpp_attribute(fallthrough)
        #define CYTHON_FALLTHROUGH [[fallthrough]]
      #endif
    #endif
    #ifndef CYTHON_FALLTHROUGH
      #if __has_cpp_attribute(clang::fallthrough)
        #define CYTHON_FALLTHROUGH [[clang::fallthrough]]
      #elif __has_cpp_attribute(gnu::fallthrough)
        #define CYTHON_FALLTHROUGH [[gnu::fallthrough]]
      #endif
    #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
#ifdef __cplusplus
  template <typename T>
  struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);};
  #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL<type>::value)
#else
  #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0)
#endif
#if CYTHON_COMPILING_IN_PYPY == 1
  #define __PYX_NEED_TP_PRINT_SLOT  (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x030A0000)
#else
  #define __PYX_NEED_TP_PRINT_SLOT  (PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000)
#endif
#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer))

#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

#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_DefaultClassType PyClass_Type
  #define __Pyx_PyCode_New(a, p, 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)
#else
  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
  #define __Pyx_DefaultClassType PyType_Type
#if CYTHON_COMPILING_IN_LIMITED_API
    static CYTHON_INLINE PyObject* __Pyx_PyCode_New(int a, int p, 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 *exception_table = NULL;
        PyObject *types_module=NULL, *code_type=NULL, *result=NULL;
        #if __PYX_LIMITED_VERSION_HEX < 0x030B0000
        PyObject *version_info;
        PyObject *py_minor_version = NULL;
        #endif
        long minor_version = 0;
        PyObject *type, *value, *traceback;
        PyErr_Fetch(&type, &value, &traceback);
        #if __PYX_LIMITED_VERSION_HEX >= 0x030B0000
        minor_version = 11;
        #else
        if (!(version_info = PySys_GetObject("version_info"))) goto end;
        if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end;
        minor_version = PyLong_AsLong(py_minor_version);
        Py_DECREF(py_minor_version);
        if (minor_version == -1 && PyErr_Occurred()) goto end;
        #endif
        if (!(types_module = PyImport_ImportModule("types"))) goto end;
        if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end;
        if (minor_version <= 7) {
            (void)p;
            result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOO", a, k, l, s, f, code,
                          c, n, v, fn, name, fline, lnos, fv, cell);
        } else if (minor_version <= 10) {
            result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOO", a,p, k, l, s, f, code,
                          c, n, v, fn, name, fline, lnos, fv, cell);
        } else {
            if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end;
            result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOO", a,p, k, l, s, f, code,
                          c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell);
        }
    end:
        Py_XDECREF(code_type);
        Py_XDECREF(exception_table);
        Py_XDECREF(types_module);
        if (type) {
            PyErr_Restore(type, value, traceback);
        }
        return result;
    }
    #ifndef CO_OPTIMIZED
    #define CO_OPTIMIZED 0x0001
    #endif
    #ifndef CO_NEWLOCALS
    #define CO_NEWLOCALS 0x0002
    #endif
    #ifndef CO_VARARGS
    #define CO_VARARGS 0x0004
    #endif
    #ifndef CO_VARKEYWORDS
    #define CO_VARKEYWORDS 0x0008
    #endif
    #ifndef CO_ASYNC_GENERATOR
    #define CO_ASYNC_GENERATOR 0x0200
    #endif
    #ifndef CO_GENERATOR
    #define CO_GENERATOR 0x0020
    #endif
    #ifndef CO_COROUTINE
    #define CO_COROUTINE 0x0080
    #endif
#elif PY_VERSION_HEX >= 0x030B0000
  static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int p, 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) {
    PyCodeObject *result;
    PyObject *empty_bytes = PyBytes_FromStringAndSize("", 0);
    if (!empty_bytes) return NULL;
    result =
      #if PY_VERSION_HEX >= 0x030C0000
        PyUnstable_Code_NewWithPosOnlyArgs
      #else
        PyCode_NewWithPosOnlyArgs
      #endif
        (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, empty_bytes);
    Py_DECREF(empty_bytes);
    return result;
  }
#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY
  #define __Pyx_PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
          PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#else
  #define __Pyx_PyCode_New(a, p, 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
#endif
#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE)
  #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type)
#else
  #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type))
#endif
#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is)
  #define __Pyx_Py_Is(x, y)  Py_Is(x, y)
#else
  #define __Pyx_Py_Is(x, y) ((x) == (y))
#endif
#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone)
  #define __Pyx_Py_IsNone(ob) Py_IsNone(ob)
#else
  #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None)
#endif
#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue)
  #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob)
#else
  #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True)
#endif
#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse)
  #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob)
#else
  #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False)
#endif
#define __Pyx_NoneAsNull(obj)  (__Pyx_Py_IsNone(obj) ? NULL : (obj))
#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY
  #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o)
#else
  #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o)
#endif
#ifndef CO_COROUTINE
  #define CO_COROUTINE 0x80
#endif
#ifndef CO_ASYNC_GENERATOR
  #define CO_ASYNC_GENERATOR 0x200
#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 Py_TPFLAGS_SEQUENCE
  #define Py_TPFLAGS_SEQUENCE 0
#endif
#ifndef Py_TPFLAGS_MAPPING
  #define Py_TPFLAGS_MAPPING 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
  #if PY_VERSION_HEX >= 0x030d00A4
  #  define __Pyx_PyCFunctionFast PyCFunctionFast
  #  define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords
  #else
  #  define __Pyx_PyCFunctionFast _PyCFunctionFast
  #  define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords
  #endif
#endif
#if CYTHON_METH_FASTCALL
  #define __Pyx_METH_FASTCALL METH_FASTCALL
  #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast
  #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords
#else
  #define __Pyx_METH_FASTCALL METH_VARARGS
  #define __Pyx_PyCFunction_FastCall PyCFunction
  #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords
#endif
#if CYTHON_VECTORCALL
  #define __pyx_vectorcallfunc vectorcallfunc
  #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET  PY_VECTORCALL_ARGUMENTS_OFFSET
  #define __Pyx_PyVectorcall_NARGS(n)  PyVectorcall_NARGS((size_t)(n))
#elif CYTHON_BACKPORT_VECTORCALL
  typedef PyObject *(*__pyx_vectorcallfunc)(PyObject *callable, PyObject *const *args,
                                            size_t nargsf, PyObject *kwnames);
  #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET  ((size_t)1 << (8 * sizeof(size_t) - 1))
  #define __Pyx_PyVectorcall_NARGS(n)  ((Py_ssize_t)(((size_t)(n)) & ~__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET))
#else
  #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET  0
  #define __Pyx_PyVectorcall_NARGS(n)  ((Py_ssize_t)(n))
#endif
#if PY_MAJOR_VERSION >= 0x030900B1
#define __Pyx_PyCFunction_CheckExact(func)  PyCFunction_CheckExact(func)
#else
#define __Pyx_PyCFunction_CheckExact(func)  PyCFunction_Check(func)
#endif
#define __Pyx_CyOrPyCFunction_Check(func)  PyCFunction_Check(func)
#if CYTHON_COMPILING_IN_CPYTHON
#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func)  (((PyCFunctionObject*)(func))->m_ml->ml_meth)
#elif !CYTHON_COMPILING_IN_LIMITED_API
#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func)  PyCFunction_GET_FUNCTION(func)
#endif
#if CYTHON_COMPILING_IN_CPYTHON
#define __Pyx_CyOrPyCFunction_GET_FLAGS(func)  (((PyCFunctionObject*)(func))->m_ml->ml_flags)
static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) {
    return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self;
}
#endif
static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void *cfunc) {
#if CYTHON_COMPILING_IN_LIMITED_API
    return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc;
#else
    return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc;
#endif
}
#define __Pyx_IsSameCFunction(func, cfunc)   __Pyx__IsSameCFunction(func, cfunc)
#if __PYX_LIMITED_VERSION_HEX < 0x030900B1
  #define __Pyx_PyType_FromModuleAndSpec(m, s, b)  ((void)m, PyType_FromSpecWithBases(s, b))
  typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *);
#else
  #define __Pyx_PyType_FromModuleAndSpec(m, s, b)  PyType_FromModuleAndSpec(m, s, b)
  #define __Pyx_PyCMethod  PyCMethod
#endif
#ifndef METH_METHOD
  #define METH_METHOD 0x200
#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_LIMITED_API
  #define __Pyx_PyCode_HasFreeVars(co)  (PyCode_GetNumFree(co) > 0)
  #define __Pyx_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_COMPILING_IN_LIMITED_API
  #define __Pyx_PyThreadState_Current PyThreadState_Get()
#elif !CYTHON_FAST_THREAD_STATE
  #define __Pyx_PyThreadState_Current PyThreadState_GET()
#elif PY_VERSION_HEX >= 0x030d00A1
  #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked()
#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 CYTHON_COMPILING_IN_LIMITED_API
static CYTHON_INLINE void *__Pyx_PyModule_GetState(PyObject *op)
{
    void *result;
    result = PyModule_GetState(op);
    if (!result)
        Py_FatalError("Couldn't find the module state");
    return result;
}
#endif
#define __Pyx_PyObject_GetSlot(obj, name, func_ctype)  __Pyx_PyType_GetSlot(Py_TYPE(obj), name, func_ctype)
#if CYTHON_COMPILING_IN_LIMITED_API
  #define __Pyx_PyType_GetSlot(type, name, func_ctype)  ((func_ctype) PyType_GetSlot((type), Py_##name))
#else
  #define __Pyx_PyType_GetSlot(type, name, func_ctype)  ((type)->name)
#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 PY_MAJOR_VERSION < 3
    #if CYTHON_COMPILING_IN_PYPY
        #if PYPY_VERSION_NUM < 0x07030600
            #if defined(__cplusplus) && __cplusplus >= 201402L
                [[deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")]]
            #elif defined(__GNUC__) || defined(__clang__)
                __attribute__ ((__deprecated__("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6")))
            #elif defined(_MSC_VER)
                __declspec(deprecated("`with nogil:` inside a nogil function will not release the GIL in PyPy2 < 7.3.6"))
            #endif
            static CYTHON_INLINE int PyGILState_Check(void) {
                return 0;
            }
        #else  // PYPY_VERSION_NUM < 0x07030600
        #endif  // PYPY_VERSION_NUM < 0x07030600
    #else
        static CYTHON_INLINE int PyGILState_Check(void) {
            PyThreadState * tstate = _PyThreadState_Current;
            return tstate && (tstate == PyGILState_GetThisThreadState());
        }
    #endif
#endif
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030d0000 || 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 > 0x030600B4 && PY_VERSION_HEX < 0x030d0000 && CYTHON_USE_UNICODE_INTERNALS
#define __Pyx_PyDict_GetItemStrWithError(dict, name)  _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash)
static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) {
    PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name);
    if (res == NULL) PyErr_Clear();
    return res;
}
#elif PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000)
#define __Pyx_PyDict_GetItemStrWithError  PyDict_GetItemWithError
#define __Pyx_PyDict_GetItemStr           PyDict_GetItem
#else
static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) {
#if CYTHON_COMPILING_IN_PYPY
    return PyDict_GetItem(dict, name);
#else
    PyDictEntry *ep;
    PyDictObject *mp = (PyDictObject*) dict;
    long hash = ((PyStringObject *) name)->ob_shash;
    assert(hash != -1);
    ep = (mp->ma_lookup)(mp, name, hash);
    if (ep == NULL) {
        return NULL;
    }
    return ep->me_value;
#endif
}
#define __Pyx_PyDict_GetItemStr           PyDict_GetItem
#endif
#if CYTHON_USE_TYPE_SLOTS
  #define __Pyx_PyType_GetFlags(tp)   (((PyTypeObject *)tp)->tp_flags)
  #define __Pyx_PyType_HasFeature(type, feature)  ((__Pyx_PyType_GetFlags(type) & (feature)) != 0)
  #define __Pyx_PyObject_GetIterNextFunc(obj)  (Py_TYPE(obj)->tp_iternext)
#else
  #define __Pyx_PyType_GetFlags(tp)   (PyType_GetFlags((PyTypeObject *)tp))
  #define __Pyx_PyType_HasFeature(type, feature)  PyType_HasFeature(type, feature)
  #define __Pyx_PyObject_GetIterNextFunc(obj)  PyIter_Next
#endif
#if CYTHON_COMPILING_IN_LIMITED_API
  #define __Pyx_SetItemOnTypeDict(tp, k, v) PyObject_GenericSetAttr((PyObject*)tp, k, v)
#else
  #define __Pyx_SetItemOnTypeDict(tp, k, v) PyDict_SetItem(tp->tp_dict, k, v)
#endif
#if CYTHON_USE_TYPE_SPECS && PY_VERSION_HEX >= 0x03080000
#define __Pyx_PyHeapTypeObject_GC_Del(obj)  {\
    PyTypeObject *type = Py_TYPE((PyObject*)obj);\
    assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\
    PyObject_GC_Del(obj);\
    Py_DECREF(type);\
}
#else
#define __Pyx_PyHeapTypeObject_GC_Del(obj)  PyObject_GC_Del(obj)
#endif
#if CYTHON_COMPILING_IN_LIMITED_API
  #define CYTHON_PEP393_ENABLED 1
  #define __Pyx_PyUnicode_READY(op)       (0)
  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GetLength(u)
  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i)
  #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u)   ((void)u, 1114111U)
  #define __Pyx_PyUnicode_KIND(u)         ((void)u, (0))
  #define __Pyx_PyUnicode_DATA(u)         ((void*)u)
  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)k, PyUnicode_ReadChar((PyObject*)(d), i))
  #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GetLength(u))
#elif PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
  #define CYTHON_PEP393_ENABLED 1
  #if PY_VERSION_HEX >= 0x030C0000
    #define __Pyx_PyUnicode_READY(op)       (0)
  #else
    #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ?\
                                                0 : _PyUnicode_Ready((PyObject *)(op)))
  #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)         ((int)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, (Py_UCS4) ch)
  #if PY_VERSION_HEX >= 0x030C0000
    #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GET_LENGTH(u))
  #else
    #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
  #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) ? 65535U : 1114111U)
  #define __Pyx_PyUnicode_KIND(u)         ((int)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] = (Py_UNICODE) 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
  #if !defined(PyUnicode_DecodeUnicodeEscape)
    #define PyUnicode_DecodeUnicodeEscape(s, size, errors)  PyUnicode_Decode(s, size, "unicode_escape", errors)
  #endif
  #if !defined(PyUnicode_Contains) || (PY_MAJOR_VERSION == 2 && PYPY_VERSION_NUM < 0x07030500)
    #undef PyUnicode_Contains
    #define PyUnicode_Contains(u, s)  PySequence_Contains(u, s)
  #endif
  #if !defined(PyByteArray_Check)
    #define PyByteArray_Check(obj)  PyObject_TypeCheck(obj, &PyByteArray_Type)
  #endif
  #if !defined(PyObject_Format)
    #define PyObject_Format(obj, fmt)  PyObject_CallMethod(obj, "__format__", "O", fmt)
  #endif
#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
#if CYTHON_COMPILING_IN_CPYTHON
  #define __Pyx_PySequence_ListKeepNew(obj)\
    (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj))
#else
  #define __Pyx_PySequence_ListKeepNew(obj)  PySequence_List(obj)
#endif
#ifndef PySet_CheckExact
  #define PySet_CheckExact(obj)        __Pyx_IS_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_ITEM(o, i) PySequence_ITEM(o, i)
  #define __Pyx_PySequence_SIZE(seq)  Py_SIZE(seq)
  #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0))
  #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0))
  #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o)
  #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o)
  #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o)
  #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o)
  #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o)
#else
  #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i)
  #define __Pyx_PySequence_SIZE(seq)  PySequence_Size(seq)
  #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v)
  #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v)
  #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o)
  #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o)
  #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o)
  #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o)
  #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o)
#endif
#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1
  #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name)
#else
  static CYTHON_INLINE PyObject *__Pyx_PyImport_AddModuleRef(const char *name) {
      PyObject *module = PyImport_AddModule(name);
      Py_XINCREF(module);
      return module;
  }
#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 __Pyx_Py3Int_Check(op)       PyLong_Check(op)
  #define __Pyx_Py3Int_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
#else
  #define __Pyx_Py3Int_Check(op)       (PyLong_Check(op) || PyInt_Check(op))
  #define __Pyx_Py3Int_CheckExact(op)  (PyLong_CheckExact(op) || PyInt_CheckExact(op))
#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 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 <math.h>
#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; }

#ifdef CYTHON_EXTERN_C
    #undef __PYX_EXTERN_C
    #define __PYX_EXTERN_C CYTHON_EXTERN_C
#elif defined(__PYX_EXTERN_C)
    #ifdef _MSC_VER
    #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.")
    #else
    #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.
    #endif
#else
  #ifdef __cplusplus
    #define __PYX_EXTERN_C extern "C"
  #else
    #define __PYX_EXTERN_C extern
  #endif
#endif

#define __PYX_HAVE__sQQideR__SQLBuilder
#define __PYX_HAVE_API__sQQideR__SQLBuilder
/* Early includes */
#ifdef _OPENMP
#include <omp.h>
#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 <cstdlib>
    #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 Py_ssize_t __Pyx_ssize_strlen(const char *s);
static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*);
static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*);
#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_uintptr_t) __Pyx_PyObject_AsString(s))
#define __Pyx_PyObject_AsWritableSString(s)    ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s))
#define __Pyx_PyObject_AsWritableUString(s)    ((unsigned char*)(__pyx_uintptr_t) __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)
#define __Pyx_PyUnicode_FromOrdinal(o)       PyUnicode_FromOrdinal((int)o)
#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
#if CYTHON_USE_PYLONG_INTERNALS
  #if PY_VERSION_HEX >= 0x030C00A7
  #ifndef _PyLong_SIGN_MASK
    #define _PyLong_SIGN_MASK 3
  #endif
  #ifndef _PyLong_NON_SIZE_BITS
    #define _PyLong_NON_SIZE_BITS 3
  #endif
  #define __Pyx_PyLong_Sign(x)  (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK)
  #define __Pyx_PyLong_IsNeg(x)  ((__Pyx_PyLong_Sign(x) & 2) != 0)
  #define __Pyx_PyLong_IsNonNeg(x)  (!__Pyx_PyLong_IsNeg(x))
  #define __Pyx_PyLong_IsZero(x)  (__Pyx_PyLong_Sign(x) & 1)
  #define __Pyx_PyLong_IsPos(x)  (__Pyx_PyLong_Sign(x) == 0)
  #define __Pyx_PyLong_CompactValueUnsigned(x)  (__Pyx_PyLong_Digits(x)[0])
  #define __Pyx_PyLong_DigitCount(x)  ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS))
  #define __Pyx_PyLong_SignedDigitCount(x)\
        ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x))
  #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue)
    #define __Pyx_PyLong_IsCompact(x)     PyUnstable_Long_IsCompact((PyLongObject*) x)
    #define __Pyx_PyLong_CompactValue(x)  PyUnstable_Long_CompactValue((PyLongObject*) x)
  #else
    #define __Pyx_PyLong_IsCompact(x)     (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS))
    #define __Pyx_PyLong_CompactValue(x)  ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0])
  #endif
  typedef Py_ssize_t  __Pyx_compact_pylong;
  typedef size_t  __Pyx_compact_upylong;
  #else
  #define __Pyx_PyLong_IsNeg(x)  (Py_SIZE(x) < 0)
  #define __Pyx_PyLong_IsNonNeg(x)  (Py_SIZE(x) >= 0)
  #define __Pyx_PyLong_IsZero(x)  (Py_SIZE(x) == 0)
  #define __Pyx_PyLong_IsPos(x)  (Py_SIZE(x) > 0)
  #define __Pyx_PyLong_CompactValueUnsigned(x)  ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0])
  #define __Pyx_PyLong_DigitCount(x)  __Pyx_sst_abs(Py_SIZE(x))
  #define __Pyx_PyLong_SignedDigitCount(x)  Py_SIZE(x)
  #define __Pyx_PyLong_IsCompact(x)  (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1)
  #define __Pyx_PyLong_CompactValue(x)\
        ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0]))
  typedef sdigit  __Pyx_compact_pylong;
  typedef digit  __Pyx_compact_upylong;
  #endif
  #if PY_VERSION_HEX >= 0x030C00A5
  #define __Pyx_PyLong_Digits(x)  (((PyLongObject*)x)->long_value.ob_digit)
  #else
  #define __Pyx_PyLong_Digits(x)  (((PyLongObject*)x)->ob_digit)
  #endif
#endif
#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
#include <string.h>
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] = (char) 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
#include <string.h>
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; }

#if !CYTHON_USE_MODULE_STATE
static PyObject *__pyx_m = NULL;
#endif
static int __pyx_lineno;
static int __pyx_clineno = 0;
static const char * __pyx_cfilenm = __FILE__;
static const char *__pyx_filename;

/* #### Code section: filename_table ### */

static const char *__pyx_f[] = {
  "sQQideR\\\\SQLBuilder.pyx",
};
/* #### Code section: utility_code_proto_before_types ### */
/* ForceInitThreads.proto */
#ifndef __PYX_FORCE_INIT_THREADS
  #define __PYX_FORCE_INIT_THREADS 0
#endif

/* #### Code section: numeric_typedefs ### */
/* #### Code section: complex_type_declarations ### */
/* #### Code section: type_declarations ### */

/*--- Type declarations ---*/
struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations;
struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr;

/* "sQQideR/SQLBuilder.pyx":683
 *         return list(table_names)
 * 
 *     def generate_additional_explorations(self, question: str, main_query: Dict, db_context: Dict) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Generate and execute additional SQL queries to explore related aspects of the main query.
 */
struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations {
  PyObject_HEAD
  PyObject *__pyx_v_question;
};


/* "sQQideR/SQLBuilder.pyx":806
 *         # 4. If the question relates to relationships, explore relationship counts
 *         relationship_keywords = ["relation", "connect", "join", "link", "between"]
 *         if any(keyword in question.lower() for keyword in relationship_keywords) and len(tables_used) > 1:             # <<<<<<<<<<<<<<
 *             # Find relationships between the used tables from context
 *             for rel in db_context.get("relationships", []):
 */
struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr {
  PyObject_HEAD
  struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *__pyx_outer_scope;
  PyObject *__pyx_genexpr_arg_0;
  PyObject *__pyx_v_keyword;
};

/* #### Code section: utility_code_proto ### */

/* --- Runtime support code (head) --- */
/* Refnanny.proto */
#ifndef CYTHON_REFNANNY
  #define CYTHON_REFNANNY 0
#endif
#if CYTHON_REFNANNY
  typedef struct {
    void (*INCREF)(void*, PyObject*, Py_ssize_t);
    void (*DECREF)(void*, PyObject*, Py_ssize_t);
    void (*GOTREF)(void*, PyObject*, Py_ssize_t);
    void (*GIVEREF)(void*, PyObject*, Py_ssize_t);
    void* (*SetupContext)(const char*, Py_ssize_t, 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__));\
          }
  #define __Pyx_RefNannyFinishContextNogil() {\
              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\
              __Pyx_RefNannyFinishContext();\
              PyGILState_Release(__pyx_gilstate_save);\
          }
#else
  #define __Pyx_RefNannySetupContext(name, acquire_gil)\
          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__))
  #define __Pyx_RefNannyFinishContextNogil() __Pyx_RefNannyFinishContext()
#endif
  #define __Pyx_RefNannyFinishContextNogil() {\
              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\
              __Pyx_RefNannyFinishContext();\
              PyGILState_Release(__pyx_gilstate_save);\
          }
  #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); else {__Pyx_INCREF(r); }} while(0)
  #define __Pyx_XDECREF(r)  do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0)
  #define __Pyx_XGOTREF(r)  do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0)
  #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0)
#else
  #define __Pyx_RefNannyDeclarations
  #define __Pyx_RefNannySetupContext(name, acquire_gil)
  #define __Pyx_RefNannyFinishContextNogil()
  #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_Py_XDECREF_SET(r, v) do {\
        PyObject *tmp = (PyObject *) r;\
        r = v; Py_XDECREF(tmp);\
    } while (0)
#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)

/* 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

/* PyThreadStateGet.proto */
#if CYTHON_FAST_THREAD_STATE
#define __Pyx_PyThreadState_declare  PyThreadState *__pyx_tstate;
#define __Pyx_PyThreadState_assign  __pyx_tstate = __Pyx_PyThreadState_Current;
#if PY_VERSION_HEX >= 0x030C00A6
#define __Pyx_PyErr_Occurred()  (__pyx_tstate->current_exception != NULL)
#define __Pyx_PyErr_CurrentExceptionType()  (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL)
#else
#define __Pyx_PyErr_Occurred()  (__pyx_tstate->curexc_type != NULL)
#define __Pyx_PyErr_CurrentExceptionType()  (__pyx_tstate->curexc_type)
#endif
#else
#define __Pyx_PyThreadState_declare
#define __Pyx_PyThreadState_assign
#define __Pyx_PyErr_Occurred()  (PyErr_Occurred() != NULL)
#define __Pyx_PyErr_CurrentExceptionType()  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 && PY_VERSION_HEX < 0x030C00A6
#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

/* 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

/* PyObjectGetAttrStrNoError.proto */
static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name);

/* GetBuiltinName.proto */
static PyObject *__Pyx_GetBuiltinName(PyObject *name);

/* TupleAndListFromArray.proto */
#if CYTHON_COMPILING_IN_CPYTHON
static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n);
static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n);
#endif

/* IncludeStringH.proto */
#include <string.h>

/* 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);

/* fastcall.proto */
#if CYTHON_AVOID_BORROWED_REFS
    #define __Pyx_Arg_VARARGS(args, i) PySequence_GetItem(args, i)
#elif CYTHON_ASSUME_SAFE_MACROS
    #define __Pyx_Arg_VARARGS(args, i) PyTuple_GET_ITEM(args, i)
#else
    #define __Pyx_Arg_VARARGS(args, i) PyTuple_GetItem(args, i)
#endif
#if CYTHON_AVOID_BORROWED_REFS
    #define __Pyx_Arg_NewRef_VARARGS(arg) __Pyx_NewRef(arg)
    #define __Pyx_Arg_XDECREF_VARARGS(arg) Py_XDECREF(arg)
#else
    #define __Pyx_Arg_NewRef_VARARGS(arg) arg
    #define __Pyx_Arg_XDECREF_VARARGS(arg)
#endif
#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds)
#define __Pyx_KwValues_VARARGS(args, nargs) NULL
#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s)
#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw)
#if CYTHON_METH_FASTCALL
    #define __Pyx_Arg_FASTCALL(args, i) args[i]
    #define __Pyx_NumKwargs_FASTCALL(kwds) PyTuple_GET_SIZE(kwds)
    #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs))
    static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s);
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000
    CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues);
  #else
    #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw)
  #endif
    #define __Pyx_Arg_NewRef_FASTCALL(arg) arg  /* no-op, __Pyx_Arg_FASTCALL is direct and this needs
                                                   to have the same reference counting */
    #define __Pyx_Arg_XDECREF_FASTCALL(arg)
#else
    #define __Pyx_Arg_FASTCALL __Pyx_Arg_VARARGS
    #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS
    #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS
    #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS
    #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS
    #define __Pyx_Arg_NewRef_FASTCALL(arg) __Pyx_Arg_NewRef_VARARGS(arg)
    #define __Pyx_Arg_XDECREF_FASTCALL(arg) __Pyx_Arg_XDECREF_VARARGS(arg)
#endif
#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
#define __Pyx_ArgsSlice_VARARGS(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_VARARGS(args, start), stop - start)
#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(&__Pyx_Arg_FASTCALL(args, start), stop - start)
#else
#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop)
#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop)
#endif

/* RaiseDoubleKeywords.proto */
static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);

/* ParseKeywords.proto */
static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject *const *kwvalues,
    PyObject **argnames[],
    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,
    const char* function_name);

/* 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);

/* ArgTypeTest.proto */
#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\
    ((likely(__Pyx_IS_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);

/* 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

/* 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)  do {\
    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);\
} while(0)
#define __Pyx_GetModuleGlobalNameUncached(var, name)  do {\
    PY_UINT64_T __pyx_dict_version;\
    PyObject *__pyx_dict_cached_value;\
    (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\
} while(0)
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

/* PyFunctionFastCall.proto */
#if CYTHON_FAST_PYCALL
#if !CYTHON_VECTORCALL
#define __Pyx_PyFunction_FastCall(func, args, nargs)\
    __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL)
static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *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_VECTORCALL
#if PY_VERSION_HEX >= 0x03080000
  #include "frameobject.h"
#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
  #ifndef Py_BUILD_CORE
    #define Py_BUILD_CORE 1
  #endif
  #include "internal/pycore_frame.h"
#endif
  #define __Pxy_PyFrame_Initialize_Offsets()
  #define __Pyx_PyFrame_GetLocalsplus(frame)  ((frame)->f_localsplus)
#else
  static size_t __pyx_pyframe_localsplus_offset = 0;
  #include "frameobject.h"
  #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
#endif
#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

/* PyObjectFastCall.proto */
#define __Pyx_PyObject_FastCall(func, args, nargs)  __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL)
static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs);

/* PyUnicode_Unicode.proto */
static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj);

/* PyObjectCallOneArg.proto */
static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);

/* GetTopmostException.proto */
#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE
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

/* 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_repr(s) :\
        likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_repr(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

/* PyObjectLookupSpecial.proto */
#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
#define __Pyx_PyObject_LookupSpecialNoError(obj, attr_name)  __Pyx__PyObject_LookupSpecial(obj, attr_name, 0)
#define __Pyx_PyObject_LookupSpecial(obj, attr_name)  __Pyx__PyObject_LookupSpecial(obj, attr_name, 1)
static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error);
#else
#define __Pyx_PyObject_LookupSpecialNoError(o,n) __Pyx_PyObject_GetAttrStrNoError(o,n)
#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n)
#endif

/* RaiseUnboundLocalError.proto */
static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);

/* dict_getitem_default.proto */
static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value);

/* 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

/* CallUnboundCMethod2.proto */
static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2);
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030600B1
static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2);
#else
#define __Pyx_CallUnboundCMethod2(cfunc, self, arg1, arg2)  __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2)
#endif

/* JoinPyUnicode.proto */
static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength,
                                      Py_UCS4 max_char);

/* PyObject_Unicode.proto */
#if PY_MAJOR_VERSION >= 3
#define __Pyx_PyObject_Unicode(obj)\
    (likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Str(obj))
#else
#define __Pyx_PyObject_Unicode(obj)\
    (likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Unicode(obj))
#endif

/* GCCDiagnostics.proto */
#if !defined(__INTEL_COMPILER) && 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);

/* 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);

/* PySequenceContains.proto */
static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) {
    int result = PySequence_Contains(seq, item);
    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
}

/* DictGetItem.proto */
#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key);
#define __Pyx_PyObject_Dict_GetItem(obj, name)\
    (likely(PyDict_CheckExact(obj)) ?\
     __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name))
#else
#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
#define __Pyx_PyObject_Dict_GetItem(obj, name)  PyObject_GetItem(obj, name)
#endif

/* RaiseUnexpectedTypeError.proto */
static int __Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj);

/* PyIntBinop.proto */
#if !CYTHON_COMPILING_IN_PYPY
static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check);
#else
#define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace, zerodivision_check)\
    (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2))
#endif

/* ListAppend.proto */
#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS
static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
    PyListObject* L = (PyListObject*) list;
    Py_ssize_t len = Py_SIZE(list);
    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
        Py_INCREF(x);
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000
        L->ob_item[len] = x;
        #else
        PyList_SET_ITEM(list, len, x);
        #endif
        __Pyx_SET_SIZE(list, len + 1);
        return 0;
    }
    return PyList_Append(list, x);
}
#else
#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
#endif

/* Import.proto */
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);

/* ImportDottedModule.proto */
static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple);
#if PY_MAJOR_VERSION >= 3
static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple);
#endif

/* PyObjectCall2Args.proto */
static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2);

/* PyObjectGetMethod.proto */
static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);

/* PyObjectCallMethod1.proto */
static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg);

/* append.proto */
static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x);

/* PyIntBinop.proto */
#if !CYTHON_COMPILING_IN_PYPY
static PyObject* __Pyx_PyInt_SubtractObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check);
#else
#define __Pyx_PyInt_SubtractObjC(op1, op2, intval, inplace, zerodivision_check)\
    (inplace ? PyNumber_InPlaceSubtract(op1, op2) : PyNumber_Subtract(op1, op2))
#endif

/* UnicodeConcatInPlace.proto */
# if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
    #if CYTHON_REFNANNY
        #define __Pyx_PyUnicode_ConcatInPlace(left, right) __Pyx_PyUnicode_ConcatInPlaceImpl(&left, right, __pyx_refnanny)
    #else
        #define __Pyx_PyUnicode_ConcatInPlace(left, right) __Pyx_PyUnicode_ConcatInPlaceImpl(&left, right)
    #endif
    static CYTHON_INLINE PyObject *__Pyx_PyUnicode_ConcatInPlaceImpl(PyObject **p_left, PyObject *right
        #if CYTHON_REFNANNY
        , void* __pyx_refnanny
        #endif
    );
#else
#define __Pyx_PyUnicode_ConcatInPlace __Pyx_PyUnicode_Concat
#endif
#define __Pyx_PyUnicode_ConcatInPlaceSafe(left, right) ((unlikely((left) == Py_None) || unlikely((right) == Py_None)) ?\
    PyNumber_InPlaceAdd(left, right) : __Pyx_PyUnicode_ConcatInPlace(left, right))

/* SliceObject.proto */
static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
        int has_cstart, int has_cstop, int wraparound);

/* RaiseTooManyValuesToUnpack.proto */
static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);

/* RaiseNeedMoreValuesToUnpack.proto */
static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);

/* IterFinish.proto */
static CYTHON_INLINE int __Pyx_IterFinish(void);

/* UnpackItemEndCheck.proto */
static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);

/* RaiseClosureNameError.proto */
static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);

/* CallUnboundCMethod0.proto */
static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self);
#if CYTHON_COMPILING_IN_CPYTHON
#define __Pyx_CallUnboundCMethod0(cfunc, self)\
    (likely((cfunc)->func) ?\
        (likely((cfunc)->flag == METH_NOARGS) ?  (*((cfunc)->func))(self, NULL) :\
         (PY_VERSION_HEX >= 0x030600B1 && likely((cfunc)->flag == METH_FASTCALL) ?\
            (PY_VERSION_HEX >= 0x030700A0 ?\
                (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)(cfunc)->func)(self, &__pyx_empty_tuple, 0) :\
                (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, &__pyx_empty_tuple, 0, NULL)) :\
          (PY_VERSION_HEX >= 0x030700A0 && (cfunc)->flag == (METH_FASTCALL | METH_KEYWORDS) ?\
            (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, &__pyx_empty_tuple, 0, NULL) :\
            (likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ?  ((*(PyCFunctionWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, __pyx_empty_tuple, NULL)) :\
               ((cfunc)->flag == METH_VARARGS ?  (*((cfunc)->func))(self, __pyx_empty_tuple) :\
               __Pyx__CallUnboundCMethod0(cfunc, self)))))) :\
        __Pyx__CallUnboundCMethod0(cfunc, self))
#else
#define __Pyx_CallUnboundCMethod0(cfunc, self)  __Pyx__CallUnboundCMethod0(cfunc, self)
#endif

/* pep479.proto */
static void __Pyx_Generator_Replace_StopIteration(int in_async_gen);

/* 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);

/* PyObjectCallNoArg.proto */
static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);

/* PyObjectCallMethod0.proto */
static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name);

/* 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);

/* 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);
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000
        L->ob_item[len] = x;
        #else
        PyList_SET_ITEM(list, len, x);
        #endif
        __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

/* PyDictContains.proto */
static CYTHON_INLINE int __Pyx_PyDict_ContainsTF(PyObject* item, PyObject* dict, int eq) {
    int result = PyDict_Contains(dict, item);
    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
}

/* PyIntCompare.proto */
static CYTHON_INLINE int __Pyx_PyInt_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace);

/* unicode_tailmatch.proto */
static int __Pyx_PyUnicode_Tailmatch(
    PyObject* s, PyObject* substr, Py_ssize_t start, Py_ssize_t end, int direction);

/* IncludeStructmemberH.proto */
#include <structmember.h>

/* FixUpExtensionType.proto */
#if CYTHON_USE_TYPE_SPECS
static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type);
#endif

/* ValidateBasesTuple.proto */
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS
static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases);
#endif

/* PyType_Ready.proto */
CYTHON_UNUSED static int __Pyx_PyType_Ready(PyTypeObject *t);

/* 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

/* ImportFrom.proto */
static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);

/* FetchSharedCythonModule.proto */
static PyObject *__Pyx_FetchSharedCythonABIModule(void);

/* FetchCommonType.proto */
#if !CYTHON_USE_TYPE_SPECS
static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
#else
static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases);
#endif

/* PyMethodNew.proto */
#if CYTHON_COMPILING_IN_LIMITED_API
static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) {
    PyObject *typesModule=NULL, *methodType=NULL, *result=NULL;
    CYTHON_UNUSED_VAR(typ);
    if (!self)
        return __Pyx_NewRef(func);
    typesModule = PyImport_ImportModule("types");
    if (!typesModule) return NULL;
    methodType = PyObject_GetAttrString(typesModule, "MethodType");
    Py_DECREF(typesModule);
    if (!methodType) return NULL;
    result = PyObject_CallFunctionObjArgs(methodType, func, self, NULL);
    Py_DECREF(methodType);
    return result;
}
#elif PY_MAJOR_VERSION >= 3
static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) {
    CYTHON_UNUSED_VAR(typ);
    if (!self)
        return __Pyx_NewRef(func);
    return PyMethod_New(func, self);
}
#else
    #define __Pyx_PyMethod_New PyMethod_New
#endif

/* PyVectorcallFastCallDict.proto */
#if CYTHON_METH_FASTCALL
static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw);
#endif

/* CythonFunctionShared.proto */
#define __Pyx_CyFunction_USED
#define __Pyx_CYFUNCTION_STATICMETHOD  0x01
#define __Pyx_CYFUNCTION_CLASSMETHOD   0x02
#define __Pyx_CYFUNCTION_CCLASS        0x04
#define __Pyx_CYFUNCTION_COROUTINE     0x08
#define __Pyx_CyFunction_GetClosure(f)\
    (((__pyx_CyFunctionObject *) (f))->func_closure)
#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API
  #define __Pyx_CyFunction_GetClassObj(f)\
      (((__pyx_CyFunctionObject *) (f))->func_classobj)
#else
  #define __Pyx_CyFunction_GetClassObj(f)\
      ((PyObject*) ((PyCMethodObject *) (f))->mm_class)
#endif
#define __Pyx_CyFunction_SetClassObj(f, classobj)\
    __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (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 {
#if CYTHON_COMPILING_IN_LIMITED_API
    PyObject_HEAD
    PyObject *func;
#elif PY_VERSION_HEX < 0x030900B1
    PyCFunctionObject func;
#else
    PyCMethodObject func;
#endif
#if CYTHON_BACKPORT_VECTORCALL
    __pyx_vectorcallfunc func_vectorcall;
#endif
#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API
    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;
#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API
    PyObject *func_classobj;
#endif
    void *defaults;
    int defaults_pyobjects;
    size_t defaults_size;
    int flags;
    PyObject *defaults_tuple;
    PyObject *defaults_kwdict;
    PyObject *(*defaults_getter)(PyObject *);
    PyObject *func_annotations;
    PyObject *func_is_coroutine;
} __pyx_CyFunctionObject;
#undef __Pyx_CyOrPyCFunction_Check
#define __Pyx_CyFunction_Check(obj)  __Pyx_TypeCheck(obj, __pyx_CyFunctionType)
#define __Pyx_CyOrPyCFunction_Check(obj)  __Pyx_TypeCheck2(obj, __pyx_CyFunctionType, &PyCFunction_Type)
#define __Pyx_CyFunction_CheckExact(obj)  __Pyx_IS_TYPE(obj, __pyx_CyFunctionType)
static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc);
#undef __Pyx_IsSameCFunction
#define __Pyx_IsSameCFunction(func, cfunc)   __Pyx__IsSameCyOrCFunction(func, cfunc)
static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml,
                                      int flags, PyObject* qualname,
                                      PyObject *closure,
                                      PyObject *module, PyObject *globals,
                                      PyObject* code);
static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj);
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(PyObject *module);
#if CYTHON_METH_FASTCALL
static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames);
#if CYTHON_BACKPORT_VECTORCALL
#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall)
#else
#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall)
#endif
#endif

/* CythonFunction.proto */
static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml,
                                      int flags, PyObject* qualname,
                                      PyObject *closure,
                                      PyObject *module, PyObject *globals,
                                      PyObject* code);

/* SetNameInClass.proto */
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && PY_VERSION_HEX < 0x030d0000
#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

/* CalculateMetaclass.proto */
static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases);

/* 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);

/* 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 */
#if !CYTHON_COMPILING_IN_LIMITED_API
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);
#endif

/* 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_long(long value);

/* FormatTypeName.proto */
#if CYTHON_COMPILING_IN_LIMITED_API
typedef PyObject *__Pyx_TypeName;
#define __Pyx_FMT_TYPENAME "%U"
static __Pyx_TypeName __Pyx_PyType_GetName(PyTypeObject* tp);
#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj)
#else
typedef const char *__Pyx_TypeName;
#define __Pyx_FMT_TYPENAME "%.200s"
#define __Pyx_PyType_GetName(tp) ((tp)->tp_name)
#define __Pyx_DECREF_TypeName(obj)
#endif

/* CIntFromPy.proto */
static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);

/* CIntFromPy.proto */
static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);

/* FastTypeChecks.proto */
#if CYTHON_COMPILING_IN_CPYTHON
#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type)
#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2)
static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b);
static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, 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_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2))
#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_PyErr_ExceptionMatches2(err1, err2)  __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2)
#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception)

/* RaiseException.proto */
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);

/* CoroutineBase.proto */
struct __pyx_CoroutineObject;
typedef PyObject *(*__pyx_coroutine_body_t)(struct __pyx_CoroutineObject *, PyThreadState *, PyObject *);
#if CYTHON_USE_EXC_INFO_STACK
#define __Pyx_ExcInfoStruct  _PyErr_StackItem
#else
typedef struct {
    PyObject *exc_type;
    PyObject *exc_value;
    PyObject *exc_traceback;
} __Pyx_ExcInfoStruct;
#endif
typedef struct __pyx_CoroutineObject {
    PyObject_HEAD
    __pyx_coroutine_body_t body;
    PyObject *closure;
    __Pyx_ExcInfoStruct gi_exc_state;
    PyObject *gi_weakreflist;
    PyObject *classobj;
    PyObject *yieldfrom;
    PyObject *gi_name;
    PyObject *gi_qualname;
    PyObject *gi_modulename;
    PyObject *gi_code;
    PyObject *gi_frame;
    int resume_label;
    char is_running;
} __pyx_CoroutineObject;
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
    PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
    PyObject *name, PyObject *qualname, PyObject *module_name);
static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
            __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
            PyObject *name, PyObject *qualname, PyObject *module_name);
static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self);
static int __Pyx_Coroutine_clear(PyObject *self);
static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value);
static PyObject *__Pyx_Coroutine_Close(PyObject *self);
static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args);
#if CYTHON_USE_EXC_INFO_STACK
#define __Pyx_Coroutine_SwapException(self)
#define __Pyx_Coroutine_ResetAndClearException(self)  __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state)
#else
#define __Pyx_Coroutine_SwapException(self) {\
    __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\
    __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\
    }
#define __Pyx_Coroutine_ResetAndClearException(self) {\
    __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\
    (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\
    }
#endif
#if CYTHON_FAST_THREAD_STATE
#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\
    __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue)
#else
#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\
    __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue)
#endif
static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue);
static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state);

/* PatchModuleWithCoroutine.proto */
static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code);

/* PatchGeneratorABC.proto */
static int __Pyx_patch_abc(void);

/* Generator.proto */
#define __Pyx_Generator_USED
#define __Pyx_Generator_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_GeneratorType)
#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)\
    __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name)
static PyObject *__Pyx_Generator_Next(PyObject *self);
static int __pyx_Generator_init(PyObject *module);

/* CheckBinaryVersion.proto */
static unsigned long __Pyx_get_runtime_version(void);
static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer);

/* InitStrings.proto */
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);

/* #### Code section: module_declarations ### */

/* Module declarations from "sQQideR.SQLBuilder" */
/* #### Code section: typeinfo ### */
/* #### Code section: before_global_var ### */
#define __Pyx_MODULE_NAME "sQQideR.SQLBuilder"
extern int __pyx_module_is_main_sQQideR__SQLBuilder;
int __pyx_module_is_main_sQQideR__SQLBuilder = 0;

/* Implementation of "sQQideR.SQLBuilder" */
/* #### Code section: global_var ### */
static PyObject *__pyx_builtin_print;
static PyObject *__pyx_builtin_open;
static PyObject *__pyx_builtin_range;
static PyObject *__pyx_builtin_enumerate;
/* #### Code section: string_decls ### */
static const char __pyx_k_b[] = "\\b";
static const char __pyx_k_e[] = "e";
static const char __pyx_k_f[] = "f";
static const char __pyx_k_i[] = "i";
static const char __pyx_k_r[] = "r";
static const char __pyx_k_w[] = "w";
static const char __pyx_k_ON[] = " ON ";
static const char __pyx_k__7[] = "";
static const char __pyx_k__9[] = "*";
static const char __pyx_k_ai[] = "ai";
static const char __pyx_k_df[] = "df";
static const char __pyx_k_gc[] = "gc";
static const char __pyx_k_or[] = " or ";
static const char __pyx_k_os[] = "os";
static const char __pyx_k_pd[] = "pd";
static const char __pyx_k_pk[] = "pk";
static const char __pyx_k_re[] = "re";
static const char __pyx_k_to[] = " to ";
static const char __pyx_k_AVG[] = "AVG(";
static const char __pyx_k_Any[] = "Any";
static const char __pyx_k_MAX[] = "MAX(";
static const char __pyx_k_MIN[] = "MIN(";
static const char __pyx_k_SQL[] = "SQL: ";
static const char __pyx_k__13[] = ": ";
static const char __pyx_k__14[] = "\n";
static const char __pyx_k__15[] = "- ";
static const char __pyx_k__16[] = " (";
static const char __pyx_k__17[] = ")\n";
static const char __pyx_k__23[] = ":\n";
static const char __pyx_k__26[] = ");";
static const char __pyx_k__29[] = ".";
static const char __pyx_k__30[] = ", ";
static const char __pyx_k__31[] = "=";
static const char __pyx_k__32[] = "): ";
static const char __pyx_k__34[] = "\n\n";
static const char __pyx_k__35[] = " ";
static const char __pyx_k__69[] = "_";
static const char __pyx_k__90[] = "?";
static const char __pyx_k_and[] = " and ";
static const char __pyx_k_col[] = "col";
static const char __pyx_k_day[] = "day";
static const char __pyx_k_doc[] = "__doc__";
static const char __pyx_k_get[] = "get";
static const char __pyx_k_now[] = "now";
static const char __pyx_k_rel[] = "rel";
static const char __pyx_k_row[] = "row";
static const char __pyx_k_sql[] = "sql";
static const char __pyx_k_str[] = "str";
static const char __pyx_k_val[] = "val";
static const char __pyx_k_Dict[] = "Dict";
static const char __pyx_k_FROM[] = " FROM ";
static const char __pyx_k_JOIN[] = " JOIN ";
static const char __pyx_k_List[] = "List";
static const char __pyx_k_None[] = "None";
static const char __pyx_k_args[] = "args";
static const char __pyx_k_bool[] = "bool";
static const char __pyx_k_conn[] = "conn";
static const char __pyx_k_data[] = "data";
static const char __pyx_k_date[] = "date";
static const char __pyx_k_dict[] = "__dict__";
static const char __pyx_k_drop[] = "drop";
static const char __pyx_k_dump[] = "dump";
static const char __pyx_k_exit[] = "__exit__";
static const char __pyx_k_head[] = "head";
static const char __pyx_k_info[] = "info";
static const char __pyx_k_init[] = "__init__";
static const char __pyx_k_join[] = "join";
static const char __pyx_k_json[] = "json";
static const char __pyx_k_link[] = "link";
static const char __pyx_k_load[] = "load";
static const char __pyx_k_main[] = "__main__";
static const char __pyx_k_name[] = "name";
static const char __pyx_k_open[] = "open";
static const char __pyx_k_path[] = "path";
static const char __pyx_k_plus[] = "\n...\n(plus ";
static const char __pyx_k_prev[] = "prev";
static const char __pyx_k_self[] = "self";
static const char __pyx_k_send[] = "send";
static const char __pyx_k_spec[] = "__spec__";
static const char __pyx_k_test[] = "__test__";
static const char __pyx_k_text[] = "text";
static const char __pyx_k_time[] = "time";
static const char __pyx_k_type[] = "type";
static const char __pyx_k_Error[] = "Error: ";
static const char __pyx_k_Query[] = "\nQuery: ";
static const char __pyx_k_Table[] = "\nTable: ";
static const char __pyx_k_Tuple[] = "Tuple";
static const char __pyx_k_Union[] = "Union";
static const char __pyx_k_alter[] = "alter";
static const char __pyx_k_block[] = "block";
static const char __pyx_k_close[] = "close";
static const char __pyx_k_count[] = "count";
static const char __pyx_k_dumps[] = "dumps";
static const char __pyx_k_empty[] = "empty";
static const char __pyx_k_enter[] = "__enter__";
static const char __pyx_k_entry[] = "entry";
static const char __pyx_k_error[] = "error";
static const char __pyx_k_float[] = "float";
static const char __pyx_k_group[] = "group";
static const char __pyx_k_items[] = "items";
static const char __pyx_k_log_e[] = "log_e";
static const char __pyx_k_lower[] = "lower";
static const char __pyx_k_match[] = "match";
static const char __pyx_k_parts[] = "parts";
static const char __pyx_k_print[] = "print";
static const char __pyx_k_query[] = "query";
static const char __pyx_k_range[] = "range";
static const char __pyx_k_score[] = "score";
static const char __pyx_k_split[] = "split";
static const char __pyx_k_sql_s[] = "```(?:sql)?\\s*(.*?)```";
static const char __pyx_k_strip[] = "strip";
static const char __pyx_k_super[] = "super";
static const char __pyx_k_table[] = " table";
static const char __pyx_k_throw[] = "throw";
static const char __pyx_k_utf_8[] = "utf-8";
static const char __pyx_k_where[] = "where";
static const char __pyx_k_AS_avg[] = ") AS avg_";
static const char __pyx_k_AS_max[] = ") AS max_";
static const char __pyx_k_AS_min[] = ") AS min_";
static const char __pyx_k_DOTALL[] = "DOTALL";
static const char __pyx_k_No_SQL[] = "No SQL";
static const char __pyx_k_Reason[] = "Reason: ";
static const char __pyx_k_Result[] = "Result: ";
static const char __pyx_k_SELECT[] = "SELECT ";
static const char __pyx_k_append[] = "append";
static const char __pyx_k_attach[] = "attach ";
static const char __pyx_k_column[] = " column";
static const char __pyx_k_create[] = "create ";
static const char __pyx_k_delete[] = "delete";
static const char __pyx_k_detach[] = "detach ";
static const char __pyx_k_enable[] = "enable";
static const char __pyx_k_escape[] = "escape";
static const char __pyx_k_exists[] = "exists";
static const char __pyx_k_import[] = "__import__";
static const char __pyx_k_indent[] = "indent";
static const char __pyx_k_insert[] = "insert";
static const char __pyx_k_module[] = "__module__";
static const char __pyx_k_name_2[] = "__name__";
static const char __pyx_k_orient[] = "orient";
static const char __pyx_k_pandas[] = "pandas";
static const char __pyx_k_pragma[] = "pragma";
static const char __pyx_k_prompt[] = "prompt";
static const char __pyx_k_result[] = "result";
static const char __pyx_k_return[] = "return";
static const char __pyx_k_sample[] = "sample";
static const char __pyx_k_search[] = "search";
static const char __pyx_k_select[] = "select ";
static const char __pyx_k_source[] = "source";
static const char __pyx_k_tables[] = "tables";
static const char __pyx_k_target[] = "target";
static const char __pyx_k_typing[] = "typing";
static const char __pyx_k_update[] = "update";
static const char __pyx_k_vacuum[] = "; vacuum";
static const char __pyx_k_Attempt[] = "\nAttempt #";
static const char __pyx_k_Columns[] = "Columns:\n";
static const char __pyx_k_LIMIT_3[] = " LIMIT 3;";
static const char __pyx_k_Results[] = "\n\nResults:\n";
static const char __pyx_k_Unknown[] = "Unknown";
static const char __pyx_k_ai_base[] = "ai_base";
static const char __pyx_k_attempt[] = "attempt";
static const char __pyx_k_b_w_4_b[] = "\\b\\w{4,}\\b";
static const char __pyx_k_between[] = "between";
static const char __pyx_k_columns[] = "columns";
static const char __pyx_k_connect[] = "connect";
static const char __pyx_k_disable[] = "disable";
static const char __pyx_k_findall[] = "findall";
static const char __pyx_k_genexpr[] = "genexpr";
static const char __pyx_k_message[] = "message";
static const char __pyx_k_notnull[] = "notnull";
static const char __pyx_k_overlap[] = "overlap";
static const char __pyx_k_pattern[] = "pattern";
static const char __pyx_k_prepare[] = "__prepare__";
static const char __pyx_k_records[] = "records";
static const char __pyx_k_results[] = "results";
static const char __pyx_k_sqlite3[] = "sqlite3";
static const char __pyx_k_success[] = "success";
static const char __pyx_k_summary[] = "summary";
static const char __pyx_k_table_2[] = "table";
static const char __pyx_k_to_dict[] = "to_dict";
static const char __pyx_k_verbose[] = "verbose";
static const char __pyx_k_GROUP_BY[] = " GROUP BY ";
static const char __pyx_k_List_str[] = "List[str]";
static const char __pyx_k_Optional[] = "Optional";
static const char __pyx_k_Question[] = "Question: ";
static const char __pyx_k_ai_query[] = "ai_query";
static const char __pyx_k_ai_score[] = "ai_score";
static const char __pyx_k_attempts[] = "attempts";
static const char __pyx_k_col_name[] = "col_name";
static const char __pyx_k_column_2[] = "column";
static const char __pyx_k_column_s[] = " column(s).";
static const char __pyx_k_date_col[] = "date_col";
static const char __pyx_k_encoding[] = "encoding";
static const char __pyx_k_exist_ok[] = "exist_ok";
static const char __pyx_k_finditer[] = "finditer";
static const char __pyx_k_iterrows[] = "iterrows";
static const char __pyx_k_main_sql[] = "main_sql";
static const char __pyx_k_makedirs[] = "makedirs";
static const char __pyx_k_num_cols[] = "num_cols";
static const char __pyx_k_num_rows[] = "num_rows";
static const char __pyx_k_qualname[] = "__qualname__";
static const char __pyx_k_question[] = "question";
static const char __pyx_k_relation[] = "relation";
static const char __pyx_k_response[] = "response";
static const char __pyx_k_set_name[] = "__set_name__";
static const char __pyx_k_truncate[] = "truncate";
static const char __pyx_k_List_Dict[] = "List[Dict]";
static const char __pyx_k_Timestamp[] = "Timestamp";
static const char __pyx_k_agg_parts[] = "agg_parts";
static const char __pyx_k_bSELECT_b[] = "\\bSELECT\\b";
static const char __pyx_k_data_type[] = "data_type";
static const char __pyx_k_enumerate[] = "enumerate";
static const char __pyx_k_error_msg[] = "error_msg";
static const char __pyx_k_file_path[] = "file_path";
static const char __pyx_k_fixed_sql[] = "fixed_sql";
static const char __pyx_k_isenabled[] = "isenabled";
static const char __pyx_k_isoformat[] = "isoformat";
static const char __pyx_k_left_side[] = "left_side";
static const char __pyx_k_metaclass[] = "__metaclass__";
static const char __pyx_k_more_rows[] = " more rows)";
static const char __pyx_k_operation[] = "operation";
static const char __pyx_k_row_count[] = "row_count";
static const char __pyx_k_sample_df[] = "sample_df";
static const char __pyx_k_sql_query[] = "sql_query";
static const char __pyx_k_succeeded[] = " succeeded!";
static const char __pyx_k_table_obj[] = "table_obj";
static const char __pyx_k_tables_df[] = "tables_df";
static const char __pyx_k_timestamp[] = "timestamp";
static const char __pyx_k_to_string[] = "to_string";
static const char __pyx_k_IGNORECASE[] = "IGNORECASE";
static const char __pyx_k_SQLBuilder[] = "SQLBuilder";
static const char __pyx_k_ai_success[] = "ai_success";
static const char __pyx_k_best_query[] = "best_query";
static const char __pyx_k_clean_text[] = "_clean_text";
static const char __pyx_k_column_obj[] = "column_obj";
static const char __pyx_k_columns_df[] = "columns_df";
static const char __pyx_k_comparison[] = "comparison";
static const char __pyx_k_conditions[] = "conditions";
static const char __pyx_k_db_context[] = "db_context";
static const char __pyx_k_failed_sql[] = "failed_sql";
static const char __pyx_k_hist_score[] = "hist_score";
static const char __pyx_k_historical[] = "historical";
static const char __pyx_k_main_query[] = "main_query";
static const char __pyx_k_name_parts[] = "name_parts";
static const char __pyx_k_retry_info[] = "retry_info";
static const char __pyx_k_right_side[] = "right_side";
static const char __pyx_k_row_s_with[] = " row(s) with ";
static const char __pyx_k_table_info[] = "table_info";
static const char __pyx_k_table_name[] = "table_name";
static const char __pyx_k_test_query[] = "test_query";
static const char __pyx_k_time_query[] = "time_query";
static const char __pyx_k_EXPLANATION[] = "EXPLANATION:(.*?)(?:$|```)";
static const char __pyx_k_SELECT_FROM[] = "SELECT * FROM ";
static const char __pyx_k_Sample_data[] = "Sample data: ";
static const char __pyx_k_cleaned_sql[] = "cleaned_sql";
static const char __pyx_k_code_blocks[] = "code_blocks";
static const char __pyx_k_count_query[] = "count_query";
static const char __pyx_k_description[] = "description";
static const char __pyx_k_explanation[] = "explanation";
static const char __pyx_k_fixed_query[] = "fixed_query";
static const char __pyx_k_sample_data[] = "sample_data";
static const char __pyx_k_schema_info[] = "schema_info";
static const char __pyx_k_table_names[] = "table_names";
static const char __pyx_k_tables_used[] = "tables_used";
static const char __pyx_k_working_sql[] = "working_sql";
static const char __pyx_k_Optional_str[] = "Optional[str]";
static const char __pyx_k_ai_generated[] = "ai_generated";
static const char __pyx_k_best_attempt[] = "best_attempt";
static const char __pyx_k_column_count[] = "column_count";
static const char __pyx_k_date_columns[] = "date_columns";
static const char __pyx_k_existing_sql[] = "existing_sql";
static const char __pyx_k_explorations[] = "explorations";
static const char __pyx_k_failed_query[] = "failed_query";
static const char __pyx_k_first_result[] = "first_result";
static const char __pyx_k_from_matches[] = "from_matches";
static const char __pyx_k_from_pattern[] = "from_pattern";
static const char __pyx_k_generate_sql[] = "generate_sql";
static const char __pyx_k_initializing[] = "_initializing";
static const char __pyx_k_intersection[] = "intersection";
static const char __pyx_k_is_coroutine[] = "_is_coroutine";
static const char __pyx_k_join_matches[] = "join_matches";
static const char __pyx_k_join_pattern[] = "join_pattern";
static const char __pyx_k_max_attempts[] = "max_attempts";
static const char __pyx_k_original_sql[] = "original_sql";
static const char __pyx_k_pd_DataFrame[] = "pd.DataFrame";
static const char __pyx_k_pragma_query[] = "pragma_query";
static const char __pyx_k_sample_query[] = "sample_query";
static const char __pyx_k_tables_query[] = "tables_query";
static const char __pyx_k_tested_query[] = "tested_query";
static const char __pyx_k_ERROR_MESSAGE[] = "\n\nERROR MESSAGE:\n";
static const char __pyx_k_Optional_Dict[] = "Optional[Dict]";
static const char __pyx_k_Retry_attempt[] = "Retry attempt #";
static const char __pyx_k_Unknown_error[] = "Unknown error";
static const char __pyx_k_clear_history[] = "clear_history";
static const char __pyx_k_database_path[] = "database_path";
static const char __pyx_k_existing_logs[] = "existing_logs";
static const char __pyx_k_init_subclass[] = "__init_subclass__";
static const char __pyx_k_relationships[] = "relationships";
static const char __pyx_k_retry_attempt[] = "retry_attempt";
static const char __pyx_k_rows_returned[] = " rows returned";
static const char __pyx_k_No_description[] = "No description";
static const char __pyx_k_Original_error[] = "Original error: ";
static const char __pyx_k_Query_returned[] = "Query returned ";
static const char __pyx_k_direct_matches[] = "direct_matches";
static const char __pyx_k_join_condition[] = "join_condition";
static const char __pyx_k_normalized_sql[] = "normalized_sql";
static const char __pyx_k_original_error[] = "original_error";
static const char __pyx_k_read_sql_query[] = "read_sql_query";
static const char __pyx_k_Relevant_Tables[] = "\nRelevant Tables:\n";
static const char __pyx_k_column_keywords[] = "column_keywords";
static const char __pyx_k_compare_queries[] = "compare_queries";
static const char __pyx_k_execution_error[] = "execution_error";
static const char __pyx_k_failed_sql_json[] = "failed_sql.json";
static const char __pyx_k_numeric_columns[] = "numeric_columns";
static const char __pyx_k_raw_ai_response[] = "raw_ai_response";
static const char __pyx_k_Count_records_in[] = "Count records in ";
static const char __pyx_k_DATABASE_CONTEXT[] = "\n\nDATABASE CONTEXT:\n";
static const char __pyx_k_FROM_s_a_zA_Z0_9[] = "FROM\\s+([a-zA-Z0-9_]+)";
static const char __pyx_k_JOIN_s_a_zA_Z0_9[] = "JOIN\\s+([a-zA-Z0-9_]+)";
static const char __pyx_k_Relevant_Columns[] = "\nRelevant Columns:\n";
static const char __pyx_k_ai_retry_attempt[] = "ai_retry_attempt_";
static const char __pyx_k_cleaned_response[] = "cleaned_response";
static const char __pyx_k_close_connection[] = "close_connection";
static const char __pyx_k_connect_database[] = "connect_database";
static const char __pyx_k_database_objects[] = "database_objects";
static const char __pyx_k_historical_query[] = "historical_query";
static const char __pyx_k_stats_query_dict[] = "stats_query_dict";
static const char __pyx_k_validation_error[] = "validation_error";
static const char __pyx_k_PRAGMA_table_info[] = "PRAGMA table_info(";
static const char __pyx_k_SQLBuilder___init[] = "SQLBuilder.__init__";
static const char __pyx_k_check_same_thread[] = "check_same_thread";
static const char __pyx_k_explanation_match[] = "explanation_match";
static const char __pyx_k_exploration_stats[] = "exploration_stats";
static const char __pyx_k_get_response_sync[] = "get_response_sync";
static const char __pyx_k_original_question[] = "original_question";
static const char __pyx_k_previous_attempts[] = "previous_attempts";
static const char __pyx_k_question_keywords[] = "question_keywords";
static const char __pyx_k_recommended_query[] = "recommended_query";
static const char __pyx_k_validate_safe_sql[] = "_validate_safe_sql";
static const char __pyx_k_ai_relevance_score[] = "ai_relevance_score";
static const char __pyx_k_asyncio_coroutines[] = "asyncio.coroutines";
static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback";
static const char __pyx_k_code_block_pattern[] = "code_block_pattern";
static const char __pyx_k_direct_sql_pattern[] = "direct_sql_pattern";
static const char __pyx_k_historical_success[] = "historical_success";
static const char __pyx_k_relationship_query[] = "relationship_query";
static const char __pyx_k_sQQideR_SQLBuilder[] = "sQQideR.SQLBuilder";
static const char __pyx_k_COUNT_as_count_FROM[] = ", COUNT(*) as count FROM ";
static const char __pyx_k_Generated_fixed_SQL[] = "Generated fixed SQL: ";
static const char __pyx_k_Statistical_summary[] = "Statistical summary";
static const char __pyx_k_Table_Relationships[] = "\nTable Relationships:\n";
static const char __pyx_k_ai_query_retry_info[] = "ai_query_retry_info";
static const char __pyx_k_cleaned_explanation[] = "cleaned_explanation";
static const char __pyx_k_explanation_pattern[] = "explanation_pattern";
static const char __pyx_k_extract_explanation[] = "_extract_explanation";
static const char __pyx_k_extract_table_names[] = "_extract_table_names";
static const char __pyx_k_original_failed_sql[] = "original_failed_sql";
static const char __pyx_k_Asking_AI_to_fix_SQL[] = " - Asking AI to fix SQL";
static const char __pyx_k_Error_generating_SQL[] = "Error generating SQL: ";
static const char __pyx_k_SQL_fixed_on_attempt[] = "SQL fixed on attempt #";
static const char __pyx_k_Security_restriction[] = "Security restriction: ";
static const char __pyx_k_dangerous_operations[] = "dangerous_operations";
static const char __pyx_k_data_failed_sql_json[] = "data/failed_sql.json";
static const char __pyx_k_detailed_explanation[] = "detailed_explanation";
static const char __pyx_k_explore_table_schema[] = "_explore_table_schema";
static const char __pyx_k_has_historical_match[] = "has_historical_match";
static const char __pyx_k_previously_run_query[] = "previously_run_query";
static const char __pyx_k_try_fix_failed_query[] = "try_fix_failed_query";
static const char __pyx_k_Connected_to_database[] = "Connected to database: ";
static const char __pyx_k_Error_during_AI_retry[] = "Error during AI retry: ";
static const char __pyx_k_Error_executing_query[] = "Error executing query: ";
static const char __pyx_k_Error_exploring_table[] = "Error exploring table ";
static const char __pyx_k_No_SQL_query_provided[] = "No SQL query provided";
static const char __pyx_k_SELECT_COUNT_DISTINCT[] = "SELECT COUNT(DISTINCT ";
static const char __pyx_k_SQLBuilder_test_query[] = "SQLBuilder.test_query";
static const char __pyx_k_Time_distribution_for[] = "Time distribution for ";
static const char __pyx_k_recommendation_reason[] = "recommendation_reason";
static const char __pyx_k_relationship_keywords[] = "relationship_keywords";
static const char __pyx_k_Failed_to_generate_SQL[] = "Failed to generate SQL: ";
static const char __pyx_k_SQLBuilder__clean_text[] = "SQLBuilder._clean_text";
static const char __pyx_k_Sample_of_first_3_rows[] = "\n\nSample of first 3 rows:\n";
static const char __pyx_k_sQQideR_SQLBuilder_pyx[] = "sQQideR\\SQLBuilder.pyx";
static const char __pyx_k_Database_file_not_found[] = "Database file not found: ";
static const char __pyx_k_Failed_to_fix_SQL_after[] = "Failed to fix SQL after ";
static const char __pyx_k_SQLBuilder_generate_sql[] = "SQLBuilder.generate_sql";
static const char __pyx_k_Statistical_summary_for[] = "Statistical summary for ";
static const char __pyx_k_additional_explorations[] = "additional_explorations";
static const char __pyx_k_attempts_Original_error[] = " attempts. Original error: ";
static const char __pyx_k_explore_database_schema[] = "_explore_database_schema";
static const char __pyx_k_generate_result_summary[] = "_generate_result_summary";
static const char __pyx_k_reused_from_failed_json[] = "reused_from_failed_json";
static const char __pyx_k_evaluate_query_relevance[] = "_evaluate_query_relevance";
static const char __pyx_k_get_best_sql_and_results[] = "get_best_sql_and_results";
static const char __pyx_k_No_original_SQL_available[] = "No original SQL available";
static const char __pyx_k_Query_returned_no_results[] = "Query returned no results.";
static const char __pyx_k_extract_sql_from_response[] = "_extract_sql_from_response";
static const char __pyx_k_Database_connection_closed[] = "Database connection closed";
static const char __pyx_k_Error_during_retry_attempt[] = "Error during retry attempt #";
static const char __pyx_k_Relationship_count_between[] = "Relationship count between ";
static const char __pyx_k_Relevant_Tables_in_Context[] = "\nRelevant Tables in Context:\n";
static const char __pyx_k_SQLBuilder_compare_queries[] = "SQLBuilder.compare_queries";
static const char __pyx_k_historical_relevance_score[] = "historical_relevance_score";
static const char __pyx_k_DATABASE_SCHEMA_INFORMATION[] = "\n\nDATABASE SCHEMA INFORMATION:\n";
static const char __pyx_k_Failed_to_log_corrected_SQL[] = "Failed to log corrected SQL: ";
static const char __pyx_k_ORDER_BY_COUNT_DESC_LIMIT_5[] = " ORDER BY COUNT(*) DESC LIMIT 5";
static const char __pyx_k_Query_executed_successfully[] = "Query executed successfully: ";
static const char __pyx_k_SQLBuilder_close_connection[] = "SQLBuilder.close_connection";
static const char __pyx_k_SQLBuilder_connect_database[] = "SQLBuilder.connect_database";
static const char __pyx_k_n_SELECT_s_n_n_nEXPLANATION[] = "(?:^|\\n)(SELECT\\s+.*?)((?:\\n\\n)|$|(?:\\nEXPLANATION:))";
static const char __pyx_k_Error_connecting_to_database[] = "Error connecting to database: ";
static const char __pyx_k_PREVIOUS_CORRECTION_ATTEMPTS[] = "\nPREVIOUS CORRECTION ATTEMPTS:\n";
static const char __pyx_k_as_distinct_connections_FROM[] = ") as distinct_connections FROM ";
static const char __pyx_k_create_sql_correction_prompt[] = "_create_sql_correction_prompt";
static const char __pyx_k_create_sql_generation_prompt[] = "_create_sql_generation_prompt";
static const char __pyx_k_Failed_to_check_existing_logs[] = "Failed to check existing logs: ";
static const char __pyx_k_SQLBuilder__validate_safe_sql[] = "SQLBuilder._validate_safe_sql";
static const char __pyx_k_Class_for_building_and_testing[] = "\n    Class for building and testing SQL queries using AI and historical data.\n    ";
static const char __pyx_k_ORIGINAL_SQL_QUERY_THAT_FAILED[] = "\n\nORIGINAL SQL QUERY THAT FAILED:\n";
static const char __pyx_k_Table_Relationships_in_Context[] = "\nTable Relationships in Context:\n";
static const char __pyx_k_AI_generated_query_appears_more[] = "AI-generated query appears more relevant to the question";
static const char __pyx_k_Blocked_dangerous_SQL_operation[] = "Blocked dangerous SQL operation: ";
static const char __pyx_k_DROP_operations_are_not_allowed[] = "DROP operations are not allowed";
static const char __pyx_k_Error_exploring_database_schema[] = "Error exploring database schema: ";
static const char __pyx_k_INSTRUCTIONS_1_Generate_a_valid[] = "\nINSTRUCTIONS:\n1. Generate a valid SQL query that answers the question using the provided database context\n2. Use proper joins based on the relationships provided\n3. Return ONLY the SQL query without any explanations or markdown formatting\n4. After the SQL, add a brief explanation of how the query works separated by \"EXPLANATION:\"\n\nRemember to use standard SQL syntax compatible with SQLite.\n";
static const char __pyx_k_PREVIOUSLY_RUN_QUERY_FOR_SIMILA[] = "\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n";
static const char __pyx_k_Previous_SQL_attempt_failed_wit[] = "'. Previous SQL attempt failed with error: '";
static const char __pyx_k_SQLBuilder_Responsible_for_cons[] = "\nSQLBuilder - Responsible for constructing SQL queries based on the DatabaseContext\n\nThis class handles:\n1. Generating SQL queries using AI models\n2. Testing queries against the database\n3. Comparing AI-generated queries with historical queries\n4. Determining which query best answers the user's question\n";
static const char __pyx_k_SQLBuilder__extract_explanation[] = "SQLBuilder._extract_explanation";
static const char __pyx_k_SQLBuilder__extract_table_names[] = "SQLBuilder._extract_table_names";
static const char __pyx_k_SQLBuilder_try_fix_failed_query[] = "SQLBuilder.try_fix_failed_query";
static const char __pyx_k_SQL_Query_Builder_only_supports[] = ". SQL Query Builder only supports SELECT operations.";
static const char __pyx_k_Shows_the_number_of_connections[] = "Shows the number of connections between ";
static const char __pyx_k_TASK_1_Analyze_the_error_messag[] = "\nTASK:\n1. Analyze the error message and schema information carefully\n2. Identify what's wrong with the original SQL query\n3. Fix the query to resolve the error\n4. Make sure your SQL is compatible with SQLite syntax\n5. Return ONLY the corrected SQL query without any explanations or markdown formatting\n6. After the SQL, add a brief explanation separated by \"EXPLANATION:\"\n\nCommon mistakes to check for:\n- Table names might be incorrect or non-existent\n- Column names might be incorrect or non-existent\n- Join conditions might reference wrong tables or columns\n- SQLite syntax differences (e.g., no TOP keyword, use LIMIT instead)\n- Case sensitivity issues in table or column names\n- Missing quotes around string values\n- Incorrect date formats\n";
static const char __pyx_k_This_working_SQL_has_been_verif[] = "'. This working SQL has been verified to execute successfully.";
static const char __pyx_k_You_are_an_expert_SQL_developer[] = "You are an expert SQL developer tasked with fixing a failed SQL query.\n\nORIGINAL QUESTION: ";
static const char __pyx_k_AI_service_not_available_for_SQL[] = "AI service not available for SQL generation";
static const char __pyx_k_AI_service_or_database_connectio[] = "AI service or database connection not available";
static const char __pyx_k_ALTER_operations_are_not_allowed[] = "ALTER operations are not allowed";
static const char __pyx_k_ATTACH_DATABASE_operations_are_n[] = "ATTACH DATABASE operations are not allowed";
static const char __pyx_k_CREATE_operations_are_not_allowe[] = "CREATE operations are not allowed";
static const char __pyx_k_DELETE_operations_are_not_allowe[] = "DELETE operations are not allowed";
static const char __pyx_k_DETACH_DATABASE_operations_are_n[] = "DETACH DATABASE operations are not allowed";
static const char __pyx_k_Equal_relevance_using_historical[] = "Equal relevance, using historical query for consistency";
static const char __pyx_k_Error_executing_count_exploratio[] = "Error executing count exploration: ";
static const char __pyx_k_Error_executing_relationship_exp[] = "Error executing relationship exploration: ";
static const char __pyx_k_Error_executing_time_exploration[] = "Error executing time exploration: ";
static const char __pyx_k_Found_previous_working_SQL_for_t[] = "Found previous working SQL for this question/query, skipping AI call.";
static const char __pyx_k_Historical_query_appears_more_re[] = "Historical query appears more relevant to the question";
static const char __pyx_k_INSERT_operations_are_not_allowe[] = "INSERT operations are not allowed";
static const char __pyx_k_Neither_query_executed_successfu[] = "Neither query executed successfully";
static const char __pyx_k_No_database_connection_available[] = "No database connection available";
static const char __pyx_k_Only_AI_generated_query_executed[] = "Only AI-generated query executed successfully";
static const char __pyx_k_Only_historical_query_executed_s[] = "Only historical query executed successfully";
static const char __pyx_k_PRAGMA_operations_are_not_allowe[] = "PRAGMA operations are not allowed";
static const char __pyx_k_Query_comparison_complete_Recomm[] = "Query comparison complete. Recommended: ";
static const char __pyx_k_SELECT_COUNT_AS_record_count_FRO[] = "SELECT COUNT(*) AS record_count FROM ";
static const char __pyx_k_SELECT_name_FROM_sqlite_master_W[] = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';";
static const char __pyx_k_SQLBuilder__create_sql_correctio[] = "SQLBuilder._create_sql_correction_prompt";
static const char __pyx_k_SQLBuilder__create_sql_generatio[] = "SQLBuilder._create_sql_generation_prompt";
static const char __pyx_k_SQLBuilder__evaluate_query_relev[] = "SQLBuilder._evaluate_query_relevance";
static const char __pyx_k_SQLBuilder__explore_database_sch[] = "SQLBuilder._explore_database_schema";
static const char __pyx_k_SQLBuilder__explore_table_schema[] = "SQLBuilder._explore_table_schema";
static const char __pyx_k_SQLBuilder__extract_sql_from_res[] = "SQLBuilder._extract_sql_from_response";
static const char __pyx_k_SQLBuilder__generate_result_summ[] = "SQLBuilder._generate_result_summary";
static const char __pyx_k_SQLBuilder_generate_additional_e[] = "SQLBuilder.generate_additional_explorations.<locals>.genexpr";
static const char __pyx_k_SQLBuilder_get_best_sql_and_resu[] = "SQLBuilder.get_best_sql_and_results";
static const char __pyx_k_Security_restriction_Only_SELECT[] = "Security restriction: Only SELECT operations are allowed.";
static const char __pyx_k_Shows_the_distribution_of_values[] = "Shows the distribution of values in the ";
static const char __pyx_k_Shows_the_total_number_of_record[] = "Shows the total number of records in the ";
static const char __pyx_k_Statistical_summary_of_numeric_v[] = "Statistical summary of numeric values from the main query";
static const char __pyx_k_Stats_exploration_failed_and_cou[] = "Stats exploration failed and couldn't be fixed: ";
static const char __pyx_k_TRUNCATE_operations_are_not_allo[] = "TRUNCATE operations are not allowed";
static const char __pyx_k_This_SQL_was_reused_from_a_previ[] = "This SQL was reused from a previously logged successful fix. Original question: '";
static const char __pyx_k_UPDATE_operations_are_not_allowe[] = "UPDATE operations are not allowed";
static const char __pyx_k_VACUUM_operations_are_not_allowe[] = "VACUUM operations are not allowed";
static const char __pyx_k_You_should_strongly_consider_usi[] = "You should strongly consider using this previous query as a starting point, but adapt it to the current question if needed.\n";
static const char __pyx_k_generate_additional_explorations[] = "generate_additional_explorations";
static const char __pyx_k_You_are_an_expert_SQL_developer_2[] = "You are an expert SQL developer. Generate a SQL query to answer the following question:\n\nQUESTION: ";
static const char __pyx_k_SQLBuilder_generate_additional_e_2[] = "SQLBuilder.generate_additional_explorations";
/* #### Code section: decls ### */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_database_path, PyObject *__pyx_v_verbose, PyObject *__pyx_v_ai_base); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_2connect_database(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_database_path); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_4close_connection(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_6generate_sql(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_8test_query(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_query); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_10compare_queries(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_historical_query, PyObject *__pyx_v_ai_query, PyObject *__pyx_v_question); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_12get_best_sql_and_results(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context, PyObject *__pyx_v_historical_query); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_14try_fix_failed_query(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_failed_query, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_16_create_sql_correction_prompt(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_original_sql, PyObject *__pyx_v_error, PyObject *__pyx_v_schema_info, PyObject *__pyx_v_previous_attempts, PyObject *__pyx_v_db_context); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_18_explore_database_schema(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_20_explore_table_schema(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_table_name); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_22_extract_table_names(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_sql); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_genexpr(PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_24generate_additional_explorations(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_main_query, PyObject *__pyx_v_db_context); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_26_create_sql_generation_prompt(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_28_extract_sql_from_response(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_response); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_30_extract_explanation(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_response); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_32_generate_result_summary(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_df); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_34_evaluate_query_relevance(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_query, PyObject *__pyx_v_question); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_36_validate_safe_sql(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_sql); /* proto */
static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_38_clean_text(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_text); /* proto */
static PyObject *__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
static PyObject *__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
static __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_get = {0, 0, 0, 0, 0};
static __Pyx_CachedCFunction __pyx_umethod_PySet_Type_intersection = {0, 0, 0, 0, 0};
static __Pyx_CachedCFunction __pyx_umethod_PySet_Type_update = {0, 0, 0, 0, 0};
static __Pyx_CachedCFunction __pyx_umethod_PyUnicode_Type_lower = {0, 0, 0, 0, 0};
static __Pyx_CachedCFunction __pyx_umethod_PyUnicode_Type_strip = {0, 0, 0, 0, 0};
/* #### Code section: late_includes ### */
/* #### Code section: module_state ### */
typedef struct {
  PyObject *__pyx_d;
  PyObject *__pyx_b;
  PyObject *__pyx_cython_runtime;
  PyObject *__pyx_empty_tuple;
  PyObject *__pyx_empty_bytes;
  PyObject *__pyx_empty_unicode;
  #ifdef __Pyx_CyFunction_USED
  PyTypeObject *__pyx_CyFunctionType;
  #endif
  #ifdef __Pyx_FusedFunction_USED
  PyTypeObject *__pyx_FusedFunctionType;
  #endif
  #ifdef __Pyx_Generator_USED
  PyTypeObject *__pyx_GeneratorType;
  #endif
  #ifdef __Pyx_IterableCoroutine_USED
  PyTypeObject *__pyx_IterableCoroutineType;
  #endif
  #ifdef __Pyx_Coroutine_USED
  PyTypeObject *__pyx_CoroutineAwaitType;
  #endif
  #ifdef __Pyx_Coroutine_USED
  PyTypeObject *__pyx_CoroutineType;
  #endif
  #if CYTHON_USE_MODULE_STATE
  PyObject *__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations;
  PyObject *__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr;
  #endif
  PyTypeObject *__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations;
  PyTypeObject *__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr;
  PyObject *__pyx_kp_u_AI_generated_query_appears_more;
  PyObject *__pyx_kp_u_AI_service_not_available_for_SQL;
  PyObject *__pyx_kp_u_AI_service_or_database_connectio;
  PyObject *__pyx_kp_u_ALTER_operations_are_not_allowed;
  PyObject *__pyx_kp_u_AS_avg;
  PyObject *__pyx_kp_u_AS_max;
  PyObject *__pyx_kp_u_AS_min;
  PyObject *__pyx_kp_u_ATTACH_DATABASE_operations_are_n;
  PyObject *__pyx_kp_u_AVG;
  PyObject *__pyx_n_s_Any;
  PyObject *__pyx_kp_u_Asking_AI_to_fix_SQL;
  PyObject *__pyx_kp_u_Attempt;
  PyObject *__pyx_kp_u_Blocked_dangerous_SQL_operation;
  PyObject *__pyx_kp_u_COUNT_as_count_FROM;
  PyObject *__pyx_kp_u_CREATE_operations_are_not_allowe;
  PyObject *__pyx_kp_s_Class_for_building_and_testing;
  PyObject *__pyx_kp_u_Columns;
  PyObject *__pyx_kp_u_Connected_to_database;
  PyObject *__pyx_kp_u_Count_records_in;
  PyObject *__pyx_kp_u_DATABASE_CONTEXT;
  PyObject *__pyx_kp_u_DATABASE_SCHEMA_INFORMATION;
  PyObject *__pyx_kp_u_DELETE_operations_are_not_allowe;
  PyObject *__pyx_kp_u_DETACH_DATABASE_operations_are_n;
  PyObject *__pyx_n_s_DOTALL;
  PyObject *__pyx_kp_u_DROP_operations_are_not_allowed;
  PyObject *__pyx_kp_u_Database_connection_closed;
  PyObject *__pyx_kp_u_Database_file_not_found;
  PyObject *__pyx_n_s_Dict;
  PyObject *__pyx_kp_u_ERROR_MESSAGE;
  PyObject *__pyx_kp_u_EXPLANATION;
  PyObject *__pyx_kp_u_Equal_relevance_using_historical;
  PyObject *__pyx_kp_u_Error;
  PyObject *__pyx_kp_u_Error_connecting_to_database;
  PyObject *__pyx_kp_u_Error_during_AI_retry;
  PyObject *__pyx_kp_u_Error_during_retry_attempt;
  PyObject *__pyx_kp_u_Error_executing_count_exploratio;
  PyObject *__pyx_kp_u_Error_executing_query;
  PyObject *__pyx_kp_u_Error_executing_relationship_exp;
  PyObject *__pyx_kp_u_Error_executing_time_exploration;
  PyObject *__pyx_kp_u_Error_exploring_database_schema;
  PyObject *__pyx_kp_u_Error_exploring_table;
  PyObject *__pyx_kp_u_Error_generating_SQL;
  PyObject *__pyx_kp_u_FROM;
  PyObject *__pyx_kp_u_FROM_s_a_zA_Z0_9;
  PyObject *__pyx_kp_u_Failed_to_check_existing_logs;
  PyObject *__pyx_kp_u_Failed_to_fix_SQL_after;
  PyObject *__pyx_kp_u_Failed_to_generate_SQL;
  PyObject *__pyx_kp_u_Failed_to_log_corrected_SQL;
  PyObject *__pyx_kp_u_Found_previous_working_SQL_for_t;
  PyObject *__pyx_kp_u_GROUP_BY;
  PyObject *__pyx_kp_u_Generated_fixed_SQL;
  PyObject *__pyx_kp_u_Historical_query_appears_more_re;
  PyObject *__pyx_n_s_IGNORECASE;
  PyObject *__pyx_kp_u_INSERT_operations_are_not_allowe;
  PyObject *__pyx_kp_u_INSTRUCTIONS_1_Generate_a_valid;
  PyObject *__pyx_kp_u_JOIN;
  PyObject *__pyx_kp_u_JOIN_s_a_zA_Z0_9;
  PyObject *__pyx_kp_u_LIMIT_3;
  PyObject *__pyx_n_s_List;
  PyObject *__pyx_kp_s_List_Dict;
  PyObject *__pyx_kp_s_List_str;
  PyObject *__pyx_kp_u_MAX;
  PyObject *__pyx_kp_u_MIN;
  PyObject *__pyx_kp_u_Neither_query_executed_successfu;
  PyObject *__pyx_kp_u_No_SQL;
  PyObject *__pyx_kp_u_No_SQL_query_provided;
  PyObject *__pyx_kp_u_No_database_connection_available;
  PyObject *__pyx_kp_u_No_description;
  PyObject *__pyx_kp_u_No_original_SQL_available;
  PyObject *__pyx_n_s_None;
  PyObject *__pyx_kp_u_None;
  PyObject *__pyx_kp_u_ON;
  PyObject *__pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5;
  PyObject *__pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED;
  PyObject *__pyx_kp_u_Only_AI_generated_query_executed;
  PyObject *__pyx_kp_u_Only_historical_query_executed_s;
  PyObject *__pyx_n_s_Optional;
  PyObject *__pyx_kp_s_Optional_Dict;
  PyObject *__pyx_kp_s_Optional_str;
  PyObject *__pyx_kp_u_Original_error;
  PyObject *__pyx_kp_u_PRAGMA_operations_are_not_allowe;
  PyObject *__pyx_kp_u_PRAGMA_table_info;
  PyObject *__pyx_kp_u_PREVIOUSLY_RUN_QUERY_FOR_SIMILA;
  PyObject *__pyx_kp_u_PREVIOUS_CORRECTION_ATTEMPTS;
  PyObject *__pyx_kp_u_Previous_SQL_attempt_failed_wit;
  PyObject *__pyx_kp_u_Query;
  PyObject *__pyx_kp_u_Query_comparison_complete_Recomm;
  PyObject *__pyx_kp_u_Query_executed_successfully;
  PyObject *__pyx_kp_u_Query_returned;
  PyObject *__pyx_kp_u_Query_returned_no_results;
  PyObject *__pyx_kp_u_Question;
  PyObject *__pyx_kp_u_Reason;
  PyObject *__pyx_kp_u_Relationship_count_between;
  PyObject *__pyx_kp_u_Relevant_Columns;
  PyObject *__pyx_kp_u_Relevant_Tables;
  PyObject *__pyx_kp_u_Relevant_Tables_in_Context;
  PyObject *__pyx_kp_u_Result;
  PyObject *__pyx_kp_u_Results;
  PyObject *__pyx_kp_u_Retry_attempt;
  PyObject *__pyx_kp_u_SELECT;
  PyObject *__pyx_kp_u_SELECT_COUNT_AS_record_count_FRO;
  PyObject *__pyx_kp_u_SELECT_COUNT_DISTINCT;
  PyObject *__pyx_kp_u_SELECT_FROM;
  PyObject *__pyx_kp_u_SELECT_name_FROM_sqlite_master_W;
  PyObject *__pyx_kp_u_SQL;
  PyObject *__pyx_n_s_SQLBuilder;
  PyObject *__pyx_n_s_SQLBuilder___init;
  PyObject *__pyx_n_s_SQLBuilder__clean_text;
  PyObject *__pyx_n_s_SQLBuilder__create_sql_correctio;
  PyObject *__pyx_n_s_SQLBuilder__create_sql_generatio;
  PyObject *__pyx_n_s_SQLBuilder__evaluate_query_relev;
  PyObject *__pyx_n_s_SQLBuilder__explore_database_sch;
  PyObject *__pyx_n_s_SQLBuilder__explore_table_schema;
  PyObject *__pyx_n_s_SQLBuilder__extract_explanation;
  PyObject *__pyx_n_s_SQLBuilder__extract_sql_from_res;
  PyObject *__pyx_n_s_SQLBuilder__extract_table_names;
  PyObject *__pyx_n_s_SQLBuilder__generate_result_summ;
  PyObject *__pyx_n_s_SQLBuilder__validate_safe_sql;
  PyObject *__pyx_n_s_SQLBuilder_close_connection;
  PyObject *__pyx_n_s_SQLBuilder_compare_queries;
  PyObject *__pyx_n_s_SQLBuilder_connect_database;
  PyObject *__pyx_n_s_SQLBuilder_generate_additional_e;
  PyObject *__pyx_n_s_SQLBuilder_generate_additional_e_2;
  PyObject *__pyx_n_s_SQLBuilder_generate_sql;
  PyObject *__pyx_n_s_SQLBuilder_get_best_sql_and_resu;
  PyObject *__pyx_n_s_SQLBuilder_test_query;
  PyObject *__pyx_n_s_SQLBuilder_try_fix_failed_query;
  PyObject *__pyx_kp_u_SQL_Query_Builder_only_supports;
  PyObject *__pyx_kp_u_SQL_fixed_on_attempt;
  PyObject *__pyx_kp_u_Sample_data;
  PyObject *__pyx_kp_u_Sample_of_first_3_rows;
  PyObject *__pyx_kp_u_Security_restriction;
  PyObject *__pyx_kp_u_Security_restriction_Only_SELECT;
  PyObject *__pyx_kp_u_Shows_the_distribution_of_values;
  PyObject *__pyx_kp_u_Shows_the_number_of_connections;
  PyObject *__pyx_kp_u_Shows_the_total_number_of_record;
  PyObject *__pyx_kp_u_Statistical_summary;
  PyObject *__pyx_kp_u_Statistical_summary_for;
  PyObject *__pyx_kp_u_Statistical_summary_of_numeric_v;
  PyObject *__pyx_kp_u_Stats_exploration_failed_and_cou;
  PyObject *__pyx_kp_u_TASK_1_Analyze_the_error_messag;
  PyObject *__pyx_kp_u_TRUNCATE_operations_are_not_allo;
  PyObject *__pyx_kp_u_Table;
  PyObject *__pyx_kp_u_Table_Relationships;
  PyObject *__pyx_kp_u_Table_Relationships_in_Context;
  PyObject *__pyx_kp_u_This_SQL_was_reused_from_a_previ;
  PyObject *__pyx_kp_u_This_working_SQL_has_been_verif;
  PyObject *__pyx_kp_u_Time_distribution_for;
  PyObject *__pyx_n_s_Timestamp;
  PyObject *__pyx_n_s_Tuple;
  PyObject *__pyx_kp_u_UPDATE_operations_are_not_allowe;
  PyObject *__pyx_n_s_Union;
  PyObject *__pyx_n_u_Unknown;
  PyObject *__pyx_kp_u_Unknown_error;
  PyObject *__pyx_kp_u_VACUUM_operations_are_not_allowe;
  PyObject *__pyx_kp_u_You_are_an_expert_SQL_developer;
  PyObject *__pyx_kp_u_You_are_an_expert_SQL_developer_2;
  PyObject *__pyx_kp_u_You_should_strongly_consider_usi;
  PyObject *__pyx_kp_u__13;
  PyObject *__pyx_kp_u__14;
  PyObject *__pyx_kp_u__15;
  PyObject *__pyx_kp_u__16;
  PyObject *__pyx_kp_u__17;
  PyObject *__pyx_kp_u__23;
  PyObject *__pyx_kp_u__26;
  PyObject *__pyx_kp_u__29;
  PyObject *__pyx_kp_u__30;
  PyObject *__pyx_kp_u__31;
  PyObject *__pyx_kp_u__32;
  PyObject *__pyx_kp_u__34;
  PyObject *__pyx_kp_u__35;
  PyObject *__pyx_n_s__69;
  PyObject *__pyx_kp_u__7;
  PyObject *__pyx_n_s__9;
  PyObject *__pyx_n_s__90;
  PyObject *__pyx_n_s_additional_explorations;
  PyObject *__pyx_n_u_additional_explorations;
  PyObject *__pyx_n_s_agg_parts;
  PyObject *__pyx_n_u_ai;
  PyObject *__pyx_n_s_ai_base;
  PyObject *__pyx_n_u_ai_generated;
  PyObject *__pyx_n_s_ai_query;
  PyObject *__pyx_n_u_ai_query;
  PyObject *__pyx_n_u_ai_query_retry_info;
  PyObject *__pyx_n_u_ai_relevance_score;
  PyObject *__pyx_n_u_ai_retry_attempt;
  PyObject *__pyx_n_s_ai_score;
  PyObject *__pyx_n_u_ai_success;
  PyObject *__pyx_n_u_alter;
  PyObject *__pyx_kp_u_and;
  PyObject *__pyx_n_s_append;
  PyObject *__pyx_n_s_args;
  PyObject *__pyx_kp_u_as_distinct_connections_FROM;
  PyObject *__pyx_n_s_asyncio_coroutines;
  PyObject *__pyx_kp_u_attach;
  PyObject *__pyx_n_s_attempt;
  PyObject *__pyx_n_s_attempts;
  PyObject *__pyx_n_u_attempts;
  PyObject *__pyx_kp_u_attempts_Original_error;
  PyObject *__pyx_kp_u_b;
  PyObject *__pyx_kp_u_bSELECT_b;
  PyObject *__pyx_kp_u_b_w_4_b;
  PyObject *__pyx_n_s_best_attempt;
  PyObject *__pyx_n_u_best_attempt;
  PyObject *__pyx_n_u_best_query;
  PyObject *__pyx_n_u_between;
  PyObject *__pyx_n_s_block;
  PyObject *__pyx_n_s_bool;
  PyObject *__pyx_n_s_check_same_thread;
  PyObject *__pyx_n_s_clean_text;
  PyObject *__pyx_n_s_cleaned_explanation;
  PyObject *__pyx_n_s_cleaned_response;
  PyObject *__pyx_n_s_cleaned_sql;
  PyObject *__pyx_n_s_clear_history;
  PyObject *__pyx_n_s_cline_in_traceback;
  PyObject *__pyx_n_s_close;
  PyObject *__pyx_n_s_close_connection;
  PyObject *__pyx_n_s_code_block_pattern;
  PyObject *__pyx_n_s_code_blocks;
  PyObject *__pyx_n_s_col;
  PyObject *__pyx_n_s_col_name;
  PyObject *__pyx_kp_u_column;
  PyObject *__pyx_n_s_column_2;
  PyObject *__pyx_n_u_column_count;
  PyObject *__pyx_n_s_column_keywords;
  PyObject *__pyx_n_s_column_obj;
  PyObject *__pyx_kp_u_column_s;
  PyObject *__pyx_n_s_columns;
  PyObject *__pyx_n_u_columns;
  PyObject *__pyx_n_s_columns_df;
  PyObject *__pyx_n_s_compare_queries;
  PyObject *__pyx_n_s_comparison;
  PyObject *__pyx_n_u_comparison;
  PyObject *__pyx_n_s_conditions;
  PyObject *__pyx_n_s_conn;
  PyObject *__pyx_n_s_connect;
  PyObject *__pyx_n_u_connect;
  PyObject *__pyx_n_s_connect_database;
  PyObject *__pyx_n_s_count;
  PyObject *__pyx_n_s_count_query;
  PyObject *__pyx_kp_u_create;
  PyObject *__pyx_n_s_create_sql_correction_prompt;
  PyObject *__pyx_n_s_create_sql_generation_prompt;
  PyObject *__pyx_n_s_dangerous_operations;
  PyObject *__pyx_n_u_data;
  PyObject *__pyx_kp_u_data_failed_sql_json;
  PyObject *__pyx_n_s_data_type;
  PyObject *__pyx_n_u_data_type;
  PyObject *__pyx_n_u_database_objects;
  PyObject *__pyx_n_s_database_path;
  PyObject *__pyx_n_u_date;
  PyObject *__pyx_n_s_date_col;
  PyObject *__pyx_n_s_date_columns;
  PyObject *__pyx_n_u_day;
  PyObject *__pyx_n_s_db_context;
  PyObject *__pyx_n_u_delete;
  PyObject *__pyx_n_u_description;
  PyObject *__pyx_kp_u_detach;
  PyObject *__pyx_n_s_detailed_explanation;
  PyObject *__pyx_n_s_df;
  PyObject *__pyx_n_s_dict;
  PyObject *__pyx_n_s_direct_matches;
  PyObject *__pyx_n_s_direct_sql_pattern;
  PyObject *__pyx_kp_u_disable;
  PyObject *__pyx_n_s_doc;
  PyObject *__pyx_n_u_drop;
  PyObject *__pyx_n_s_dump;
  PyObject *__pyx_n_s_dumps;
  PyObject *__pyx_n_s_e;
  PyObject *__pyx_n_s_empty;
  PyObject *__pyx_kp_u_enable;
  PyObject *__pyx_n_s_encoding;
  PyObject *__pyx_n_s_enter;
  PyObject *__pyx_n_s_entry;
  PyObject *__pyx_n_s_enumerate;
  PyObject *__pyx_n_s_error;
  PyObject *__pyx_n_u_error;
  PyObject *__pyx_n_s_error_msg;
  PyObject *__pyx_n_s_escape;
  PyObject *__pyx_n_s_evaluate_query_relevance;
  PyObject *__pyx_n_u_execution_error;
  PyObject *__pyx_n_s_exist_ok;
  PyObject *__pyx_n_s_existing_logs;
  PyObject *__pyx_n_u_existing_sql;
  PyObject *__pyx_n_s_exists;
  PyObject *__pyx_n_s_exit;
  PyObject *__pyx_n_s_explanation;
  PyObject *__pyx_n_u_explanation;
  PyObject *__pyx_n_s_explanation_match;
  PyObject *__pyx_n_s_explanation_pattern;
  PyObject *__pyx_n_u_exploration_stats;
  PyObject *__pyx_n_s_explorations;
  PyObject *__pyx_n_s_explore_database_schema;
  PyObject *__pyx_n_s_explore_table_schema;
  PyObject *__pyx_n_s_extract_explanation;
  PyObject *__pyx_n_s_extract_sql_from_response;
  PyObject *__pyx_n_s_extract_table_names;
  PyObject *__pyx_n_s_f;
  PyObject *__pyx_n_s_failed_query;
  PyObject *__pyx_n_u_failed_sql;
  PyObject *__pyx_kp_u_failed_sql_json;
  PyObject *__pyx_n_s_file_path;
  PyObject *__pyx_n_s_findall;
  PyObject *__pyx_n_s_finditer;
  PyObject *__pyx_n_s_first_result;
  PyObject *__pyx_n_s_fixed_query;
  PyObject *__pyx_n_s_fixed_sql;
  PyObject *__pyx_n_s_float;
  PyObject *__pyx_n_s_from_matches;
  PyObject *__pyx_n_s_from_pattern;
  PyObject *__pyx_kp_u_gc;
  PyObject *__pyx_n_s_generate_additional_explorations;
  PyObject *__pyx_n_s_generate_result_summary;
  PyObject *__pyx_n_s_generate_sql;
  PyObject *__pyx_n_s_genexpr;
  PyObject *__pyx_n_s_get;
  PyObject *__pyx_n_s_get_best_sql_and_results;
  PyObject *__pyx_n_s_get_response_sync;
  PyObject *__pyx_n_s_group;
  PyObject *__pyx_n_u_has_historical_match;
  PyObject *__pyx_n_s_head;
  PyObject *__pyx_n_s_hist_score;
  PyObject *__pyx_n_u_historical;
  PyObject *__pyx_n_s_historical_query;
  PyObject *__pyx_n_u_historical_query;
  PyObject *__pyx_n_u_historical_relevance_score;
  PyObject *__pyx_n_u_historical_success;
  PyObject *__pyx_n_s_i;
  PyObject *__pyx_n_s_import;
  PyObject *__pyx_n_s_indent;
  PyObject *__pyx_n_s_info;
  PyObject *__pyx_n_s_init;
  PyObject *__pyx_n_s_init_subclass;
  PyObject *__pyx_n_s_initializing;
  PyObject *__pyx_n_u_insert;
  PyObject *__pyx_n_s_intersection;
  PyObject *__pyx_n_s_is_coroutine;
  PyObject *__pyx_kp_u_isenabled;
  PyObject *__pyx_n_s_isoformat;
  PyObject *__pyx_n_s_items;
  PyObject *__pyx_n_s_iterrows;
  PyObject *__pyx_n_s_join;
  PyObject *__pyx_n_u_join;
  PyObject *__pyx_n_s_join_condition;
  PyObject *__pyx_n_u_join_condition;
  PyObject *__pyx_n_s_join_matches;
  PyObject *__pyx_n_s_join_pattern;
  PyObject *__pyx_n_s_json;
  PyObject *__pyx_n_s_left_side;
  PyObject *__pyx_n_u_link;
  PyObject *__pyx_n_s_load;
  PyObject *__pyx_n_s_log_e;
  PyObject *__pyx_n_s_lower;
  PyObject *__pyx_n_s_main;
  PyObject *__pyx_n_s_main_query;
  PyObject *__pyx_n_s_main_sql;
  PyObject *__pyx_n_s_makedirs;
  PyObject *__pyx_n_s_match;
  PyObject *__pyx_n_s_max_attempts;
  PyObject *__pyx_n_u_message;
  PyObject *__pyx_n_s_metaclass;
  PyObject *__pyx_n_s_module;
  PyObject *__pyx_kp_u_more_rows;
  PyObject *__pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION;
  PyObject *__pyx_n_u_name;
  PyObject *__pyx_n_s_name_2;
  PyObject *__pyx_n_s_name_parts;
  PyObject *__pyx_n_s_normalized_sql;
  PyObject *__pyx_n_u_notnull;
  PyObject *__pyx_n_s_now;
  PyObject *__pyx_n_s_num_cols;
  PyObject *__pyx_n_s_num_rows;
  PyObject *__pyx_n_s_numeric_columns;
  PyObject *__pyx_n_s_open;
  PyObject *__pyx_n_s_operation;
  PyObject *__pyx_kp_u_or;
  PyObject *__pyx_n_s_orient;
  PyObject *__pyx_n_s_original_error;
  PyObject *__pyx_n_u_original_error;
  PyObject *__pyx_n_s_original_failed_sql;
  PyObject *__pyx_n_u_original_failed_sql;
  PyObject *__pyx_n_s_original_question;
  PyObject *__pyx_n_s_original_sql;
  PyObject *__pyx_n_s_os;
  PyObject *__pyx_n_s_overlap;
  PyObject *__pyx_n_s_pandas;
  PyObject *__pyx_n_s_parts;
  PyObject *__pyx_n_s_path;
  PyObject *__pyx_n_s_pattern;
  PyObject *__pyx_n_s_pd;
  PyObject *__pyx_kp_s_pd_DataFrame;
  PyObject *__pyx_n_u_pk;
  PyObject *__pyx_kp_u_plus;
  PyObject *__pyx_n_u_pragma;
  PyObject *__pyx_n_s_pragma_query;
  PyObject *__pyx_n_s_prepare;
  PyObject *__pyx_n_s_prev;
  PyObject *__pyx_n_s_previous_attempts;
  PyObject *__pyx_n_u_previously_run_query;
  PyObject *__pyx_n_s_print;
  PyObject *__pyx_n_s_prompt;
  PyObject *__pyx_n_s_qualname;
  PyObject *__pyx_n_s_query;
  PyObject *__pyx_n_s_question;
  PyObject *__pyx_n_u_question;
  PyObject *__pyx_n_s_question_keywords;
  PyObject *__pyx_n_u_r;
  PyObject *__pyx_n_s_range;
  PyObject *__pyx_n_u_raw_ai_response;
  PyObject *__pyx_n_s_re;
  PyObject *__pyx_n_s_read_sql_query;
  PyObject *__pyx_n_u_recommendation_reason;
  PyObject *__pyx_n_u_recommended_query;
  PyObject *__pyx_n_u_records;
  PyObject *__pyx_n_s_rel;
  PyObject *__pyx_n_u_relation;
  PyObject *__pyx_n_s_relationship_keywords;
  PyObject *__pyx_n_s_relationship_query;
  PyObject *__pyx_n_s_relationships;
  PyObject *__pyx_n_u_relationships;
  PyObject *__pyx_n_s_response;
  PyObject *__pyx_n_s_result;
  PyObject *__pyx_n_u_result;
  PyObject *__pyx_n_u_results;
  PyObject *__pyx_n_u_retry_attempt;
  PyObject *__pyx_n_s_retry_info;
  PyObject *__pyx_n_s_return;
  PyObject *__pyx_n_u_reused_from_failed_json;
  PyObject *__pyx_n_s_right_side;
  PyObject *__pyx_n_s_row;
  PyObject *__pyx_n_s_row_count;
  PyObject *__pyx_n_u_row_count;
  PyObject *__pyx_kp_u_row_s_with;
  PyObject *__pyx_kp_u_rows_returned;
  PyObject *__pyx_n_s_sQQideR_SQLBuilder;
  PyObject *__pyx_kp_s_sQQideR_SQLBuilder_pyx;
  PyObject *__pyx_n_s_sample;
  PyObject *__pyx_n_s_sample_data;
  PyObject *__pyx_n_u_sample_data;
  PyObject *__pyx_n_s_sample_df;
  PyObject *__pyx_n_s_sample_query;
  PyObject *__pyx_n_s_schema_info;
  PyObject *__pyx_n_s_score;
  PyObject *__pyx_n_s_search;
  PyObject *__pyx_kp_u_select;
  PyObject *__pyx_n_s_self;
  PyObject *__pyx_n_s_send;
  PyObject *__pyx_n_s_set_name;
  PyObject *__pyx_n_s_source;
  PyObject *__pyx_n_u_source;
  PyObject *__pyx_n_s_spec;
  PyObject *__pyx_n_s_split;
  PyObject *__pyx_n_s_sql;
  PyObject *__pyx_n_u_sql;
  PyObject *__pyx_n_s_sql_query;
  PyObject *__pyx_kp_u_sql_s;
  PyObject *__pyx_n_s_sqlite3;
  PyObject *__pyx_n_s_stats_query_dict;
  PyObject *__pyx_n_s_str;
  PyObject *__pyx_n_s_strip;
  PyObject *__pyx_kp_u_succeeded;
  PyObject *__pyx_n_u_success;
  PyObject *__pyx_n_s_summary;
  PyObject *__pyx_n_u_summary;
  PyObject *__pyx_n_s_super;
  PyObject *__pyx_kp_u_table;
  PyObject *__pyx_n_s_table_2;
  PyObject *__pyx_n_s_table_info;
  PyObject *__pyx_n_s_table_name;
  PyObject *__pyx_n_u_table_name;
  PyObject *__pyx_n_s_table_names;
  PyObject *__pyx_n_s_table_obj;
  PyObject *__pyx_n_s_tables;
  PyObject *__pyx_n_u_tables;
  PyObject *__pyx_n_s_tables_df;
  PyObject *__pyx_n_s_tables_query;
  PyObject *__pyx_n_s_tables_used;
  PyObject *__pyx_n_s_target;
  PyObject *__pyx_n_u_target;
  PyObject *__pyx_n_s_test;
  PyObject *__pyx_n_s_test_query;
  PyObject *__pyx_n_s_tested_query;
  PyObject *__pyx_n_s_text;
  PyObject *__pyx_n_s_throw;
  PyObject *__pyx_n_u_time;
  PyObject *__pyx_n_s_time_query;
  PyObject *__pyx_n_u_timestamp;
  PyObject *__pyx_kp_u_to;
  PyObject *__pyx_n_s_to_dict;
  PyObject *__pyx_n_s_to_string;
  PyObject *__pyx_n_u_truncate;
  PyObject *__pyx_n_s_try_fix_failed_query;
  PyObject *__pyx_n_u_type;
  PyObject *__pyx_n_s_typing;
  PyObject *__pyx_n_s_update;
  PyObject *__pyx_n_u_update;
  PyObject *__pyx_kp_u_utf_8;
  PyObject *__pyx_kp_u_vacuum;
  PyObject *__pyx_n_s_val;
  PyObject *__pyx_n_s_validate_safe_sql;
  PyObject *__pyx_n_s_validation_error;
  PyObject *__pyx_n_s_verbose;
  PyObject *__pyx_n_u_w;
  PyObject *__pyx_n_u_where;
  PyObject *__pyx_n_s_working_sql;
  PyObject *__pyx_n_u_working_sql;
  PyObject *__pyx_float_0_0;
  PyObject *__pyx_float_0_5;
  PyObject *__pyx_float_5_0;
  PyObject *__pyx_int_0;
  PyObject *__pyx_int_1;
  PyObject *__pyx_int_2;
  PyObject *__pyx_int_3;
  PyObject *__pyx_int_5;
  PyObject *__pyx_int_20;
  PyObject *__pyx_int_100;
  PyObject *__pyx_tuple_;
  PyObject *__pyx_tuple__2;
  PyObject *__pyx_tuple__3;
  PyObject *__pyx_tuple__4;
  PyObject *__pyx_tuple__5;
  PyObject *__pyx_tuple__6;
  PyObject *__pyx_tuple__8;
  PyObject *__pyx_slice__18;
  PyObject *__pyx_tuple__10;
  PyObject *__pyx_tuple__11;
  PyObject *__pyx_tuple__12;
  PyObject *__pyx_tuple__19;
  PyObject *__pyx_tuple__20;
  PyObject *__pyx_tuple__21;
  PyObject *__pyx_tuple__22;
  PyObject *__pyx_tuple__24;
  PyObject *__pyx_tuple__25;
  PyObject *__pyx_tuple__27;
  PyObject *__pyx_tuple__28;
  PyObject *__pyx_tuple__33;
  PyObject *__pyx_tuple__36;
  PyObject *__pyx_tuple__37;
  PyObject *__pyx_tuple__38;
  PyObject *__pyx_tuple__39;
  PyObject *__pyx_tuple__40;
  PyObject *__pyx_tuple__41;
  PyObject *__pyx_tuple__42;
  PyObject *__pyx_tuple__43;
  PyObject *__pyx_tuple__44;
  PyObject *__pyx_tuple__45;
  PyObject *__pyx_tuple__46;
  PyObject *__pyx_tuple__47;
  PyObject *__pyx_tuple__49;
  PyObject *__pyx_tuple__50;
  PyObject *__pyx_tuple__52;
  PyObject *__pyx_tuple__54;
  PyObject *__pyx_tuple__56;
  PyObject *__pyx_tuple__58;
  PyObject *__pyx_tuple__60;
  PyObject *__pyx_tuple__62;
  PyObject *__pyx_tuple__63;
  PyObject *__pyx_tuple__65;
  PyObject *__pyx_tuple__67;
  PyObject *__pyx_tuple__70;
  PyObject *__pyx_tuple__72;
  PyObject *__pyx_tuple__74;
  PyObject *__pyx_tuple__76;
  PyObject *__pyx_tuple__78;
  PyObject *__pyx_tuple__80;
  PyObject *__pyx_tuple__82;
  PyObject *__pyx_tuple__84;
  PyObject *__pyx_tuple__86;
  PyObject *__pyx_tuple__88;
  PyObject *__pyx_codeobj__48;
  PyObject *__pyx_codeobj__51;
  PyObject *__pyx_codeobj__53;
  PyObject *__pyx_codeobj__55;
  PyObject *__pyx_codeobj__57;
  PyObject *__pyx_codeobj__59;
  PyObject *__pyx_codeobj__61;
  PyObject *__pyx_codeobj__64;
  PyObject *__pyx_codeobj__66;
  PyObject *__pyx_codeobj__68;
  PyObject *__pyx_codeobj__71;
  PyObject *__pyx_codeobj__73;
  PyObject *__pyx_codeobj__75;
  PyObject *__pyx_codeobj__77;
  PyObject *__pyx_codeobj__79;
  PyObject *__pyx_codeobj__81;
  PyObject *__pyx_codeobj__83;
  PyObject *__pyx_codeobj__85;
  PyObject *__pyx_codeobj__87;
  PyObject *__pyx_codeobj__89;
} __pyx_mstate;

#if CYTHON_USE_MODULE_STATE
#ifdef __cplusplus
namespace {
  extern struct PyModuleDef __pyx_moduledef;
} /* anonymous namespace */
#else
static struct PyModuleDef __pyx_moduledef;
#endif

#define __pyx_mstate(o) ((__pyx_mstate *)__Pyx_PyModule_GetState(o))

#define __pyx_mstate_global (__pyx_mstate(PyState_FindModule(&__pyx_moduledef)))

#define __pyx_m (PyState_FindModule(&__pyx_moduledef))
#else
static __pyx_mstate __pyx_mstate_global_static =
#ifdef __cplusplus
    {};
#else
    {0};
#endif
static __pyx_mstate *__pyx_mstate_global = &__pyx_mstate_global_static;
#endif
/* #### Code section: module_state_clear ### */
#if CYTHON_USE_MODULE_STATE
static int __pyx_m_clear(PyObject *m) {
  __pyx_mstate *clear_module_state = __pyx_mstate(m);
  if (!clear_module_state) return 0;
  Py_CLEAR(clear_module_state->__pyx_d);
  Py_CLEAR(clear_module_state->__pyx_b);
  Py_CLEAR(clear_module_state->__pyx_cython_runtime);
  Py_CLEAR(clear_module_state->__pyx_empty_tuple);
  Py_CLEAR(clear_module_state->__pyx_empty_bytes);
  Py_CLEAR(clear_module_state->__pyx_empty_unicode);
  #ifdef __Pyx_CyFunction_USED
  Py_CLEAR(clear_module_state->__pyx_CyFunctionType);
  #endif
  #ifdef __Pyx_FusedFunction_USED
  Py_CLEAR(clear_module_state->__pyx_FusedFunctionType);
  #endif
  Py_CLEAR(clear_module_state->__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations);
  Py_CLEAR(clear_module_state->__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations);
  Py_CLEAR(clear_module_state->__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr);
  Py_CLEAR(clear_module_state->__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr);
  Py_CLEAR(clear_module_state->__pyx_kp_u_AI_generated_query_appears_more);
  Py_CLEAR(clear_module_state->__pyx_kp_u_AI_service_not_available_for_SQL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_AI_service_or_database_connectio);
  Py_CLEAR(clear_module_state->__pyx_kp_u_ALTER_operations_are_not_allowed);
  Py_CLEAR(clear_module_state->__pyx_kp_u_AS_avg);
  Py_CLEAR(clear_module_state->__pyx_kp_u_AS_max);
  Py_CLEAR(clear_module_state->__pyx_kp_u_AS_min);
  Py_CLEAR(clear_module_state->__pyx_kp_u_ATTACH_DATABASE_operations_are_n);
  Py_CLEAR(clear_module_state->__pyx_kp_u_AVG);
  Py_CLEAR(clear_module_state->__pyx_n_s_Any);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Asking_AI_to_fix_SQL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Attempt);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Blocked_dangerous_SQL_operation);
  Py_CLEAR(clear_module_state->__pyx_kp_u_COUNT_as_count_FROM);
  Py_CLEAR(clear_module_state->__pyx_kp_u_CREATE_operations_are_not_allowe);
  Py_CLEAR(clear_module_state->__pyx_kp_s_Class_for_building_and_testing);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Columns);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Connected_to_database);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Count_records_in);
  Py_CLEAR(clear_module_state->__pyx_kp_u_DATABASE_CONTEXT);
  Py_CLEAR(clear_module_state->__pyx_kp_u_DATABASE_SCHEMA_INFORMATION);
  Py_CLEAR(clear_module_state->__pyx_kp_u_DELETE_operations_are_not_allowe);
  Py_CLEAR(clear_module_state->__pyx_kp_u_DETACH_DATABASE_operations_are_n);
  Py_CLEAR(clear_module_state->__pyx_n_s_DOTALL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_DROP_operations_are_not_allowed);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Database_connection_closed);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Database_file_not_found);
  Py_CLEAR(clear_module_state->__pyx_n_s_Dict);
  Py_CLEAR(clear_module_state->__pyx_kp_u_ERROR_MESSAGE);
  Py_CLEAR(clear_module_state->__pyx_kp_u_EXPLANATION);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Equal_relevance_using_historical);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_connecting_to_database);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_during_AI_retry);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_during_retry_attempt);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_executing_count_exploratio);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_executing_query);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_executing_relationship_exp);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_executing_time_exploration);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_exploring_database_schema);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_exploring_table);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Error_generating_SQL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_FROM);
  Py_CLEAR(clear_module_state->__pyx_kp_u_FROM_s_a_zA_Z0_9);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Failed_to_check_existing_logs);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Failed_to_fix_SQL_after);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Failed_to_generate_SQL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Failed_to_log_corrected_SQL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Found_previous_working_SQL_for_t);
  Py_CLEAR(clear_module_state->__pyx_kp_u_GROUP_BY);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Generated_fixed_SQL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Historical_query_appears_more_re);
  Py_CLEAR(clear_module_state->__pyx_n_s_IGNORECASE);
  Py_CLEAR(clear_module_state->__pyx_kp_u_INSERT_operations_are_not_allowe);
  Py_CLEAR(clear_module_state->__pyx_kp_u_INSTRUCTIONS_1_Generate_a_valid);
  Py_CLEAR(clear_module_state->__pyx_kp_u_JOIN);
  Py_CLEAR(clear_module_state->__pyx_kp_u_JOIN_s_a_zA_Z0_9);
  Py_CLEAR(clear_module_state->__pyx_kp_u_LIMIT_3);
  Py_CLEAR(clear_module_state->__pyx_n_s_List);
  Py_CLEAR(clear_module_state->__pyx_kp_s_List_Dict);
  Py_CLEAR(clear_module_state->__pyx_kp_s_List_str);
  Py_CLEAR(clear_module_state->__pyx_kp_u_MAX);
  Py_CLEAR(clear_module_state->__pyx_kp_u_MIN);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Neither_query_executed_successfu);
  Py_CLEAR(clear_module_state->__pyx_kp_u_No_SQL);
  Py_CLEAR(clear_module_state->__pyx_kp_u_No_SQL_query_provided);
  Py_CLEAR(clear_module_state->__pyx_kp_u_No_database_connection_available);
  Py_CLEAR(clear_module_state->__pyx_kp_u_No_description);
  Py_CLEAR(clear_module_state->__pyx_kp_u_No_original_SQL_available);
  Py_CLEAR(clear_module_state->__pyx_n_s_None);
  Py_CLEAR(clear_module_state->__pyx_kp_u_None);
  Py_CLEAR(clear_module_state->__pyx_kp_u_ON);
  Py_CLEAR(clear_module_state->__pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5);
  Py_CLEAR(clear_module_state->__pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Only_AI_generated_query_executed);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Only_historical_query_executed_s);
  Py_CLEAR(clear_module_state->__pyx_n_s_Optional);
  Py_CLEAR(clear_module_state->__pyx_kp_s_Optional_Dict);
  Py_CLEAR(clear_module_state->__pyx_kp_s_Optional_str);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Original_error);
  Py_CLEAR(clear_module_state->__pyx_kp_u_PRAGMA_operations_are_not_allowe);
  Py_CLEAR(clear_module_state->__pyx_kp_u_PRAGMA_table_info);
  Py_CLEAR(clear_module_state->__pyx_kp_u_PREVIOUSLY_RUN_QUERY_FOR_SIMILA);
  Py_CLEAR(clear_module_state->__pyx_kp_u_PREVIOUS_CORRECTION_ATTEMPTS);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Previous_SQL_attempt_failed_wit);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Query);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Query_comparison_complete_Recomm);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Query_executed_successfully);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Query_returned);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Query_returned_no_results);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Question);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Reason);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Relationship_count_between);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Relevant_Columns);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Relevant_Tables);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Relevant_Tables_in_Context);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Result);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Results);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Retry_attempt);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SELECT);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SELECT_COUNT_AS_record_count_FRO);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SELECT_COUNT_DISTINCT);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SELECT_FROM);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SELECT_name_FROM_sqlite_master_W);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SQL);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder___init);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__clean_text);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__create_sql_correctio);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__create_sql_generatio);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__evaluate_query_relev);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__explore_database_sch);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__explore_table_schema);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__extract_explanation);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__extract_sql_from_res);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__extract_table_names);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__generate_result_summ);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder__validate_safe_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_close_connection);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_compare_queries);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_connect_database);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_generate_additional_e);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_generate_additional_e_2);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_generate_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_get_best_sql_and_resu);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_test_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_SQLBuilder_try_fix_failed_query);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SQL_Query_Builder_only_supports);
  Py_CLEAR(clear_module_state->__pyx_kp_u_SQL_fixed_on_attempt);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Sample_data);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Sample_of_first_3_rows);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Security_restriction);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Security_restriction_Only_SELECT);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Shows_the_distribution_of_values);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Shows_the_number_of_connections);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Shows_the_total_number_of_record);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Statistical_summary);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Statistical_summary_for);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Statistical_summary_of_numeric_v);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Stats_exploration_failed_and_cou);
  Py_CLEAR(clear_module_state->__pyx_kp_u_TASK_1_Analyze_the_error_messag);
  Py_CLEAR(clear_module_state->__pyx_kp_u_TRUNCATE_operations_are_not_allo);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Table);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Table_Relationships);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Table_Relationships_in_Context);
  Py_CLEAR(clear_module_state->__pyx_kp_u_This_SQL_was_reused_from_a_previ);
  Py_CLEAR(clear_module_state->__pyx_kp_u_This_working_SQL_has_been_verif);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Time_distribution_for);
  Py_CLEAR(clear_module_state->__pyx_n_s_Timestamp);
  Py_CLEAR(clear_module_state->__pyx_n_s_Tuple);
  Py_CLEAR(clear_module_state->__pyx_kp_u_UPDATE_operations_are_not_allowe);
  Py_CLEAR(clear_module_state->__pyx_n_s_Union);
  Py_CLEAR(clear_module_state->__pyx_n_u_Unknown);
  Py_CLEAR(clear_module_state->__pyx_kp_u_Unknown_error);
  Py_CLEAR(clear_module_state->__pyx_kp_u_VACUUM_operations_are_not_allowe);
  Py_CLEAR(clear_module_state->__pyx_kp_u_You_are_an_expert_SQL_developer);
  Py_CLEAR(clear_module_state->__pyx_kp_u_You_are_an_expert_SQL_developer_2);
  Py_CLEAR(clear_module_state->__pyx_kp_u_You_should_strongly_consider_usi);
  Py_CLEAR(clear_module_state->__pyx_kp_u__13);
  Py_CLEAR(clear_module_state->__pyx_kp_u__14);
  Py_CLEAR(clear_module_state->__pyx_kp_u__15);
  Py_CLEAR(clear_module_state->__pyx_kp_u__16);
  Py_CLEAR(clear_module_state->__pyx_kp_u__17);
  Py_CLEAR(clear_module_state->__pyx_kp_u__23);
  Py_CLEAR(clear_module_state->__pyx_kp_u__26);
  Py_CLEAR(clear_module_state->__pyx_kp_u__29);
  Py_CLEAR(clear_module_state->__pyx_kp_u__30);
  Py_CLEAR(clear_module_state->__pyx_kp_u__31);
  Py_CLEAR(clear_module_state->__pyx_kp_u__32);
  Py_CLEAR(clear_module_state->__pyx_kp_u__34);
  Py_CLEAR(clear_module_state->__pyx_kp_u__35);
  Py_CLEAR(clear_module_state->__pyx_n_s__69);
  Py_CLEAR(clear_module_state->__pyx_kp_u__7);
  Py_CLEAR(clear_module_state->__pyx_n_s__9);
  Py_CLEAR(clear_module_state->__pyx_n_s__90);
  Py_CLEAR(clear_module_state->__pyx_n_s_additional_explorations);
  Py_CLEAR(clear_module_state->__pyx_n_u_additional_explorations);
  Py_CLEAR(clear_module_state->__pyx_n_s_agg_parts);
  Py_CLEAR(clear_module_state->__pyx_n_u_ai);
  Py_CLEAR(clear_module_state->__pyx_n_s_ai_base);
  Py_CLEAR(clear_module_state->__pyx_n_u_ai_generated);
  Py_CLEAR(clear_module_state->__pyx_n_s_ai_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_ai_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_ai_query_retry_info);
  Py_CLEAR(clear_module_state->__pyx_n_u_ai_relevance_score);
  Py_CLEAR(clear_module_state->__pyx_n_u_ai_retry_attempt);
  Py_CLEAR(clear_module_state->__pyx_n_s_ai_score);
  Py_CLEAR(clear_module_state->__pyx_n_u_ai_success);
  Py_CLEAR(clear_module_state->__pyx_n_u_alter);
  Py_CLEAR(clear_module_state->__pyx_kp_u_and);
  Py_CLEAR(clear_module_state->__pyx_n_s_append);
  Py_CLEAR(clear_module_state->__pyx_n_s_args);
  Py_CLEAR(clear_module_state->__pyx_kp_u_as_distinct_connections_FROM);
  Py_CLEAR(clear_module_state->__pyx_n_s_asyncio_coroutines);
  Py_CLEAR(clear_module_state->__pyx_kp_u_attach);
  Py_CLEAR(clear_module_state->__pyx_n_s_attempt);
  Py_CLEAR(clear_module_state->__pyx_n_s_attempts);
  Py_CLEAR(clear_module_state->__pyx_n_u_attempts);
  Py_CLEAR(clear_module_state->__pyx_kp_u_attempts_Original_error);
  Py_CLEAR(clear_module_state->__pyx_kp_u_b);
  Py_CLEAR(clear_module_state->__pyx_kp_u_bSELECT_b);
  Py_CLEAR(clear_module_state->__pyx_kp_u_b_w_4_b);
  Py_CLEAR(clear_module_state->__pyx_n_s_best_attempt);
  Py_CLEAR(clear_module_state->__pyx_n_u_best_attempt);
  Py_CLEAR(clear_module_state->__pyx_n_u_best_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_between);
  Py_CLEAR(clear_module_state->__pyx_n_s_block);
  Py_CLEAR(clear_module_state->__pyx_n_s_bool);
  Py_CLEAR(clear_module_state->__pyx_n_s_check_same_thread);
  Py_CLEAR(clear_module_state->__pyx_n_s_clean_text);
  Py_CLEAR(clear_module_state->__pyx_n_s_cleaned_explanation);
  Py_CLEAR(clear_module_state->__pyx_n_s_cleaned_response);
  Py_CLEAR(clear_module_state->__pyx_n_s_cleaned_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_clear_history);
  Py_CLEAR(clear_module_state->__pyx_n_s_cline_in_traceback);
  Py_CLEAR(clear_module_state->__pyx_n_s_close);
  Py_CLEAR(clear_module_state->__pyx_n_s_close_connection);
  Py_CLEAR(clear_module_state->__pyx_n_s_code_block_pattern);
  Py_CLEAR(clear_module_state->__pyx_n_s_code_blocks);
  Py_CLEAR(clear_module_state->__pyx_n_s_col);
  Py_CLEAR(clear_module_state->__pyx_n_s_col_name);
  Py_CLEAR(clear_module_state->__pyx_kp_u_column);
  Py_CLEAR(clear_module_state->__pyx_n_s_column_2);
  Py_CLEAR(clear_module_state->__pyx_n_u_column_count);
  Py_CLEAR(clear_module_state->__pyx_n_s_column_keywords);
  Py_CLEAR(clear_module_state->__pyx_n_s_column_obj);
  Py_CLEAR(clear_module_state->__pyx_kp_u_column_s);
  Py_CLEAR(clear_module_state->__pyx_n_s_columns);
  Py_CLEAR(clear_module_state->__pyx_n_u_columns);
  Py_CLEAR(clear_module_state->__pyx_n_s_columns_df);
  Py_CLEAR(clear_module_state->__pyx_n_s_compare_queries);
  Py_CLEAR(clear_module_state->__pyx_n_s_comparison);
  Py_CLEAR(clear_module_state->__pyx_n_u_comparison);
  Py_CLEAR(clear_module_state->__pyx_n_s_conditions);
  Py_CLEAR(clear_module_state->__pyx_n_s_conn);
  Py_CLEAR(clear_module_state->__pyx_n_s_connect);
  Py_CLEAR(clear_module_state->__pyx_n_u_connect);
  Py_CLEAR(clear_module_state->__pyx_n_s_connect_database);
  Py_CLEAR(clear_module_state->__pyx_n_s_count);
  Py_CLEAR(clear_module_state->__pyx_n_s_count_query);
  Py_CLEAR(clear_module_state->__pyx_kp_u_create);
  Py_CLEAR(clear_module_state->__pyx_n_s_create_sql_correction_prompt);
  Py_CLEAR(clear_module_state->__pyx_n_s_create_sql_generation_prompt);
  Py_CLEAR(clear_module_state->__pyx_n_s_dangerous_operations);
  Py_CLEAR(clear_module_state->__pyx_n_u_data);
  Py_CLEAR(clear_module_state->__pyx_kp_u_data_failed_sql_json);
  Py_CLEAR(clear_module_state->__pyx_n_s_data_type);
  Py_CLEAR(clear_module_state->__pyx_n_u_data_type);
  Py_CLEAR(clear_module_state->__pyx_n_u_database_objects);
  Py_CLEAR(clear_module_state->__pyx_n_s_database_path);
  Py_CLEAR(clear_module_state->__pyx_n_u_date);
  Py_CLEAR(clear_module_state->__pyx_n_s_date_col);
  Py_CLEAR(clear_module_state->__pyx_n_s_date_columns);
  Py_CLEAR(clear_module_state->__pyx_n_u_day);
  Py_CLEAR(clear_module_state->__pyx_n_s_db_context);
  Py_CLEAR(clear_module_state->__pyx_n_u_delete);
  Py_CLEAR(clear_module_state->__pyx_n_u_description);
  Py_CLEAR(clear_module_state->__pyx_kp_u_detach);
  Py_CLEAR(clear_module_state->__pyx_n_s_detailed_explanation);
  Py_CLEAR(clear_module_state->__pyx_n_s_df);
  Py_CLEAR(clear_module_state->__pyx_n_s_dict);
  Py_CLEAR(clear_module_state->__pyx_n_s_direct_matches);
  Py_CLEAR(clear_module_state->__pyx_n_s_direct_sql_pattern);
  Py_CLEAR(clear_module_state->__pyx_kp_u_disable);
  Py_CLEAR(clear_module_state->__pyx_n_s_doc);
  Py_CLEAR(clear_module_state->__pyx_n_u_drop);
  Py_CLEAR(clear_module_state->__pyx_n_s_dump);
  Py_CLEAR(clear_module_state->__pyx_n_s_dumps);
  Py_CLEAR(clear_module_state->__pyx_n_s_e);
  Py_CLEAR(clear_module_state->__pyx_n_s_empty);
  Py_CLEAR(clear_module_state->__pyx_kp_u_enable);
  Py_CLEAR(clear_module_state->__pyx_n_s_encoding);
  Py_CLEAR(clear_module_state->__pyx_n_s_enter);
  Py_CLEAR(clear_module_state->__pyx_n_s_entry);
  Py_CLEAR(clear_module_state->__pyx_n_s_enumerate);
  Py_CLEAR(clear_module_state->__pyx_n_s_error);
  Py_CLEAR(clear_module_state->__pyx_n_u_error);
  Py_CLEAR(clear_module_state->__pyx_n_s_error_msg);
  Py_CLEAR(clear_module_state->__pyx_n_s_escape);
  Py_CLEAR(clear_module_state->__pyx_n_s_evaluate_query_relevance);
  Py_CLEAR(clear_module_state->__pyx_n_u_execution_error);
  Py_CLEAR(clear_module_state->__pyx_n_s_exist_ok);
  Py_CLEAR(clear_module_state->__pyx_n_s_existing_logs);
  Py_CLEAR(clear_module_state->__pyx_n_u_existing_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_exists);
  Py_CLEAR(clear_module_state->__pyx_n_s_exit);
  Py_CLEAR(clear_module_state->__pyx_n_s_explanation);
  Py_CLEAR(clear_module_state->__pyx_n_u_explanation);
  Py_CLEAR(clear_module_state->__pyx_n_s_explanation_match);
  Py_CLEAR(clear_module_state->__pyx_n_s_explanation_pattern);
  Py_CLEAR(clear_module_state->__pyx_n_u_exploration_stats);
  Py_CLEAR(clear_module_state->__pyx_n_s_explorations);
  Py_CLEAR(clear_module_state->__pyx_n_s_explore_database_schema);
  Py_CLEAR(clear_module_state->__pyx_n_s_explore_table_schema);
  Py_CLEAR(clear_module_state->__pyx_n_s_extract_explanation);
  Py_CLEAR(clear_module_state->__pyx_n_s_extract_sql_from_response);
  Py_CLEAR(clear_module_state->__pyx_n_s_extract_table_names);
  Py_CLEAR(clear_module_state->__pyx_n_s_f);
  Py_CLEAR(clear_module_state->__pyx_n_s_failed_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_failed_sql);
  Py_CLEAR(clear_module_state->__pyx_kp_u_failed_sql_json);
  Py_CLEAR(clear_module_state->__pyx_n_s_file_path);
  Py_CLEAR(clear_module_state->__pyx_n_s_findall);
  Py_CLEAR(clear_module_state->__pyx_n_s_finditer);
  Py_CLEAR(clear_module_state->__pyx_n_s_first_result);
  Py_CLEAR(clear_module_state->__pyx_n_s_fixed_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_fixed_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_float);
  Py_CLEAR(clear_module_state->__pyx_n_s_from_matches);
  Py_CLEAR(clear_module_state->__pyx_n_s_from_pattern);
  Py_CLEAR(clear_module_state->__pyx_kp_u_gc);
  Py_CLEAR(clear_module_state->__pyx_n_s_generate_additional_explorations);
  Py_CLEAR(clear_module_state->__pyx_n_s_generate_result_summary);
  Py_CLEAR(clear_module_state->__pyx_n_s_generate_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_genexpr);
  Py_CLEAR(clear_module_state->__pyx_n_s_get);
  Py_CLEAR(clear_module_state->__pyx_n_s_get_best_sql_and_results);
  Py_CLEAR(clear_module_state->__pyx_n_s_get_response_sync);
  Py_CLEAR(clear_module_state->__pyx_n_s_group);
  Py_CLEAR(clear_module_state->__pyx_n_u_has_historical_match);
  Py_CLEAR(clear_module_state->__pyx_n_s_head);
  Py_CLEAR(clear_module_state->__pyx_n_s_hist_score);
  Py_CLEAR(clear_module_state->__pyx_n_u_historical);
  Py_CLEAR(clear_module_state->__pyx_n_s_historical_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_historical_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_historical_relevance_score);
  Py_CLEAR(clear_module_state->__pyx_n_u_historical_success);
  Py_CLEAR(clear_module_state->__pyx_n_s_i);
  Py_CLEAR(clear_module_state->__pyx_n_s_import);
  Py_CLEAR(clear_module_state->__pyx_n_s_indent);
  Py_CLEAR(clear_module_state->__pyx_n_s_info);
  Py_CLEAR(clear_module_state->__pyx_n_s_init);
  Py_CLEAR(clear_module_state->__pyx_n_s_init_subclass);
  Py_CLEAR(clear_module_state->__pyx_n_s_initializing);
  Py_CLEAR(clear_module_state->__pyx_n_u_insert);
  Py_CLEAR(clear_module_state->__pyx_n_s_intersection);
  Py_CLEAR(clear_module_state->__pyx_n_s_is_coroutine);
  Py_CLEAR(clear_module_state->__pyx_kp_u_isenabled);
  Py_CLEAR(clear_module_state->__pyx_n_s_isoformat);
  Py_CLEAR(clear_module_state->__pyx_n_s_items);
  Py_CLEAR(clear_module_state->__pyx_n_s_iterrows);
  Py_CLEAR(clear_module_state->__pyx_n_s_join);
  Py_CLEAR(clear_module_state->__pyx_n_u_join);
  Py_CLEAR(clear_module_state->__pyx_n_s_join_condition);
  Py_CLEAR(clear_module_state->__pyx_n_u_join_condition);
  Py_CLEAR(clear_module_state->__pyx_n_s_join_matches);
  Py_CLEAR(clear_module_state->__pyx_n_s_join_pattern);
  Py_CLEAR(clear_module_state->__pyx_n_s_json);
  Py_CLEAR(clear_module_state->__pyx_n_s_left_side);
  Py_CLEAR(clear_module_state->__pyx_n_u_link);
  Py_CLEAR(clear_module_state->__pyx_n_s_load);
  Py_CLEAR(clear_module_state->__pyx_n_s_log_e);
  Py_CLEAR(clear_module_state->__pyx_n_s_lower);
  Py_CLEAR(clear_module_state->__pyx_n_s_main);
  Py_CLEAR(clear_module_state->__pyx_n_s_main_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_main_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_makedirs);
  Py_CLEAR(clear_module_state->__pyx_n_s_match);
  Py_CLEAR(clear_module_state->__pyx_n_s_max_attempts);
  Py_CLEAR(clear_module_state->__pyx_n_u_message);
  Py_CLEAR(clear_module_state->__pyx_n_s_metaclass);
  Py_CLEAR(clear_module_state->__pyx_n_s_module);
  Py_CLEAR(clear_module_state->__pyx_kp_u_more_rows);
  Py_CLEAR(clear_module_state->__pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION);
  Py_CLEAR(clear_module_state->__pyx_n_u_name);
  Py_CLEAR(clear_module_state->__pyx_n_s_name_2);
  Py_CLEAR(clear_module_state->__pyx_n_s_name_parts);
  Py_CLEAR(clear_module_state->__pyx_n_s_normalized_sql);
  Py_CLEAR(clear_module_state->__pyx_n_u_notnull);
  Py_CLEAR(clear_module_state->__pyx_n_s_now);
  Py_CLEAR(clear_module_state->__pyx_n_s_num_cols);
  Py_CLEAR(clear_module_state->__pyx_n_s_num_rows);
  Py_CLEAR(clear_module_state->__pyx_n_s_numeric_columns);
  Py_CLEAR(clear_module_state->__pyx_n_s_open);
  Py_CLEAR(clear_module_state->__pyx_n_s_operation);
  Py_CLEAR(clear_module_state->__pyx_kp_u_or);
  Py_CLEAR(clear_module_state->__pyx_n_s_orient);
  Py_CLEAR(clear_module_state->__pyx_n_s_original_error);
  Py_CLEAR(clear_module_state->__pyx_n_u_original_error);
  Py_CLEAR(clear_module_state->__pyx_n_s_original_failed_sql);
  Py_CLEAR(clear_module_state->__pyx_n_u_original_failed_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_original_question);
  Py_CLEAR(clear_module_state->__pyx_n_s_original_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_os);
  Py_CLEAR(clear_module_state->__pyx_n_s_overlap);
  Py_CLEAR(clear_module_state->__pyx_n_s_pandas);
  Py_CLEAR(clear_module_state->__pyx_n_s_parts);
  Py_CLEAR(clear_module_state->__pyx_n_s_path);
  Py_CLEAR(clear_module_state->__pyx_n_s_pattern);
  Py_CLEAR(clear_module_state->__pyx_n_s_pd);
  Py_CLEAR(clear_module_state->__pyx_kp_s_pd_DataFrame);
  Py_CLEAR(clear_module_state->__pyx_n_u_pk);
  Py_CLEAR(clear_module_state->__pyx_kp_u_plus);
  Py_CLEAR(clear_module_state->__pyx_n_u_pragma);
  Py_CLEAR(clear_module_state->__pyx_n_s_pragma_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_prepare);
  Py_CLEAR(clear_module_state->__pyx_n_s_prev);
  Py_CLEAR(clear_module_state->__pyx_n_s_previous_attempts);
  Py_CLEAR(clear_module_state->__pyx_n_u_previously_run_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_print);
  Py_CLEAR(clear_module_state->__pyx_n_s_prompt);
  Py_CLEAR(clear_module_state->__pyx_n_s_qualname);
  Py_CLEAR(clear_module_state->__pyx_n_s_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_question);
  Py_CLEAR(clear_module_state->__pyx_n_u_question);
  Py_CLEAR(clear_module_state->__pyx_n_s_question_keywords);
  Py_CLEAR(clear_module_state->__pyx_n_u_r);
  Py_CLEAR(clear_module_state->__pyx_n_s_range);
  Py_CLEAR(clear_module_state->__pyx_n_u_raw_ai_response);
  Py_CLEAR(clear_module_state->__pyx_n_s_re);
  Py_CLEAR(clear_module_state->__pyx_n_s_read_sql_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_recommendation_reason);
  Py_CLEAR(clear_module_state->__pyx_n_u_recommended_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_records);
  Py_CLEAR(clear_module_state->__pyx_n_s_rel);
  Py_CLEAR(clear_module_state->__pyx_n_u_relation);
  Py_CLEAR(clear_module_state->__pyx_n_s_relationship_keywords);
  Py_CLEAR(clear_module_state->__pyx_n_s_relationship_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_relationships);
  Py_CLEAR(clear_module_state->__pyx_n_u_relationships);
  Py_CLEAR(clear_module_state->__pyx_n_s_response);
  Py_CLEAR(clear_module_state->__pyx_n_s_result);
  Py_CLEAR(clear_module_state->__pyx_n_u_result);
  Py_CLEAR(clear_module_state->__pyx_n_u_results);
  Py_CLEAR(clear_module_state->__pyx_n_u_retry_attempt);
  Py_CLEAR(clear_module_state->__pyx_n_s_retry_info);
  Py_CLEAR(clear_module_state->__pyx_n_s_return);
  Py_CLEAR(clear_module_state->__pyx_n_u_reused_from_failed_json);
  Py_CLEAR(clear_module_state->__pyx_n_s_right_side);
  Py_CLEAR(clear_module_state->__pyx_n_s_row);
  Py_CLEAR(clear_module_state->__pyx_n_s_row_count);
  Py_CLEAR(clear_module_state->__pyx_n_u_row_count);
  Py_CLEAR(clear_module_state->__pyx_kp_u_row_s_with);
  Py_CLEAR(clear_module_state->__pyx_kp_u_rows_returned);
  Py_CLEAR(clear_module_state->__pyx_n_s_sQQideR_SQLBuilder);
  Py_CLEAR(clear_module_state->__pyx_kp_s_sQQideR_SQLBuilder_pyx);
  Py_CLEAR(clear_module_state->__pyx_n_s_sample);
  Py_CLEAR(clear_module_state->__pyx_n_s_sample_data);
  Py_CLEAR(clear_module_state->__pyx_n_u_sample_data);
  Py_CLEAR(clear_module_state->__pyx_n_s_sample_df);
  Py_CLEAR(clear_module_state->__pyx_n_s_sample_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_schema_info);
  Py_CLEAR(clear_module_state->__pyx_n_s_score);
  Py_CLEAR(clear_module_state->__pyx_n_s_search);
  Py_CLEAR(clear_module_state->__pyx_kp_u_select);
  Py_CLEAR(clear_module_state->__pyx_n_s_self);
  Py_CLEAR(clear_module_state->__pyx_n_s_send);
  Py_CLEAR(clear_module_state->__pyx_n_s_set_name);
  Py_CLEAR(clear_module_state->__pyx_n_s_source);
  Py_CLEAR(clear_module_state->__pyx_n_u_source);
  Py_CLEAR(clear_module_state->__pyx_n_s_spec);
  Py_CLEAR(clear_module_state->__pyx_n_s_split);
  Py_CLEAR(clear_module_state->__pyx_n_s_sql);
  Py_CLEAR(clear_module_state->__pyx_n_u_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_sql_query);
  Py_CLEAR(clear_module_state->__pyx_kp_u_sql_s);
  Py_CLEAR(clear_module_state->__pyx_n_s_sqlite3);
  Py_CLEAR(clear_module_state->__pyx_n_s_stats_query_dict);
  Py_CLEAR(clear_module_state->__pyx_n_s_str);
  Py_CLEAR(clear_module_state->__pyx_n_s_strip);
  Py_CLEAR(clear_module_state->__pyx_kp_u_succeeded);
  Py_CLEAR(clear_module_state->__pyx_n_u_success);
  Py_CLEAR(clear_module_state->__pyx_n_s_summary);
  Py_CLEAR(clear_module_state->__pyx_n_u_summary);
  Py_CLEAR(clear_module_state->__pyx_n_s_super);
  Py_CLEAR(clear_module_state->__pyx_kp_u_table);
  Py_CLEAR(clear_module_state->__pyx_n_s_table_2);
  Py_CLEAR(clear_module_state->__pyx_n_s_table_info);
  Py_CLEAR(clear_module_state->__pyx_n_s_table_name);
  Py_CLEAR(clear_module_state->__pyx_n_u_table_name);
  Py_CLEAR(clear_module_state->__pyx_n_s_table_names);
  Py_CLEAR(clear_module_state->__pyx_n_s_table_obj);
  Py_CLEAR(clear_module_state->__pyx_n_s_tables);
  Py_CLEAR(clear_module_state->__pyx_n_u_tables);
  Py_CLEAR(clear_module_state->__pyx_n_s_tables_df);
  Py_CLEAR(clear_module_state->__pyx_n_s_tables_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_tables_used);
  Py_CLEAR(clear_module_state->__pyx_n_s_target);
  Py_CLEAR(clear_module_state->__pyx_n_u_target);
  Py_CLEAR(clear_module_state->__pyx_n_s_test);
  Py_CLEAR(clear_module_state->__pyx_n_s_test_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_tested_query);
  Py_CLEAR(clear_module_state->__pyx_n_s_text);
  Py_CLEAR(clear_module_state->__pyx_n_s_throw);
  Py_CLEAR(clear_module_state->__pyx_n_u_time);
  Py_CLEAR(clear_module_state->__pyx_n_s_time_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_timestamp);
  Py_CLEAR(clear_module_state->__pyx_kp_u_to);
  Py_CLEAR(clear_module_state->__pyx_n_s_to_dict);
  Py_CLEAR(clear_module_state->__pyx_n_s_to_string);
  Py_CLEAR(clear_module_state->__pyx_n_u_truncate);
  Py_CLEAR(clear_module_state->__pyx_n_s_try_fix_failed_query);
  Py_CLEAR(clear_module_state->__pyx_n_u_type);
  Py_CLEAR(clear_module_state->__pyx_n_s_typing);
  Py_CLEAR(clear_module_state->__pyx_n_s_update);
  Py_CLEAR(clear_module_state->__pyx_n_u_update);
  Py_CLEAR(clear_module_state->__pyx_kp_u_utf_8);
  Py_CLEAR(clear_module_state->__pyx_kp_u_vacuum);
  Py_CLEAR(clear_module_state->__pyx_n_s_val);
  Py_CLEAR(clear_module_state->__pyx_n_s_validate_safe_sql);
  Py_CLEAR(clear_module_state->__pyx_n_s_validation_error);
  Py_CLEAR(clear_module_state->__pyx_n_s_verbose);
  Py_CLEAR(clear_module_state->__pyx_n_u_w);
  Py_CLEAR(clear_module_state->__pyx_n_u_where);
  Py_CLEAR(clear_module_state->__pyx_n_s_working_sql);
  Py_CLEAR(clear_module_state->__pyx_n_u_working_sql);
  Py_CLEAR(clear_module_state->__pyx_float_0_0);
  Py_CLEAR(clear_module_state->__pyx_float_0_5);
  Py_CLEAR(clear_module_state->__pyx_float_5_0);
  Py_CLEAR(clear_module_state->__pyx_int_0);
  Py_CLEAR(clear_module_state->__pyx_int_1);
  Py_CLEAR(clear_module_state->__pyx_int_2);
  Py_CLEAR(clear_module_state->__pyx_int_3);
  Py_CLEAR(clear_module_state->__pyx_int_5);
  Py_CLEAR(clear_module_state->__pyx_int_20);
  Py_CLEAR(clear_module_state->__pyx_int_100);
  Py_CLEAR(clear_module_state->__pyx_tuple_);
  Py_CLEAR(clear_module_state->__pyx_tuple__2);
  Py_CLEAR(clear_module_state->__pyx_tuple__3);
  Py_CLEAR(clear_module_state->__pyx_tuple__4);
  Py_CLEAR(clear_module_state->__pyx_tuple__5);
  Py_CLEAR(clear_module_state->__pyx_tuple__6);
  Py_CLEAR(clear_module_state->__pyx_tuple__8);
  Py_CLEAR(clear_module_state->__pyx_slice__18);
  Py_CLEAR(clear_module_state->__pyx_tuple__10);
  Py_CLEAR(clear_module_state->__pyx_tuple__11);
  Py_CLEAR(clear_module_state->__pyx_tuple__12);
  Py_CLEAR(clear_module_state->__pyx_tuple__19);
  Py_CLEAR(clear_module_state->__pyx_tuple__20);
  Py_CLEAR(clear_module_state->__pyx_tuple__21);
  Py_CLEAR(clear_module_state->__pyx_tuple__22);
  Py_CLEAR(clear_module_state->__pyx_tuple__24);
  Py_CLEAR(clear_module_state->__pyx_tuple__25);
  Py_CLEAR(clear_module_state->__pyx_tuple__27);
  Py_CLEAR(clear_module_state->__pyx_tuple__28);
  Py_CLEAR(clear_module_state->__pyx_tuple__33);
  Py_CLEAR(clear_module_state->__pyx_tuple__36);
  Py_CLEAR(clear_module_state->__pyx_tuple__37);
  Py_CLEAR(clear_module_state->__pyx_tuple__38);
  Py_CLEAR(clear_module_state->__pyx_tuple__39);
  Py_CLEAR(clear_module_state->__pyx_tuple__40);
  Py_CLEAR(clear_module_state->__pyx_tuple__41);
  Py_CLEAR(clear_module_state->__pyx_tuple__42);
  Py_CLEAR(clear_module_state->__pyx_tuple__43);
  Py_CLEAR(clear_module_state->__pyx_tuple__44);
  Py_CLEAR(clear_module_state->__pyx_tuple__45);
  Py_CLEAR(clear_module_state->__pyx_tuple__46);
  Py_CLEAR(clear_module_state->__pyx_tuple__47);
  Py_CLEAR(clear_module_state->__pyx_tuple__49);
  Py_CLEAR(clear_module_state->__pyx_tuple__50);
  Py_CLEAR(clear_module_state->__pyx_tuple__52);
  Py_CLEAR(clear_module_state->__pyx_tuple__54);
  Py_CLEAR(clear_module_state->__pyx_tuple__56);
  Py_CLEAR(clear_module_state->__pyx_tuple__58);
  Py_CLEAR(clear_module_state->__pyx_tuple__60);
  Py_CLEAR(clear_module_state->__pyx_tuple__62);
  Py_CLEAR(clear_module_state->__pyx_tuple__63);
  Py_CLEAR(clear_module_state->__pyx_tuple__65);
  Py_CLEAR(clear_module_state->__pyx_tuple__67);
  Py_CLEAR(clear_module_state->__pyx_tuple__70);
  Py_CLEAR(clear_module_state->__pyx_tuple__72);
  Py_CLEAR(clear_module_state->__pyx_tuple__74);
  Py_CLEAR(clear_module_state->__pyx_tuple__76);
  Py_CLEAR(clear_module_state->__pyx_tuple__78);
  Py_CLEAR(clear_module_state->__pyx_tuple__80);
  Py_CLEAR(clear_module_state->__pyx_tuple__82);
  Py_CLEAR(clear_module_state->__pyx_tuple__84);
  Py_CLEAR(clear_module_state->__pyx_tuple__86);
  Py_CLEAR(clear_module_state->__pyx_tuple__88);
  Py_CLEAR(clear_module_state->__pyx_codeobj__48);
  Py_CLEAR(clear_module_state->__pyx_codeobj__51);
  Py_CLEAR(clear_module_state->__pyx_codeobj__53);
  Py_CLEAR(clear_module_state->__pyx_codeobj__55);
  Py_CLEAR(clear_module_state->__pyx_codeobj__57);
  Py_CLEAR(clear_module_state->__pyx_codeobj__59);
  Py_CLEAR(clear_module_state->__pyx_codeobj__61);
  Py_CLEAR(clear_module_state->__pyx_codeobj__64);
  Py_CLEAR(clear_module_state->__pyx_codeobj__66);
  Py_CLEAR(clear_module_state->__pyx_codeobj__68);
  Py_CLEAR(clear_module_state->__pyx_codeobj__71);
  Py_CLEAR(clear_module_state->__pyx_codeobj__73);
  Py_CLEAR(clear_module_state->__pyx_codeobj__75);
  Py_CLEAR(clear_module_state->__pyx_codeobj__77);
  Py_CLEAR(clear_module_state->__pyx_codeobj__79);
  Py_CLEAR(clear_module_state->__pyx_codeobj__81);
  Py_CLEAR(clear_module_state->__pyx_codeobj__83);
  Py_CLEAR(clear_module_state->__pyx_codeobj__85);
  Py_CLEAR(clear_module_state->__pyx_codeobj__87);
  Py_CLEAR(clear_module_state->__pyx_codeobj__89);
  return 0;
}
#endif
/* #### Code section: module_state_traverse ### */
#if CYTHON_USE_MODULE_STATE
static int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) {
  __pyx_mstate *traverse_module_state = __pyx_mstate(m);
  if (!traverse_module_state) return 0;
  Py_VISIT(traverse_module_state->__pyx_d);
  Py_VISIT(traverse_module_state->__pyx_b);
  Py_VISIT(traverse_module_state->__pyx_cython_runtime);
  Py_VISIT(traverse_module_state->__pyx_empty_tuple);
  Py_VISIT(traverse_module_state->__pyx_empty_bytes);
  Py_VISIT(traverse_module_state->__pyx_empty_unicode);
  #ifdef __Pyx_CyFunction_USED
  Py_VISIT(traverse_module_state->__pyx_CyFunctionType);
  #endif
  #ifdef __Pyx_FusedFunction_USED
  Py_VISIT(traverse_module_state->__pyx_FusedFunctionType);
  #endif
  Py_VISIT(traverse_module_state->__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations);
  Py_VISIT(traverse_module_state->__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations);
  Py_VISIT(traverse_module_state->__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr);
  Py_VISIT(traverse_module_state->__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr);
  Py_VISIT(traverse_module_state->__pyx_kp_u_AI_generated_query_appears_more);
  Py_VISIT(traverse_module_state->__pyx_kp_u_AI_service_not_available_for_SQL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_AI_service_or_database_connectio);
  Py_VISIT(traverse_module_state->__pyx_kp_u_ALTER_operations_are_not_allowed);
  Py_VISIT(traverse_module_state->__pyx_kp_u_AS_avg);
  Py_VISIT(traverse_module_state->__pyx_kp_u_AS_max);
  Py_VISIT(traverse_module_state->__pyx_kp_u_AS_min);
  Py_VISIT(traverse_module_state->__pyx_kp_u_ATTACH_DATABASE_operations_are_n);
  Py_VISIT(traverse_module_state->__pyx_kp_u_AVG);
  Py_VISIT(traverse_module_state->__pyx_n_s_Any);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Asking_AI_to_fix_SQL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Attempt);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Blocked_dangerous_SQL_operation);
  Py_VISIT(traverse_module_state->__pyx_kp_u_COUNT_as_count_FROM);
  Py_VISIT(traverse_module_state->__pyx_kp_u_CREATE_operations_are_not_allowe);
  Py_VISIT(traverse_module_state->__pyx_kp_s_Class_for_building_and_testing);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Columns);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Connected_to_database);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Count_records_in);
  Py_VISIT(traverse_module_state->__pyx_kp_u_DATABASE_CONTEXT);
  Py_VISIT(traverse_module_state->__pyx_kp_u_DATABASE_SCHEMA_INFORMATION);
  Py_VISIT(traverse_module_state->__pyx_kp_u_DELETE_operations_are_not_allowe);
  Py_VISIT(traverse_module_state->__pyx_kp_u_DETACH_DATABASE_operations_are_n);
  Py_VISIT(traverse_module_state->__pyx_n_s_DOTALL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_DROP_operations_are_not_allowed);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Database_connection_closed);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Database_file_not_found);
  Py_VISIT(traverse_module_state->__pyx_n_s_Dict);
  Py_VISIT(traverse_module_state->__pyx_kp_u_ERROR_MESSAGE);
  Py_VISIT(traverse_module_state->__pyx_kp_u_EXPLANATION);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Equal_relevance_using_historical);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_connecting_to_database);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_during_AI_retry);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_during_retry_attempt);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_executing_count_exploratio);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_executing_query);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_executing_relationship_exp);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_executing_time_exploration);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_exploring_database_schema);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_exploring_table);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Error_generating_SQL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_FROM);
  Py_VISIT(traverse_module_state->__pyx_kp_u_FROM_s_a_zA_Z0_9);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Failed_to_check_existing_logs);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Failed_to_fix_SQL_after);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Failed_to_generate_SQL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Failed_to_log_corrected_SQL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Found_previous_working_SQL_for_t);
  Py_VISIT(traverse_module_state->__pyx_kp_u_GROUP_BY);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Generated_fixed_SQL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Historical_query_appears_more_re);
  Py_VISIT(traverse_module_state->__pyx_n_s_IGNORECASE);
  Py_VISIT(traverse_module_state->__pyx_kp_u_INSERT_operations_are_not_allowe);
  Py_VISIT(traverse_module_state->__pyx_kp_u_INSTRUCTIONS_1_Generate_a_valid);
  Py_VISIT(traverse_module_state->__pyx_kp_u_JOIN);
  Py_VISIT(traverse_module_state->__pyx_kp_u_JOIN_s_a_zA_Z0_9);
  Py_VISIT(traverse_module_state->__pyx_kp_u_LIMIT_3);
  Py_VISIT(traverse_module_state->__pyx_n_s_List);
  Py_VISIT(traverse_module_state->__pyx_kp_s_List_Dict);
  Py_VISIT(traverse_module_state->__pyx_kp_s_List_str);
  Py_VISIT(traverse_module_state->__pyx_kp_u_MAX);
  Py_VISIT(traverse_module_state->__pyx_kp_u_MIN);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Neither_query_executed_successfu);
  Py_VISIT(traverse_module_state->__pyx_kp_u_No_SQL);
  Py_VISIT(traverse_module_state->__pyx_kp_u_No_SQL_query_provided);
  Py_VISIT(traverse_module_state->__pyx_kp_u_No_database_connection_available);
  Py_VISIT(traverse_module_state->__pyx_kp_u_No_description);
  Py_VISIT(traverse_module_state->__pyx_kp_u_No_original_SQL_available);
  Py_VISIT(traverse_module_state->__pyx_n_s_None);
  Py_VISIT(traverse_module_state->__pyx_kp_u_None);
  Py_VISIT(traverse_module_state->__pyx_kp_u_ON);
  Py_VISIT(traverse_module_state->__pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5);
  Py_VISIT(traverse_module_state->__pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Only_AI_generated_query_executed);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Only_historical_query_executed_s);
  Py_VISIT(traverse_module_state->__pyx_n_s_Optional);
  Py_VISIT(traverse_module_state->__pyx_kp_s_Optional_Dict);
  Py_VISIT(traverse_module_state->__pyx_kp_s_Optional_str);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Original_error);
  Py_VISIT(traverse_module_state->__pyx_kp_u_PRAGMA_operations_are_not_allowe);
  Py_VISIT(traverse_module_state->__pyx_kp_u_PRAGMA_table_info);
  Py_VISIT(traverse_module_state->__pyx_kp_u_PREVIOUSLY_RUN_QUERY_FOR_SIMILA);
  Py_VISIT(traverse_module_state->__pyx_kp_u_PREVIOUS_CORRECTION_ATTEMPTS);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Previous_SQL_attempt_failed_wit);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Query);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Query_comparison_complete_Recomm);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Query_executed_successfully);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Query_returned);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Query_returned_no_results);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Question);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Reason);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Relationship_count_between);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Relevant_Columns);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Relevant_Tables);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Relevant_Tables_in_Context);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Result);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Results);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Retry_attempt);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SELECT);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SELECT_COUNT_AS_record_count_FRO);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SELECT_COUNT_DISTINCT);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SELECT_FROM);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SELECT_name_FROM_sqlite_master_W);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SQL);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder___init);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__clean_text);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__create_sql_correctio);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__create_sql_generatio);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__evaluate_query_relev);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__explore_database_sch);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__explore_table_schema);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__extract_explanation);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__extract_sql_from_res);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__extract_table_names);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__generate_result_summ);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder__validate_safe_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_close_connection);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_compare_queries);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_connect_database);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_generate_additional_e);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_generate_additional_e_2);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_generate_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_get_best_sql_and_resu);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_test_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_SQLBuilder_try_fix_failed_query);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SQL_Query_Builder_only_supports);
  Py_VISIT(traverse_module_state->__pyx_kp_u_SQL_fixed_on_attempt);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Sample_data);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Sample_of_first_3_rows);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Security_restriction);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Security_restriction_Only_SELECT);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Shows_the_distribution_of_values);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Shows_the_number_of_connections);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Shows_the_total_number_of_record);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Statistical_summary);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Statistical_summary_for);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Statistical_summary_of_numeric_v);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Stats_exploration_failed_and_cou);
  Py_VISIT(traverse_module_state->__pyx_kp_u_TASK_1_Analyze_the_error_messag);
  Py_VISIT(traverse_module_state->__pyx_kp_u_TRUNCATE_operations_are_not_allo);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Table);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Table_Relationships);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Table_Relationships_in_Context);
  Py_VISIT(traverse_module_state->__pyx_kp_u_This_SQL_was_reused_from_a_previ);
  Py_VISIT(traverse_module_state->__pyx_kp_u_This_working_SQL_has_been_verif);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Time_distribution_for);
  Py_VISIT(traverse_module_state->__pyx_n_s_Timestamp);
  Py_VISIT(traverse_module_state->__pyx_n_s_Tuple);
  Py_VISIT(traverse_module_state->__pyx_kp_u_UPDATE_operations_are_not_allowe);
  Py_VISIT(traverse_module_state->__pyx_n_s_Union);
  Py_VISIT(traverse_module_state->__pyx_n_u_Unknown);
  Py_VISIT(traverse_module_state->__pyx_kp_u_Unknown_error);
  Py_VISIT(traverse_module_state->__pyx_kp_u_VACUUM_operations_are_not_allowe);
  Py_VISIT(traverse_module_state->__pyx_kp_u_You_are_an_expert_SQL_developer);
  Py_VISIT(traverse_module_state->__pyx_kp_u_You_are_an_expert_SQL_developer_2);
  Py_VISIT(traverse_module_state->__pyx_kp_u_You_should_strongly_consider_usi);
  Py_VISIT(traverse_module_state->__pyx_kp_u__13);
  Py_VISIT(traverse_module_state->__pyx_kp_u__14);
  Py_VISIT(traverse_module_state->__pyx_kp_u__15);
  Py_VISIT(traverse_module_state->__pyx_kp_u__16);
  Py_VISIT(traverse_module_state->__pyx_kp_u__17);
  Py_VISIT(traverse_module_state->__pyx_kp_u__23);
  Py_VISIT(traverse_module_state->__pyx_kp_u__26);
  Py_VISIT(traverse_module_state->__pyx_kp_u__29);
  Py_VISIT(traverse_module_state->__pyx_kp_u__30);
  Py_VISIT(traverse_module_state->__pyx_kp_u__31);
  Py_VISIT(traverse_module_state->__pyx_kp_u__32);
  Py_VISIT(traverse_module_state->__pyx_kp_u__34);
  Py_VISIT(traverse_module_state->__pyx_kp_u__35);
  Py_VISIT(traverse_module_state->__pyx_n_s__69);
  Py_VISIT(traverse_module_state->__pyx_kp_u__7);
  Py_VISIT(traverse_module_state->__pyx_n_s__9);
  Py_VISIT(traverse_module_state->__pyx_n_s__90);
  Py_VISIT(traverse_module_state->__pyx_n_s_additional_explorations);
  Py_VISIT(traverse_module_state->__pyx_n_u_additional_explorations);
  Py_VISIT(traverse_module_state->__pyx_n_s_agg_parts);
  Py_VISIT(traverse_module_state->__pyx_n_u_ai);
  Py_VISIT(traverse_module_state->__pyx_n_s_ai_base);
  Py_VISIT(traverse_module_state->__pyx_n_u_ai_generated);
  Py_VISIT(traverse_module_state->__pyx_n_s_ai_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_ai_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_ai_query_retry_info);
  Py_VISIT(traverse_module_state->__pyx_n_u_ai_relevance_score);
  Py_VISIT(traverse_module_state->__pyx_n_u_ai_retry_attempt);
  Py_VISIT(traverse_module_state->__pyx_n_s_ai_score);
  Py_VISIT(traverse_module_state->__pyx_n_u_ai_success);
  Py_VISIT(traverse_module_state->__pyx_n_u_alter);
  Py_VISIT(traverse_module_state->__pyx_kp_u_and);
  Py_VISIT(traverse_module_state->__pyx_n_s_append);
  Py_VISIT(traverse_module_state->__pyx_n_s_args);
  Py_VISIT(traverse_module_state->__pyx_kp_u_as_distinct_connections_FROM);
  Py_VISIT(traverse_module_state->__pyx_n_s_asyncio_coroutines);
  Py_VISIT(traverse_module_state->__pyx_kp_u_attach);
  Py_VISIT(traverse_module_state->__pyx_n_s_attempt);
  Py_VISIT(traverse_module_state->__pyx_n_s_attempts);
  Py_VISIT(traverse_module_state->__pyx_n_u_attempts);
  Py_VISIT(traverse_module_state->__pyx_kp_u_attempts_Original_error);
  Py_VISIT(traverse_module_state->__pyx_kp_u_b);
  Py_VISIT(traverse_module_state->__pyx_kp_u_bSELECT_b);
  Py_VISIT(traverse_module_state->__pyx_kp_u_b_w_4_b);
  Py_VISIT(traverse_module_state->__pyx_n_s_best_attempt);
  Py_VISIT(traverse_module_state->__pyx_n_u_best_attempt);
  Py_VISIT(traverse_module_state->__pyx_n_u_best_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_between);
  Py_VISIT(traverse_module_state->__pyx_n_s_block);
  Py_VISIT(traverse_module_state->__pyx_n_s_bool);
  Py_VISIT(traverse_module_state->__pyx_n_s_check_same_thread);
  Py_VISIT(traverse_module_state->__pyx_n_s_clean_text);
  Py_VISIT(traverse_module_state->__pyx_n_s_cleaned_explanation);
  Py_VISIT(traverse_module_state->__pyx_n_s_cleaned_response);
  Py_VISIT(traverse_module_state->__pyx_n_s_cleaned_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_clear_history);
  Py_VISIT(traverse_module_state->__pyx_n_s_cline_in_traceback);
  Py_VISIT(traverse_module_state->__pyx_n_s_close);
  Py_VISIT(traverse_module_state->__pyx_n_s_close_connection);
  Py_VISIT(traverse_module_state->__pyx_n_s_code_block_pattern);
  Py_VISIT(traverse_module_state->__pyx_n_s_code_blocks);
  Py_VISIT(traverse_module_state->__pyx_n_s_col);
  Py_VISIT(traverse_module_state->__pyx_n_s_col_name);
  Py_VISIT(traverse_module_state->__pyx_kp_u_column);
  Py_VISIT(traverse_module_state->__pyx_n_s_column_2);
  Py_VISIT(traverse_module_state->__pyx_n_u_column_count);
  Py_VISIT(traverse_module_state->__pyx_n_s_column_keywords);
  Py_VISIT(traverse_module_state->__pyx_n_s_column_obj);
  Py_VISIT(traverse_module_state->__pyx_kp_u_column_s);
  Py_VISIT(traverse_module_state->__pyx_n_s_columns);
  Py_VISIT(traverse_module_state->__pyx_n_u_columns);
  Py_VISIT(traverse_module_state->__pyx_n_s_columns_df);
  Py_VISIT(traverse_module_state->__pyx_n_s_compare_queries);
  Py_VISIT(traverse_module_state->__pyx_n_s_comparison);
  Py_VISIT(traverse_module_state->__pyx_n_u_comparison);
  Py_VISIT(traverse_module_state->__pyx_n_s_conditions);
  Py_VISIT(traverse_module_state->__pyx_n_s_conn);
  Py_VISIT(traverse_module_state->__pyx_n_s_connect);
  Py_VISIT(traverse_module_state->__pyx_n_u_connect);
  Py_VISIT(traverse_module_state->__pyx_n_s_connect_database);
  Py_VISIT(traverse_module_state->__pyx_n_s_count);
  Py_VISIT(traverse_module_state->__pyx_n_s_count_query);
  Py_VISIT(traverse_module_state->__pyx_kp_u_create);
  Py_VISIT(traverse_module_state->__pyx_n_s_create_sql_correction_prompt);
  Py_VISIT(traverse_module_state->__pyx_n_s_create_sql_generation_prompt);
  Py_VISIT(traverse_module_state->__pyx_n_s_dangerous_operations);
  Py_VISIT(traverse_module_state->__pyx_n_u_data);
  Py_VISIT(traverse_module_state->__pyx_kp_u_data_failed_sql_json);
  Py_VISIT(traverse_module_state->__pyx_n_s_data_type);
  Py_VISIT(traverse_module_state->__pyx_n_u_data_type);
  Py_VISIT(traverse_module_state->__pyx_n_u_database_objects);
  Py_VISIT(traverse_module_state->__pyx_n_s_database_path);
  Py_VISIT(traverse_module_state->__pyx_n_u_date);
  Py_VISIT(traverse_module_state->__pyx_n_s_date_col);
  Py_VISIT(traverse_module_state->__pyx_n_s_date_columns);
  Py_VISIT(traverse_module_state->__pyx_n_u_day);
  Py_VISIT(traverse_module_state->__pyx_n_s_db_context);
  Py_VISIT(traverse_module_state->__pyx_n_u_delete);
  Py_VISIT(traverse_module_state->__pyx_n_u_description);
  Py_VISIT(traverse_module_state->__pyx_kp_u_detach);
  Py_VISIT(traverse_module_state->__pyx_n_s_detailed_explanation);
  Py_VISIT(traverse_module_state->__pyx_n_s_df);
  Py_VISIT(traverse_module_state->__pyx_n_s_dict);
  Py_VISIT(traverse_module_state->__pyx_n_s_direct_matches);
  Py_VISIT(traverse_module_state->__pyx_n_s_direct_sql_pattern);
  Py_VISIT(traverse_module_state->__pyx_kp_u_disable);
  Py_VISIT(traverse_module_state->__pyx_n_s_doc);
  Py_VISIT(traverse_module_state->__pyx_n_u_drop);
  Py_VISIT(traverse_module_state->__pyx_n_s_dump);
  Py_VISIT(traverse_module_state->__pyx_n_s_dumps);
  Py_VISIT(traverse_module_state->__pyx_n_s_e);
  Py_VISIT(traverse_module_state->__pyx_n_s_empty);
  Py_VISIT(traverse_module_state->__pyx_kp_u_enable);
  Py_VISIT(traverse_module_state->__pyx_n_s_encoding);
  Py_VISIT(traverse_module_state->__pyx_n_s_enter);
  Py_VISIT(traverse_module_state->__pyx_n_s_entry);
  Py_VISIT(traverse_module_state->__pyx_n_s_enumerate);
  Py_VISIT(traverse_module_state->__pyx_n_s_error);
  Py_VISIT(traverse_module_state->__pyx_n_u_error);
  Py_VISIT(traverse_module_state->__pyx_n_s_error_msg);
  Py_VISIT(traverse_module_state->__pyx_n_s_escape);
  Py_VISIT(traverse_module_state->__pyx_n_s_evaluate_query_relevance);
  Py_VISIT(traverse_module_state->__pyx_n_u_execution_error);
  Py_VISIT(traverse_module_state->__pyx_n_s_exist_ok);
  Py_VISIT(traverse_module_state->__pyx_n_s_existing_logs);
  Py_VISIT(traverse_module_state->__pyx_n_u_existing_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_exists);
  Py_VISIT(traverse_module_state->__pyx_n_s_exit);
  Py_VISIT(traverse_module_state->__pyx_n_s_explanation);
  Py_VISIT(traverse_module_state->__pyx_n_u_explanation);
  Py_VISIT(traverse_module_state->__pyx_n_s_explanation_match);
  Py_VISIT(traverse_module_state->__pyx_n_s_explanation_pattern);
  Py_VISIT(traverse_module_state->__pyx_n_u_exploration_stats);
  Py_VISIT(traverse_module_state->__pyx_n_s_explorations);
  Py_VISIT(traverse_module_state->__pyx_n_s_explore_database_schema);
  Py_VISIT(traverse_module_state->__pyx_n_s_explore_table_schema);
  Py_VISIT(traverse_module_state->__pyx_n_s_extract_explanation);
  Py_VISIT(traverse_module_state->__pyx_n_s_extract_sql_from_response);
  Py_VISIT(traverse_module_state->__pyx_n_s_extract_table_names);
  Py_VISIT(traverse_module_state->__pyx_n_s_f);
  Py_VISIT(traverse_module_state->__pyx_n_s_failed_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_failed_sql);
  Py_VISIT(traverse_module_state->__pyx_kp_u_failed_sql_json);
  Py_VISIT(traverse_module_state->__pyx_n_s_file_path);
  Py_VISIT(traverse_module_state->__pyx_n_s_findall);
  Py_VISIT(traverse_module_state->__pyx_n_s_finditer);
  Py_VISIT(traverse_module_state->__pyx_n_s_first_result);
  Py_VISIT(traverse_module_state->__pyx_n_s_fixed_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_fixed_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_float);
  Py_VISIT(traverse_module_state->__pyx_n_s_from_matches);
  Py_VISIT(traverse_module_state->__pyx_n_s_from_pattern);
  Py_VISIT(traverse_module_state->__pyx_kp_u_gc);
  Py_VISIT(traverse_module_state->__pyx_n_s_generate_additional_explorations);
  Py_VISIT(traverse_module_state->__pyx_n_s_generate_result_summary);
  Py_VISIT(traverse_module_state->__pyx_n_s_generate_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_genexpr);
  Py_VISIT(traverse_module_state->__pyx_n_s_get);
  Py_VISIT(traverse_module_state->__pyx_n_s_get_best_sql_and_results);
  Py_VISIT(traverse_module_state->__pyx_n_s_get_response_sync);
  Py_VISIT(traverse_module_state->__pyx_n_s_group);
  Py_VISIT(traverse_module_state->__pyx_n_u_has_historical_match);
  Py_VISIT(traverse_module_state->__pyx_n_s_head);
  Py_VISIT(traverse_module_state->__pyx_n_s_hist_score);
  Py_VISIT(traverse_module_state->__pyx_n_u_historical);
  Py_VISIT(traverse_module_state->__pyx_n_s_historical_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_historical_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_historical_relevance_score);
  Py_VISIT(traverse_module_state->__pyx_n_u_historical_success);
  Py_VISIT(traverse_module_state->__pyx_n_s_i);
  Py_VISIT(traverse_module_state->__pyx_n_s_import);
  Py_VISIT(traverse_module_state->__pyx_n_s_indent);
  Py_VISIT(traverse_module_state->__pyx_n_s_info);
  Py_VISIT(traverse_module_state->__pyx_n_s_init);
  Py_VISIT(traverse_module_state->__pyx_n_s_init_subclass);
  Py_VISIT(traverse_module_state->__pyx_n_s_initializing);
  Py_VISIT(traverse_module_state->__pyx_n_u_insert);
  Py_VISIT(traverse_module_state->__pyx_n_s_intersection);
  Py_VISIT(traverse_module_state->__pyx_n_s_is_coroutine);
  Py_VISIT(traverse_module_state->__pyx_kp_u_isenabled);
  Py_VISIT(traverse_module_state->__pyx_n_s_isoformat);
  Py_VISIT(traverse_module_state->__pyx_n_s_items);
  Py_VISIT(traverse_module_state->__pyx_n_s_iterrows);
  Py_VISIT(traverse_module_state->__pyx_n_s_join);
  Py_VISIT(traverse_module_state->__pyx_n_u_join);
  Py_VISIT(traverse_module_state->__pyx_n_s_join_condition);
  Py_VISIT(traverse_module_state->__pyx_n_u_join_condition);
  Py_VISIT(traverse_module_state->__pyx_n_s_join_matches);
  Py_VISIT(traverse_module_state->__pyx_n_s_join_pattern);
  Py_VISIT(traverse_module_state->__pyx_n_s_json);
  Py_VISIT(traverse_module_state->__pyx_n_s_left_side);
  Py_VISIT(traverse_module_state->__pyx_n_u_link);
  Py_VISIT(traverse_module_state->__pyx_n_s_load);
  Py_VISIT(traverse_module_state->__pyx_n_s_log_e);
  Py_VISIT(traverse_module_state->__pyx_n_s_lower);
  Py_VISIT(traverse_module_state->__pyx_n_s_main);
  Py_VISIT(traverse_module_state->__pyx_n_s_main_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_main_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_makedirs);
  Py_VISIT(traverse_module_state->__pyx_n_s_match);
  Py_VISIT(traverse_module_state->__pyx_n_s_max_attempts);
  Py_VISIT(traverse_module_state->__pyx_n_u_message);
  Py_VISIT(traverse_module_state->__pyx_n_s_metaclass);
  Py_VISIT(traverse_module_state->__pyx_n_s_module);
  Py_VISIT(traverse_module_state->__pyx_kp_u_more_rows);
  Py_VISIT(traverse_module_state->__pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION);
  Py_VISIT(traverse_module_state->__pyx_n_u_name);
  Py_VISIT(traverse_module_state->__pyx_n_s_name_2);
  Py_VISIT(traverse_module_state->__pyx_n_s_name_parts);
  Py_VISIT(traverse_module_state->__pyx_n_s_normalized_sql);
  Py_VISIT(traverse_module_state->__pyx_n_u_notnull);
  Py_VISIT(traverse_module_state->__pyx_n_s_now);
  Py_VISIT(traverse_module_state->__pyx_n_s_num_cols);
  Py_VISIT(traverse_module_state->__pyx_n_s_num_rows);
  Py_VISIT(traverse_module_state->__pyx_n_s_numeric_columns);
  Py_VISIT(traverse_module_state->__pyx_n_s_open);
  Py_VISIT(traverse_module_state->__pyx_n_s_operation);
  Py_VISIT(traverse_module_state->__pyx_kp_u_or);
  Py_VISIT(traverse_module_state->__pyx_n_s_orient);
  Py_VISIT(traverse_module_state->__pyx_n_s_original_error);
  Py_VISIT(traverse_module_state->__pyx_n_u_original_error);
  Py_VISIT(traverse_module_state->__pyx_n_s_original_failed_sql);
  Py_VISIT(traverse_module_state->__pyx_n_u_original_failed_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_original_question);
  Py_VISIT(traverse_module_state->__pyx_n_s_original_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_os);
  Py_VISIT(traverse_module_state->__pyx_n_s_overlap);
  Py_VISIT(traverse_module_state->__pyx_n_s_pandas);
  Py_VISIT(traverse_module_state->__pyx_n_s_parts);
  Py_VISIT(traverse_module_state->__pyx_n_s_path);
  Py_VISIT(traverse_module_state->__pyx_n_s_pattern);
  Py_VISIT(traverse_module_state->__pyx_n_s_pd);
  Py_VISIT(traverse_module_state->__pyx_kp_s_pd_DataFrame);
  Py_VISIT(traverse_module_state->__pyx_n_u_pk);
  Py_VISIT(traverse_module_state->__pyx_kp_u_plus);
  Py_VISIT(traverse_module_state->__pyx_n_u_pragma);
  Py_VISIT(traverse_module_state->__pyx_n_s_pragma_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_prepare);
  Py_VISIT(traverse_module_state->__pyx_n_s_prev);
  Py_VISIT(traverse_module_state->__pyx_n_s_previous_attempts);
  Py_VISIT(traverse_module_state->__pyx_n_u_previously_run_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_print);
  Py_VISIT(traverse_module_state->__pyx_n_s_prompt);
  Py_VISIT(traverse_module_state->__pyx_n_s_qualname);
  Py_VISIT(traverse_module_state->__pyx_n_s_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_question);
  Py_VISIT(traverse_module_state->__pyx_n_u_question);
  Py_VISIT(traverse_module_state->__pyx_n_s_question_keywords);
  Py_VISIT(traverse_module_state->__pyx_n_u_r);
  Py_VISIT(traverse_module_state->__pyx_n_s_range);
  Py_VISIT(traverse_module_state->__pyx_n_u_raw_ai_response);
  Py_VISIT(traverse_module_state->__pyx_n_s_re);
  Py_VISIT(traverse_module_state->__pyx_n_s_read_sql_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_recommendation_reason);
  Py_VISIT(traverse_module_state->__pyx_n_u_recommended_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_records);
  Py_VISIT(traverse_module_state->__pyx_n_s_rel);
  Py_VISIT(traverse_module_state->__pyx_n_u_relation);
  Py_VISIT(traverse_module_state->__pyx_n_s_relationship_keywords);
  Py_VISIT(traverse_module_state->__pyx_n_s_relationship_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_relationships);
  Py_VISIT(traverse_module_state->__pyx_n_u_relationships);
  Py_VISIT(traverse_module_state->__pyx_n_s_response);
  Py_VISIT(traverse_module_state->__pyx_n_s_result);
  Py_VISIT(traverse_module_state->__pyx_n_u_result);
  Py_VISIT(traverse_module_state->__pyx_n_u_results);
  Py_VISIT(traverse_module_state->__pyx_n_u_retry_attempt);
  Py_VISIT(traverse_module_state->__pyx_n_s_retry_info);
  Py_VISIT(traverse_module_state->__pyx_n_s_return);
  Py_VISIT(traverse_module_state->__pyx_n_u_reused_from_failed_json);
  Py_VISIT(traverse_module_state->__pyx_n_s_right_side);
  Py_VISIT(traverse_module_state->__pyx_n_s_row);
  Py_VISIT(traverse_module_state->__pyx_n_s_row_count);
  Py_VISIT(traverse_module_state->__pyx_n_u_row_count);
  Py_VISIT(traverse_module_state->__pyx_kp_u_row_s_with);
  Py_VISIT(traverse_module_state->__pyx_kp_u_rows_returned);
  Py_VISIT(traverse_module_state->__pyx_n_s_sQQideR_SQLBuilder);
  Py_VISIT(traverse_module_state->__pyx_kp_s_sQQideR_SQLBuilder_pyx);
  Py_VISIT(traverse_module_state->__pyx_n_s_sample);
  Py_VISIT(traverse_module_state->__pyx_n_s_sample_data);
  Py_VISIT(traverse_module_state->__pyx_n_u_sample_data);
  Py_VISIT(traverse_module_state->__pyx_n_s_sample_df);
  Py_VISIT(traverse_module_state->__pyx_n_s_sample_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_schema_info);
  Py_VISIT(traverse_module_state->__pyx_n_s_score);
  Py_VISIT(traverse_module_state->__pyx_n_s_search);
  Py_VISIT(traverse_module_state->__pyx_kp_u_select);
  Py_VISIT(traverse_module_state->__pyx_n_s_self);
  Py_VISIT(traverse_module_state->__pyx_n_s_send);
  Py_VISIT(traverse_module_state->__pyx_n_s_set_name);
  Py_VISIT(traverse_module_state->__pyx_n_s_source);
  Py_VISIT(traverse_module_state->__pyx_n_u_source);
  Py_VISIT(traverse_module_state->__pyx_n_s_spec);
  Py_VISIT(traverse_module_state->__pyx_n_s_split);
  Py_VISIT(traverse_module_state->__pyx_n_s_sql);
  Py_VISIT(traverse_module_state->__pyx_n_u_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_sql_query);
  Py_VISIT(traverse_module_state->__pyx_kp_u_sql_s);
  Py_VISIT(traverse_module_state->__pyx_n_s_sqlite3);
  Py_VISIT(traverse_module_state->__pyx_n_s_stats_query_dict);
  Py_VISIT(traverse_module_state->__pyx_n_s_str);
  Py_VISIT(traverse_module_state->__pyx_n_s_strip);
  Py_VISIT(traverse_module_state->__pyx_kp_u_succeeded);
  Py_VISIT(traverse_module_state->__pyx_n_u_success);
  Py_VISIT(traverse_module_state->__pyx_n_s_summary);
  Py_VISIT(traverse_module_state->__pyx_n_u_summary);
  Py_VISIT(traverse_module_state->__pyx_n_s_super);
  Py_VISIT(traverse_module_state->__pyx_kp_u_table);
  Py_VISIT(traverse_module_state->__pyx_n_s_table_2);
  Py_VISIT(traverse_module_state->__pyx_n_s_table_info);
  Py_VISIT(traverse_module_state->__pyx_n_s_table_name);
  Py_VISIT(traverse_module_state->__pyx_n_u_table_name);
  Py_VISIT(traverse_module_state->__pyx_n_s_table_names);
  Py_VISIT(traverse_module_state->__pyx_n_s_table_obj);
  Py_VISIT(traverse_module_state->__pyx_n_s_tables);
  Py_VISIT(traverse_module_state->__pyx_n_u_tables);
  Py_VISIT(traverse_module_state->__pyx_n_s_tables_df);
  Py_VISIT(traverse_module_state->__pyx_n_s_tables_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_tables_used);
  Py_VISIT(traverse_module_state->__pyx_n_s_target);
  Py_VISIT(traverse_module_state->__pyx_n_u_target);
  Py_VISIT(traverse_module_state->__pyx_n_s_test);
  Py_VISIT(traverse_module_state->__pyx_n_s_test_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_tested_query);
  Py_VISIT(traverse_module_state->__pyx_n_s_text);
  Py_VISIT(traverse_module_state->__pyx_n_s_throw);
  Py_VISIT(traverse_module_state->__pyx_n_u_time);
  Py_VISIT(traverse_module_state->__pyx_n_s_time_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_timestamp);
  Py_VISIT(traverse_module_state->__pyx_kp_u_to);
  Py_VISIT(traverse_module_state->__pyx_n_s_to_dict);
  Py_VISIT(traverse_module_state->__pyx_n_s_to_string);
  Py_VISIT(traverse_module_state->__pyx_n_u_truncate);
  Py_VISIT(traverse_module_state->__pyx_n_s_try_fix_failed_query);
  Py_VISIT(traverse_module_state->__pyx_n_u_type);
  Py_VISIT(traverse_module_state->__pyx_n_s_typing);
  Py_VISIT(traverse_module_state->__pyx_n_s_update);
  Py_VISIT(traverse_module_state->__pyx_n_u_update);
  Py_VISIT(traverse_module_state->__pyx_kp_u_utf_8);
  Py_VISIT(traverse_module_state->__pyx_kp_u_vacuum);
  Py_VISIT(traverse_module_state->__pyx_n_s_val);
  Py_VISIT(traverse_module_state->__pyx_n_s_validate_safe_sql);
  Py_VISIT(traverse_module_state->__pyx_n_s_validation_error);
  Py_VISIT(traverse_module_state->__pyx_n_s_verbose);
  Py_VISIT(traverse_module_state->__pyx_n_u_w);
  Py_VISIT(traverse_module_state->__pyx_n_u_where);
  Py_VISIT(traverse_module_state->__pyx_n_s_working_sql);
  Py_VISIT(traverse_module_state->__pyx_n_u_working_sql);
  Py_VISIT(traverse_module_state->__pyx_float_0_0);
  Py_VISIT(traverse_module_state->__pyx_float_0_5);
  Py_VISIT(traverse_module_state->__pyx_float_5_0);
  Py_VISIT(traverse_module_state->__pyx_int_0);
  Py_VISIT(traverse_module_state->__pyx_int_1);
  Py_VISIT(traverse_module_state->__pyx_int_2);
  Py_VISIT(traverse_module_state->__pyx_int_3);
  Py_VISIT(traverse_module_state->__pyx_int_5);
  Py_VISIT(traverse_module_state->__pyx_int_20);
  Py_VISIT(traverse_module_state->__pyx_int_100);
  Py_VISIT(traverse_module_state->__pyx_tuple_);
  Py_VISIT(traverse_module_state->__pyx_tuple__2);
  Py_VISIT(traverse_module_state->__pyx_tuple__3);
  Py_VISIT(traverse_module_state->__pyx_tuple__4);
  Py_VISIT(traverse_module_state->__pyx_tuple__5);
  Py_VISIT(traverse_module_state->__pyx_tuple__6);
  Py_VISIT(traverse_module_state->__pyx_tuple__8);
  Py_VISIT(traverse_module_state->__pyx_slice__18);
  Py_VISIT(traverse_module_state->__pyx_tuple__10);
  Py_VISIT(traverse_module_state->__pyx_tuple__11);
  Py_VISIT(traverse_module_state->__pyx_tuple__12);
  Py_VISIT(traverse_module_state->__pyx_tuple__19);
  Py_VISIT(traverse_module_state->__pyx_tuple__20);
  Py_VISIT(traverse_module_state->__pyx_tuple__21);
  Py_VISIT(traverse_module_state->__pyx_tuple__22);
  Py_VISIT(traverse_module_state->__pyx_tuple__24);
  Py_VISIT(traverse_module_state->__pyx_tuple__25);
  Py_VISIT(traverse_module_state->__pyx_tuple__27);
  Py_VISIT(traverse_module_state->__pyx_tuple__28);
  Py_VISIT(traverse_module_state->__pyx_tuple__33);
  Py_VISIT(traverse_module_state->__pyx_tuple__36);
  Py_VISIT(traverse_module_state->__pyx_tuple__37);
  Py_VISIT(traverse_module_state->__pyx_tuple__38);
  Py_VISIT(traverse_module_state->__pyx_tuple__39);
  Py_VISIT(traverse_module_state->__pyx_tuple__40);
  Py_VISIT(traverse_module_state->__pyx_tuple__41);
  Py_VISIT(traverse_module_state->__pyx_tuple__42);
  Py_VISIT(traverse_module_state->__pyx_tuple__43);
  Py_VISIT(traverse_module_state->__pyx_tuple__44);
  Py_VISIT(traverse_module_state->__pyx_tuple__45);
  Py_VISIT(traverse_module_state->__pyx_tuple__46);
  Py_VISIT(traverse_module_state->__pyx_tuple__47);
  Py_VISIT(traverse_module_state->__pyx_tuple__49);
  Py_VISIT(traverse_module_state->__pyx_tuple__50);
  Py_VISIT(traverse_module_state->__pyx_tuple__52);
  Py_VISIT(traverse_module_state->__pyx_tuple__54);
  Py_VISIT(traverse_module_state->__pyx_tuple__56);
  Py_VISIT(traverse_module_state->__pyx_tuple__58);
  Py_VISIT(traverse_module_state->__pyx_tuple__60);
  Py_VISIT(traverse_module_state->__pyx_tuple__62);
  Py_VISIT(traverse_module_state->__pyx_tuple__63);
  Py_VISIT(traverse_module_state->__pyx_tuple__65);
  Py_VISIT(traverse_module_state->__pyx_tuple__67);
  Py_VISIT(traverse_module_state->__pyx_tuple__70);
  Py_VISIT(traverse_module_state->__pyx_tuple__72);
  Py_VISIT(traverse_module_state->__pyx_tuple__74);
  Py_VISIT(traverse_module_state->__pyx_tuple__76);
  Py_VISIT(traverse_module_state->__pyx_tuple__78);
  Py_VISIT(traverse_module_state->__pyx_tuple__80);
  Py_VISIT(traverse_module_state->__pyx_tuple__82);
  Py_VISIT(traverse_module_state->__pyx_tuple__84);
  Py_VISIT(traverse_module_state->__pyx_tuple__86);
  Py_VISIT(traverse_module_state->__pyx_tuple__88);
  Py_VISIT(traverse_module_state->__pyx_codeobj__48);
  Py_VISIT(traverse_module_state->__pyx_codeobj__51);
  Py_VISIT(traverse_module_state->__pyx_codeobj__53);
  Py_VISIT(traverse_module_state->__pyx_codeobj__55);
  Py_VISIT(traverse_module_state->__pyx_codeobj__57);
  Py_VISIT(traverse_module_state->__pyx_codeobj__59);
  Py_VISIT(traverse_module_state->__pyx_codeobj__61);
  Py_VISIT(traverse_module_state->__pyx_codeobj__64);
  Py_VISIT(traverse_module_state->__pyx_codeobj__66);
  Py_VISIT(traverse_module_state->__pyx_codeobj__68);
  Py_VISIT(traverse_module_state->__pyx_codeobj__71);
  Py_VISIT(traverse_module_state->__pyx_codeobj__73);
  Py_VISIT(traverse_module_state->__pyx_codeobj__75);
  Py_VISIT(traverse_module_state->__pyx_codeobj__77);
  Py_VISIT(traverse_module_state->__pyx_codeobj__79);
  Py_VISIT(traverse_module_state->__pyx_codeobj__81);
  Py_VISIT(traverse_module_state->__pyx_codeobj__83);
  Py_VISIT(traverse_module_state->__pyx_codeobj__85);
  Py_VISIT(traverse_module_state->__pyx_codeobj__87);
  Py_VISIT(traverse_module_state->__pyx_codeobj__89);
  return 0;
}
#endif
/* #### Code section: module_state_defines ### */
#define __pyx_d __pyx_mstate_global->__pyx_d
#define __pyx_b __pyx_mstate_global->__pyx_b
#define __pyx_cython_runtime __pyx_mstate_global->__pyx_cython_runtime
#define __pyx_empty_tuple __pyx_mstate_global->__pyx_empty_tuple
#define __pyx_empty_bytes __pyx_mstate_global->__pyx_empty_bytes
#define __pyx_empty_unicode __pyx_mstate_global->__pyx_empty_unicode
#ifdef __Pyx_CyFunction_USED
#define __pyx_CyFunctionType __pyx_mstate_global->__pyx_CyFunctionType
#endif
#ifdef __Pyx_FusedFunction_USED
#define __pyx_FusedFunctionType __pyx_mstate_global->__pyx_FusedFunctionType
#endif
#ifdef __Pyx_Generator_USED
#define __pyx_GeneratorType __pyx_mstate_global->__pyx_GeneratorType
#endif
#ifdef __Pyx_IterableCoroutine_USED
#define __pyx_IterableCoroutineType __pyx_mstate_global->__pyx_IterableCoroutineType
#endif
#ifdef __Pyx_Coroutine_USED
#define __pyx_CoroutineAwaitType __pyx_mstate_global->__pyx_CoroutineAwaitType
#endif
#ifdef __Pyx_Coroutine_USED
#define __pyx_CoroutineType __pyx_mstate_global->__pyx_CoroutineType
#endif
#if CYTHON_USE_MODULE_STATE
#define __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations __pyx_mstate_global->__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations
#define __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr __pyx_mstate_global->__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr
#endif
#define __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations __pyx_mstate_global->__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations
#define __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr __pyx_mstate_global->__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr
#define __pyx_kp_u_AI_generated_query_appears_more __pyx_mstate_global->__pyx_kp_u_AI_generated_query_appears_more
#define __pyx_kp_u_AI_service_not_available_for_SQL __pyx_mstate_global->__pyx_kp_u_AI_service_not_available_for_SQL
#define __pyx_kp_u_AI_service_or_database_connectio __pyx_mstate_global->__pyx_kp_u_AI_service_or_database_connectio
#define __pyx_kp_u_ALTER_operations_are_not_allowed __pyx_mstate_global->__pyx_kp_u_ALTER_operations_are_not_allowed
#define __pyx_kp_u_AS_avg __pyx_mstate_global->__pyx_kp_u_AS_avg
#define __pyx_kp_u_AS_max __pyx_mstate_global->__pyx_kp_u_AS_max
#define __pyx_kp_u_AS_min __pyx_mstate_global->__pyx_kp_u_AS_min
#define __pyx_kp_u_ATTACH_DATABASE_operations_are_n __pyx_mstate_global->__pyx_kp_u_ATTACH_DATABASE_operations_are_n
#define __pyx_kp_u_AVG __pyx_mstate_global->__pyx_kp_u_AVG
#define __pyx_n_s_Any __pyx_mstate_global->__pyx_n_s_Any
#define __pyx_kp_u_Asking_AI_to_fix_SQL __pyx_mstate_global->__pyx_kp_u_Asking_AI_to_fix_SQL
#define __pyx_kp_u_Attempt __pyx_mstate_global->__pyx_kp_u_Attempt
#define __pyx_kp_u_Blocked_dangerous_SQL_operation __pyx_mstate_global->__pyx_kp_u_Blocked_dangerous_SQL_operation
#define __pyx_kp_u_COUNT_as_count_FROM __pyx_mstate_global->__pyx_kp_u_COUNT_as_count_FROM
#define __pyx_kp_u_CREATE_operations_are_not_allowe __pyx_mstate_global->__pyx_kp_u_CREATE_operations_are_not_allowe
#define __pyx_kp_s_Class_for_building_and_testing __pyx_mstate_global->__pyx_kp_s_Class_for_building_and_testing
#define __pyx_kp_u_Columns __pyx_mstate_global->__pyx_kp_u_Columns
#define __pyx_kp_u_Connected_to_database __pyx_mstate_global->__pyx_kp_u_Connected_to_database
#define __pyx_kp_u_Count_records_in __pyx_mstate_global->__pyx_kp_u_Count_records_in
#define __pyx_kp_u_DATABASE_CONTEXT __pyx_mstate_global->__pyx_kp_u_DATABASE_CONTEXT
#define __pyx_kp_u_DATABASE_SCHEMA_INFORMATION __pyx_mstate_global->__pyx_kp_u_DATABASE_SCHEMA_INFORMATION
#define __pyx_kp_u_DELETE_operations_are_not_allowe __pyx_mstate_global->__pyx_kp_u_DELETE_operations_are_not_allowe
#define __pyx_kp_u_DETACH_DATABASE_operations_are_n __pyx_mstate_global->__pyx_kp_u_DETACH_DATABASE_operations_are_n
#define __pyx_n_s_DOTALL __pyx_mstate_global->__pyx_n_s_DOTALL
#define __pyx_kp_u_DROP_operations_are_not_allowed __pyx_mstate_global->__pyx_kp_u_DROP_operations_are_not_allowed
#define __pyx_kp_u_Database_connection_closed __pyx_mstate_global->__pyx_kp_u_Database_connection_closed
#define __pyx_kp_u_Database_file_not_found __pyx_mstate_global->__pyx_kp_u_Database_file_not_found
#define __pyx_n_s_Dict __pyx_mstate_global->__pyx_n_s_Dict
#define __pyx_kp_u_ERROR_MESSAGE __pyx_mstate_global->__pyx_kp_u_ERROR_MESSAGE
#define __pyx_kp_u_EXPLANATION __pyx_mstate_global->__pyx_kp_u_EXPLANATION
#define __pyx_kp_u_Equal_relevance_using_historical __pyx_mstate_global->__pyx_kp_u_Equal_relevance_using_historical
#define __pyx_kp_u_Error __pyx_mstate_global->__pyx_kp_u_Error
#define __pyx_kp_u_Error_connecting_to_database __pyx_mstate_global->__pyx_kp_u_Error_connecting_to_database
#define __pyx_kp_u_Error_during_AI_retry __pyx_mstate_global->__pyx_kp_u_Error_during_AI_retry
#define __pyx_kp_u_Error_during_retry_attempt __pyx_mstate_global->__pyx_kp_u_Error_during_retry_attempt
#define __pyx_kp_u_Error_executing_count_exploratio __pyx_mstate_global->__pyx_kp_u_Error_executing_count_exploratio
#define __pyx_kp_u_Error_executing_query __pyx_mstate_global->__pyx_kp_u_Error_executing_query
#define __pyx_kp_u_Error_executing_relationship_exp __pyx_mstate_global->__pyx_kp_u_Error_executing_relationship_exp
#define __pyx_kp_u_Error_executing_time_exploration __pyx_mstate_global->__pyx_kp_u_Error_executing_time_exploration
#define __pyx_kp_u_Error_exploring_database_schema __pyx_mstate_global->__pyx_kp_u_Error_exploring_database_schema
#define __pyx_kp_u_Error_exploring_table __pyx_mstate_global->__pyx_kp_u_Error_exploring_table
#define __pyx_kp_u_Error_generating_SQL __pyx_mstate_global->__pyx_kp_u_Error_generating_SQL
#define __pyx_kp_u_FROM __pyx_mstate_global->__pyx_kp_u_FROM
#define __pyx_kp_u_FROM_s_a_zA_Z0_9 __pyx_mstate_global->__pyx_kp_u_FROM_s_a_zA_Z0_9
#define __pyx_kp_u_Failed_to_check_existing_logs __pyx_mstate_global->__pyx_kp_u_Failed_to_check_existing_logs
#define __pyx_kp_u_Failed_to_fix_SQL_after __pyx_mstate_global->__pyx_kp_u_Failed_to_fix_SQL_after
#define __pyx_kp_u_Failed_to_generate_SQL __pyx_mstate_global->__pyx_kp_u_Failed_to_generate_SQL
#define __pyx_kp_u_Failed_to_log_corrected_SQL __pyx_mstate_global->__pyx_kp_u_Failed_to_log_corrected_SQL
#define __pyx_kp_u_Found_previous_working_SQL_for_t __pyx_mstate_global->__pyx_kp_u_Found_previous_working_SQL_for_t
#define __pyx_kp_u_GROUP_BY __pyx_mstate_global->__pyx_kp_u_GROUP_BY
#define __pyx_kp_u_Generated_fixed_SQL __pyx_mstate_global->__pyx_kp_u_Generated_fixed_SQL
#define __pyx_kp_u_Historical_query_appears_more_re __pyx_mstate_global->__pyx_kp_u_Historical_query_appears_more_re
#define __pyx_n_s_IGNORECASE __pyx_mstate_global->__pyx_n_s_IGNORECASE
#define __pyx_kp_u_INSERT_operations_are_not_allowe __pyx_mstate_global->__pyx_kp_u_INSERT_operations_are_not_allowe
#define __pyx_kp_u_INSTRUCTIONS_1_Generate_a_valid __pyx_mstate_global->__pyx_kp_u_INSTRUCTIONS_1_Generate_a_valid
#define __pyx_kp_u_JOIN __pyx_mstate_global->__pyx_kp_u_JOIN
#define __pyx_kp_u_JOIN_s_a_zA_Z0_9 __pyx_mstate_global->__pyx_kp_u_JOIN_s_a_zA_Z0_9
#define __pyx_kp_u_LIMIT_3 __pyx_mstate_global->__pyx_kp_u_LIMIT_3
#define __pyx_n_s_List __pyx_mstate_global->__pyx_n_s_List
#define __pyx_kp_s_List_Dict __pyx_mstate_global->__pyx_kp_s_List_Dict
#define __pyx_kp_s_List_str __pyx_mstate_global->__pyx_kp_s_List_str
#define __pyx_kp_u_MAX __pyx_mstate_global->__pyx_kp_u_MAX
#define __pyx_kp_u_MIN __pyx_mstate_global->__pyx_kp_u_MIN
#define __pyx_kp_u_Neither_query_executed_successfu __pyx_mstate_global->__pyx_kp_u_Neither_query_executed_successfu
#define __pyx_kp_u_No_SQL __pyx_mstate_global->__pyx_kp_u_No_SQL
#define __pyx_kp_u_No_SQL_query_provided __pyx_mstate_global->__pyx_kp_u_No_SQL_query_provided
#define __pyx_kp_u_No_database_connection_available __pyx_mstate_global->__pyx_kp_u_No_database_connection_available
#define __pyx_kp_u_No_description __pyx_mstate_global->__pyx_kp_u_No_description
#define __pyx_kp_u_No_original_SQL_available __pyx_mstate_global->__pyx_kp_u_No_original_SQL_available
#define __pyx_n_s_None __pyx_mstate_global->__pyx_n_s_None
#define __pyx_kp_u_None __pyx_mstate_global->__pyx_kp_u_None
#define __pyx_kp_u_ON __pyx_mstate_global->__pyx_kp_u_ON
#define __pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5 __pyx_mstate_global->__pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5
#define __pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED __pyx_mstate_global->__pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED
#define __pyx_kp_u_Only_AI_generated_query_executed __pyx_mstate_global->__pyx_kp_u_Only_AI_generated_query_executed
#define __pyx_kp_u_Only_historical_query_executed_s __pyx_mstate_global->__pyx_kp_u_Only_historical_query_executed_s
#define __pyx_n_s_Optional __pyx_mstate_global->__pyx_n_s_Optional
#define __pyx_kp_s_Optional_Dict __pyx_mstate_global->__pyx_kp_s_Optional_Dict
#define __pyx_kp_s_Optional_str __pyx_mstate_global->__pyx_kp_s_Optional_str
#define __pyx_kp_u_Original_error __pyx_mstate_global->__pyx_kp_u_Original_error
#define __pyx_kp_u_PRAGMA_operations_are_not_allowe __pyx_mstate_global->__pyx_kp_u_PRAGMA_operations_are_not_allowe
#define __pyx_kp_u_PRAGMA_table_info __pyx_mstate_global->__pyx_kp_u_PRAGMA_table_info
#define __pyx_kp_u_PREVIOUSLY_RUN_QUERY_FOR_SIMILA __pyx_mstate_global->__pyx_kp_u_PREVIOUSLY_RUN_QUERY_FOR_SIMILA
#define __pyx_kp_u_PREVIOUS_CORRECTION_ATTEMPTS __pyx_mstate_global->__pyx_kp_u_PREVIOUS_CORRECTION_ATTEMPTS
#define __pyx_kp_u_Previous_SQL_attempt_failed_wit __pyx_mstate_global->__pyx_kp_u_Previous_SQL_attempt_failed_wit
#define __pyx_kp_u_Query __pyx_mstate_global->__pyx_kp_u_Query
#define __pyx_kp_u_Query_comparison_complete_Recomm __pyx_mstate_global->__pyx_kp_u_Query_comparison_complete_Recomm
#define __pyx_kp_u_Query_executed_successfully __pyx_mstate_global->__pyx_kp_u_Query_executed_successfully
#define __pyx_kp_u_Query_returned __pyx_mstate_global->__pyx_kp_u_Query_returned
#define __pyx_kp_u_Query_returned_no_results __pyx_mstate_global->__pyx_kp_u_Query_returned_no_results
#define __pyx_kp_u_Question __pyx_mstate_global->__pyx_kp_u_Question
#define __pyx_kp_u_Reason __pyx_mstate_global->__pyx_kp_u_Reason
#define __pyx_kp_u_Relationship_count_between __pyx_mstate_global->__pyx_kp_u_Relationship_count_between
#define __pyx_kp_u_Relevant_Columns __pyx_mstate_global->__pyx_kp_u_Relevant_Columns
#define __pyx_kp_u_Relevant_Tables __pyx_mstate_global->__pyx_kp_u_Relevant_Tables
#define __pyx_kp_u_Relevant_Tables_in_Context __pyx_mstate_global->__pyx_kp_u_Relevant_Tables_in_Context
#define __pyx_kp_u_Result __pyx_mstate_global->__pyx_kp_u_Result
#define __pyx_kp_u_Results __pyx_mstate_global->__pyx_kp_u_Results
#define __pyx_kp_u_Retry_attempt __pyx_mstate_global->__pyx_kp_u_Retry_attempt
#define __pyx_kp_u_SELECT __pyx_mstate_global->__pyx_kp_u_SELECT
#define __pyx_kp_u_SELECT_COUNT_AS_record_count_FRO __pyx_mstate_global->__pyx_kp_u_SELECT_COUNT_AS_record_count_FRO
#define __pyx_kp_u_SELECT_COUNT_DISTINCT __pyx_mstate_global->__pyx_kp_u_SELECT_COUNT_DISTINCT
#define __pyx_kp_u_SELECT_FROM __pyx_mstate_global->__pyx_kp_u_SELECT_FROM
#define __pyx_kp_u_SELECT_name_FROM_sqlite_master_W __pyx_mstate_global->__pyx_kp_u_SELECT_name_FROM_sqlite_master_W
#define __pyx_kp_u_SQL __pyx_mstate_global->__pyx_kp_u_SQL
#define __pyx_n_s_SQLBuilder __pyx_mstate_global->__pyx_n_s_SQLBuilder
#define __pyx_n_s_SQLBuilder___init __pyx_mstate_global->__pyx_n_s_SQLBuilder___init
#define __pyx_n_s_SQLBuilder__clean_text __pyx_mstate_global->__pyx_n_s_SQLBuilder__clean_text
#define __pyx_n_s_SQLBuilder__create_sql_correctio __pyx_mstate_global->__pyx_n_s_SQLBuilder__create_sql_correctio
#define __pyx_n_s_SQLBuilder__create_sql_generatio __pyx_mstate_global->__pyx_n_s_SQLBuilder__create_sql_generatio
#define __pyx_n_s_SQLBuilder__evaluate_query_relev __pyx_mstate_global->__pyx_n_s_SQLBuilder__evaluate_query_relev
#define __pyx_n_s_SQLBuilder__explore_database_sch __pyx_mstate_global->__pyx_n_s_SQLBuilder__explore_database_sch
#define __pyx_n_s_SQLBuilder__explore_table_schema __pyx_mstate_global->__pyx_n_s_SQLBuilder__explore_table_schema
#define __pyx_n_s_SQLBuilder__extract_explanation __pyx_mstate_global->__pyx_n_s_SQLBuilder__extract_explanation
#define __pyx_n_s_SQLBuilder__extract_sql_from_res __pyx_mstate_global->__pyx_n_s_SQLBuilder__extract_sql_from_res
#define __pyx_n_s_SQLBuilder__extract_table_names __pyx_mstate_global->__pyx_n_s_SQLBuilder__extract_table_names
#define __pyx_n_s_SQLBuilder__generate_result_summ __pyx_mstate_global->__pyx_n_s_SQLBuilder__generate_result_summ
#define __pyx_n_s_SQLBuilder__validate_safe_sql __pyx_mstate_global->__pyx_n_s_SQLBuilder__validate_safe_sql
#define __pyx_n_s_SQLBuilder_close_connection __pyx_mstate_global->__pyx_n_s_SQLBuilder_close_connection
#define __pyx_n_s_SQLBuilder_compare_queries __pyx_mstate_global->__pyx_n_s_SQLBuilder_compare_queries
#define __pyx_n_s_SQLBuilder_connect_database __pyx_mstate_global->__pyx_n_s_SQLBuilder_connect_database
#define __pyx_n_s_SQLBuilder_generate_additional_e __pyx_mstate_global->__pyx_n_s_SQLBuilder_generate_additional_e
#define __pyx_n_s_SQLBuilder_generate_additional_e_2 __pyx_mstate_global->__pyx_n_s_SQLBuilder_generate_additional_e_2
#define __pyx_n_s_SQLBuilder_generate_sql __pyx_mstate_global->__pyx_n_s_SQLBuilder_generate_sql
#define __pyx_n_s_SQLBuilder_get_best_sql_and_resu __pyx_mstate_global->__pyx_n_s_SQLBuilder_get_best_sql_and_resu
#define __pyx_n_s_SQLBuilder_test_query __pyx_mstate_global->__pyx_n_s_SQLBuilder_test_query
#define __pyx_n_s_SQLBuilder_try_fix_failed_query __pyx_mstate_global->__pyx_n_s_SQLBuilder_try_fix_failed_query
#define __pyx_kp_u_SQL_Query_Builder_only_supports __pyx_mstate_global->__pyx_kp_u_SQL_Query_Builder_only_supports
#define __pyx_kp_u_SQL_fixed_on_attempt __pyx_mstate_global->__pyx_kp_u_SQL_fixed_on_attempt
#define __pyx_kp_u_Sample_data __pyx_mstate_global->__pyx_kp_u_Sample_data
#define __pyx_kp_u_Sample_of_first_3_rows __pyx_mstate_global->__pyx_kp_u_Sample_of_first_3_rows
#define __pyx_kp_u_Security_restriction __pyx_mstate_global->__pyx_kp_u_Security_restriction
#define __pyx_kp_u_Security_restriction_Only_SELECT __pyx_mstate_global->__pyx_kp_u_Security_restriction_Only_SELECT
#define __pyx_kp_u_Shows_the_distribution_of_values __pyx_mstate_global->__pyx_kp_u_Shows_the_distribution_of_values
#define __pyx_kp_u_Shows_the_number_of_connections __pyx_mstate_global->__pyx_kp_u_Shows_the_number_of_connections
#define __pyx_kp_u_Shows_the_total_number_of_record __pyx_mstate_global->__pyx_kp_u_Shows_the_total_number_of_record
#define __pyx_kp_u_Statistical_summary __pyx_mstate_global->__pyx_kp_u_Statistical_summary
#define __pyx_kp_u_Statistical_summary_for __pyx_mstate_global->__pyx_kp_u_Statistical_summary_for
#define __pyx_kp_u_Statistical_summary_of_numeric_v __pyx_mstate_global->__pyx_kp_u_Statistical_summary_of_numeric_v
#define __pyx_kp_u_Stats_exploration_failed_and_cou __pyx_mstate_global->__pyx_kp_u_Stats_exploration_failed_and_cou
#define __pyx_kp_u_TASK_1_Analyze_the_error_messag __pyx_mstate_global->__pyx_kp_u_TASK_1_Analyze_the_error_messag
#define __pyx_kp_u_TRUNCATE_operations_are_not_allo __pyx_mstate_global->__pyx_kp_u_TRUNCATE_operations_are_not_allo
#define __pyx_kp_u_Table __pyx_mstate_global->__pyx_kp_u_Table
#define __pyx_kp_u_Table_Relationships __pyx_mstate_global->__pyx_kp_u_Table_Relationships
#define __pyx_kp_u_Table_Relationships_in_Context __pyx_mstate_global->__pyx_kp_u_Table_Relationships_in_Context
#define __pyx_kp_u_This_SQL_was_reused_from_a_previ __pyx_mstate_global->__pyx_kp_u_This_SQL_was_reused_from_a_previ
#define __pyx_kp_u_This_working_SQL_has_been_verif __pyx_mstate_global->__pyx_kp_u_This_working_SQL_has_been_verif
#define __pyx_kp_u_Time_distribution_for __pyx_mstate_global->__pyx_kp_u_Time_distribution_for
#define __pyx_n_s_Timestamp __pyx_mstate_global->__pyx_n_s_Timestamp
#define __pyx_n_s_Tuple __pyx_mstate_global->__pyx_n_s_Tuple
#define __pyx_kp_u_UPDATE_operations_are_not_allowe __pyx_mstate_global->__pyx_kp_u_UPDATE_operations_are_not_allowe
#define __pyx_n_s_Union __pyx_mstate_global->__pyx_n_s_Union
#define __pyx_n_u_Unknown __pyx_mstate_global->__pyx_n_u_Unknown
#define __pyx_kp_u_Unknown_error __pyx_mstate_global->__pyx_kp_u_Unknown_error
#define __pyx_kp_u_VACUUM_operations_are_not_allowe __pyx_mstate_global->__pyx_kp_u_VACUUM_operations_are_not_allowe
#define __pyx_kp_u_You_are_an_expert_SQL_developer __pyx_mstate_global->__pyx_kp_u_You_are_an_expert_SQL_developer
#define __pyx_kp_u_You_are_an_expert_SQL_developer_2 __pyx_mstate_global->__pyx_kp_u_You_are_an_expert_SQL_developer_2
#define __pyx_kp_u_You_should_strongly_consider_usi __pyx_mstate_global->__pyx_kp_u_You_should_strongly_consider_usi
#define __pyx_kp_u__13 __pyx_mstate_global->__pyx_kp_u__13
#define __pyx_kp_u__14 __pyx_mstate_global->__pyx_kp_u__14
#define __pyx_kp_u__15 __pyx_mstate_global->__pyx_kp_u__15
#define __pyx_kp_u__16 __pyx_mstate_global->__pyx_kp_u__16
#define __pyx_kp_u__17 __pyx_mstate_global->__pyx_kp_u__17
#define __pyx_kp_u__23 __pyx_mstate_global->__pyx_kp_u__23
#define __pyx_kp_u__26 __pyx_mstate_global->__pyx_kp_u__26
#define __pyx_kp_u__29 __pyx_mstate_global->__pyx_kp_u__29
#define __pyx_kp_u__30 __pyx_mstate_global->__pyx_kp_u__30
#define __pyx_kp_u__31 __pyx_mstate_global->__pyx_kp_u__31
#define __pyx_kp_u__32 __pyx_mstate_global->__pyx_kp_u__32
#define __pyx_kp_u__34 __pyx_mstate_global->__pyx_kp_u__34
#define __pyx_kp_u__35 __pyx_mstate_global->__pyx_kp_u__35
#define __pyx_n_s__69 __pyx_mstate_global->__pyx_n_s__69
#define __pyx_kp_u__7 __pyx_mstate_global->__pyx_kp_u__7
#define __pyx_n_s__9 __pyx_mstate_global->__pyx_n_s__9
#define __pyx_n_s__90 __pyx_mstate_global->__pyx_n_s__90
#define __pyx_n_s_additional_explorations __pyx_mstate_global->__pyx_n_s_additional_explorations
#define __pyx_n_u_additional_explorations __pyx_mstate_global->__pyx_n_u_additional_explorations
#define __pyx_n_s_agg_parts __pyx_mstate_global->__pyx_n_s_agg_parts
#define __pyx_n_u_ai __pyx_mstate_global->__pyx_n_u_ai
#define __pyx_n_s_ai_base __pyx_mstate_global->__pyx_n_s_ai_base
#define __pyx_n_u_ai_generated __pyx_mstate_global->__pyx_n_u_ai_generated
#define __pyx_n_s_ai_query __pyx_mstate_global->__pyx_n_s_ai_query
#define __pyx_n_u_ai_query __pyx_mstate_global->__pyx_n_u_ai_query
#define __pyx_n_u_ai_query_retry_info __pyx_mstate_global->__pyx_n_u_ai_query_retry_info
#define __pyx_n_u_ai_relevance_score __pyx_mstate_global->__pyx_n_u_ai_relevance_score
#define __pyx_n_u_ai_retry_attempt __pyx_mstate_global->__pyx_n_u_ai_retry_attempt
#define __pyx_n_s_ai_score __pyx_mstate_global->__pyx_n_s_ai_score
#define __pyx_n_u_ai_success __pyx_mstate_global->__pyx_n_u_ai_success
#define __pyx_n_u_alter __pyx_mstate_global->__pyx_n_u_alter
#define __pyx_kp_u_and __pyx_mstate_global->__pyx_kp_u_and
#define __pyx_n_s_append __pyx_mstate_global->__pyx_n_s_append
#define __pyx_n_s_args __pyx_mstate_global->__pyx_n_s_args
#define __pyx_kp_u_as_distinct_connections_FROM __pyx_mstate_global->__pyx_kp_u_as_distinct_connections_FROM
#define __pyx_n_s_asyncio_coroutines __pyx_mstate_global->__pyx_n_s_asyncio_coroutines
#define __pyx_kp_u_attach __pyx_mstate_global->__pyx_kp_u_attach
#define __pyx_n_s_attempt __pyx_mstate_global->__pyx_n_s_attempt
#define __pyx_n_s_attempts __pyx_mstate_global->__pyx_n_s_attempts
#define __pyx_n_u_attempts __pyx_mstate_global->__pyx_n_u_attempts
#define __pyx_kp_u_attempts_Original_error __pyx_mstate_global->__pyx_kp_u_attempts_Original_error
#define __pyx_kp_u_b __pyx_mstate_global->__pyx_kp_u_b
#define __pyx_kp_u_bSELECT_b __pyx_mstate_global->__pyx_kp_u_bSELECT_b
#define __pyx_kp_u_b_w_4_b __pyx_mstate_global->__pyx_kp_u_b_w_4_b
#define __pyx_n_s_best_attempt __pyx_mstate_global->__pyx_n_s_best_attempt
#define __pyx_n_u_best_attempt __pyx_mstate_global->__pyx_n_u_best_attempt
#define __pyx_n_u_best_query __pyx_mstate_global->__pyx_n_u_best_query
#define __pyx_n_u_between __pyx_mstate_global->__pyx_n_u_between
#define __pyx_n_s_block __pyx_mstate_global->__pyx_n_s_block
#define __pyx_n_s_bool __pyx_mstate_global->__pyx_n_s_bool
#define __pyx_n_s_check_same_thread __pyx_mstate_global->__pyx_n_s_check_same_thread
#define __pyx_n_s_clean_text __pyx_mstate_global->__pyx_n_s_clean_text
#define __pyx_n_s_cleaned_explanation __pyx_mstate_global->__pyx_n_s_cleaned_explanation
#define __pyx_n_s_cleaned_response __pyx_mstate_global->__pyx_n_s_cleaned_response
#define __pyx_n_s_cleaned_sql __pyx_mstate_global->__pyx_n_s_cleaned_sql
#define __pyx_n_s_clear_history __pyx_mstate_global->__pyx_n_s_clear_history
#define __pyx_n_s_cline_in_traceback __pyx_mstate_global->__pyx_n_s_cline_in_traceback
#define __pyx_n_s_close __pyx_mstate_global->__pyx_n_s_close
#define __pyx_n_s_close_connection __pyx_mstate_global->__pyx_n_s_close_connection
#define __pyx_n_s_code_block_pattern __pyx_mstate_global->__pyx_n_s_code_block_pattern
#define __pyx_n_s_code_blocks __pyx_mstate_global->__pyx_n_s_code_blocks
#define __pyx_n_s_col __pyx_mstate_global->__pyx_n_s_col
#define __pyx_n_s_col_name __pyx_mstate_global->__pyx_n_s_col_name
#define __pyx_kp_u_column __pyx_mstate_global->__pyx_kp_u_column
#define __pyx_n_s_column_2 __pyx_mstate_global->__pyx_n_s_column_2
#define __pyx_n_u_column_count __pyx_mstate_global->__pyx_n_u_column_count
#define __pyx_n_s_column_keywords __pyx_mstate_global->__pyx_n_s_column_keywords
#define __pyx_n_s_column_obj __pyx_mstate_global->__pyx_n_s_column_obj
#define __pyx_kp_u_column_s __pyx_mstate_global->__pyx_kp_u_column_s
#define __pyx_n_s_columns __pyx_mstate_global->__pyx_n_s_columns
#define __pyx_n_u_columns __pyx_mstate_global->__pyx_n_u_columns
#define __pyx_n_s_columns_df __pyx_mstate_global->__pyx_n_s_columns_df
#define __pyx_n_s_compare_queries __pyx_mstate_global->__pyx_n_s_compare_queries
#define __pyx_n_s_comparison __pyx_mstate_global->__pyx_n_s_comparison
#define __pyx_n_u_comparison __pyx_mstate_global->__pyx_n_u_comparison
#define __pyx_n_s_conditions __pyx_mstate_global->__pyx_n_s_conditions
#define __pyx_n_s_conn __pyx_mstate_global->__pyx_n_s_conn
#define __pyx_n_s_connect __pyx_mstate_global->__pyx_n_s_connect
#define __pyx_n_u_connect __pyx_mstate_global->__pyx_n_u_connect
#define __pyx_n_s_connect_database __pyx_mstate_global->__pyx_n_s_connect_database
#define __pyx_n_s_count __pyx_mstate_global->__pyx_n_s_count
#define __pyx_n_s_count_query __pyx_mstate_global->__pyx_n_s_count_query
#define __pyx_kp_u_create __pyx_mstate_global->__pyx_kp_u_create
#define __pyx_n_s_create_sql_correction_prompt __pyx_mstate_global->__pyx_n_s_create_sql_correction_prompt
#define __pyx_n_s_create_sql_generation_prompt __pyx_mstate_global->__pyx_n_s_create_sql_generation_prompt
#define __pyx_n_s_dangerous_operations __pyx_mstate_global->__pyx_n_s_dangerous_operations
#define __pyx_n_u_data __pyx_mstate_global->__pyx_n_u_data
#define __pyx_kp_u_data_failed_sql_json __pyx_mstate_global->__pyx_kp_u_data_failed_sql_json
#define __pyx_n_s_data_type __pyx_mstate_global->__pyx_n_s_data_type
#define __pyx_n_u_data_type __pyx_mstate_global->__pyx_n_u_data_type
#define __pyx_n_u_database_objects __pyx_mstate_global->__pyx_n_u_database_objects
#define __pyx_n_s_database_path __pyx_mstate_global->__pyx_n_s_database_path
#define __pyx_n_u_date __pyx_mstate_global->__pyx_n_u_date
#define __pyx_n_s_date_col __pyx_mstate_global->__pyx_n_s_date_col
#define __pyx_n_s_date_columns __pyx_mstate_global->__pyx_n_s_date_columns
#define __pyx_n_u_day __pyx_mstate_global->__pyx_n_u_day
#define __pyx_n_s_db_context __pyx_mstate_global->__pyx_n_s_db_context
#define __pyx_n_u_delete __pyx_mstate_global->__pyx_n_u_delete
#define __pyx_n_u_description __pyx_mstate_global->__pyx_n_u_description
#define __pyx_kp_u_detach __pyx_mstate_global->__pyx_kp_u_detach
#define __pyx_n_s_detailed_explanation __pyx_mstate_global->__pyx_n_s_detailed_explanation
#define __pyx_n_s_df __pyx_mstate_global->__pyx_n_s_df
#define __pyx_n_s_dict __pyx_mstate_global->__pyx_n_s_dict
#define __pyx_n_s_direct_matches __pyx_mstate_global->__pyx_n_s_direct_matches
#define __pyx_n_s_direct_sql_pattern __pyx_mstate_global->__pyx_n_s_direct_sql_pattern
#define __pyx_kp_u_disable __pyx_mstate_global->__pyx_kp_u_disable
#define __pyx_n_s_doc __pyx_mstate_global->__pyx_n_s_doc
#define __pyx_n_u_drop __pyx_mstate_global->__pyx_n_u_drop
#define __pyx_n_s_dump __pyx_mstate_global->__pyx_n_s_dump
#define __pyx_n_s_dumps __pyx_mstate_global->__pyx_n_s_dumps
#define __pyx_n_s_e __pyx_mstate_global->__pyx_n_s_e
#define __pyx_n_s_empty __pyx_mstate_global->__pyx_n_s_empty
#define __pyx_kp_u_enable __pyx_mstate_global->__pyx_kp_u_enable
#define __pyx_n_s_encoding __pyx_mstate_global->__pyx_n_s_encoding
#define __pyx_n_s_enter __pyx_mstate_global->__pyx_n_s_enter
#define __pyx_n_s_entry __pyx_mstate_global->__pyx_n_s_entry
#define __pyx_n_s_enumerate __pyx_mstate_global->__pyx_n_s_enumerate
#define __pyx_n_s_error __pyx_mstate_global->__pyx_n_s_error
#define __pyx_n_u_error __pyx_mstate_global->__pyx_n_u_error
#define __pyx_n_s_error_msg __pyx_mstate_global->__pyx_n_s_error_msg
#define __pyx_n_s_escape __pyx_mstate_global->__pyx_n_s_escape
#define __pyx_n_s_evaluate_query_relevance __pyx_mstate_global->__pyx_n_s_evaluate_query_relevance
#define __pyx_n_u_execution_error __pyx_mstate_global->__pyx_n_u_execution_error
#define __pyx_n_s_exist_ok __pyx_mstate_global->__pyx_n_s_exist_ok
#define __pyx_n_s_existing_logs __pyx_mstate_global->__pyx_n_s_existing_logs
#define __pyx_n_u_existing_sql __pyx_mstate_global->__pyx_n_u_existing_sql
#define __pyx_n_s_exists __pyx_mstate_global->__pyx_n_s_exists
#define __pyx_n_s_exit __pyx_mstate_global->__pyx_n_s_exit
#define __pyx_n_s_explanation __pyx_mstate_global->__pyx_n_s_explanation
#define __pyx_n_u_explanation __pyx_mstate_global->__pyx_n_u_explanation
#define __pyx_n_s_explanation_match __pyx_mstate_global->__pyx_n_s_explanation_match
#define __pyx_n_s_explanation_pattern __pyx_mstate_global->__pyx_n_s_explanation_pattern
#define __pyx_n_u_exploration_stats __pyx_mstate_global->__pyx_n_u_exploration_stats
#define __pyx_n_s_explorations __pyx_mstate_global->__pyx_n_s_explorations
#define __pyx_n_s_explore_database_schema __pyx_mstate_global->__pyx_n_s_explore_database_schema
#define __pyx_n_s_explore_table_schema __pyx_mstate_global->__pyx_n_s_explore_table_schema
#define __pyx_n_s_extract_explanation __pyx_mstate_global->__pyx_n_s_extract_explanation
#define __pyx_n_s_extract_sql_from_response __pyx_mstate_global->__pyx_n_s_extract_sql_from_response
#define __pyx_n_s_extract_table_names __pyx_mstate_global->__pyx_n_s_extract_table_names
#define __pyx_n_s_f __pyx_mstate_global->__pyx_n_s_f
#define __pyx_n_s_failed_query __pyx_mstate_global->__pyx_n_s_failed_query
#define __pyx_n_u_failed_sql __pyx_mstate_global->__pyx_n_u_failed_sql
#define __pyx_kp_u_failed_sql_json __pyx_mstate_global->__pyx_kp_u_failed_sql_json
#define __pyx_n_s_file_path __pyx_mstate_global->__pyx_n_s_file_path
#define __pyx_n_s_findall __pyx_mstate_global->__pyx_n_s_findall
#define __pyx_n_s_finditer __pyx_mstate_global->__pyx_n_s_finditer
#define __pyx_n_s_first_result __pyx_mstate_global->__pyx_n_s_first_result
#define __pyx_n_s_fixed_query __pyx_mstate_global->__pyx_n_s_fixed_query
#define __pyx_n_s_fixed_sql __pyx_mstate_global->__pyx_n_s_fixed_sql
#define __pyx_n_s_float __pyx_mstate_global->__pyx_n_s_float
#define __pyx_n_s_from_matches __pyx_mstate_global->__pyx_n_s_from_matches
#define __pyx_n_s_from_pattern __pyx_mstate_global->__pyx_n_s_from_pattern
#define __pyx_kp_u_gc __pyx_mstate_global->__pyx_kp_u_gc
#define __pyx_n_s_generate_additional_explorations __pyx_mstate_global->__pyx_n_s_generate_additional_explorations
#define __pyx_n_s_generate_result_summary __pyx_mstate_global->__pyx_n_s_generate_result_summary
#define __pyx_n_s_generate_sql __pyx_mstate_global->__pyx_n_s_generate_sql
#define __pyx_n_s_genexpr __pyx_mstate_global->__pyx_n_s_genexpr
#define __pyx_n_s_get __pyx_mstate_global->__pyx_n_s_get
#define __pyx_n_s_get_best_sql_and_results __pyx_mstate_global->__pyx_n_s_get_best_sql_and_results
#define __pyx_n_s_get_response_sync __pyx_mstate_global->__pyx_n_s_get_response_sync
#define __pyx_n_s_group __pyx_mstate_global->__pyx_n_s_group
#define __pyx_n_u_has_historical_match __pyx_mstate_global->__pyx_n_u_has_historical_match
#define __pyx_n_s_head __pyx_mstate_global->__pyx_n_s_head
#define __pyx_n_s_hist_score __pyx_mstate_global->__pyx_n_s_hist_score
#define __pyx_n_u_historical __pyx_mstate_global->__pyx_n_u_historical
#define __pyx_n_s_historical_query __pyx_mstate_global->__pyx_n_s_historical_query
#define __pyx_n_u_historical_query __pyx_mstate_global->__pyx_n_u_historical_query
#define __pyx_n_u_historical_relevance_score __pyx_mstate_global->__pyx_n_u_historical_relevance_score
#define __pyx_n_u_historical_success __pyx_mstate_global->__pyx_n_u_historical_success
#define __pyx_n_s_i __pyx_mstate_global->__pyx_n_s_i
#define __pyx_n_s_import __pyx_mstate_global->__pyx_n_s_import
#define __pyx_n_s_indent __pyx_mstate_global->__pyx_n_s_indent
#define __pyx_n_s_info __pyx_mstate_global->__pyx_n_s_info
#define __pyx_n_s_init __pyx_mstate_global->__pyx_n_s_init
#define __pyx_n_s_init_subclass __pyx_mstate_global->__pyx_n_s_init_subclass
#define __pyx_n_s_initializing __pyx_mstate_global->__pyx_n_s_initializing
#define __pyx_n_u_insert __pyx_mstate_global->__pyx_n_u_insert
#define __pyx_n_s_intersection __pyx_mstate_global->__pyx_n_s_intersection
#define __pyx_n_s_is_coroutine __pyx_mstate_global->__pyx_n_s_is_coroutine
#define __pyx_kp_u_isenabled __pyx_mstate_global->__pyx_kp_u_isenabled
#define __pyx_n_s_isoformat __pyx_mstate_global->__pyx_n_s_isoformat
#define __pyx_n_s_items __pyx_mstate_global->__pyx_n_s_items
#define __pyx_n_s_iterrows __pyx_mstate_global->__pyx_n_s_iterrows
#define __pyx_n_s_join __pyx_mstate_global->__pyx_n_s_join
#define __pyx_n_u_join __pyx_mstate_global->__pyx_n_u_join
#define __pyx_n_s_join_condition __pyx_mstate_global->__pyx_n_s_join_condition
#define __pyx_n_u_join_condition __pyx_mstate_global->__pyx_n_u_join_condition
#define __pyx_n_s_join_matches __pyx_mstate_global->__pyx_n_s_join_matches
#define __pyx_n_s_join_pattern __pyx_mstate_global->__pyx_n_s_join_pattern
#define __pyx_n_s_json __pyx_mstate_global->__pyx_n_s_json
#define __pyx_n_s_left_side __pyx_mstate_global->__pyx_n_s_left_side
#define __pyx_n_u_link __pyx_mstate_global->__pyx_n_u_link
#define __pyx_n_s_load __pyx_mstate_global->__pyx_n_s_load
#define __pyx_n_s_log_e __pyx_mstate_global->__pyx_n_s_log_e
#define __pyx_n_s_lower __pyx_mstate_global->__pyx_n_s_lower
#define __pyx_n_s_main __pyx_mstate_global->__pyx_n_s_main
#define __pyx_n_s_main_query __pyx_mstate_global->__pyx_n_s_main_query
#define __pyx_n_s_main_sql __pyx_mstate_global->__pyx_n_s_main_sql
#define __pyx_n_s_makedirs __pyx_mstate_global->__pyx_n_s_makedirs
#define __pyx_n_s_match __pyx_mstate_global->__pyx_n_s_match
#define __pyx_n_s_max_attempts __pyx_mstate_global->__pyx_n_s_max_attempts
#define __pyx_n_u_message __pyx_mstate_global->__pyx_n_u_message
#define __pyx_n_s_metaclass __pyx_mstate_global->__pyx_n_s_metaclass
#define __pyx_n_s_module __pyx_mstate_global->__pyx_n_s_module
#define __pyx_kp_u_more_rows __pyx_mstate_global->__pyx_kp_u_more_rows
#define __pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION __pyx_mstate_global->__pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION
#define __pyx_n_u_name __pyx_mstate_global->__pyx_n_u_name
#define __pyx_n_s_name_2 __pyx_mstate_global->__pyx_n_s_name_2
#define __pyx_n_s_name_parts __pyx_mstate_global->__pyx_n_s_name_parts
#define __pyx_n_s_normalized_sql __pyx_mstate_global->__pyx_n_s_normalized_sql
#define __pyx_n_u_notnull __pyx_mstate_global->__pyx_n_u_notnull
#define __pyx_n_s_now __pyx_mstate_global->__pyx_n_s_now
#define __pyx_n_s_num_cols __pyx_mstate_global->__pyx_n_s_num_cols
#define __pyx_n_s_num_rows __pyx_mstate_global->__pyx_n_s_num_rows
#define __pyx_n_s_numeric_columns __pyx_mstate_global->__pyx_n_s_numeric_columns
#define __pyx_n_s_open __pyx_mstate_global->__pyx_n_s_open
#define __pyx_n_s_operation __pyx_mstate_global->__pyx_n_s_operation
#define __pyx_kp_u_or __pyx_mstate_global->__pyx_kp_u_or
#define __pyx_n_s_orient __pyx_mstate_global->__pyx_n_s_orient
#define __pyx_n_s_original_error __pyx_mstate_global->__pyx_n_s_original_error
#define __pyx_n_u_original_error __pyx_mstate_global->__pyx_n_u_original_error
#define __pyx_n_s_original_failed_sql __pyx_mstate_global->__pyx_n_s_original_failed_sql
#define __pyx_n_u_original_failed_sql __pyx_mstate_global->__pyx_n_u_original_failed_sql
#define __pyx_n_s_original_question __pyx_mstate_global->__pyx_n_s_original_question
#define __pyx_n_s_original_sql __pyx_mstate_global->__pyx_n_s_original_sql
#define __pyx_n_s_os __pyx_mstate_global->__pyx_n_s_os
#define __pyx_n_s_overlap __pyx_mstate_global->__pyx_n_s_overlap
#define __pyx_n_s_pandas __pyx_mstate_global->__pyx_n_s_pandas
#define __pyx_n_s_parts __pyx_mstate_global->__pyx_n_s_parts
#define __pyx_n_s_path __pyx_mstate_global->__pyx_n_s_path
#define __pyx_n_s_pattern __pyx_mstate_global->__pyx_n_s_pattern
#define __pyx_n_s_pd __pyx_mstate_global->__pyx_n_s_pd
#define __pyx_kp_s_pd_DataFrame __pyx_mstate_global->__pyx_kp_s_pd_DataFrame
#define __pyx_n_u_pk __pyx_mstate_global->__pyx_n_u_pk
#define __pyx_kp_u_plus __pyx_mstate_global->__pyx_kp_u_plus
#define __pyx_n_u_pragma __pyx_mstate_global->__pyx_n_u_pragma
#define __pyx_n_s_pragma_query __pyx_mstate_global->__pyx_n_s_pragma_query
#define __pyx_n_s_prepare __pyx_mstate_global->__pyx_n_s_prepare
#define __pyx_n_s_prev __pyx_mstate_global->__pyx_n_s_prev
#define __pyx_n_s_previous_attempts __pyx_mstate_global->__pyx_n_s_previous_attempts
#define __pyx_n_u_previously_run_query __pyx_mstate_global->__pyx_n_u_previously_run_query
#define __pyx_n_s_print __pyx_mstate_global->__pyx_n_s_print
#define __pyx_n_s_prompt __pyx_mstate_global->__pyx_n_s_prompt
#define __pyx_n_s_qualname __pyx_mstate_global->__pyx_n_s_qualname
#define __pyx_n_s_query __pyx_mstate_global->__pyx_n_s_query
#define __pyx_n_s_question __pyx_mstate_global->__pyx_n_s_question
#define __pyx_n_u_question __pyx_mstate_global->__pyx_n_u_question
#define __pyx_n_s_question_keywords __pyx_mstate_global->__pyx_n_s_question_keywords
#define __pyx_n_u_r __pyx_mstate_global->__pyx_n_u_r
#define __pyx_n_s_range __pyx_mstate_global->__pyx_n_s_range
#define __pyx_n_u_raw_ai_response __pyx_mstate_global->__pyx_n_u_raw_ai_response
#define __pyx_n_s_re __pyx_mstate_global->__pyx_n_s_re
#define __pyx_n_s_read_sql_query __pyx_mstate_global->__pyx_n_s_read_sql_query
#define __pyx_n_u_recommendation_reason __pyx_mstate_global->__pyx_n_u_recommendation_reason
#define __pyx_n_u_recommended_query __pyx_mstate_global->__pyx_n_u_recommended_query
#define __pyx_n_u_records __pyx_mstate_global->__pyx_n_u_records
#define __pyx_n_s_rel __pyx_mstate_global->__pyx_n_s_rel
#define __pyx_n_u_relation __pyx_mstate_global->__pyx_n_u_relation
#define __pyx_n_s_relationship_keywords __pyx_mstate_global->__pyx_n_s_relationship_keywords
#define __pyx_n_s_relationship_query __pyx_mstate_global->__pyx_n_s_relationship_query
#define __pyx_n_s_relationships __pyx_mstate_global->__pyx_n_s_relationships
#define __pyx_n_u_relationships __pyx_mstate_global->__pyx_n_u_relationships
#define __pyx_n_s_response __pyx_mstate_global->__pyx_n_s_response
#define __pyx_n_s_result __pyx_mstate_global->__pyx_n_s_result
#define __pyx_n_u_result __pyx_mstate_global->__pyx_n_u_result
#define __pyx_n_u_results __pyx_mstate_global->__pyx_n_u_results
#define __pyx_n_u_retry_attempt __pyx_mstate_global->__pyx_n_u_retry_attempt
#define __pyx_n_s_retry_info __pyx_mstate_global->__pyx_n_s_retry_info
#define __pyx_n_s_return __pyx_mstate_global->__pyx_n_s_return
#define __pyx_n_u_reused_from_failed_json __pyx_mstate_global->__pyx_n_u_reused_from_failed_json
#define __pyx_n_s_right_side __pyx_mstate_global->__pyx_n_s_right_side
#define __pyx_n_s_row __pyx_mstate_global->__pyx_n_s_row
#define __pyx_n_s_row_count __pyx_mstate_global->__pyx_n_s_row_count
#define __pyx_n_u_row_count __pyx_mstate_global->__pyx_n_u_row_count
#define __pyx_kp_u_row_s_with __pyx_mstate_global->__pyx_kp_u_row_s_with
#define __pyx_kp_u_rows_returned __pyx_mstate_global->__pyx_kp_u_rows_returned
#define __pyx_n_s_sQQideR_SQLBuilder __pyx_mstate_global->__pyx_n_s_sQQideR_SQLBuilder
#define __pyx_kp_s_sQQideR_SQLBuilder_pyx __pyx_mstate_global->__pyx_kp_s_sQQideR_SQLBuilder_pyx
#define __pyx_n_s_sample __pyx_mstate_global->__pyx_n_s_sample
#define __pyx_n_s_sample_data __pyx_mstate_global->__pyx_n_s_sample_data
#define __pyx_n_u_sample_data __pyx_mstate_global->__pyx_n_u_sample_data
#define __pyx_n_s_sample_df __pyx_mstate_global->__pyx_n_s_sample_df
#define __pyx_n_s_sample_query __pyx_mstate_global->__pyx_n_s_sample_query
#define __pyx_n_s_schema_info __pyx_mstate_global->__pyx_n_s_schema_info
#define __pyx_n_s_score __pyx_mstate_global->__pyx_n_s_score
#define __pyx_n_s_search __pyx_mstate_global->__pyx_n_s_search
#define __pyx_kp_u_select __pyx_mstate_global->__pyx_kp_u_select
#define __pyx_n_s_self __pyx_mstate_global->__pyx_n_s_self
#define __pyx_n_s_send __pyx_mstate_global->__pyx_n_s_send
#define __pyx_n_s_set_name __pyx_mstate_global->__pyx_n_s_set_name
#define __pyx_n_s_source __pyx_mstate_global->__pyx_n_s_source
#define __pyx_n_u_source __pyx_mstate_global->__pyx_n_u_source
#define __pyx_n_s_spec __pyx_mstate_global->__pyx_n_s_spec
#define __pyx_n_s_split __pyx_mstate_global->__pyx_n_s_split
#define __pyx_n_s_sql __pyx_mstate_global->__pyx_n_s_sql
#define __pyx_n_u_sql __pyx_mstate_global->__pyx_n_u_sql
#define __pyx_n_s_sql_query __pyx_mstate_global->__pyx_n_s_sql_query
#define __pyx_kp_u_sql_s __pyx_mstate_global->__pyx_kp_u_sql_s
#define __pyx_n_s_sqlite3 __pyx_mstate_global->__pyx_n_s_sqlite3
#define __pyx_n_s_stats_query_dict __pyx_mstate_global->__pyx_n_s_stats_query_dict
#define __pyx_n_s_str __pyx_mstate_global->__pyx_n_s_str
#define __pyx_n_s_strip __pyx_mstate_global->__pyx_n_s_strip
#define __pyx_kp_u_succeeded __pyx_mstate_global->__pyx_kp_u_succeeded
#define __pyx_n_u_success __pyx_mstate_global->__pyx_n_u_success
#define __pyx_n_s_summary __pyx_mstate_global->__pyx_n_s_summary
#define __pyx_n_u_summary __pyx_mstate_global->__pyx_n_u_summary
#define __pyx_n_s_super __pyx_mstate_global->__pyx_n_s_super
#define __pyx_kp_u_table __pyx_mstate_global->__pyx_kp_u_table
#define __pyx_n_s_table_2 __pyx_mstate_global->__pyx_n_s_table_2
#define __pyx_n_s_table_info __pyx_mstate_global->__pyx_n_s_table_info
#define __pyx_n_s_table_name __pyx_mstate_global->__pyx_n_s_table_name
#define __pyx_n_u_table_name __pyx_mstate_global->__pyx_n_u_table_name
#define __pyx_n_s_table_names __pyx_mstate_global->__pyx_n_s_table_names
#define __pyx_n_s_table_obj __pyx_mstate_global->__pyx_n_s_table_obj
#define __pyx_n_s_tables __pyx_mstate_global->__pyx_n_s_tables
#define __pyx_n_u_tables __pyx_mstate_global->__pyx_n_u_tables
#define __pyx_n_s_tables_df __pyx_mstate_global->__pyx_n_s_tables_df
#define __pyx_n_s_tables_query __pyx_mstate_global->__pyx_n_s_tables_query
#define __pyx_n_s_tables_used __pyx_mstate_global->__pyx_n_s_tables_used
#define __pyx_n_s_target __pyx_mstate_global->__pyx_n_s_target
#define __pyx_n_u_target __pyx_mstate_global->__pyx_n_u_target
#define __pyx_n_s_test __pyx_mstate_global->__pyx_n_s_test
#define __pyx_n_s_test_query __pyx_mstate_global->__pyx_n_s_test_query
#define __pyx_n_s_tested_query __pyx_mstate_global->__pyx_n_s_tested_query
#define __pyx_n_s_text __pyx_mstate_global->__pyx_n_s_text
#define __pyx_n_s_throw __pyx_mstate_global->__pyx_n_s_throw
#define __pyx_n_u_time __pyx_mstate_global->__pyx_n_u_time
#define __pyx_n_s_time_query __pyx_mstate_global->__pyx_n_s_time_query
#define __pyx_n_u_timestamp __pyx_mstate_global->__pyx_n_u_timestamp
#define __pyx_kp_u_to __pyx_mstate_global->__pyx_kp_u_to
#define __pyx_n_s_to_dict __pyx_mstate_global->__pyx_n_s_to_dict
#define __pyx_n_s_to_string __pyx_mstate_global->__pyx_n_s_to_string
#define __pyx_n_u_truncate __pyx_mstate_global->__pyx_n_u_truncate
#define __pyx_n_s_try_fix_failed_query __pyx_mstate_global->__pyx_n_s_try_fix_failed_query
#define __pyx_n_u_type __pyx_mstate_global->__pyx_n_u_type
#define __pyx_n_s_typing __pyx_mstate_global->__pyx_n_s_typing
#define __pyx_n_s_update __pyx_mstate_global->__pyx_n_s_update
#define __pyx_n_u_update __pyx_mstate_global->__pyx_n_u_update
#define __pyx_kp_u_utf_8 __pyx_mstate_global->__pyx_kp_u_utf_8
#define __pyx_kp_u_vacuum __pyx_mstate_global->__pyx_kp_u_vacuum
#define __pyx_n_s_val __pyx_mstate_global->__pyx_n_s_val
#define __pyx_n_s_validate_safe_sql __pyx_mstate_global->__pyx_n_s_validate_safe_sql
#define __pyx_n_s_validation_error __pyx_mstate_global->__pyx_n_s_validation_error
#define __pyx_n_s_verbose __pyx_mstate_global->__pyx_n_s_verbose
#define __pyx_n_u_w __pyx_mstate_global->__pyx_n_u_w
#define __pyx_n_u_where __pyx_mstate_global->__pyx_n_u_where
#define __pyx_n_s_working_sql __pyx_mstate_global->__pyx_n_s_working_sql
#define __pyx_n_u_working_sql __pyx_mstate_global->__pyx_n_u_working_sql
#define __pyx_float_0_0 __pyx_mstate_global->__pyx_float_0_0
#define __pyx_float_0_5 __pyx_mstate_global->__pyx_float_0_5
#define __pyx_float_5_0 __pyx_mstate_global->__pyx_float_5_0
#define __pyx_int_0 __pyx_mstate_global->__pyx_int_0
#define __pyx_int_1 __pyx_mstate_global->__pyx_int_1
#define __pyx_int_2 __pyx_mstate_global->__pyx_int_2
#define __pyx_int_3 __pyx_mstate_global->__pyx_int_3
#define __pyx_int_5 __pyx_mstate_global->__pyx_int_5
#define __pyx_int_20 __pyx_mstate_global->__pyx_int_20
#define __pyx_int_100 __pyx_mstate_global->__pyx_int_100
#define __pyx_tuple_ __pyx_mstate_global->__pyx_tuple_
#define __pyx_tuple__2 __pyx_mstate_global->__pyx_tuple__2
#define __pyx_tuple__3 __pyx_mstate_global->__pyx_tuple__3
#define __pyx_tuple__4 __pyx_mstate_global->__pyx_tuple__4
#define __pyx_tuple__5 __pyx_mstate_global->__pyx_tuple__5
#define __pyx_tuple__6 __pyx_mstate_global->__pyx_tuple__6
#define __pyx_tuple__8 __pyx_mstate_global->__pyx_tuple__8
#define __pyx_slice__18 __pyx_mstate_global->__pyx_slice__18
#define __pyx_tuple__10 __pyx_mstate_global->__pyx_tuple__10
#define __pyx_tuple__11 __pyx_mstate_global->__pyx_tuple__11
#define __pyx_tuple__12 __pyx_mstate_global->__pyx_tuple__12
#define __pyx_tuple__19 __pyx_mstate_global->__pyx_tuple__19
#define __pyx_tuple__20 __pyx_mstate_global->__pyx_tuple__20
#define __pyx_tuple__21 __pyx_mstate_global->__pyx_tuple__21
#define __pyx_tuple__22 __pyx_mstate_global->__pyx_tuple__22
#define __pyx_tuple__24 __pyx_mstate_global->__pyx_tuple__24
#define __pyx_tuple__25 __pyx_mstate_global->__pyx_tuple__25
#define __pyx_tuple__27 __pyx_mstate_global->__pyx_tuple__27
#define __pyx_tuple__28 __pyx_mstate_global->__pyx_tuple__28
#define __pyx_tuple__33 __pyx_mstate_global->__pyx_tuple__33
#define __pyx_tuple__36 __pyx_mstate_global->__pyx_tuple__36
#define __pyx_tuple__37 __pyx_mstate_global->__pyx_tuple__37
#define __pyx_tuple__38 __pyx_mstate_global->__pyx_tuple__38
#define __pyx_tuple__39 __pyx_mstate_global->__pyx_tuple__39
#define __pyx_tuple__40 __pyx_mstate_global->__pyx_tuple__40
#define __pyx_tuple__41 __pyx_mstate_global->__pyx_tuple__41
#define __pyx_tuple__42 __pyx_mstate_global->__pyx_tuple__42
#define __pyx_tuple__43 __pyx_mstate_global->__pyx_tuple__43
#define __pyx_tuple__44 __pyx_mstate_global->__pyx_tuple__44
#define __pyx_tuple__45 __pyx_mstate_global->__pyx_tuple__45
#define __pyx_tuple__46 __pyx_mstate_global->__pyx_tuple__46
#define __pyx_tuple__47 __pyx_mstate_global->__pyx_tuple__47
#define __pyx_tuple__49 __pyx_mstate_global->__pyx_tuple__49
#define __pyx_tuple__50 __pyx_mstate_global->__pyx_tuple__50
#define __pyx_tuple__52 __pyx_mstate_global->__pyx_tuple__52
#define __pyx_tuple__54 __pyx_mstate_global->__pyx_tuple__54
#define __pyx_tuple__56 __pyx_mstate_global->__pyx_tuple__56
#define __pyx_tuple__58 __pyx_mstate_global->__pyx_tuple__58
#define __pyx_tuple__60 __pyx_mstate_global->__pyx_tuple__60
#define __pyx_tuple__62 __pyx_mstate_global->__pyx_tuple__62
#define __pyx_tuple__63 __pyx_mstate_global->__pyx_tuple__63
#define __pyx_tuple__65 __pyx_mstate_global->__pyx_tuple__65
#define __pyx_tuple__67 __pyx_mstate_global->__pyx_tuple__67
#define __pyx_tuple__70 __pyx_mstate_global->__pyx_tuple__70
#define __pyx_tuple__72 __pyx_mstate_global->__pyx_tuple__72
#define __pyx_tuple__74 __pyx_mstate_global->__pyx_tuple__74
#define __pyx_tuple__76 __pyx_mstate_global->__pyx_tuple__76
#define __pyx_tuple__78 __pyx_mstate_global->__pyx_tuple__78
#define __pyx_tuple__80 __pyx_mstate_global->__pyx_tuple__80
#define __pyx_tuple__82 __pyx_mstate_global->__pyx_tuple__82
#define __pyx_tuple__84 __pyx_mstate_global->__pyx_tuple__84
#define __pyx_tuple__86 __pyx_mstate_global->__pyx_tuple__86
#define __pyx_tuple__88 __pyx_mstate_global->__pyx_tuple__88
#define __pyx_codeobj__48 __pyx_mstate_global->__pyx_codeobj__48
#define __pyx_codeobj__51 __pyx_mstate_global->__pyx_codeobj__51
#define __pyx_codeobj__53 __pyx_mstate_global->__pyx_codeobj__53
#define __pyx_codeobj__55 __pyx_mstate_global->__pyx_codeobj__55
#define __pyx_codeobj__57 __pyx_mstate_global->__pyx_codeobj__57
#define __pyx_codeobj__59 __pyx_mstate_global->__pyx_codeobj__59
#define __pyx_codeobj__61 __pyx_mstate_global->__pyx_codeobj__61
#define __pyx_codeobj__64 __pyx_mstate_global->__pyx_codeobj__64
#define __pyx_codeobj__66 __pyx_mstate_global->__pyx_codeobj__66
#define __pyx_codeobj__68 __pyx_mstate_global->__pyx_codeobj__68
#define __pyx_codeobj__71 __pyx_mstate_global->__pyx_codeobj__71
#define __pyx_codeobj__73 __pyx_mstate_global->__pyx_codeobj__73
#define __pyx_codeobj__75 __pyx_mstate_global->__pyx_codeobj__75
#define __pyx_codeobj__77 __pyx_mstate_global->__pyx_codeobj__77
#define __pyx_codeobj__79 __pyx_mstate_global->__pyx_codeobj__79
#define __pyx_codeobj__81 __pyx_mstate_global->__pyx_codeobj__81
#define __pyx_codeobj__83 __pyx_mstate_global->__pyx_codeobj__83
#define __pyx_codeobj__85 __pyx_mstate_global->__pyx_codeobj__85
#define __pyx_codeobj__87 __pyx_mstate_global->__pyx_codeobj__87
#define __pyx_codeobj__89 __pyx_mstate_global->__pyx_codeobj__89
/* #### Code section: module_code ### */

/* "sQQideR/SQLBuilder.pyx":23
 *     """
 * 
 *     def __init__(self, database_path: str = None, verbose: bool = False, ai_base=None):             # <<<<<<<<<<<<<<
 *         """
 *         Initialize the SQLBuilder with optional database connection.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_1__init__(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder___init__, "\n        Initialize the SQLBuilder with optional database connection.\n        \n        Args:\n            database_path: Path to the SQLite database file\n            verbose: Whether to print verbose output during operations\n            ai_base: AIBase instance for generating SQL with AI\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_1__init__ = {"__init__", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_1__init__, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder___init__};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_1__init__(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_database_path = 0;
  PyObject *__pyx_v_verbose = 0;
  PyObject *__pyx_v_ai_base = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[4] = {0,0,0,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);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_database_path,&__pyx_n_s_verbose,&__pyx_n_s_ai_base,0};
    values[1] = __Pyx_Arg_NewRef_FASTCALL(((PyObject*)Py_None));
    values[2] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)((PyObject *)Py_False)));
    values[3] = __Pyx_Arg_NewRef_FASTCALL(((PyObject *)Py_None));
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_database_path);
          if (value) { values[1] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_verbose);
          if (value) { values[2] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ai_base);
          if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "__init__") < 0)) __PYX_ERR(0, 23, __pyx_L3_error)
      }
    } else {
      switch (__pyx_nargs) {
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_self = values[0];
    __pyx_v_database_path = ((PyObject*)values[1]);
    __pyx_v_verbose = values[2];
    __pyx_v_ai_base = values[3];
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 4, __pyx_nargs); __PYX_ERR(0, 23, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_database_path), (&PyUnicode_Type), 1, "database_path", 1))) __PYX_ERR(0, 23, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder___init__(__pyx_self, __pyx_v_self, __pyx_v_database_path, __pyx_v_verbose, __pyx_v_ai_base);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_database_path, PyObject *__pyx_v_verbose, PyObject *__pyx_v_ai_base) {
  PyObject *__pyx_r = NULL;
  __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;
  unsigned int __pyx_t_6;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("__init__", 1);

  /* "sQQideR/SQLBuilder.pyx":32
 *             ai_base: AIBase instance for generating SQL with AI
 *         """
 *         self.verbose = verbose             # <<<<<<<<<<<<<<
 *         self.ai_base = ai_base
 *         self.database_path = database_path
 */
  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_verbose, __pyx_v_verbose) < 0) __PYX_ERR(0, 32, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":33
 *         """
 *         self.verbose = verbose
 *         self.ai_base = ai_base             # <<<<<<<<<<<<<<
 *         self.database_path = database_path
 *         self.conn = None
 */
  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_ai_base, __pyx_v_ai_base) < 0) __PYX_ERR(0, 33, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":34
 *         self.verbose = verbose
 *         self.ai_base = ai_base
 *         self.database_path = database_path             # <<<<<<<<<<<<<<
 *         self.conn = None
 * 
 */
  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_database_path, __pyx_v_database_path) < 0) __PYX_ERR(0, 34, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":35
 *         self.ai_base = ai_base
 *         self.database_path = database_path
 *         self.conn = None             # <<<<<<<<<<<<<<
 * 
 *         if database_path and os.path.exists(database_path):
 */
  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_conn, Py_None) < 0) __PYX_ERR(0, 35, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":37
 *         self.conn = None
 * 
 *         if database_path and os.path.exists(database_path):             # <<<<<<<<<<<<<<
 *             self.connect_database(database_path)
 *         elif database_path:
 */
  __pyx_t_2 = (__pyx_v_database_path != Py_None)&&(__Pyx_PyUnicode_IS_TRUE(__pyx_v_database_path) != 0);
  if (__pyx_t_2) {
  } else {
    __pyx_t_1 = __pyx_t_2;
    goto __pyx_L4_bool_binop_done;
  }
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_os); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 37, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_path); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 37, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_exists); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 37, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(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;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_database_path};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 37, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_1 = __pyx_t_2;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {

    /* "sQQideR/SQLBuilder.pyx":38
 * 
 *         if database_path and os.path.exists(database_path):
 *             self.connect_database(database_path)             # <<<<<<<<<<<<<<
 *         elif database_path:
 *             if self.verbose:
 */
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_connect_database); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 38, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_5 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(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;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_database_path};
      __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 38, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;

    /* "sQQideR/SQLBuilder.pyx":37
 *         self.conn = None
 * 
 *         if database_path and os.path.exists(database_path):             # <<<<<<<<<<<<<<
 *             self.connect_database(database_path)
 *         elif database_path:
 */
    goto __pyx_L3;
  }

  /* "sQQideR/SQLBuilder.pyx":39
 *         if database_path and os.path.exists(database_path):
 *             self.connect_database(database_path)
 *         elif database_path:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Database file not found: {database_path}")
 */
  __pyx_t_1 = (__pyx_v_database_path != Py_None)&&(__Pyx_PyUnicode_IS_TRUE(__pyx_v_database_path) != 0);
  if (__pyx_t_1) {

    /* "sQQideR/SQLBuilder.pyx":40
 *             self.connect_database(database_path)
 *         elif database_path:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Database file not found: {database_path}")
 * 
 */
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 40, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 40, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (__pyx_t_1) {

      /* "sQQideR/SQLBuilder.pyx":41
 *         elif database_path:
 *             if self.verbose:
 *                 print(f"Database file not found: {database_path}")             # <<<<<<<<<<<<<<
 * 
 *     def connect_database(self, database_path: str) -> bool:
 */
      __pyx_t_3 = __Pyx_PyUnicode_Unicode(__pyx_v_database_path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 41, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Database_file_not_found, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 41, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 41, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;

      /* "sQQideR/SQLBuilder.pyx":40
 *             self.connect_database(database_path)
 *         elif database_path:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Database file not found: {database_path}")
 * 
 */
    }

    /* "sQQideR/SQLBuilder.pyx":39
 *         if database_path and os.path.exists(database_path):
 *             self.connect_database(database_path)
 *         elif database_path:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Database file not found: {database_path}")
 */
  }
  __pyx_L3:;

  /* "sQQideR/SQLBuilder.pyx":23
 *     """
 * 
 *     def __init__(self, database_path: str = None, verbose: bool = False, ai_base=None):             # <<<<<<<<<<<<<<
 *         """
 *         Initialize the SQLBuilder with optional database connection.
 */

  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":43
 *                 print(f"Database file not found: {database_path}")
 * 
 *     def connect_database(self, database_path: str) -> bool:             # <<<<<<<<<<<<<<
 *         """
 *         Connect to the specified SQLite database.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_3connect_database(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_2connect_database, "\n        Connect to the specified SQLite database.\n        \n        Args:\n            database_path: Path to the SQLite database file\n            \n        Returns:\n            True if connection was successful, False otherwise\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_3connect_database = {"connect_database", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_3connect_database, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_2connect_database};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_3connect_database(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_database_path = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("connect_database (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_database_path,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 43, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_database_path)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 43, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("connect_database", 1, 2, 2, 1); __PYX_ERR(0, 43, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "connect_database") < 0)) __PYX_ERR(0, 43, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_database_path = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("connect_database", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 43, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.connect_database", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_database_path), (&PyUnicode_Type), 0, "database_path", 1))) __PYX_ERR(0, 43, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_2connect_database(__pyx_self, __pyx_v_self, __pyx_v_database_path);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_2connect_database(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_database_path) {
  PyObject *__pyx_v_e = NULL;
  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;
  PyObject *__pyx_t_6 = NULL;
  PyObject *__pyx_t_7 = NULL;
  int __pyx_t_8;
  int __pyx_t_9;
  PyObject *__pyx_t_10 = NULL;
  int __pyx_t_11;
  char const *__pyx_t_12;
  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;
  PyObject *__pyx_t_18 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("connect_database", 1);

  /* "sQQideR/SQLBuilder.pyx":53
 *             True if connection was successful, False otherwise
 *         """
 *         try:             # <<<<<<<<<<<<<<
 *             self.conn = sqlite3.connect(database_path, check_same_thread=False)
 *             self.database_path = database_path
 */
  {
    __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:*/ {

      /* "sQQideR/SQLBuilder.pyx":54
 *         """
 *         try:
 *             self.conn = sqlite3.connect(database_path, check_same_thread=False)             # <<<<<<<<<<<<<<
 *             self.database_path = database_path
 *             if self.verbose:
 */
      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_sqlite3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L3_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_connect); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L3_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L3_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_INCREF(__pyx_v_database_path);
      __Pyx_GIVEREF(__pyx_v_database_path);
      if (__Pyx_PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_database_path)) __PYX_ERR(0, 54, __pyx_L3_error);
      __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 54, __pyx_L3_error)
      __Pyx_GOTREF(__pyx_t_6);
      if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_check_same_thread, Py_False) < 0) __PYX_ERR(0, 54, __pyx_L3_error)
      __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 54, __pyx_L3_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_conn, __pyx_t_7) < 0) __PYX_ERR(0, 54, __pyx_L3_error)
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;

      /* "sQQideR/SQLBuilder.pyx":55
 *         try:
 *             self.conn = sqlite3.connect(database_path, check_same_thread=False)
 *             self.database_path = database_path             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Connected to database: {database_path}")
 */
      if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_database_path, __pyx_v_database_path) < 0) __PYX_ERR(0, 55, __pyx_L3_error)

      /* "sQQideR/SQLBuilder.pyx":56
 *             self.conn = sqlite3.connect(database_path, check_same_thread=False)
 *             self.database_path = database_path
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Connected to database: {database_path}")
 *             return True
 */
      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 56, __pyx_L3_error)
      __Pyx_GOTREF(__pyx_t_7);
      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 56, __pyx_L3_error)
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      if (__pyx_t_8) {

        /* "sQQideR/SQLBuilder.pyx":57
 *             self.database_path = database_path
 *             if self.verbose:
 *                 print(f"Connected to database: {database_path}")             # <<<<<<<<<<<<<<
 *             return True
 *         except Exception as e:
 */
        __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Connected_to_database, __pyx_v_database_path); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 57, __pyx_L3_error)
        __Pyx_GOTREF(__pyx_t_7);
        __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 57, __pyx_L3_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

        /* "sQQideR/SQLBuilder.pyx":56
 *             self.conn = sqlite3.connect(database_path, check_same_thread=False)
 *             self.database_path = database_path
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Connected to database: {database_path}")
 *             return True
 */
      }

      /* "sQQideR/SQLBuilder.pyx":58
 *             if self.verbose:
 *                 print(f"Connected to database: {database_path}")
 *             return True             # <<<<<<<<<<<<<<
 *         except Exception as e:
 *             if self.verbose:
 */
      __Pyx_XDECREF(__pyx_r);
      __Pyx_INCREF(Py_True);
      __pyx_r = Py_True;
      goto __pyx_L7_try_return;

      /* "sQQideR/SQLBuilder.pyx":53
 *             True if connection was successful, False otherwise
 *         """
 *         try:             # <<<<<<<<<<<<<<
 *             self.conn = sqlite3.connect(database_path, check_same_thread=False)
 *             self.database_path = database_path
 */
    }
    __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;
    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;

    /* "sQQideR/SQLBuilder.pyx":59
 *                 print(f"Connected to database: {database_path}")
 *             return True
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error connecting to database: {e}")
 */
    __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
    if (__pyx_t_9) {
      __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.connect_database", __pyx_clineno, __pyx_lineno, __pyx_filename);
      if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_4) < 0) __PYX_ERR(0, 59, __pyx_L5_except_error)
      __Pyx_XGOTREF(__pyx_t_6);
      __Pyx_XGOTREF(__pyx_t_7);
      __Pyx_XGOTREF(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_7);
      __pyx_v_e = __pyx_t_7;
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":60
 *             return True
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error connecting to database: {e}")
 *             self.conn = None
 */
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 60, __pyx_L15_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 60, __pyx_L15_error)
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        if (__pyx_t_8) {

          /* "sQQideR/SQLBuilder.pyx":61
 *         except Exception as e:
 *             if self.verbose:
 *                 print(f"Error connecting to database: {e}")             # <<<<<<<<<<<<<<
 *             self.conn = None
 *             return False
 */
          __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 61, __pyx_L15_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_connecting_to_database, __pyx_t_5); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 61, __pyx_L15_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_10); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 61, __pyx_L15_error)
          __Pyx_GOTREF(__pyx_t_5);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

          /* "sQQideR/SQLBuilder.pyx":60
 *             return True
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error connecting to database: {e}")
 *             self.conn = None
 */
        }

        /* "sQQideR/SQLBuilder.pyx":62
 *             if self.verbose:
 *                 print(f"Error connecting to database: {e}")
 *             self.conn = None             # <<<<<<<<<<<<<<
 *             return False
 * 
 */
        if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_conn, Py_None) < 0) __PYX_ERR(0, 62, __pyx_L15_error)

        /* "sQQideR/SQLBuilder.pyx":63
 *                 print(f"Error connecting to database: {e}")
 *             self.conn = None
 *             return False             # <<<<<<<<<<<<<<
 * 
 *     def close_connection(self) -> None:
 */
        __Pyx_XDECREF(__pyx_r);
        __Pyx_INCREF(Py_False);
        __pyx_r = Py_False;
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        goto __pyx_L14_return;
      }

      /* "sQQideR/SQLBuilder.pyx":59
 *                 print(f"Connected to database: {database_path}")
 *             return True
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error connecting to database: {e}")
 */
      /*finally:*/ {
        __pyx_L15_error:;
        /*exception exit:*/{
          __Pyx_PyThreadState_declare
          __Pyx_PyThreadState_assign
          __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0;
          __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_16, &__pyx_t_17, &__pyx_t_18);
          if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15) < 0)) __Pyx_ErrFetch(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15);
          __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_XGOTREF(__pyx_t_18);
          __pyx_t_9 = __pyx_lineno; __pyx_t_11 = __pyx_clineno; __pyx_t_12 = __pyx_filename;
          {
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          }
          if (PY_MAJOR_VERSION >= 3) {
            __Pyx_XGIVEREF(__pyx_t_16);
            __Pyx_XGIVEREF(__pyx_t_17);
            __Pyx_XGIVEREF(__pyx_t_18);
            __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_17, __pyx_t_18);
          }
          __Pyx_XGIVEREF(__pyx_t_13);
          __Pyx_XGIVEREF(__pyx_t_14);
          __Pyx_XGIVEREF(__pyx_t_15);
          __Pyx_ErrRestore(__pyx_t_13, __pyx_t_14, __pyx_t_15);
          __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0;
          __pyx_lineno = __pyx_t_9; __pyx_clineno = __pyx_t_11; __pyx_filename = __pyx_t_12;
          goto __pyx_L5_except_error;
        }
        __pyx_L14_return: {
          __pyx_t_18 = __pyx_r;
          __pyx_r = 0;
          __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          __pyx_r = __pyx_t_18;
          __pyx_t_18 = 0;
          goto __pyx_L6_except_return;
        }
      }
    }
    goto __pyx_L5_except_error;

    /* "sQQideR/SQLBuilder.pyx":53
 *             True if connection was successful, False otherwise
 *         """
 *         try:             # <<<<<<<<<<<<<<
 *             self.conn = sqlite3.connect(database_path, check_same_thread=False)
 *             self.database_path = database_path
 */
    __pyx_L5_except_error:;
    __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;
    __pyx_L6_except_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;
  }

  /* "sQQideR/SQLBuilder.pyx":43
 *                 print(f"Database file not found: {database_path}")
 * 
 *     def connect_database(self, database_path: str) -> bool:             # <<<<<<<<<<<<<<
 *         """
 *         Connect to the specified SQLite database.
 */

  /* 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_XDECREF(__pyx_t_10);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.connect_database", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_e);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":65
 *             return False
 * 
 *     def close_connection(self) -> None:             # <<<<<<<<<<<<<<
 *         """Close the database connection if open."""
 *         if self.conn:
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_5close_connection(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_4close_connection, "Close the database connection if open.");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_5close_connection = {"close_connection", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_5close_connection, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_4close_connection};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_5close_connection(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[1] = {0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("close_connection (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 65, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "close_connection") < 0)) __PYX_ERR(0, 65, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 1)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
    }
    __pyx_v_self = values[0];
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("close_connection", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 65, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.close_connection", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_4close_connection(__pyx_self, __pyx_v_self);

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_4close_connection(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  int __pyx_t_2;
  PyObject *__pyx_t_3 = NULL;
  PyObject *__pyx_t_4 = NULL;
  unsigned int __pyx_t_5;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("close_connection", 1);

  /* "sQQideR/SQLBuilder.pyx":67
 *     def close_connection(self) -> None:
 *         """Close the database connection if open."""
 *         if self.conn:             # <<<<<<<<<<<<<<
 *             self.conn.close()
 *             self.conn = None
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 67, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 67, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_2) {

    /* "sQQideR/SQLBuilder.pyx":68
 *         """Close the database connection if open."""
 *         if self.conn:
 *             self.conn.close()             # <<<<<<<<<<<<<<
 *             self.conn = None
 *             if self.verbose:
 */
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 68, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_close); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 68, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_3 = NULL;
    __pyx_t_5 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_4))) {
      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
      if (likely(__pyx_t_3)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
        __Pyx_INCREF(__pyx_t_3);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_4, function);
        __pyx_t_5 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 0+__pyx_t_5);
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":69
 *         if self.conn:
 *             self.conn.close()
 *             self.conn = None             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print("Database connection closed")
 */
    if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_conn, Py_None) < 0) __PYX_ERR(0, 69, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":70
 *             self.conn.close()
 *             self.conn = None
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print("Database connection closed")
 * 
 */
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 70, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (__pyx_t_2) {

      /* "sQQideR/SQLBuilder.pyx":71
 *             self.conn = None
 *             if self.verbose:
 *                 print("Database connection closed")             # <<<<<<<<<<<<<<
 * 
 *     def generate_sql(self, question: str, db_context: Dict) -> Dict:
 */
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 71, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":70
 *             self.conn.close()
 *             self.conn = None
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print("Database connection closed")
 * 
 */
    }

    /* "sQQideR/SQLBuilder.pyx":67
 *     def close_connection(self) -> None:
 *         """Close the database connection if open."""
 *         if self.conn:             # <<<<<<<<<<<<<<
 *             self.conn.close()
 *             self.conn = None
 */
  }

  /* "sQQideR/SQLBuilder.pyx":65
 *             return False
 * 
 *     def close_connection(self) -> None:             # <<<<<<<<<<<<<<
 *         """Close the database connection if open."""
 *         if self.conn:
 */

  /* 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_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.close_connection", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":73
 *                 print("Database connection closed")
 * 
 *     def generate_sql(self, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Generate SQL based on the natural language question and database context.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_7generate_sql(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_6generate_sql, "\n        Generate SQL based on the natural language question and database context.\n        \n        Args:\n            question: The natural language question\n            db_context: Database context information\n            \n        Returns:\n            Dictionary containing the generated SQL and related information\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_7generate_sql = {"generate_sql", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_7generate_sql, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_6generate_sql};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_7generate_sql(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_question = 0;
  PyObject *__pyx_v_db_context = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[3] = {0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("generate_sql (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_question,&__pyx_n_s_db_context,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("generate_sql", 1, 3, 3, 1); __PYX_ERR(0, 73, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_db_context)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("generate_sql", 1, 3, 3, 2); __PYX_ERR(0, 73, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "generate_sql") < 0)) __PYX_ERR(0, 73, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 3)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
    }
    __pyx_v_self = values[0];
    __pyx_v_question = ((PyObject*)values[1]);
    __pyx_v_db_context = ((PyObject*)values[2]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("generate_sql", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 73, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_sql", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 73, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_db_context), (&PyDict_Type), 0, "db_context", 1))) __PYX_ERR(0, 73, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_6generate_sql(__pyx_self, __pyx_v_self, __pyx_v_question, __pyx_v_db_context);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_6generate_sql(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context) {
  PyObject *__pyx_v_f = NULL;
  PyObject *__pyx_v_existing_logs = NULL;
  PyObject *__pyx_v_entry = NULL;
  PyObject *__pyx_v_working_sql = NULL;
  PyObject *__pyx_v_original_error = NULL;
  PyObject *__pyx_v_original_failed_sql = NULL;
  PyObject *__pyx_v_original_question = NULL;
  PyObject *__pyx_v_detailed_explanation = NULL;
  PyObject *__pyx_v_e = NULL;
  PyObject *__pyx_v_prompt = NULL;
  PyObject *__pyx_v_response = NULL;
  PyObject *__pyx_v_sql_query = NULL;
  PyObject *__pyx_v_explanation = NULL;
  PyObject *__pyx_v_cleaned_response = NULL;
  PyObject *__pyx_v_cleaned_explanation = NULL;
  PyObject *__pyx_v_cleaned_sql = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  int __pyx_t_2;
  int __pyx_t_3;
  PyObject *__pyx_t_4 = NULL;
  PyObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  PyObject *__pyx_t_7 = NULL;
  PyObject *__pyx_t_8 = NULL;
  PyObject *__pyx_t_9 = NULL;
  PyObject *__pyx_t_10 = NULL;
  PyObject *__pyx_t_11 = NULL;
  PyObject *__pyx_t_12 = NULL;
  PyObject *__pyx_t_13 = NULL;
  PyObject *__pyx_t_14 = NULL;
  PyObject *__pyx_t_15 = NULL;
  Py_ssize_t __pyx_t_16;
  PyObject *(*__pyx_t_17)(PyObject *);
  Py_ssize_t __pyx_t_18;
  Py_UCS4 __pyx_t_19;
  int __pyx_t_20;
  PyObject *__pyx_t_21 = NULL;
  int __pyx_t_22;
  char const *__pyx_t_23;
  PyObject *__pyx_t_24 = NULL;
  PyObject *__pyx_t_25 = NULL;
  char const *__pyx_t_26;
  PyObject *__pyx_t_27 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("generate_sql", 1);

  /* "sQQideR/SQLBuilder.pyx":84
 *             Dictionary containing the generated SQL and related information
 *         """
 *         if not self.ai_base:             # <<<<<<<<<<<<<<
 *             return {"error": "AI service not available for SQL generation"}
 * 
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_ai_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 84, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 84, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = (!__pyx_t_2);
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":85
 *         """
 *         if not self.ai_base:
 *             return {"error": "AI service not available for SQL generation"}             # <<<<<<<<<<<<<<
 * 
 *         if os.path.exists("data/failed_sql.json"):
 */
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_error, __pyx_kp_u_AI_service_not_available_for_SQL) < 0) __PYX_ERR(0, 85, __pyx_L1_error)
    __pyx_r = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":84
 *             Dictionary containing the generated SQL and related information
 *         """
 *         if not self.ai_base:             # <<<<<<<<<<<<<<
 *             return {"error": "AI service not available for SQL generation"}
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":87
 *             return {"error": "AI service not available for SQL generation"}
 * 
 *         if os.path.exists("data/failed_sql.json"):             # <<<<<<<<<<<<<<
 *             try:
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 */
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_os); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 87, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_path); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_exists); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 87, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(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;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_kp_u_data_failed_sql_json};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 87, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":88
 * 
 *         if os.path.exists("data/failed_sql.json"):
 *             try:             # <<<<<<<<<<<<<<
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 *                     existing_logs = json.load(f)
 */
    {
      __Pyx_PyThreadState_declare
      __Pyx_PyThreadState_assign
      __Pyx_ExceptionSave(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9);
      __Pyx_XGOTREF(__pyx_t_7);
      __Pyx_XGOTREF(__pyx_t_8);
      __Pyx_XGOTREF(__pyx_t_9);
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":89
 *         if os.path.exists("data/failed_sql.json"):
 *             try:
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:             # <<<<<<<<<<<<<<
 *                     existing_logs = json.load(f)
 *                 for entry in existing_logs:
 */
        /*with:*/ {
          __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_1);
          if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_encoding, __pyx_kp_u_utf_8) < 0) __PYX_ERR(0, 89, __pyx_L5_error)
          __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_tuple__2, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 89, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_4);
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          __pyx_t_10 = __Pyx_PyObject_LookupSpecial(__pyx_t_4, __pyx_n_s_exit); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 89, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_10);
          __pyx_t_5 = __Pyx_PyObject_LookupSpecial(__pyx_t_4, __pyx_n_s_enter); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 89, __pyx_L11_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_11 = NULL;
          __pyx_t_6 = 0;
          #if CYTHON_UNPACK_METHODS
          if (likely(PyMethod_Check(__pyx_t_5))) {
            __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_5);
            if (likely(__pyx_t_11)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
              __Pyx_INCREF(__pyx_t_11);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_5, function);
              __pyx_t_6 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[2] = {__pyx_t_11, NULL};
            __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 0+__pyx_t_6);
            __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
            if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L11_error)
            __Pyx_GOTREF(__pyx_t_1);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          }
          __pyx_t_5 = __pyx_t_1;
          __pyx_t_1 = 0;
          __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
          /*try:*/ {
            {
              __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:*/ {
                __pyx_v_f = __pyx_t_5;
                __pyx_t_5 = 0;

                /* "sQQideR/SQLBuilder.pyx":90
 *             try:
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 *                     existing_logs = json.load(f)             # <<<<<<<<<<<<<<
 *                 for entry in existing_logs:
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):
 */
                __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_json); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 90, __pyx_L15_error)
                __Pyx_GOTREF(__pyx_t_4);
                __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_load); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 90, __pyx_L15_error)
                __Pyx_GOTREF(__pyx_t_1);
                __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
                __pyx_t_4 = NULL;
                __pyx_t_6 = 0;
                #if CYTHON_UNPACK_METHODS
                if (unlikely(PyMethod_Check(__pyx_t_1))) {
                  __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
                  if (likely(__pyx_t_4)) {
                    PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
                    __Pyx_INCREF(__pyx_t_4);
                    __Pyx_INCREF(function);
                    __Pyx_DECREF_SET(__pyx_t_1, function);
                    __pyx_t_6 = 1;
                  }
                }
                #endif
                {
                  PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_f};
                  __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
                  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
                  if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 90, __pyx_L15_error)
                  __Pyx_GOTREF(__pyx_t_5);
                  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
                }
                __pyx_v_existing_logs = __pyx_t_5;
                __pyx_t_5 = 0;

                /* "sQQideR/SQLBuilder.pyx":89
 *         if os.path.exists("data/failed_sql.json"):
 *             try:
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:             # <<<<<<<<<<<<<<
 *                     existing_logs = json.load(f)
 *                 for entry in existing_logs:
 */
              }
              __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_L20_try_end;
              __pyx_L15_error:;
              __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
              __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
              __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
              __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
              /*except:*/ {
                __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_sql", __pyx_clineno, __pyx_lineno, __pyx_filename);
                if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_1, &__pyx_t_4) < 0) __PYX_ERR(0, 89, __pyx_L17_except_error)
                __Pyx_XGOTREF(__pyx_t_5);
                __Pyx_XGOTREF(__pyx_t_1);
                __Pyx_XGOTREF(__pyx_t_4);
                __pyx_t_11 = PyTuple_Pack(3, __pyx_t_5, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 89, __pyx_L17_except_error)
                __Pyx_GOTREF(__pyx_t_11);
                __pyx_t_15 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_11, NULL);
                __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
                if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 89, __pyx_L17_except_error)
                __Pyx_GOTREF(__pyx_t_15);
                __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_15);
                __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
                if (__pyx_t_3 < 0) __PYX_ERR(0, 89, __pyx_L17_except_error)
                __pyx_t_2 = (!__pyx_t_3);
                if (unlikely(__pyx_t_2)) {
                  __Pyx_GIVEREF(__pyx_t_5);
                  __Pyx_GIVEREF(__pyx_t_1);
                  __Pyx_XGIVEREF(__pyx_t_4);
                  __Pyx_ErrRestoreWithState(__pyx_t_5, __pyx_t_1, __pyx_t_4);
                  __pyx_t_5 = 0; __pyx_t_1 = 0; __pyx_t_4 = 0; 
                  __PYX_ERR(0, 89, __pyx_L17_except_error)
                }
                __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
                __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
                goto __pyx_L16_exception_handled;
              }
              __pyx_L17_except_error:;
              __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_L5_error;
              __pyx_L16_exception_handled:;
              __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);
              __pyx_L20_try_end:;
            }
          }
          /*finally:*/ {
            /*normal exit:*/{
              if (__pyx_t_10) {
                __pyx_t_14 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__3, NULL);
                __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 89, __pyx_L5_error)
                __Pyx_GOTREF(__pyx_t_14);
                __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
              }
              goto __pyx_L14;
            }
            __pyx_L14:;
          }
          goto __pyx_L24;
          __pyx_L11_error:;
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          goto __pyx_L5_error;
          __pyx_L24:;
        }

        /* "sQQideR/SQLBuilder.pyx":91
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 *                     existing_logs = json.load(f)
 *                 for entry in existing_logs:             # <<<<<<<<<<<<<<
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):
 *                         working_sql = entry.get("working_sql")
 */
        if (unlikely(!__pyx_v_existing_logs)) { __Pyx_RaiseUnboundLocalError("existing_logs"); __PYX_ERR(0, 91, __pyx_L5_error) }
        if (likely(PyList_CheckExact(__pyx_v_existing_logs)) || PyTuple_CheckExact(__pyx_v_existing_logs)) {
          __pyx_t_4 = __pyx_v_existing_logs; __Pyx_INCREF(__pyx_t_4);
          __pyx_t_16 = 0;
          __pyx_t_17 = NULL;
        } else {
          __pyx_t_16 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_existing_logs); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 91, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_4);
          __pyx_t_17 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 91, __pyx_L5_error)
        }
        for (;;) {
          if (likely(!__pyx_t_17)) {
            if (likely(PyList_CheckExact(__pyx_t_4))) {
              {
                Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_4);
                #if !CYTHON_ASSUME_SAFE_MACROS
                if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 91, __pyx_L5_error)
                #endif
                if (__pyx_t_16 >= __pyx_temp) break;
              }
              #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
              __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_16); __Pyx_INCREF(__pyx_t_1); __pyx_t_16++; if (unlikely((0 < 0))) __PYX_ERR(0, 91, __pyx_L5_error)
              #else
              __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_16); __pyx_t_16++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_1);
              #endif
            } else {
              {
                Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_4);
                #if !CYTHON_ASSUME_SAFE_MACROS
                if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 91, __pyx_L5_error)
                #endif
                if (__pyx_t_16 >= __pyx_temp) break;
              }
              #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
              __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_16); __Pyx_INCREF(__pyx_t_1); __pyx_t_16++; if (unlikely((0 < 0))) __PYX_ERR(0, 91, __pyx_L5_error)
              #else
              __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_16); __pyx_t_16++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 91, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_1);
              #endif
            }
          } else {
            __pyx_t_1 = __pyx_t_17(__pyx_t_4);
            if (unlikely(!__pyx_t_1)) {
              PyObject* exc_type = PyErr_Occurred();
              if (exc_type) {
                if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
                else __PYX_ERR(0, 91, __pyx_L5_error)
              }
              break;
            }
            __Pyx_GOTREF(__pyx_t_1);
          }
          __Pyx_XDECREF_SET(__pyx_v_entry, __pyx_t_1);
          __pyx_t_1 = 0;

          /* "sQQideR/SQLBuilder.pyx":92
 *                     existing_logs = json.load(f)
 *                 for entry in existing_logs:
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):             # <<<<<<<<<<<<<<
 *                         working_sql = entry.get("working_sql")
 *                         if working_sql:
 */
          __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_entry, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 92, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_11 = NULL;
          __pyx_t_6 = 0;
          #if CYTHON_UNPACK_METHODS
          if (likely(PyMethod_Check(__pyx_t_5))) {
            __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_5);
            if (likely(__pyx_t_11)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
              __Pyx_INCREF(__pyx_t_11);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_5, function);
              __pyx_t_6 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_n_u_question};
            __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
            __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
            if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L5_error)
            __Pyx_GOTREF(__pyx_t_1);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          }
          __pyx_t_3 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_v_question, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 92, __pyx_L5_error)
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          if (!__pyx_t_3) {
          } else {
            __pyx_t_2 = __pyx_t_3;
            goto __pyx_L28_bool_binop_done;
          }
          __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_entry, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 92, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_11 = NULL;
          __pyx_t_6 = 0;
          #if CYTHON_UNPACK_METHODS
          if (likely(PyMethod_Check(__pyx_t_5))) {
            __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_5);
            if (likely(__pyx_t_11)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
              __Pyx_INCREF(__pyx_t_11);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_5, function);
              __pyx_t_6 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_n_u_failed_sql};
            __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
            __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
            if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L5_error)
            __Pyx_GOTREF(__pyx_t_1);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          }
          __pyx_t_5 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_existing_sql, Py_None); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 92, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_11 = PyObject_RichCompare(__pyx_t_1, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_11); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 92, __pyx_L5_error)
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 92, __pyx_L5_error)
          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
          __pyx_t_2 = __pyx_t_3;
          __pyx_L28_bool_binop_done:;
          if (__pyx_t_2) {

            /* "sQQideR/SQLBuilder.pyx":93
 *                 for entry in existing_logs:
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):
 *                         working_sql = entry.get("working_sql")             # <<<<<<<<<<<<<<
 *                         if working_sql:
 *                             if self.verbose:
 */
            __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_entry, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 93, __pyx_L5_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_1 = NULL;
            __pyx_t_6 = 0;
            #if CYTHON_UNPACK_METHODS
            if (likely(PyMethod_Check(__pyx_t_5))) {
              __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
              if (likely(__pyx_t_1)) {
                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                __Pyx_INCREF(__pyx_t_1);
                __Pyx_INCREF(function);
                __Pyx_DECREF_SET(__pyx_t_5, function);
                __pyx_t_6 = 1;
              }
            }
            #endif
            {
              PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_n_u_working_sql};
              __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
              __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
              if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 93, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_11);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            }
            __Pyx_XDECREF_SET(__pyx_v_working_sql, __pyx_t_11);
            __pyx_t_11 = 0;

            /* "sQQideR/SQLBuilder.pyx":94
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):
 *                         working_sql = entry.get("working_sql")
 *                         if working_sql:             # <<<<<<<<<<<<<<
 *                             if self.verbose:
 *                                 print("Found previous working SQL for this question/query, skipping AI call.")
 */
            __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_working_sql); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 94, __pyx_L5_error)
            if (__pyx_t_2) {

              /* "sQQideR/SQLBuilder.pyx":95
 *                         working_sql = entry.get("working_sql")
 *                         if working_sql:
 *                             if self.verbose:             # <<<<<<<<<<<<<<
 *                                 print("Found previous working SQL for this question/query, skipping AI call.")
 * 
 */
              __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 95, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_11);
              __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 95, __pyx_L5_error)
              __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
              if (__pyx_t_2) {

                /* "sQQideR/SQLBuilder.pyx":96
 *                         if working_sql:
 *                             if self.verbose:
 *                                 print("Found previous working SQL for this question/query, skipping AI call.")             # <<<<<<<<<<<<<<
 * 
 *                             # Create a more detailed explanation for traceability
 */
                __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 96, __pyx_L5_error)
                __Pyx_GOTREF(__pyx_t_11);
                __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;

                /* "sQQideR/SQLBuilder.pyx":95
 *                         working_sql = entry.get("working_sql")
 *                         if working_sql:
 *                             if self.verbose:             # <<<<<<<<<<<<<<
 *                                 print("Found previous working SQL for this question/query, skipping AI call.")
 * 
 */
              }

              /* "sQQideR/SQLBuilder.pyx":99
 * 
 *                             # Create a more detailed explanation for traceability
 *                             original_error = entry.get("error", "Unknown error")             # <<<<<<<<<<<<<<
 *                             original_failed_sql = entry.get("failed_sql", "No original SQL available")
 *                             original_question = entry.get("question", question)
 */
              __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_entry, __pyx_n_s_get); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 99, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_11);
              __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_5);
              __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
              __pyx_v_original_error = __pyx_t_5;
              __pyx_t_5 = 0;

              /* "sQQideR/SQLBuilder.pyx":100
 *                             # Create a more detailed explanation for traceability
 *                             original_error = entry.get("error", "Unknown error")
 *                             original_failed_sql = entry.get("failed_sql", "No original SQL available")             # <<<<<<<<<<<<<<
 *                             original_question = entry.get("question", question)
 * 
 */
              __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_entry, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 100, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 100, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_11);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __pyx_v_original_failed_sql = __pyx_t_11;
              __pyx_t_11 = 0;

              /* "sQQideR/SQLBuilder.pyx":101
 *                             original_error = entry.get("error", "Unknown error")
 *                             original_failed_sql = entry.get("failed_sql", "No original SQL available")
 *                             original_question = entry.get("question", question)             # <<<<<<<<<<<<<<
 * 
 *                             detailed_explanation = (
 */
              __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_entry, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 101, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_1 = NULL;
              __pyx_t_6 = 0;
              #if CYTHON_UNPACK_METHODS
              if (likely(PyMethod_Check(__pyx_t_5))) {
                __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
                if (likely(__pyx_t_1)) {
                  PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                  __Pyx_INCREF(__pyx_t_1);
                  __Pyx_INCREF(function);
                  __Pyx_DECREF_SET(__pyx_t_5, function);
                  __pyx_t_6 = 1;
                }
              }
              #endif
              {
                PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_n_u_question, __pyx_v_question};
                __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6);
                __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
                if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 101, __pyx_L5_error)
                __Pyx_GOTREF(__pyx_t_11);
                __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              }
              __pyx_v_original_question = __pyx_t_11;
              __pyx_t_11 = 0;

              /* "sQQideR/SQLBuilder.pyx":104
 * 
 *                             detailed_explanation = (
 *                                 f"This SQL was reused from a previously logged successful fix. "             # <<<<<<<<<<<<<<
 *                                 f"Original question: '{original_question}'. "
 *                                 f"Previous SQL attempt failed with error: '{original_error}'. "
 */
              __pyx_t_11 = PyTuple_New(5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 104, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_11);
              __pyx_t_18 = 0;
              __pyx_t_19 = 127;
              __Pyx_INCREF(__pyx_kp_u_This_SQL_was_reused_from_a_previ);
              __pyx_t_18 += 81;
              __Pyx_GIVEREF(__pyx_kp_u_This_SQL_was_reused_from_a_previ);
              PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_kp_u_This_SQL_was_reused_from_a_previ);

              /* "sQQideR/SQLBuilder.pyx":105
 *                             detailed_explanation = (
 *                                 f"This SQL was reused from a previously logged successful fix. "
 *                                 f"Original question: '{original_question}'. "             # <<<<<<<<<<<<<<
 *                                 f"Previous SQL attempt failed with error: '{original_error}'. "
 *                                 f"This working SQL has been verified to execute successfully."
 */
              __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_original_question, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 105, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_19 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_19) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_19;
              __pyx_t_18 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
              __Pyx_GIVEREF(__pyx_t_5);
              PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_5);
              __pyx_t_5 = 0;
              __Pyx_INCREF(__pyx_kp_u_Previous_SQL_attempt_failed_wit);
              __pyx_t_18 += 44;
              __Pyx_GIVEREF(__pyx_kp_u_Previous_SQL_attempt_failed_wit);
              PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_kp_u_Previous_SQL_attempt_failed_wit);

              /* "sQQideR/SQLBuilder.pyx":106
 *                                 f"This SQL was reused from a previously logged successful fix. "
 *                                 f"Original question: '{original_question}'. "
 *                                 f"Previous SQL attempt failed with error: '{original_error}'. "             # <<<<<<<<<<<<<<
 *                                 f"This working SQL has been verified to execute successfully."
 *                             )
 */
              __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_original_error, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 106, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_19 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_19) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_19;
              __pyx_t_18 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
              __Pyx_GIVEREF(__pyx_t_5);
              PyTuple_SET_ITEM(__pyx_t_11, 3, __pyx_t_5);
              __pyx_t_5 = 0;
              __Pyx_INCREF(__pyx_kp_u_This_working_SQL_has_been_verif);
              __pyx_t_18 += 62;
              __Pyx_GIVEREF(__pyx_kp_u_This_working_SQL_has_been_verif);
              PyTuple_SET_ITEM(__pyx_t_11, 4, __pyx_kp_u_This_working_SQL_has_been_verif);

              /* "sQQideR/SQLBuilder.pyx":104
 * 
 *                             detailed_explanation = (
 *                                 f"This SQL was reused from a previously logged successful fix. "             # <<<<<<<<<<<<<<
 *                                 f"Original question: '{original_question}'. "
 *                                 f"Previous SQL attempt failed with error: '{original_error}'. "
 */
              __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_11, 5, __pyx_t_18, __pyx_t_19); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 104, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_5);
              __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
              __pyx_v_detailed_explanation = ((PyObject*)__pyx_t_5);
              __pyx_t_5 = 0;

              /* "sQQideR/SQLBuilder.pyx":110
 *                             )
 * 
 *                             return {             # <<<<<<<<<<<<<<
 *                                 "question": question,
 *                                 "sql": working_sql,
 */
              __Pyx_XDECREF(__pyx_r);

              /* "sQQideR/SQLBuilder.pyx":111
 * 
 *                             return {
 *                                 "question": question,             # <<<<<<<<<<<<<<
 *                                 "sql": working_sql,
 *                                 "source": "reused_from_failed_json",
 */
              __pyx_t_5 = __Pyx_PyDict_NewPresized(6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L5_error)
              __Pyx_GOTREF(__pyx_t_5);
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_question, __pyx_v_question) < 0) __PYX_ERR(0, 111, __pyx_L5_error)

              /* "sQQideR/SQLBuilder.pyx":112
 *                             return {
 *                                 "question": question,
 *                                 "sql": working_sql,             # <<<<<<<<<<<<<<
 *                                 "source": "reused_from_failed_json",
 *                                 "explanation": detailed_explanation,
 */
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_sql, __pyx_v_working_sql) < 0) __PYX_ERR(0, 111, __pyx_L5_error)
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_source, __pyx_n_u_reused_from_failed_json) < 0) __PYX_ERR(0, 111, __pyx_L5_error)

              /* "sQQideR/SQLBuilder.pyx":114
 *                                 "sql": working_sql,
 *                                 "source": "reused_from_failed_json",
 *                                 "explanation": detailed_explanation,             # <<<<<<<<<<<<<<
 *                                 "original_failed_sql": original_failed_sql,
 *                                 "original_error": original_error
 */
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_explanation, __pyx_v_detailed_explanation) < 0) __PYX_ERR(0, 111, __pyx_L5_error)

              /* "sQQideR/SQLBuilder.pyx":115
 *                                 "source": "reused_from_failed_json",
 *                                 "explanation": detailed_explanation,
 *                                 "original_failed_sql": original_failed_sql,             # <<<<<<<<<<<<<<
 *                                 "original_error": original_error
 *                             }
 */
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_original_failed_sql, __pyx_v_original_failed_sql) < 0) __PYX_ERR(0, 111, __pyx_L5_error)

              /* "sQQideR/SQLBuilder.pyx":116
 *                                 "explanation": detailed_explanation,
 *                                 "original_failed_sql": original_failed_sql,
 *                                 "original_error": original_error             # <<<<<<<<<<<<<<
 *                             }
 *             except Exception as e:
 */
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_original_error, __pyx_v_original_error) < 0) __PYX_ERR(0, 111, __pyx_L5_error)
              __pyx_r = ((PyObject*)__pyx_t_5);
              __pyx_t_5 = 0;
              __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
              goto __pyx_L9_try_return;

              /* "sQQideR/SQLBuilder.pyx":94
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):
 *                         working_sql = entry.get("working_sql")
 *                         if working_sql:             # <<<<<<<<<<<<<<
 *                             if self.verbose:
 *                                 print("Found previous working SQL for this question/query, skipping AI call.")
 */
            }

            /* "sQQideR/SQLBuilder.pyx":92
 *                     existing_logs = json.load(f)
 *                 for entry in existing_logs:
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):             # <<<<<<<<<<<<<<
 *                         working_sql = entry.get("working_sql")
 *                         if working_sql:
 */
          }

          /* "sQQideR/SQLBuilder.pyx":91
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 *                     existing_logs = json.load(f)
 *                 for entry in existing_logs:             # <<<<<<<<<<<<<<
 *                     if entry.get("question") == question or entry.get("failed_sql") == db_context.get("existing_sql"):
 *                         working_sql = entry.get("working_sql")
 */
        }
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

        /* "sQQideR/SQLBuilder.pyx":88
 * 
 *         if os.path.exists("data/failed_sql.json"):
 *             try:             # <<<<<<<<<<<<<<
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 *                     existing_logs = json.load(f)
 */
      }
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      goto __pyx_L10_try_end;
      __pyx_L5_error:;
      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":118
 *                                 "original_error": original_error
 *                             }
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Failed to check existing logs: {e}")
 */
      __pyx_t_20 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
      if (__pyx_t_20) {
        __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_sql", __pyx_clineno, __pyx_lineno, __pyx_filename);
        if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_5, &__pyx_t_11) < 0) __PYX_ERR(0, 118, __pyx_L7_except_error)
        __Pyx_XGOTREF(__pyx_t_4);
        __Pyx_XGOTREF(__pyx_t_5);
        __Pyx_XGOTREF(__pyx_t_11);
        __Pyx_INCREF(__pyx_t_5);
        __pyx_v_e = __pyx_t_5;
        /*try:*/ {

          /* "sQQideR/SQLBuilder.pyx":119
 *                             }
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Failed to check existing logs: {e}")
 * 
 */
          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 119, __pyx_L38_error)
          __Pyx_GOTREF(__pyx_t_1);
          __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 119, __pyx_L38_error)
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          if (__pyx_t_2) {

            /* "sQQideR/SQLBuilder.pyx":120
 *             except Exception as e:
 *                 if self.verbose:
 *                     print(f"Failed to check existing logs: {e}")             # <<<<<<<<<<<<<<
 * 
 *         # Create a rich prompt for the AI model
 */
            __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 120, __pyx_L38_error)
            __Pyx_GOTREF(__pyx_t_1);
            __pyx_t_21 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Failed_to_check_existing_logs, __pyx_t_1); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 120, __pyx_L38_error)
            __Pyx_GOTREF(__pyx_t_21);
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
            __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_21); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 120, __pyx_L38_error)
            __Pyx_GOTREF(__pyx_t_1);
            __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

            /* "sQQideR/SQLBuilder.pyx":119
 *                             }
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Failed to check existing logs: {e}")
 * 
 */
          }
        }

        /* "sQQideR/SQLBuilder.pyx":118
 *                                 "original_error": original_error
 *                             }
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Failed to check existing logs: {e}")
 */
        /*finally:*/ {
          /*normal exit:*/{
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            goto __pyx_L39;
          }
          __pyx_L38_error:;
          /*exception exit:*/{
            __Pyx_PyThreadState_declare
            __Pyx_PyThreadState_assign
            __pyx_t_10 = 0; __pyx_t_14 = 0; __pyx_t_13 = 0; __pyx_t_12 = 0; __pyx_t_15 = 0; __pyx_t_24 = 0;
            __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
            __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
            if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_12, &__pyx_t_15, &__pyx_t_24);
            if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_10, &__pyx_t_14, &__pyx_t_13) < 0)) __Pyx_ErrFetch(&__pyx_t_10, &__pyx_t_14, &__pyx_t_13);
            __Pyx_XGOTREF(__pyx_t_10);
            __Pyx_XGOTREF(__pyx_t_14);
            __Pyx_XGOTREF(__pyx_t_13);
            __Pyx_XGOTREF(__pyx_t_12);
            __Pyx_XGOTREF(__pyx_t_15);
            __Pyx_XGOTREF(__pyx_t_24);
            __pyx_t_20 = __pyx_lineno; __pyx_t_22 = __pyx_clineno; __pyx_t_23 = __pyx_filename;
            {
              __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            }
            if (PY_MAJOR_VERSION >= 3) {
              __Pyx_XGIVEREF(__pyx_t_12);
              __Pyx_XGIVEREF(__pyx_t_15);
              __Pyx_XGIVEREF(__pyx_t_24);
              __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_15, __pyx_t_24);
            }
            __Pyx_XGIVEREF(__pyx_t_10);
            __Pyx_XGIVEREF(__pyx_t_14);
            __Pyx_XGIVEREF(__pyx_t_13);
            __Pyx_ErrRestore(__pyx_t_10, __pyx_t_14, __pyx_t_13);
            __pyx_t_10 = 0; __pyx_t_14 = 0; __pyx_t_13 = 0; __pyx_t_12 = 0; __pyx_t_15 = 0; __pyx_t_24 = 0;
            __pyx_lineno = __pyx_t_20; __pyx_clineno = __pyx_t_22; __pyx_filename = __pyx_t_23;
            goto __pyx_L7_except_error;
          }
          __pyx_L39:;
        }
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
        goto __pyx_L6_exception_handled;
      }
      goto __pyx_L7_except_error;

      /* "sQQideR/SQLBuilder.pyx":88
 * 
 *         if os.path.exists("data/failed_sql.json"):
 *             try:             # <<<<<<<<<<<<<<
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 *                     existing_logs = json.load(f)
 */
      __pyx_L7_except_error:;
      __Pyx_XGIVEREF(__pyx_t_7);
      __Pyx_XGIVEREF(__pyx_t_8);
      __Pyx_XGIVEREF(__pyx_t_9);
      __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
      goto __pyx_L1_error;
      __pyx_L9_try_return:;
      __Pyx_XGIVEREF(__pyx_t_7);
      __Pyx_XGIVEREF(__pyx_t_8);
      __Pyx_XGIVEREF(__pyx_t_9);
      __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
      goto __pyx_L0;
      __pyx_L6_exception_handled:;
      __Pyx_XGIVEREF(__pyx_t_7);
      __Pyx_XGIVEREF(__pyx_t_8);
      __Pyx_XGIVEREF(__pyx_t_9);
      __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
      __pyx_L10_try_end:;
    }

    /* "sQQideR/SQLBuilder.pyx":87
 *             return {"error": "AI service not available for SQL generation"}
 * 
 *         if os.path.exists("data/failed_sql.json"):             # <<<<<<<<<<<<<<
 *             try:
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:
 */
  }

  /* "sQQideR/SQLBuilder.pyx":123
 * 
 *         # Create a rich prompt for the AI model
 *         prompt = self._create_sql_generation_prompt(question, db_context)             # <<<<<<<<<<<<<<
 * 
 *         try:
 */
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_create_sql_generation_prompt); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 123, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_4 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_6 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_v_question, __pyx_v_db_context};
    __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 123, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_11);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_v_prompt = __pyx_t_11;
  __pyx_t_11 = 0;

  /* "sQQideR/SQLBuilder.pyx":125
 *         prompt = self._create_sql_generation_prompt(question, db_context)
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Clear any previous conversation
 *             self.ai_base.clear_history()
 */
  {
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    __Pyx_ExceptionSave(&__pyx_t_9, &__pyx_t_8, &__pyx_t_7);
    __Pyx_XGOTREF(__pyx_t_9);
    __Pyx_XGOTREF(__pyx_t_8);
    __Pyx_XGOTREF(__pyx_t_7);
    /*try:*/ {

      /* "sQQideR/SQLBuilder.pyx":127
 *         try:
 *             # Clear any previous conversation
 *             self.ai_base.clear_history()             # <<<<<<<<<<<<<<
 * 
 *             # Get SQL from AI
 */
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_ai_base); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 127, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_clear_history); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 127, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_5 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(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;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL};
        __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 0+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 127, __pyx_L45_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      }
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;

      /* "sQQideR/SQLBuilder.pyx":130
 * 
 *             # Get SQL from AI
 *             response = self.ai_base.get_response_sync(prompt)             # <<<<<<<<<<<<<<
 * 
 *             # Extract SQL from response
 */
      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_ai_base); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 130, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_get_response_sync); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 130, __pyx_L45_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
      if (likely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_prompt};
        __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 130, __pyx_L45_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __pyx_v_response = __pyx_t_11;
      __pyx_t_11 = 0;

      /* "sQQideR/SQLBuilder.pyx":133
 * 
 *             # Extract SQL from response
 *             sql_query = self._extract_sql_from_response(response)             # <<<<<<<<<<<<<<
 * 
 *             # Extract explanation if available
 */
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_extract_sql_from_response); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 133, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_4 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_response};
        __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 133, __pyx_L45_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __pyx_v_sql_query = __pyx_t_11;
      __pyx_t_11 = 0;

      /* "sQQideR/SQLBuilder.pyx":136
 * 
 *             # Extract explanation if available
 *             explanation = self._extract_explanation(response)             # <<<<<<<<<<<<<<
 * 
 *             # Clean text fields for downstream system (remove "\n" and extra spaces)
 */
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_extract_explanation); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 136, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_4 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_response};
        __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 136, __pyx_L45_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __pyx_v_explanation = __pyx_t_11;
      __pyx_t_11 = 0;

      /* "sQQideR/SQLBuilder.pyx":139
 * 
 *             # Clean text fields for downstream system (remove "\n" and extra spaces)
 *             cleaned_response = self._clean_text(response)             # <<<<<<<<<<<<<<
 *             cleaned_explanation = self._clean_text(explanation)
 *             cleaned_sql = self._clean_text(sql_query)
 */
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_clean_text); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 139, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_4 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_response};
        __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 139, __pyx_L45_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __pyx_v_cleaned_response = __pyx_t_11;
      __pyx_t_11 = 0;

      /* "sQQideR/SQLBuilder.pyx":140
 *             # Clean text fields for downstream system (remove "\n" and extra spaces)
 *             cleaned_response = self._clean_text(response)
 *             cleaned_explanation = self._clean_text(explanation)             # <<<<<<<<<<<<<<
 *             cleaned_sql = self._clean_text(sql_query)
 * 
 */
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_clean_text); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 140, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_4 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_explanation};
        __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 140, __pyx_L45_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __pyx_v_cleaned_explanation = __pyx_t_11;
      __pyx_t_11 = 0;

      /* "sQQideR/SQLBuilder.pyx":141
 *             cleaned_response = self._clean_text(response)
 *             cleaned_explanation = self._clean_text(explanation)
 *             cleaned_sql = self._clean_text(sql_query)             # <<<<<<<<<<<<<<
 * 
 *             return {
 */
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_clean_text); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 141, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_4 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_sql_query};
        __pyx_t_11 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 141, __pyx_L45_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __pyx_v_cleaned_sql = __pyx_t_11;
      __pyx_t_11 = 0;

      /* "sQQideR/SQLBuilder.pyx":143
 *             cleaned_sql = self._clean_text(sql_query)
 * 
 *             return {             # <<<<<<<<<<<<<<
 *                 "question": question,
 *                 "sql": cleaned_sql,
 */
      __Pyx_XDECREF(__pyx_r);

      /* "sQQideR/SQLBuilder.pyx":144
 * 
 *             return {
 *                 "question": question,             # <<<<<<<<<<<<<<
 *                 "sql": cleaned_sql,
 *                 "raw_ai_response": cleaned_response,
 */
      __pyx_t_11 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 144, __pyx_L45_error)
      __Pyx_GOTREF(__pyx_t_11);
      if (PyDict_SetItem(__pyx_t_11, __pyx_n_u_question, __pyx_v_question) < 0) __PYX_ERR(0, 144, __pyx_L45_error)

      /* "sQQideR/SQLBuilder.pyx":145
 *             return {
 *                 "question": question,
 *                 "sql": cleaned_sql,             # <<<<<<<<<<<<<<
 *                 "raw_ai_response": cleaned_response,
 *                 "explanation": cleaned_explanation,
 */
      if (PyDict_SetItem(__pyx_t_11, __pyx_n_u_sql, __pyx_v_cleaned_sql) < 0) __PYX_ERR(0, 144, __pyx_L45_error)

      /* "sQQideR/SQLBuilder.pyx":146
 *                 "question": question,
 *                 "sql": cleaned_sql,
 *                 "raw_ai_response": cleaned_response,             # <<<<<<<<<<<<<<
 *                 "explanation": cleaned_explanation,
 *                 "source": "ai_generated"
 */
      if (PyDict_SetItem(__pyx_t_11, __pyx_n_u_raw_ai_response, __pyx_v_cleaned_response) < 0) __PYX_ERR(0, 144, __pyx_L45_error)

      /* "sQQideR/SQLBuilder.pyx":147
 *                 "sql": cleaned_sql,
 *                 "raw_ai_response": cleaned_response,
 *                 "explanation": cleaned_explanation,             # <<<<<<<<<<<<<<
 *                 "source": "ai_generated"
 *             }
 */
      if (PyDict_SetItem(__pyx_t_11, __pyx_n_u_explanation, __pyx_v_cleaned_explanation) < 0) __PYX_ERR(0, 144, __pyx_L45_error)
      if (PyDict_SetItem(__pyx_t_11, __pyx_n_u_source, __pyx_n_u_ai_generated) < 0) __PYX_ERR(0, 144, __pyx_L45_error)
      __pyx_r = ((PyObject*)__pyx_t_11);
      __pyx_t_11 = 0;
      goto __pyx_L49_try_return;

      /* "sQQideR/SQLBuilder.pyx":125
 *         prompt = self._create_sql_generation_prompt(question, db_context)
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Clear any previous conversation
 *             self.ai_base.clear_history()
 */
    }
    __pyx_L45_error:;
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
    __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":150
 *                 "source": "ai_generated"
 *             }
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error generating SQL: {e}")
 */
    __pyx_t_22 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
    if (__pyx_t_22) {
      __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_sql", __pyx_clineno, __pyx_lineno, __pyx_filename);
      if (__Pyx_GetException(&__pyx_t_11, &__pyx_t_5, &__pyx_t_4) < 0) __PYX_ERR(0, 150, __pyx_L47_except_error)
      __Pyx_XGOTREF(__pyx_t_11);
      __Pyx_XGOTREF(__pyx_t_5);
      __Pyx_XGOTREF(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_5);
      __pyx_v_e = __pyx_t_5;
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":151
 *             }
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error generating SQL: {e}")
 *             return {
 */
        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 151, __pyx_L56_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 151, __pyx_L56_error)
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        if (__pyx_t_2) {

          /* "sQQideR/SQLBuilder.pyx":152
 *         except Exception as e:
 *             if self.verbose:
 *                 print(f"Error generating SQL: {e}")             # <<<<<<<<<<<<<<
 *             return {
 *                 "error": f"Failed to generate SQL: {str(e)}",
 */
          __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 152, __pyx_L56_error)
          __Pyx_GOTREF(__pyx_t_1);
          __pyx_t_21 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_generating_SQL, __pyx_t_1); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 152, __pyx_L56_error)
          __Pyx_GOTREF(__pyx_t_21);
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_21); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 152, __pyx_L56_error)
          __Pyx_GOTREF(__pyx_t_1);
          __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

          /* "sQQideR/SQLBuilder.pyx":151
 *             }
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error generating SQL: {e}")
 *             return {
 */
        }

        /* "sQQideR/SQLBuilder.pyx":153
 *             if self.verbose:
 *                 print(f"Error generating SQL: {e}")
 *             return {             # <<<<<<<<<<<<<<
 *                 "error": f"Failed to generate SQL: {str(e)}",
 *                 "question": question,
 */
        __Pyx_XDECREF(__pyx_r);

        /* "sQQideR/SQLBuilder.pyx":154
 *                 print(f"Error generating SQL: {e}")
 *             return {
 *                 "error": f"Failed to generate SQL: {str(e)}",             # <<<<<<<<<<<<<<
 *                 "question": question,
 *                 "source": "ai_generated"
 */
        __pyx_t_1 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 154, __pyx_L56_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_21 = __Pyx_PyObject_Unicode(__pyx_v_e); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 154, __pyx_L56_error)
        __Pyx_GOTREF(__pyx_t_21);
        __pyx_t_25 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Failed_to_generate_SQL, __pyx_t_21); if (unlikely(!__pyx_t_25)) __PYX_ERR(0, 154, __pyx_L56_error)
        __Pyx_GOTREF(__pyx_t_25);
        __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
        if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_error, __pyx_t_25) < 0) __PYX_ERR(0, 154, __pyx_L56_error)
        __Pyx_DECREF(__pyx_t_25); __pyx_t_25 = 0;

        /* "sQQideR/SQLBuilder.pyx":155
 *             return {
 *                 "error": f"Failed to generate SQL: {str(e)}",
 *                 "question": question,             # <<<<<<<<<<<<<<
 *                 "source": "ai_generated"
 *             }
 */
        if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_question, __pyx_v_question) < 0) __PYX_ERR(0, 154, __pyx_L56_error)
        if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_source, __pyx_n_u_ai_generated) < 0) __PYX_ERR(0, 154, __pyx_L56_error)
        __pyx_r = ((PyObject*)__pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        goto __pyx_L55_return;
      }

      /* "sQQideR/SQLBuilder.pyx":150
 *                 "source": "ai_generated"
 *             }
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error generating SQL: {e}")
 */
      /*finally:*/ {
        __pyx_L56_error:;
        /*exception exit:*/{
          __Pyx_PyThreadState_declare
          __Pyx_PyThreadState_assign
          __pyx_t_24 = 0; __pyx_t_15 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_10 = 0;
          __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
          __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
          __Pyx_XDECREF(__pyx_t_25); __pyx_t_25 = 0;
          if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_13, &__pyx_t_14, &__pyx_t_10);
          if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_24, &__pyx_t_15, &__pyx_t_12) < 0)) __Pyx_ErrFetch(&__pyx_t_24, &__pyx_t_15, &__pyx_t_12);
          __Pyx_XGOTREF(__pyx_t_24);
          __Pyx_XGOTREF(__pyx_t_15);
          __Pyx_XGOTREF(__pyx_t_12);
          __Pyx_XGOTREF(__pyx_t_13);
          __Pyx_XGOTREF(__pyx_t_14);
          __Pyx_XGOTREF(__pyx_t_10);
          __pyx_t_22 = __pyx_lineno; __pyx_t_20 = __pyx_clineno; __pyx_t_26 = __pyx_filename;
          {
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          }
          if (PY_MAJOR_VERSION >= 3) {
            __Pyx_XGIVEREF(__pyx_t_13);
            __Pyx_XGIVEREF(__pyx_t_14);
            __Pyx_XGIVEREF(__pyx_t_10);
            __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_10);
          }
          __Pyx_XGIVEREF(__pyx_t_24);
          __Pyx_XGIVEREF(__pyx_t_15);
          __Pyx_XGIVEREF(__pyx_t_12);
          __Pyx_ErrRestore(__pyx_t_24, __pyx_t_15, __pyx_t_12);
          __pyx_t_24 = 0; __pyx_t_15 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_10 = 0;
          __pyx_lineno = __pyx_t_22; __pyx_clineno = __pyx_t_20; __pyx_filename = __pyx_t_26;
          goto __pyx_L47_except_error;
        }
        __pyx_L55_return: {
          __pyx_t_27 = __pyx_r;
          __pyx_r = 0;
          __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          __pyx_r = __pyx_t_27;
          __pyx_t_27 = 0;
          goto __pyx_L48_except_return;
        }
      }
    }
    goto __pyx_L47_except_error;

    /* "sQQideR/SQLBuilder.pyx":125
 *         prompt = self._create_sql_generation_prompt(question, db_context)
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Clear any previous conversation
 *             self.ai_base.clear_history()
 */
    __pyx_L47_except_error:;
    __Pyx_XGIVEREF(__pyx_t_9);
    __Pyx_XGIVEREF(__pyx_t_8);
    __Pyx_XGIVEREF(__pyx_t_7);
    __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_8, __pyx_t_7);
    goto __pyx_L1_error;
    __pyx_L49_try_return:;
    __Pyx_XGIVEREF(__pyx_t_9);
    __Pyx_XGIVEREF(__pyx_t_8);
    __Pyx_XGIVEREF(__pyx_t_7);
    __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_8, __pyx_t_7);
    goto __pyx_L0;
    __pyx_L48_except_return:;
    __Pyx_XGIVEREF(__pyx_t_9);
    __Pyx_XGIVEREF(__pyx_t_8);
    __Pyx_XGIVEREF(__pyx_t_7);
    __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_8, __pyx_t_7);
    goto __pyx_L0;
  }

  /* "sQQideR/SQLBuilder.pyx":73
 *                 print("Database connection closed")
 * 
 *     def generate_sql(self, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Generate SQL based on the natural language question and database context.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_XDECREF(__pyx_t_21);
  __Pyx_XDECREF(__pyx_t_25);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_sql", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_f);
  __Pyx_XDECREF(__pyx_v_existing_logs);
  __Pyx_XDECREF(__pyx_v_entry);
  __Pyx_XDECREF(__pyx_v_working_sql);
  __Pyx_XDECREF(__pyx_v_original_error);
  __Pyx_XDECREF(__pyx_v_original_failed_sql);
  __Pyx_XDECREF(__pyx_v_original_question);
  __Pyx_XDECREF(__pyx_v_detailed_explanation);
  __Pyx_XDECREF(__pyx_v_e);
  __Pyx_XDECREF(__pyx_v_prompt);
  __Pyx_XDECREF(__pyx_v_response);
  __Pyx_XDECREF(__pyx_v_sql_query);
  __Pyx_XDECREF(__pyx_v_explanation);
  __Pyx_XDECREF(__pyx_v_cleaned_response);
  __Pyx_XDECREF(__pyx_v_cleaned_explanation);
  __Pyx_XDECREF(__pyx_v_cleaned_sql);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":159
 *             }
 * 
 *     def test_query(self, query: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Test a SQL query against the database and add the results.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_9test_query(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_8test_query, "\n        Test a SQL query against the database and add the results.\n        \n        Args:\n            query: Dictionary containing SQL query information\n            \n        Returns:\n            Updated query dictionary with results\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_9test_query = {"test_query", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_9test_query, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_8test_query};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_9test_query(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_query = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("test_query (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_query,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_query)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("test_query", 1, 2, 2, 1); __PYX_ERR(0, 159, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "test_query") < 0)) __PYX_ERR(0, 159, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_query = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("test_query", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 159, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.test_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), (&PyDict_Type), 0, "query", 1))) __PYX_ERR(0, 159, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_8test_query(__pyx_self, __pyx_v_self, __pyx_v_query);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_8test_query(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_query) {
  PyObject *__pyx_v_sql = NULL;
  PyObject *__pyx_v_validation_error = NULL;
  PyObject *__pyx_v_df = NULL;
  PyObject *__pyx_v_e = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  int __pyx_t_2;
  int __pyx_t_3;
  PyObject *__pyx_t_4 = NULL;
  PyObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  PyObject *__pyx_t_7 = NULL;
  PyObject *__pyx_t_8 = NULL;
  PyObject *__pyx_t_9 = NULL;
  PyObject *__pyx_t_10 = NULL;
  Py_ssize_t __pyx_t_11;
  Py_UCS4 __pyx_t_12;
  Py_ssize_t __pyx_t_13;
  int __pyx_t_14;
  PyObject *__pyx_t_15 = NULL;
  int __pyx_t_16;
  char const *__pyx_t_17;
  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;
  PyObject *__pyx_t_23 = NULL;
  PyObject *__pyx_t_24 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("test_query", 1);

  /* "sQQideR/SQLBuilder.pyx":169
 *             Updated query dictionary with results
 *         """
 *         if not self.conn:             # <<<<<<<<<<<<<<
 *             query["execution_error"] = "No database connection available"
 *             query["success"] = False
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 169, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 169, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = (!__pyx_t_2);
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":170
 *         """
 *         if not self.conn:
 *             query["execution_error"] = "No database connection available"             # <<<<<<<<<<<<<<
 *             query["success"] = False
 *             return query
 */
    if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_execution_error, __pyx_kp_u_No_database_connection_available) < 0))) __PYX_ERR(0, 170, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":171
 *         if not self.conn:
 *             query["execution_error"] = "No database connection available"
 *             query["success"] = False             # <<<<<<<<<<<<<<
 *             return query
 * 
 */
    if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_success, Py_False) < 0))) __PYX_ERR(0, 171, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":172
 *             query["execution_error"] = "No database connection available"
 *             query["success"] = False
 *             return query             # <<<<<<<<<<<<<<
 * 
 *         sql = query.get("sql", "")
 */
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_v_query);
    __pyx_r = __pyx_v_query;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":169
 *             Updated query dictionary with results
 *         """
 *         if not self.conn:             # <<<<<<<<<<<<<<
 *             query["execution_error"] = "No database connection available"
 *             query["success"] = False
 */
  }

  /* "sQQideR/SQLBuilder.pyx":174
 *             return query
 * 
 *         sql = query.get("sql", "")             # <<<<<<<<<<<<<<
 *         if not sql:
 *             query["execution_error"] = "No SQL query provided"
 */
  __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_query, __pyx_n_u_sql, __pyx_kp_u__7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 174, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_v_sql = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":175
 * 
 *         sql = query.get("sql", "")
 *         if not sql:             # <<<<<<<<<<<<<<
 *             query["execution_error"] = "No SQL query provided"
 *             query["success"] = False
 */
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_sql); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 175, __pyx_L1_error)
  __pyx_t_2 = (!__pyx_t_3);
  if (__pyx_t_2) {

    /* "sQQideR/SQLBuilder.pyx":176
 *         sql = query.get("sql", "")
 *         if not sql:
 *             query["execution_error"] = "No SQL query provided"             # <<<<<<<<<<<<<<
 *             query["success"] = False
 *             return query
 */
    if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_execution_error, __pyx_kp_u_No_SQL_query_provided) < 0))) __PYX_ERR(0, 176, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":177
 *         if not sql:
 *             query["execution_error"] = "No SQL query provided"
 *             query["success"] = False             # <<<<<<<<<<<<<<
 *             return query
 * 
 */
    if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_success, Py_False) < 0))) __PYX_ERR(0, 177, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":178
 *             query["execution_error"] = "No SQL query provided"
 *             query["success"] = False
 *             return query             # <<<<<<<<<<<<<<
 * 
 *         # Validate query for dangerous operations before execution
 */
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_v_query);
    __pyx_r = __pyx_v_query;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":175
 * 
 *         sql = query.get("sql", "")
 *         if not sql:             # <<<<<<<<<<<<<<
 *             query["execution_error"] = "No SQL query provided"
 *             query["success"] = False
 */
  }

  /* "sQQideR/SQLBuilder.pyx":181
 * 
 *         # Validate query for dangerous operations before execution
 *         validation_error = self._validate_safe_sql(sql)             # <<<<<<<<<<<<<<
 *         if validation_error:
 *             query["execution_error"] = validation_error
 */
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_validate_safe_sql); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 181, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(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;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_sql};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 181, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  __pyx_v_validation_error = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":182
 *         # Validate query for dangerous operations before execution
 *         validation_error = self._validate_safe_sql(sql)
 *         if validation_error:             # <<<<<<<<<<<<<<
 *             query["execution_error"] = validation_error
 *             query["success"] = False
 */
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_validation_error); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 182, __pyx_L1_error)
  if (__pyx_t_2) {

    /* "sQQideR/SQLBuilder.pyx":183
 *         validation_error = self._validate_safe_sql(sql)
 *         if validation_error:
 *             query["execution_error"] = validation_error             # <<<<<<<<<<<<<<
 *             query["success"] = False
 *             return query
 */
    if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_execution_error, __pyx_v_validation_error) < 0))) __PYX_ERR(0, 183, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":184
 *         if validation_error:
 *             query["execution_error"] = validation_error
 *             query["success"] = False             # <<<<<<<<<<<<<<
 *             return query
 * 
 */
    if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_success, Py_False) < 0))) __PYX_ERR(0, 184, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":185
 *             query["execution_error"] = validation_error
 *             query["success"] = False
 *             return query             # <<<<<<<<<<<<<<
 * 
 *         try:
 */
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_v_query);
    __pyx_r = __pyx_v_query;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":182
 *         # Validate query for dangerous operations before execution
 *         validation_error = self._validate_safe_sql(sql)
 *         if validation_error:             # <<<<<<<<<<<<<<
 *             query["execution_error"] = validation_error
 *             query["success"] = False
 */
  }

  /* "sQQideR/SQLBuilder.pyx":187
 *             return query
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Execute the query and get results
 *             df = pd.read_sql_query(sql, self.conn)
 */
  {
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    __Pyx_ExceptionSave(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9);
    __Pyx_XGOTREF(__pyx_t_7);
    __Pyx_XGOTREF(__pyx_t_8);
    __Pyx_XGOTREF(__pyx_t_9);
    /*try:*/ {

      /* "sQQideR/SQLBuilder.pyx":189
 *         try:
 *             # Execute the query and get results
 *             df = pd.read_sql_query(sql, self.conn)             # <<<<<<<<<<<<<<
 * 
 *             # Add results to the query dictionary
 */
      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pd); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 189, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_read_sql_query); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 189, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 189, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_10 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (unlikely(PyMethod_Check(__pyx_t_5))) {
        __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_5);
        if (likely(__pyx_t_10)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
          __Pyx_INCREF(__pyx_t_10);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_5, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[3] = {__pyx_t_10, __pyx_v_sql, __pyx_t_4};
        __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 189, __pyx_L6_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      }
      __pyx_v_df = __pyx_t_1;
      __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":192
 * 
 *             # Add results to the query dictionary
 *             query["success"] = True             # <<<<<<<<<<<<<<
 *             query["row_count"] = len(df)
 *             query["column_count"] = len(df.columns)
 */
      if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_success, Py_True) < 0))) __PYX_ERR(0, 192, __pyx_L6_error)

      /* "sQQideR/SQLBuilder.pyx":193
 *             # Add results to the query dictionary
 *             query["success"] = True
 *             query["row_count"] = len(df)             # <<<<<<<<<<<<<<
 *             query["column_count"] = len(df.columns)
 *             query["columns"] = list(df.columns)
 */
      __pyx_t_11 = PyObject_Length(__pyx_v_df); if (unlikely(__pyx_t_11 == ((Py_ssize_t)-1))) __PYX_ERR(0, 193, __pyx_L6_error)
      __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 193, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_row_count, __pyx_t_1) < 0))) __PYX_ERR(0, 193, __pyx_L6_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":194
 *             query["success"] = True
 *             query["row_count"] = len(df)
 *             query["column_count"] = len(df.columns)             # <<<<<<<<<<<<<<
 *             query["columns"] = list(df.columns)
 * 
 */
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 194, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_11 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_11 == ((Py_ssize_t)-1))) __PYX_ERR(0, 194, __pyx_L6_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 194, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_column_count, __pyx_t_1) < 0))) __PYX_ERR(0, 194, __pyx_L6_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":195
 *             query["row_count"] = len(df)
 *             query["column_count"] = len(df.columns)
 *             query["columns"] = list(df.columns)             # <<<<<<<<<<<<<<
 * 
 *             # Convert DataFrame to records for JSON serialization
 */
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 195, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_5 = __Pyx_PySequence_ListKeepNew(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 195, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_columns, __pyx_t_5) < 0))) __PYX_ERR(0, 195, __pyx_L6_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":198
 * 
 *             # Convert DataFrame to records for JSON serialization
 *             query["results"] = df.to_dict(orient="records")             # <<<<<<<<<<<<<<
 * 
 *             # Generate a result summary
 */
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_to_dict); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 198, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 198, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_orient, __pyx_n_u_records) < 0) __PYX_ERR(0, 198, __pyx_L6_error)
      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 198, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_results, __pyx_t_4) < 0))) __PYX_ERR(0, 198, __pyx_L6_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

      /* "sQQideR/SQLBuilder.pyx":201
 * 
 *             # Generate a result summary
 *             query["summary"] = self._generate_result_summary(df)             # <<<<<<<<<<<<<<
 * 
 *             if self.verbose:
 */
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_generate_result_summary); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 201, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_5 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_1))) {
        __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
        if (likely(__pyx_t_5)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
          __Pyx_INCREF(__pyx_t_5);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_1, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_df};
        __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 201, __pyx_L6_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      }
      if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_summary, __pyx_t_4) < 0))) __PYX_ERR(0, 201, __pyx_L6_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

      /* "sQQideR/SQLBuilder.pyx":203
 *             query["summary"] = self._generate_result_summary(df)
 * 
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Query executed successfully: {len(df)} rows returned")
 * 
 */
      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 203, __pyx_L6_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 203, __pyx_L6_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (__pyx_t_2) {

        /* "sQQideR/SQLBuilder.pyx":204
 * 
 *             if self.verbose:
 *                 print(f"Query executed successfully: {len(df)} rows returned")             # <<<<<<<<<<<<<<
 * 
 *             return query
 */
        __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 204, __pyx_L6_error)
        __Pyx_GOTREF(__pyx_t_4);
        __pyx_t_11 = 0;
        __pyx_t_12 = 127;
        __Pyx_INCREF(__pyx_kp_u_Query_executed_successfully);
        __pyx_t_11 += 29;
        __Pyx_GIVEREF(__pyx_kp_u_Query_executed_successfully);
        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_kp_u_Query_executed_successfully);
        __pyx_t_13 = PyObject_Length(__pyx_v_df); if (unlikely(__pyx_t_13 == ((Py_ssize_t)-1))) __PYX_ERR(0, 204, __pyx_L6_error)
        __pyx_t_1 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_t_13, 0, ' ', 'd'); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 204, __pyx_L6_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_11 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_1);
        PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_INCREF(__pyx_kp_u_rows_returned);
        __pyx_t_11 += 14;
        __Pyx_GIVEREF(__pyx_kp_u_rows_returned);
        PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_kp_u_rows_returned);
        __pyx_t_1 = __Pyx_PyUnicode_Join(__pyx_t_4, 3, __pyx_t_11, __pyx_t_12); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 204, __pyx_L6_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 204, __pyx_L6_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

        /* "sQQideR/SQLBuilder.pyx":203
 *             query["summary"] = self._generate_result_summary(df)
 * 
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Query executed successfully: {len(df)} rows returned")
 * 
 */
      }

      /* "sQQideR/SQLBuilder.pyx":206
 *                 print(f"Query executed successfully: {len(df)} rows returned")
 * 
 *             return query             # <<<<<<<<<<<<<<
 *         except Exception as e:
 *             if self.verbose:
 */
      __Pyx_XDECREF(__pyx_r);
      __Pyx_INCREF(__pyx_v_query);
      __pyx_r = __pyx_v_query;
      goto __pyx_L10_try_return;

      /* "sQQideR/SQLBuilder.pyx":187
 *             return query
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Execute the query and get results
 *             df = pd.read_sql_query(sql, self.conn)
 */
    }
    __pyx_L6_error:;
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":207
 * 
 *             return query
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error executing query: {e}")
 */
    __pyx_t_14 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
    if (__pyx_t_14) {
      __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.test_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_1, &__pyx_t_5) < 0) __PYX_ERR(0, 207, __pyx_L8_except_error)
      __Pyx_XGOTREF(__pyx_t_4);
      __Pyx_XGOTREF(__pyx_t_1);
      __Pyx_XGOTREF(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_1);
      __pyx_v_e = __pyx_t_1;
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":208
 *             return query
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error executing query: {e}")
 * 
 */
        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 208, __pyx_L18_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 208, __pyx_L18_error)
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        if (__pyx_t_2) {

          /* "sQQideR/SQLBuilder.pyx":209
 *         except Exception as e:
 *             if self.verbose:
 *                 print(f"Error executing query: {e}")             # <<<<<<<<<<<<<<
 * 
 *             query["execution_error"] = str(e)
 */
          __pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 209, __pyx_L18_error)
          __Pyx_GOTREF(__pyx_t_10);
          __pyx_t_15 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_executing_query, __pyx_t_10); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 209, __pyx_L18_error)
          __Pyx_GOTREF(__pyx_t_15);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_15); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 209, __pyx_L18_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

          /* "sQQideR/SQLBuilder.pyx":208
 *             return query
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error executing query: {e}")
 * 
 */
        }

        /* "sQQideR/SQLBuilder.pyx":211
 *                 print(f"Error executing query: {e}")
 * 
 *             query["execution_error"] = str(e)             # <<<<<<<<<<<<<<
 *             query["success"] = False
 *             return query
 */
        __pyx_t_10 = __Pyx_PyObject_Unicode(__pyx_v_e); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 211, __pyx_L18_error)
        __Pyx_GOTREF(__pyx_t_10);
        if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_execution_error, __pyx_t_10) < 0))) __PYX_ERR(0, 211, __pyx_L18_error)
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

        /* "sQQideR/SQLBuilder.pyx":212
 * 
 *             query["execution_error"] = str(e)
 *             query["success"] = False             # <<<<<<<<<<<<<<
 *             return query
 * 
 */
        if (unlikely((PyDict_SetItem(__pyx_v_query, __pyx_n_u_success, Py_False) < 0))) __PYX_ERR(0, 212, __pyx_L18_error)

        /* "sQQideR/SQLBuilder.pyx":213
 *             query["execution_error"] = str(e)
 *             query["success"] = False
 *             return query             # <<<<<<<<<<<<<<
 * 
 *     def compare_queries(self, historical_query: Dict, ai_query: Dict, question: str) -> Dict:
 */
        __Pyx_XDECREF(__pyx_r);
        __Pyx_INCREF(__pyx_v_query);
        __pyx_r = __pyx_v_query;
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        goto __pyx_L17_return;
      }

      /* "sQQideR/SQLBuilder.pyx":207
 * 
 *             return query
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error executing query: {e}")
 */
      /*finally:*/ {
        __pyx_L18_error:;
        /*exception exit:*/{
          __Pyx_PyThreadState_declare
          __Pyx_PyThreadState_assign
          __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0;
          __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
          if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_21, &__pyx_t_22, &__pyx_t_23);
          if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20) < 0)) __Pyx_ErrFetch(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20);
          __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_XGOTREF(__pyx_t_23);
          __pyx_t_14 = __pyx_lineno; __pyx_t_16 = __pyx_clineno; __pyx_t_17 = __pyx_filename;
          {
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          }
          if (PY_MAJOR_VERSION >= 3) {
            __Pyx_XGIVEREF(__pyx_t_21);
            __Pyx_XGIVEREF(__pyx_t_22);
            __Pyx_XGIVEREF(__pyx_t_23);
            __Pyx_ExceptionReset(__pyx_t_21, __pyx_t_22, __pyx_t_23);
          }
          __Pyx_XGIVEREF(__pyx_t_18);
          __Pyx_XGIVEREF(__pyx_t_19);
          __Pyx_XGIVEREF(__pyx_t_20);
          __Pyx_ErrRestore(__pyx_t_18, __pyx_t_19, __pyx_t_20);
          __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0;
          __pyx_lineno = __pyx_t_14; __pyx_clineno = __pyx_t_16; __pyx_filename = __pyx_t_17;
          goto __pyx_L8_except_error;
        }
        __pyx_L17_return: {
          __pyx_t_24 = __pyx_r;
          __pyx_r = 0;
          __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          __pyx_r = __pyx_t_24;
          __pyx_t_24 = 0;
          goto __pyx_L9_except_return;
        }
      }
    }
    goto __pyx_L8_except_error;

    /* "sQQideR/SQLBuilder.pyx":187
 *             return query
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Execute the query and get results
 *             df = pd.read_sql_query(sql, self.conn)
 */
    __pyx_L8_except_error:;
    __Pyx_XGIVEREF(__pyx_t_7);
    __Pyx_XGIVEREF(__pyx_t_8);
    __Pyx_XGIVEREF(__pyx_t_9);
    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
    goto __pyx_L1_error;
    __pyx_L10_try_return:;
    __Pyx_XGIVEREF(__pyx_t_7);
    __Pyx_XGIVEREF(__pyx_t_8);
    __Pyx_XGIVEREF(__pyx_t_9);
    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
    goto __pyx_L0;
    __pyx_L9_except_return:;
    __Pyx_XGIVEREF(__pyx_t_7);
    __Pyx_XGIVEREF(__pyx_t_8);
    __Pyx_XGIVEREF(__pyx_t_9);
    __Pyx_ExceptionReset(__pyx_t_7, __pyx_t_8, __pyx_t_9);
    goto __pyx_L0;
  }

  /* "sQQideR/SQLBuilder.pyx":159
 *             }
 * 
 *     def test_query(self, query: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Test a SQL query against the database and add the results.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_XDECREF(__pyx_t_15);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.test_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_sql);
  __Pyx_XDECREF(__pyx_v_validation_error);
  __Pyx_XDECREF(__pyx_v_df);
  __Pyx_XDECREF(__pyx_v_e);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":215
 *             return query
 * 
 *     def compare_queries(self, historical_query: Dict, ai_query: Dict, question: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Compare results from historical and AI-generated queries to see which best answers the question.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_11compare_queries(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_10compare_queries, "\n        Compare results from historical and AI-generated queries to see which best answers the question.\n        \n        Args:\n            historical_query: Query from history with results\n            ai_query: AI-generated query with results\n            question: The original natural language question\n            \n        Returns:\n            Dictionary with comparison results and recommendations\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_11compare_queries = {"compare_queries", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_11compare_queries, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_10compare_queries};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_11compare_queries(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_historical_query = 0;
  PyObject *__pyx_v_ai_query = 0;
  PyObject *__pyx_v_question = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[4] = {0,0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("compare_queries (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_historical_query,&__pyx_n_s_ai_query,&__pyx_n_s_question,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 215, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_historical_query)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 215, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("compare_queries", 1, 4, 4, 1); __PYX_ERR(0, 215, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_ai_query)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 215, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("compare_queries", 1, 4, 4, 2); __PYX_ERR(0, 215, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[3]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 215, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("compare_queries", 1, 4, 4, 3); __PYX_ERR(0, 215, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "compare_queries") < 0)) __PYX_ERR(0, 215, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 4)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
      values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
    }
    __pyx_v_self = values[0];
    __pyx_v_historical_query = ((PyObject*)values[1]);
    __pyx_v_ai_query = ((PyObject*)values[2]);
    __pyx_v_question = ((PyObject*)values[3]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("compare_queries", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 215, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.compare_queries", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_historical_query), (&PyDict_Type), 0, "historical_query", 1))) __PYX_ERR(0, 215, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ai_query), (&PyDict_Type), 0, "ai_query", 1))) __PYX_ERR(0, 215, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 215, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_10compare_queries(__pyx_self, __pyx_v_self, __pyx_v_historical_query, __pyx_v_ai_query, __pyx_v_question);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_10compare_queries(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_historical_query, PyObject *__pyx_v_ai_query, PyObject *__pyx_v_question) {
  PyObject *__pyx_v_comparison = NULL;
  PyObject *__pyx_v_hist_score = NULL;
  PyObject *__pyx_v_ai_score = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  PyObject *__pyx_t_2 = NULL;
  int __pyx_t_3;
  int __pyx_t_4;
  PyObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("compare_queries", 1);

  /* "sQQideR/SQLBuilder.pyx":228
 *         """
 *         comparison = {
 *             "question": question,             # <<<<<<<<<<<<<<
 *             "historical_query": historical_query,
 *             "ai_query": ai_query,
 */
  __pyx_t_1 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 228, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_question, __pyx_v_question) < 0) __PYX_ERR(0, 228, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":229
 *         comparison = {
 *             "question": question,
 *             "historical_query": historical_query,             # <<<<<<<<<<<<<<
 *             "ai_query": ai_query,
 *             "historical_success": historical_query.get("success", False),
 */
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_historical_query, __pyx_v_historical_query) < 0) __PYX_ERR(0, 228, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":230
 *             "question": question,
 *             "historical_query": historical_query,
 *             "ai_query": ai_query,             # <<<<<<<<<<<<<<
 *             "historical_success": historical_query.get("success", False),
 *             "ai_success": ai_query.get("success", False)
 */
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_ai_query, __pyx_v_ai_query) < 0) __PYX_ERR(0, 228, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":231
 *             "historical_query": historical_query,
 *             "ai_query": ai_query,
 *             "historical_success": historical_query.get("success", False),             # <<<<<<<<<<<<<<
 *             "ai_success": ai_query.get("success", False)
 *         }
 */
  __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_historical_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 231, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_historical_success, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":232
 *             "ai_query": ai_query,
 *             "historical_success": historical_query.get("success", False),
 *             "ai_success": ai_query.get("success", False)             # <<<<<<<<<<<<<<
 *         }
 * 
 */
  __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_ai_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_ai_success, __pyx_t_2) < 0) __PYX_ERR(0, 228, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_comparison = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":236
 * 
 *         # If both queries succeeded, attempt to determine which is better
 *         if historical_query.get("success", False) and ai_query.get("success", False):             # <<<<<<<<<<<<<<
 *             hist_score = self._evaluate_query_relevance(historical_query, question)
 *             ai_score = self._evaluate_query_relevance(ai_query, question)
 */
  __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_historical_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 236, __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(0, 236, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_4) {
  } else {
    __pyx_t_3 = __pyx_t_4;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_ai_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 236, __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(0, 236, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = __pyx_t_4;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":237
 *         # If both queries succeeded, attempt to determine which is better
 *         if historical_query.get("success", False) and ai_query.get("success", False):
 *             hist_score = self._evaluate_query_relevance(historical_query, question)             # <<<<<<<<<<<<<<
 *             ai_score = self._evaluate_query_relevance(ai_query, question)
 * 
 */
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_evaluate_query_relevance); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 237, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(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;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_v_historical_query, __pyx_v_question};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 237, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    }
    __pyx_v_hist_score = __pyx_t_1;
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":238
 *         if historical_query.get("success", False) and ai_query.get("success", False):
 *             hist_score = self._evaluate_query_relevance(historical_query, question)
 *             ai_score = self._evaluate_query_relevance(ai_query, question)             # <<<<<<<<<<<<<<
 * 
 *             comparison["historical_relevance_score"] = hist_score
 */
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_evaluate_query_relevance); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(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;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_v_ai_query, __pyx_v_question};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 238, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    }
    __pyx_v_ai_score = __pyx_t_1;
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":240
 *             ai_score = self._evaluate_query_relevance(ai_query, question)
 * 
 *             comparison["historical_relevance_score"] = hist_score             # <<<<<<<<<<<<<<
 *             comparison["ai_relevance_score"] = ai_score
 * 
 */
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_historical_relevance_score, __pyx_v_hist_score) < 0))) __PYX_ERR(0, 240, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":241
 * 
 *             comparison["historical_relevance_score"] = hist_score
 *             comparison["ai_relevance_score"] = ai_score             # <<<<<<<<<<<<<<
 * 
 *             # Determine recommended query based on scores
 */
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_ai_relevance_score, __pyx_v_ai_score) < 0))) __PYX_ERR(0, 241, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":244
 * 
 *             # Determine recommended query based on scores
 *             if hist_score > ai_score:             # <<<<<<<<<<<<<<
 *                 comparison["recommended_query"] = "historical"
 *                 comparison["recommendation_reason"] = "Historical query appears more relevant to the question"
 */
    __pyx_t_1 = PyObject_RichCompare(__pyx_v_hist_score, __pyx_v_ai_score, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 244, __pyx_L1_error)
    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 244, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (__pyx_t_3) {

      /* "sQQideR/SQLBuilder.pyx":245
 *             # Determine recommended query based on scores
 *             if hist_score > ai_score:
 *                 comparison["recommended_query"] = "historical"             # <<<<<<<<<<<<<<
 *                 comparison["recommendation_reason"] = "Historical query appears more relevant to the question"
 *             elif ai_score > hist_score:
 */
      if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommended_query, __pyx_n_u_historical) < 0))) __PYX_ERR(0, 245, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":246
 *             if hist_score > ai_score:
 *                 comparison["recommended_query"] = "historical"
 *                 comparison["recommendation_reason"] = "Historical query appears more relevant to the question"             # <<<<<<<<<<<<<<
 *             elif ai_score > hist_score:
 *                 comparison["recommended_query"] = "ai"
 */
      if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommendation_reason, __pyx_kp_u_Historical_query_appears_more_re) < 0))) __PYX_ERR(0, 246, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":244
 * 
 *             # Determine recommended query based on scores
 *             if hist_score > ai_score:             # <<<<<<<<<<<<<<
 *                 comparison["recommended_query"] = "historical"
 *                 comparison["recommendation_reason"] = "Historical query appears more relevant to the question"
 */
      goto __pyx_L6;
    }

    /* "sQQideR/SQLBuilder.pyx":247
 *                 comparison["recommended_query"] = "historical"
 *                 comparison["recommendation_reason"] = "Historical query appears more relevant to the question"
 *             elif ai_score > hist_score:             # <<<<<<<<<<<<<<
 *                 comparison["recommended_query"] = "ai"
 *                 comparison["recommendation_reason"] = "AI-generated query appears more relevant to the question"
 */
    __pyx_t_1 = PyObject_RichCompare(__pyx_v_ai_score, __pyx_v_hist_score, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 247, __pyx_L1_error)
    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 247, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (__pyx_t_3) {

      /* "sQQideR/SQLBuilder.pyx":248
 *                 comparison["recommendation_reason"] = "Historical query appears more relevant to the question"
 *             elif ai_score > hist_score:
 *                 comparison["recommended_query"] = "ai"             # <<<<<<<<<<<<<<
 *                 comparison["recommendation_reason"] = "AI-generated query appears more relevant to the question"
 *             else:
 */
      if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommended_query, __pyx_n_u_ai) < 0))) __PYX_ERR(0, 248, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":249
 *             elif ai_score > hist_score:
 *                 comparison["recommended_query"] = "ai"
 *                 comparison["recommendation_reason"] = "AI-generated query appears more relevant to the question"             # <<<<<<<<<<<<<<
 *             else:
 *                 # If scores are equal, prefer historical for stability
 */
      if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommendation_reason, __pyx_kp_u_AI_generated_query_appears_more) < 0))) __PYX_ERR(0, 249, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":247
 *                 comparison["recommended_query"] = "historical"
 *                 comparison["recommendation_reason"] = "Historical query appears more relevant to the question"
 *             elif ai_score > hist_score:             # <<<<<<<<<<<<<<
 *                 comparison["recommended_query"] = "ai"
 *                 comparison["recommendation_reason"] = "AI-generated query appears more relevant to the question"
 */
      goto __pyx_L6;
    }

    /* "sQQideR/SQLBuilder.pyx":252
 *             else:
 *                 # If scores are equal, prefer historical for stability
 *                 comparison["recommended_query"] = "historical"             # <<<<<<<<<<<<<<
 *                 comparison["recommendation_reason"] = "Equal relevance, using historical query for consistency"
 * 
 */
    /*else*/ {
      if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommended_query, __pyx_n_u_historical) < 0))) __PYX_ERR(0, 252, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":253
 *                 # If scores are equal, prefer historical for stability
 *                 comparison["recommended_query"] = "historical"
 *                 comparison["recommendation_reason"] = "Equal relevance, using historical query for consistency"             # <<<<<<<<<<<<<<
 * 
 *         # If only one query succeeded, recommend that one
 */
      if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommendation_reason, __pyx_kp_u_Equal_relevance_using_historical) < 0))) __PYX_ERR(0, 253, __pyx_L1_error)
    }
    __pyx_L6:;

    /* "sQQideR/SQLBuilder.pyx":236
 * 
 *         # If both queries succeeded, attempt to determine which is better
 *         if historical_query.get("success", False) and ai_query.get("success", False):             # <<<<<<<<<<<<<<
 *             hist_score = self._evaluate_query_relevance(historical_query, question)
 *             ai_score = self._evaluate_query_relevance(ai_query, question)
 */
    goto __pyx_L3;
  }

  /* "sQQideR/SQLBuilder.pyx":256
 * 
 *         # If only one query succeeded, recommend that one
 *         elif historical_query.get("success", False):             # <<<<<<<<<<<<<<
 *             comparison["recommended_query"] = "historical"
 *             comparison["recommendation_reason"] = "Only historical query executed successfully"
 */
  __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_historical_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 256, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 256, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":257
 *         # If only one query succeeded, recommend that one
 *         elif historical_query.get("success", False):
 *             comparison["recommended_query"] = "historical"             # <<<<<<<<<<<<<<
 *             comparison["recommendation_reason"] = "Only historical query executed successfully"
 *         elif ai_query.get("success", False):
 */
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommended_query, __pyx_n_u_historical) < 0))) __PYX_ERR(0, 257, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":258
 *         elif historical_query.get("success", False):
 *             comparison["recommended_query"] = "historical"
 *             comparison["recommendation_reason"] = "Only historical query executed successfully"             # <<<<<<<<<<<<<<
 *         elif ai_query.get("success", False):
 *             comparison["recommended_query"] = "ai"
 */
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommendation_reason, __pyx_kp_u_Only_historical_query_executed_s) < 0))) __PYX_ERR(0, 258, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":256
 * 
 *         # If only one query succeeded, recommend that one
 *         elif historical_query.get("success", False):             # <<<<<<<<<<<<<<
 *             comparison["recommended_query"] = "historical"
 *             comparison["recommendation_reason"] = "Only historical query executed successfully"
 */
    goto __pyx_L3;
  }

  /* "sQQideR/SQLBuilder.pyx":259
 *             comparison["recommended_query"] = "historical"
 *             comparison["recommendation_reason"] = "Only historical query executed successfully"
 *         elif ai_query.get("success", False):             # <<<<<<<<<<<<<<
 *             comparison["recommended_query"] = "ai"
 *             comparison["recommendation_reason"] = "Only AI-generated query executed successfully"
 */
  __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_ai_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 259, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 259, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":260
 *             comparison["recommendation_reason"] = "Only historical query executed successfully"
 *         elif ai_query.get("success", False):
 *             comparison["recommended_query"] = "ai"             # <<<<<<<<<<<<<<
 *             comparison["recommendation_reason"] = "Only AI-generated query executed successfully"
 *         else:
 */
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommended_query, __pyx_n_u_ai) < 0))) __PYX_ERR(0, 260, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":261
 *         elif ai_query.get("success", False):
 *             comparison["recommended_query"] = "ai"
 *             comparison["recommendation_reason"] = "Only AI-generated query executed successfully"             # <<<<<<<<<<<<<<
 *         else:
 *             comparison["recommended_query"] = None
 */
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommendation_reason, __pyx_kp_u_Only_AI_generated_query_executed) < 0))) __PYX_ERR(0, 261, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":259
 *             comparison["recommended_query"] = "historical"
 *             comparison["recommendation_reason"] = "Only historical query executed successfully"
 *         elif ai_query.get("success", False):             # <<<<<<<<<<<<<<
 *             comparison["recommended_query"] = "ai"
 *             comparison["recommendation_reason"] = "Only AI-generated query executed successfully"
 */
    goto __pyx_L3;
  }

  /* "sQQideR/SQLBuilder.pyx":263
 *             comparison["recommendation_reason"] = "Only AI-generated query executed successfully"
 *         else:
 *             comparison["recommended_query"] = None             # <<<<<<<<<<<<<<
 *             comparison["recommendation_reason"] = "Neither query executed successfully"
 * 
 */
  /*else*/ {
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommended_query, Py_None) < 0))) __PYX_ERR(0, 263, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":264
 *         else:
 *             comparison["recommended_query"] = None
 *             comparison["recommendation_reason"] = "Neither query executed successfully"             # <<<<<<<<<<<<<<
 * 
 *         if self.verbose:
 */
    if (unlikely((PyDict_SetItem(__pyx_v_comparison, __pyx_n_u_recommendation_reason, __pyx_kp_u_Neither_query_executed_successfu) < 0))) __PYX_ERR(0, 264, __pyx_L1_error)
  }
  __pyx_L3:;

  /* "sQQideR/SQLBuilder.pyx":266
 *             comparison["recommendation_reason"] = "Neither query executed successfully"
 * 
 *         if self.verbose:             # <<<<<<<<<<<<<<
 *             print(f"Query comparison complete. Recommended: {comparison.get('recommended_query')}")
 *             print(f"Reason: {comparison.get('recommendation_reason')}")
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 266, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 266, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":267
 * 
 *         if self.verbose:
 *             print(f"Query comparison complete. Recommended: {comparison.get('recommended_query')}")             # <<<<<<<<<<<<<<
 *             print(f"Reason: {comparison.get('recommendation_reason')}")
 * 
 */
    __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_comparison, __pyx_n_u_recommended_query, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 267, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 267, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Query_comparison_complete_Recomm, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 267, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 267, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":268
 *         if self.verbose:
 *             print(f"Query comparison complete. Recommended: {comparison.get('recommended_query')}")
 *             print(f"Reason: {comparison.get('recommendation_reason')}")             # <<<<<<<<<<<<<<
 * 
 *         return comparison
 */
    __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_comparison, __pyx_n_u_recommendation_reason, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 268, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 268, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Reason, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 268, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 268, __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;

    /* "sQQideR/SQLBuilder.pyx":266
 *             comparison["recommendation_reason"] = "Neither query executed successfully"
 * 
 *         if self.verbose:             # <<<<<<<<<<<<<<
 *             print(f"Query comparison complete. Recommended: {comparison.get('recommended_query')}")
 *             print(f"Reason: {comparison.get('recommendation_reason')}")
 */
  }

  /* "sQQideR/SQLBuilder.pyx":270
 *             print(f"Reason: {comparison.get('recommendation_reason')}")
 * 
 *         return comparison             # <<<<<<<<<<<<<<
 * 
 *     def get_best_sql_and_results(self, question: str, db_context: Dict, historical_query: Optional[Dict] = None) -> Dict:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_comparison);
  __pyx_r = __pyx_v_comparison;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":215
 *             return query
 * 
 *     def compare_queries(self, historical_query: Dict, ai_query: Dict, question: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Compare results from historical and AI-generated queries to see which best answers the question.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.compare_queries", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_comparison);
  __Pyx_XDECREF(__pyx_v_hist_score);
  __Pyx_XDECREF(__pyx_v_ai_score);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":272
 *         return comparison
 * 
 *     def get_best_sql_and_results(self, question: str, db_context: Dict, historical_query: Optional[Dict] = None) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Get the best SQL query and results for the given question.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_13get_best_sql_and_results(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_12get_best_sql_and_results, "\n        Get the best SQL query and results for the given question.\n        \n        This is the main method to call, it handles:\n        1. Generating SQL with AI\n        2. Testing both historical and AI queries\n        3. Comparing results to select the best query\n        \n        Args:\n            question: The natural language question\n            db_context: Database context information\n            historical_query: Optional historical query to prefer\n            \n        Returns:\n            Dictionary with the best query, results and comparison information\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_13get_best_sql_and_results = {"get_best_sql_and_results", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_13get_best_sql_and_results, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_12get_best_sql_and_results};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_13get_best_sql_and_results(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_question = 0;
  PyObject *__pyx_v_db_context = 0;
  PyObject *__pyx_v_historical_query = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[4] = {0,0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("get_best_sql_and_results (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_question,&__pyx_n_s_db_context,&__pyx_n_s_historical_query,0};
    values[3] = __Pyx_Arg_NewRef_FASTCALL(((PyObject*)Py_None));
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 272, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 272, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("get_best_sql_and_results", 0, 3, 4, 1); __PYX_ERR(0, 272, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_db_context)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 272, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("get_best_sql_and_results", 0, 3, 4, 2); __PYX_ERR(0, 272, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_historical_query);
          if (value) { values[3] = __Pyx_Arg_NewRef_FASTCALL(value); kw_args--; }
          else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 272, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "get_best_sql_and_results") < 0)) __PYX_ERR(0, 272, __pyx_L3_error)
      }
    } else {
      switch (__pyx_nargs) {
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_self = values[0];
    __pyx_v_question = ((PyObject*)values[1]);
    __pyx_v_db_context = ((PyObject*)values[2]);
    __pyx_v_historical_query = ((PyObject*)values[3]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("get_best_sql_and_results", 0, 3, 4, __pyx_nargs); __PYX_ERR(0, 272, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.get_best_sql_and_results", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 272, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_db_context), (&PyDict_Type), 0, "db_context", 1))) __PYX_ERR(0, 272, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_historical_query), (&PyDict_Type), 1, "historical_query", 1))) __PYX_ERR(0, 272, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_12get_best_sql_and_results(__pyx_self, __pyx_v_self, __pyx_v_question, __pyx_v_db_context, __pyx_v_historical_query);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_12get_best_sql_and_results(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context, PyObject *__pyx_v_historical_query) {
  PyObject *__pyx_v_result = NULL;
  PyObject *__pyx_v_ai_query = NULL;
  PyObject *__pyx_v_retry_info = NULL;
  PyObject *__pyx_v_comparison = NULL;
  PyObject *__pyx_v_additional_explorations = NULL;
  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;
  unsigned int __pyx_t_6;
  int __pyx_t_7;
  int __pyx_t_8;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("get_best_sql_and_results", 0);
  __Pyx_INCREF(__pyx_v_historical_query);

  /* "sQQideR/SQLBuilder.pyx":290
 *         """
 *         result = {
 *             "question": question,             # <<<<<<<<<<<<<<
 *             "timestamp": pd.Timestamp.now().isoformat(),
 *             "has_historical_match": historical_query is not None
 */
  __pyx_t_1 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 290, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_question, __pyx_v_question) < 0) __PYX_ERR(0, 290, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":291
 *         result = {
 *             "question": question,
 *             "timestamp": pd.Timestamp.now().isoformat(),             # <<<<<<<<<<<<<<
 *             "has_historical_match": historical_query is not None
 *         }
 */
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pd); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 291, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_Timestamp); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 291, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_now); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 291, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(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;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL};
    __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 0+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 291, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isoformat); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 291, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
      __pyx_t_6 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_6, 0+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 291, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_timestamp, __pyx_t_2) < 0) __PYX_ERR(0, 290, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":292
 *             "question": question,
 *             "timestamp": pd.Timestamp.now().isoformat(),
 *             "has_historical_match": historical_query is not None             # <<<<<<<<<<<<<<
 *         }
 * 
 */
  __pyx_t_7 = (__pyx_v_historical_query != ((PyObject*)Py_None));
  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 292, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_has_historical_match, __pyx_t_2) < 0) __PYX_ERR(0, 290, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_result = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":296
 * 
 *         # Generate AI query
 *         ai_query = self.generate_sql(question, db_context)             # <<<<<<<<<<<<<<
 *         result["ai_query"] = ai_query
 * 
 */
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_generate_sql); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(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;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_v_question, __pyx_v_db_context};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 2+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 296, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  }
  __pyx_v_ai_query = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":297
 *         # Generate AI query
 *         ai_query = self.generate_sql(question, db_context)
 *         result["ai_query"] = ai_query             # <<<<<<<<<<<<<<
 * 
 *         # Test AI query
 */
  if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_ai_query, __pyx_v_ai_query) < 0))) __PYX_ERR(0, 297, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":300
 * 
 *         # Test AI query
 *         if "error" not in ai_query:             # <<<<<<<<<<<<<<
 *             ai_query = self.test_query(ai_query)
 * 
 */
  __pyx_t_7 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_error, __pyx_v_ai_query, Py_NE)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 300, __pyx_L1_error)
  if (__pyx_t_7) {

    /* "sQQideR/SQLBuilder.pyx":301
 *         # Test AI query
 *         if "error" not in ai_query:
 *             ai_query = self.test_query(ai_query)             # <<<<<<<<<<<<<<
 * 
 *             # If AI query failed, try to fix it (up to 3 attempts)
 */
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_test_query); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 301, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_4 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(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;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_ai_query};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 301, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    }
    __Pyx_DECREF_SET(__pyx_v_ai_query, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":304
 * 
 *             # If AI query failed, try to fix it (up to 3 attempts)
 *             if not ai_query.get("success", False):             # <<<<<<<<<<<<<<
 *                 retry_info = self.try_fix_failed_query(ai_query, question, db_context)
 *                 ai_query = retry_info["best_attempt"] if retry_info["best_attempt"] else ai_query
 */
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_ai_query, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 304, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 304, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 304, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_8 = (!__pyx_t_7);
    if (__pyx_t_8) {

      /* "sQQideR/SQLBuilder.pyx":305
 *             # If AI query failed, try to fix it (up to 3 attempts)
 *             if not ai_query.get("success", False):
 *                 retry_info = self.try_fix_failed_query(ai_query, question, db_context)             # <<<<<<<<<<<<<<
 *                 ai_query = retry_info["best_attempt"] if retry_info["best_attempt"] else ai_query
 *                 result["ai_query_retry_info"] = retry_info
 */
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_try_fix_failed_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 305, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_4 = NULL;
      __pyx_t_6 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_1))) {
        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
        if (likely(__pyx_t_4)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
          __Pyx_INCREF(__pyx_t_4);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_1, function);
          __pyx_t_6 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[4] = {__pyx_t_4, __pyx_v_ai_query, __pyx_v_question, __pyx_v_db_context};
        __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 305, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      }
      __pyx_v_retry_info = __pyx_t_2;
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":306
 *             if not ai_query.get("success", False):
 *                 retry_info = self.try_fix_failed_query(ai_query, question, db_context)
 *                 ai_query = retry_info["best_attempt"] if retry_info["best_attempt"] else ai_query             # <<<<<<<<<<<<<<
 *                 result["ai_query_retry_info"] = retry_info
 * 
 */
      __pyx_t_1 = __Pyx_PyObject_Dict_GetItem(__pyx_v_retry_info, __pyx_n_u_best_attempt); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 306, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 306, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (__pyx_t_8) {
        __pyx_t_1 = __Pyx_PyObject_Dict_GetItem(__pyx_v_retry_info, __pyx_n_u_best_attempt); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 306, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_2 = __pyx_t_1;
        __pyx_t_1 = 0;
      } else {
        __Pyx_INCREF(__pyx_v_ai_query);
        __pyx_t_2 = __pyx_v_ai_query;
      }
      __Pyx_DECREF_SET(__pyx_v_ai_query, __pyx_t_2);
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":307
 *                 retry_info = self.try_fix_failed_query(ai_query, question, db_context)
 *                 ai_query = retry_info["best_attempt"] if retry_info["best_attempt"] else ai_query
 *                 result["ai_query_retry_info"] = retry_info             # <<<<<<<<<<<<<<
 * 
 *         # If we have a historical query, test it too
 */
      if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_ai_query_retry_info, __pyx_v_retry_info) < 0))) __PYX_ERR(0, 307, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":304
 * 
 *             # If AI query failed, try to fix it (up to 3 attempts)
 *             if not ai_query.get("success", False):             # <<<<<<<<<<<<<<
 *                 retry_info = self.try_fix_failed_query(ai_query, question, db_context)
 *                 ai_query = retry_info["best_attempt"] if retry_info["best_attempt"] else ai_query
 */
    }

    /* "sQQideR/SQLBuilder.pyx":300
 * 
 *         # Test AI query
 *         if "error" not in ai_query:             # <<<<<<<<<<<<<<
 *             ai_query = self.test_query(ai_query)
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":310
 * 
 *         # If we have a historical query, test it too
 *         if historical_query:             # <<<<<<<<<<<<<<
 *             historical_query["source"] = "historical"
 *             historical_query = self.test_query(historical_query)
 */
  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_historical_query); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 310, __pyx_L1_error)
  if (__pyx_t_8) {

    /* "sQQideR/SQLBuilder.pyx":311
 *         # If we have a historical query, test it too
 *         if historical_query:
 *             historical_query["source"] = "historical"             # <<<<<<<<<<<<<<
 *             historical_query = self.test_query(historical_query)
 *             result["historical_query"] = historical_query
 */
    if (unlikely(__pyx_v_historical_query == Py_None)) {
      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
      __PYX_ERR(0, 311, __pyx_L1_error)
    }
    if (unlikely((PyDict_SetItem(__pyx_v_historical_query, __pyx_n_u_source, __pyx_n_u_historical) < 0))) __PYX_ERR(0, 311, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":312
 *         if historical_query:
 *             historical_query["source"] = "historical"
 *             historical_query = self.test_query(historical_query)             # <<<<<<<<<<<<<<
 *             result["historical_query"] = historical_query
 * 
 */
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_test_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 312, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_4)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_4);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
        __pyx_t_6 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_v_historical_query};
      __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 312, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    }
    if (!(likely(PyDict_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None) || __Pyx_RaiseUnexpectedTypeError("dict", __pyx_t_2))) __PYX_ERR(0, 312, __pyx_L1_error)
    __Pyx_DECREF_SET(__pyx_v_historical_query, ((PyObject*)__pyx_t_2));
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":313
 *             historical_query["source"] = "historical"
 *             historical_query = self.test_query(historical_query)
 *             result["historical_query"] = historical_query             # <<<<<<<<<<<<<<
 * 
 *             # Compare queries
 */
    if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_historical_query, __pyx_v_historical_query) < 0))) __PYX_ERR(0, 313, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":316
 * 
 *             # Compare queries
 *             comparison = self.compare_queries(historical_query, ai_query, question)             # <<<<<<<<<<<<<<
 *             result["comparison"] = comparison
 * 
 */
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_compare_queries); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 316, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_4)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_4);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
        __pyx_t_6 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[4] = {__pyx_t_4, __pyx_v_historical_query, __pyx_v_ai_query, __pyx_v_question};
      __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 316, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    }
    __pyx_v_comparison = __pyx_t_2;
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":317
 *             # Compare queries
 *             comparison = self.compare_queries(historical_query, ai_query, question)
 *             result["comparison"] = comparison             # <<<<<<<<<<<<<<
 * 
 *             # Set best query based on comparison
 */
    if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_comparison, __pyx_v_comparison) < 0))) __PYX_ERR(0, 317, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":320
 * 
 *             # Set best query based on comparison
 *             if comparison["recommended_query"] == "historical":             # <<<<<<<<<<<<<<
 *                 result["best_query"] = historical_query
 *             else:
 */
    __pyx_t_2 = __Pyx_PyObject_Dict_GetItem(__pyx_v_comparison, __pyx_n_u_recommended_query); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 320, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_8 = (__Pyx_PyUnicode_Equals(__pyx_t_2, __pyx_n_u_historical, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 320, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (__pyx_t_8) {

      /* "sQQideR/SQLBuilder.pyx":321
 *             # Set best query based on comparison
 *             if comparison["recommended_query"] == "historical":
 *                 result["best_query"] = historical_query             # <<<<<<<<<<<<<<
 *             else:
 *                 result["best_query"] = ai_query
 */
      if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_best_query, __pyx_v_historical_query) < 0))) __PYX_ERR(0, 321, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":320
 * 
 *             # Set best query based on comparison
 *             if comparison["recommended_query"] == "historical":             # <<<<<<<<<<<<<<
 *                 result["best_query"] = historical_query
 *             else:
 */
      goto __pyx_L6;
    }

    /* "sQQideR/SQLBuilder.pyx":323
 *                 result["best_query"] = historical_query
 *             else:
 *                 result["best_query"] = ai_query             # <<<<<<<<<<<<<<
 *         else:
 *             # No historical query, AI query is the best we have
 */
    /*else*/ {
      if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_best_query, __pyx_v_ai_query) < 0))) __PYX_ERR(0, 323, __pyx_L1_error)
    }
    __pyx_L6:;

    /* "sQQideR/SQLBuilder.pyx":310
 * 
 *         # If we have a historical query, test it too
 *         if historical_query:             # <<<<<<<<<<<<<<
 *             historical_query["source"] = "historical"
 *             historical_query = self.test_query(historical_query)
 */
    goto __pyx_L5;
  }

  /* "sQQideR/SQLBuilder.pyx":326
 *         else:
 *             # No historical query, AI query is the best we have
 *             result["best_query"] = ai_query             # <<<<<<<<<<<<<<
 * 
 *         # Generate additional explorations based on the best query
 */
  /*else*/ {
    if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_best_query, __pyx_v_ai_query) < 0))) __PYX_ERR(0, 326, __pyx_L1_error)
  }
  __pyx_L5:;

  /* "sQQideR/SQLBuilder.pyx":329
 * 
 *         # Generate additional explorations based on the best query
 *         if result["best_query"].get("success", False):             # <<<<<<<<<<<<<<
 *             additional_explorations = self.generate_additional_explorations(
 *                 question,
 */
  __pyx_t_2 = __Pyx_PyDict_GetItem(__pyx_v_result, __pyx_n_u_best_query); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 329, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 329, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 329, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 329, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (__pyx_t_8) {

    /* "sQQideR/SQLBuilder.pyx":330
 *         # Generate additional explorations based on the best query
 *         if result["best_query"].get("success", False):
 *             additional_explorations = self.generate_additional_explorations(             # <<<<<<<<<<<<<<
 *                 question,
 *                 result["best_query"],
 */
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_generate_additional_explorations); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 330, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);

    /* "sQQideR/SQLBuilder.pyx":332
 *             additional_explorations = self.generate_additional_explorations(
 *                 question,
 *                 result["best_query"],             # <<<<<<<<<<<<<<
 *                 db_context
 *             )
 */
    __pyx_t_4 = __Pyx_PyDict_GetItem(__pyx_v_result, __pyx_n_u_best_query); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 332, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);

    /* "sQQideR/SQLBuilder.pyx":333
 *                 question,
 *                 result["best_query"],
 *                 db_context             # <<<<<<<<<<<<<<
 *             )
 *             result["additional_explorations"] = additional_explorations
 */
    __pyx_t_3 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_3)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_3);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
        __pyx_t_6 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_question, __pyx_t_4, __pyx_v_db_context};
      __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 330, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    }
    __pyx_v_additional_explorations = __pyx_t_2;
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":335
 *                 db_context
 *             )
 *             result["additional_explorations"] = additional_explorations             # <<<<<<<<<<<<<<
 * 
 *         return result
 */
    if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_additional_explorations, __pyx_v_additional_explorations) < 0))) __PYX_ERR(0, 335, __pyx_L1_error)

    /* "sQQideR/SQLBuilder.pyx":329
 * 
 *         # Generate additional explorations based on the best query
 *         if result["best_query"].get("success", False):             # <<<<<<<<<<<<<<
 *             additional_explorations = self.generate_additional_explorations(
 *                 question,
 */
  }

  /* "sQQideR/SQLBuilder.pyx":337
 *             result["additional_explorations"] = additional_explorations
 * 
 *         return result             # <<<<<<<<<<<<<<
 * 
 *     def try_fix_failed_query(self, failed_query: Dict, question: str, db_context: Dict) -> Dict:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_result);
  __pyx_r = __pyx_v_result;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":272
 *         return comparison
 * 
 *     def get_best_sql_and_results(self, question: str, db_context: Dict, historical_query: Optional[Dict] = None) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Get the best SQL query and results for the given question.
 */

  /* 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_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.get_best_sql_and_results", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_result);
  __Pyx_XDECREF(__pyx_v_ai_query);
  __Pyx_XDECREF(__pyx_v_retry_info);
  __Pyx_XDECREF(__pyx_v_comparison);
  __Pyx_XDECREF(__pyx_v_additional_explorations);
  __Pyx_XDECREF(__pyx_v_historical_query);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":339
 *         return result
 * 
 *     def try_fix_failed_query(self, failed_query: Dict, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Try to fix a failed SQL query using AI assistance and schema exploration.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_15try_fix_failed_query(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_14try_fix_failed_query, "\n        Try to fix a failed SQL query using AI assistance and schema exploration.\n        \n        Args:\n            failed_query: The failed query dictionary\n            question: The original natural language question\n            db_context: The database context information\n            \n        Returns:\n            Dictionary with retry information and best attempt\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_15try_fix_failed_query = {"try_fix_failed_query", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_15try_fix_failed_query, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_14try_fix_failed_query};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_15try_fix_failed_query(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_failed_query = 0;
  PyObject *__pyx_v_question = 0;
  PyObject *__pyx_v_db_context = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[4] = {0,0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("try_fix_failed_query (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_failed_query,&__pyx_n_s_question,&__pyx_n_s_db_context,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 339, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_failed_query)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 339, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("try_fix_failed_query", 1, 4, 4, 1); __PYX_ERR(0, 339, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 339, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("try_fix_failed_query", 1, 4, 4, 2); __PYX_ERR(0, 339, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_db_context)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[3]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 339, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("try_fix_failed_query", 1, 4, 4, 3); __PYX_ERR(0, 339, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "try_fix_failed_query") < 0)) __PYX_ERR(0, 339, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 4)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
      values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
    }
    __pyx_v_self = values[0];
    __pyx_v_failed_query = ((PyObject*)values[1]);
    __pyx_v_question = ((PyObject*)values[2]);
    __pyx_v_db_context = ((PyObject*)values[3]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("try_fix_failed_query", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 339, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.try_fix_failed_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_failed_query), (&PyDict_Type), 0, "failed_query", 1))) __PYX_ERR(0, 339, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 339, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_db_context), (&PyDict_Type), 0, "db_context", 1))) __PYX_ERR(0, 339, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_14try_fix_failed_query(__pyx_self, __pyx_v_self, __pyx_v_failed_query, __pyx_v_question, __pyx_v_db_context);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_14try_fix_failed_query(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_failed_query, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context) {
  PyObject *__pyx_v_max_attempts = NULL;
  PyObject *__pyx_v_attempts = NULL;
  PyObject *__pyx_v_best_attempt = NULL;
  PyObject *__pyx_v_original_error = NULL;
  PyObject *__pyx_v_original_sql = NULL;
  PyObject *__pyx_v_result = NULL;
  PyObject *__pyx_v_schema_info = NULL;
  PyObject *__pyx_v_attempt = NULL;
  PyObject *__pyx_v_prompt = NULL;
  PyObject *__pyx_v_response = NULL;
  PyObject *__pyx_v_fixed_sql = NULL;
  PyObject *__pyx_v_explanation = NULL;
  PyObject *__pyx_v_fixed_query = NULL;
  PyObject *__pyx_v_os = NULL;
  PyObject *__pyx_v_file_path = NULL;
  PyObject *__pyx_v_f = NULL;
  PyObject *__pyx_v_existing_logs = NULL;
  PyObject *__pyx_v_log_e = NULL;
  PyObject *__pyx_v_table_names = NULL;
  PyObject *__pyx_v_table = NULL;
  PyObject *__pyx_v_table_info = NULL;
  PyObject *__pyx_v_e = NULL;
  PyObject *__pyx_r = NULL;
  __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;
  unsigned int __pyx_t_7;
  Py_ssize_t __pyx_t_8;
  PyObject *(*__pyx_t_9)(PyObject *);
  PyObject *__pyx_t_10 = NULL;
  PyObject *__pyx_t_11 = NULL;
  PyObject *__pyx_t_12 = NULL;
  PyObject *__pyx_t_13 = NULL;
  Py_ssize_t __pyx_t_14;
  Py_UCS4 __pyx_t_15;
  int __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;
  PyObject *__pyx_t_23 = NULL;
  PyObject *__pyx_t_24 = NULL;
  PyObject *__pyx_t_25 = NULL;
  int __pyx_t_26;
  PyObject *__pyx_t_27 = NULL;
  int __pyx_t_28;
  char const *__pyx_t_29;
  PyObject *__pyx_t_30 = NULL;
  PyObject *(*__pyx_t_31)(PyObject *);
  PyObject *__pyx_t_32 = NULL;
  char const *__pyx_t_33;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("try_fix_failed_query", 1);

  /* "sQQideR/SQLBuilder.pyx":351
 *             Dictionary with retry information and best attempt
 *         """
 *         if not self.ai_base or not self.conn:             # <<<<<<<<<<<<<<
 *             return {"success": False, "message": "AI service or database connection not available", "attempts": [], "best_attempt": None}
 * 
 */
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_ai_base); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_4 = (!__pyx_t_3);
  if (!__pyx_t_4) {
  } else {
    __pyx_t_1 = __pyx_t_4;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 351, __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(0, 351, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_3 = (!__pyx_t_4);
  __pyx_t_1 = __pyx_t_3;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {

    /* "sQQideR/SQLBuilder.pyx":352
 *         """
 *         if not self.ai_base or not self.conn:
 *             return {"success": False, "message": "AI service or database connection not available", "attempts": [], "best_attempt": None}             # <<<<<<<<<<<<<<
 * 
 *         max_attempts = 3
 */
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_2 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 352, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_success, Py_False) < 0) __PYX_ERR(0, 352, __pyx_L1_error)
    if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_message, __pyx_kp_u_AI_service_or_database_connectio) < 0) __PYX_ERR(0, 352, __pyx_L1_error)
    __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 352, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_attempts, __pyx_t_5) < 0) __PYX_ERR(0, 352, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_best_attempt, Py_None) < 0) __PYX_ERR(0, 352, __pyx_L1_error)
    __pyx_r = ((PyObject*)__pyx_t_2);
    __pyx_t_2 = 0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":351
 *             Dictionary with retry information and best attempt
 *         """
 *         if not self.ai_base or not self.conn:             # <<<<<<<<<<<<<<
 *             return {"success": False, "message": "AI service or database connection not available", "attempts": [], "best_attempt": None}
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":354
 *             return {"success": False, "message": "AI service or database connection not available", "attempts": [], "best_attempt": None}
 * 
 *         max_attempts = 3             # <<<<<<<<<<<<<<
 *         attempts = []
 *         best_attempt = None
 */
  __Pyx_INCREF(__pyx_int_3);
  __pyx_v_max_attempts = __pyx_int_3;

  /* "sQQideR/SQLBuilder.pyx":355
 * 
 *         max_attempts = 3
 *         attempts = []             # <<<<<<<<<<<<<<
 *         best_attempt = None
 * 
 */
  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 355, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_v_attempts = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":356
 *         max_attempts = 3
 *         attempts = []
 *         best_attempt = None             # <<<<<<<<<<<<<<
 * 
 *         # Store the original error for reference
 */
  __Pyx_INCREF(Py_None);
  __pyx_v_best_attempt = Py_None;

  /* "sQQideR/SQLBuilder.pyx":359
 * 
 *         # Store the original error for reference
 *         original_error = failed_query.get("execution_error", "Unknown error")             # <<<<<<<<<<<<<<
 *         original_sql = failed_query.get("sql", "")
 * 
 */
  __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_failed_query, __pyx_n_u_execution_error, __pyx_kp_u_Unknown_error); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_v_original_error = __pyx_t_2;
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":360
 *         # Store the original error for reference
 *         original_error = failed_query.get("execution_error", "Unknown error")
 *         original_sql = failed_query.get("sql", "")             # <<<<<<<<<<<<<<
 * 
 *         # Create result to track all attempts
 */
  __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_failed_query, __pyx_n_u_sql, __pyx_kp_u__7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 360, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_v_original_sql = __pyx_t_2;
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":364
 *         # Create result to track all attempts
 *         result = {
 *             "success": False,             # <<<<<<<<<<<<<<
 *             "message": f"Original error: {original_error}",
 *             "attempts": attempts,
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 364, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_success, Py_False) < 0) __PYX_ERR(0, 364, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":365
 *         result = {
 *             "success": False,
 *             "message": f"Original error: {original_error}",             # <<<<<<<<<<<<<<
 *             "attempts": attempts,
 *             "best_attempt": None
 */
  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_original_error, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 365, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Original_error, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 365, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_message, __pyx_t_6) < 0) __PYX_ERR(0, 364, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

  /* "sQQideR/SQLBuilder.pyx":366
 *             "success": False,
 *             "message": f"Original error: {original_error}",
 *             "attempts": attempts,             # <<<<<<<<<<<<<<
 *             "best_attempt": None
 *         }
 */
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_attempts, __pyx_v_attempts) < 0) __PYX_ERR(0, 364, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":367
 *             "message": f"Original error: {original_error}",
 *             "attempts": attempts,
 *             "best_attempt": None             # <<<<<<<<<<<<<<
 *         }
 * 
 */
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_best_attempt, Py_None) < 0) __PYX_ERR(0, 364, __pyx_L1_error)
  __pyx_v_result = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":371
 * 
 *         # Create a list to store exploratory schema information
 *         schema_info = self._explore_database_schema()             # <<<<<<<<<<<<<<
 * 
 *         for attempt in range(max_attempts):
 */
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_explore_database_schema); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 371, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_5 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (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_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 371, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  }
  __pyx_v_schema_info = __pyx_t_2;
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":373
 *         schema_info = self._explore_database_schema()
 * 
 *         for attempt in range(max_attempts):             # <<<<<<<<<<<<<<
 *             # Build the prompt for the AI
 *             prompt = self._create_sql_correction_prompt(
 */
  __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_range, __pyx_v_max_attempts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 373, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) {
    __pyx_t_6 = __pyx_t_2; __Pyx_INCREF(__pyx_t_6);
    __pyx_t_8 = 0;
    __pyx_t_9 = NULL;
  } else {
    __pyx_t_8 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 373, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 373, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  for (;;) {
    if (likely(!__pyx_t_9)) {
      if (likely(PyList_CheckExact(__pyx_t_6))) {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 373, __pyx_L1_error)
          #endif
          if (__pyx_t_8 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_2); __pyx_t_8++; if (unlikely((0 < 0))) __PYX_ERR(0, 373, __pyx_L1_error)
        #else
        __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 373, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        #endif
      } else {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 373, __pyx_L1_error)
          #endif
          if (__pyx_t_8 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_8); __Pyx_INCREF(__pyx_t_2); __pyx_t_8++; if (unlikely((0 < 0))) __PYX_ERR(0, 373, __pyx_L1_error)
        #else
        __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 373, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        #endif
      }
    } else {
      __pyx_t_2 = __pyx_t_9(__pyx_t_6);
      if (unlikely(!__pyx_t_2)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 373, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_2);
    }
    __Pyx_XDECREF_SET(__pyx_v_attempt, __pyx_t_2);
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":375
 *         for attempt in range(max_attempts):
 *             # Build the prompt for the AI
 *             prompt = self._create_sql_correction_prompt(             # <<<<<<<<<<<<<<
 *                 question,
 *                 original_sql,
 */
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_create_sql_correction_prompt); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 375, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);

    /* "sQQideR/SQLBuilder.pyx":381
 *                 schema_info,
 *                 attempts,
 *                 db_context             # <<<<<<<<<<<<<<
 *             )
 * 
 */
    __pyx_t_10 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_10)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_10);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[7] = {__pyx_t_10, __pyx_v_question, __pyx_v_original_sql, __pyx_v_original_error, __pyx_v_schema_info, __pyx_v_attempts, __pyx_v_db_context};
      __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 6+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 375, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __Pyx_XDECREF_SET(__pyx_v_prompt, __pyx_t_2);
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":384
 *             )
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 # Get improved SQL from AI
 *                 if self.verbose:
 */
    {
      __Pyx_PyThreadState_declare
      __Pyx_PyThreadState_assign
      __Pyx_ExceptionSave(&__pyx_t_11, &__pyx_t_12, &__pyx_t_13);
      __Pyx_XGOTREF(__pyx_t_11);
      __Pyx_XGOTREF(__pyx_t_12);
      __Pyx_XGOTREF(__pyx_t_13);
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":386
 *             try:
 *                 # Get improved SQL from AI
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Retry attempt #{attempt+1} - Asking AI to fix SQL")
 * 
 */
        __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 386, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 386, __pyx_L8_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        if (__pyx_t_1) {

          /* "sQQideR/SQLBuilder.pyx":387
 *                 # Get improved SQL from AI
 *                 if self.verbose:
 *                     print(f"Retry attempt #{attempt+1} - Asking AI to fix SQL")             # <<<<<<<<<<<<<<
 * 
 *                 # Create a fresh AI session for each attempt
 */
          __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 387, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __pyx_t_14 = 0;
          __pyx_t_15 = 127;
          __Pyx_INCREF(__pyx_kp_u_Retry_attempt);
          __pyx_t_14 += 15;
          __Pyx_GIVEREF(__pyx_kp_u_Retry_attempt);
          PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_Retry_attempt);
          __pyx_t_5 = __Pyx_PyInt_AddObjC(__pyx_v_attempt, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 387, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 387, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          __pyx_t_15 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) > __pyx_t_15) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_10) : __pyx_t_15;
          __pyx_t_14 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_10);
          __Pyx_GIVEREF(__pyx_t_10);
          PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_10);
          __pyx_t_10 = 0;
          __Pyx_INCREF(__pyx_kp_u_Asking_AI_to_fix_SQL);
          __pyx_t_14 += 23;
          __Pyx_GIVEREF(__pyx_kp_u_Asking_AI_to_fix_SQL);
          PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u_Asking_AI_to_fix_SQL);
          __pyx_t_10 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_14, __pyx_t_15); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 387, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
          __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_10); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 387, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

          /* "sQQideR/SQLBuilder.pyx":386
 *             try:
 *                 # Get improved SQL from AI
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Retry attempt #{attempt+1} - Asking AI to fix SQL")
 * 
 */
        }

        /* "sQQideR/SQLBuilder.pyx":390
 * 
 *                 # Create a fresh AI session for each attempt
 *                 self.ai_base.clear_history()             # <<<<<<<<<<<<<<
 *                 response = self.ai_base.get_response_sync(prompt)
 * 
 */
        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_ai_base); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 390, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_clear_history); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 390, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        __pyx_t_10 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_5))) {
          __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_5);
          if (likely(__pyx_t_10)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
            __Pyx_INCREF(__pyx_t_10);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_5, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_10, NULL};
          __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
          if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 390, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        }
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":391
 *                 # Create a fresh AI session for each attempt
 *                 self.ai_base.clear_history()
 *                 response = self.ai_base.get_response_sync(prompt)             # <<<<<<<<<<<<<<
 * 
 *                 # Extract SQL from response
 */
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_ai_base); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 391, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_get_response_sync); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 391, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __pyx_t_5 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_10))) {
          __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
          if (likely(__pyx_t_5)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
            __Pyx_INCREF(__pyx_t_5);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_10, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_prompt};
          __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 391, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        }
        __Pyx_XDECREF_SET(__pyx_v_response, __pyx_t_2);
        __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":394
 * 
 *                 # Extract SQL from response
 *                 fixed_sql = self._extract_sql_from_response(response)             # <<<<<<<<<<<<<<
 *                 explanation = self._extract_explanation(response)
 * 
 */
        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_extract_sql_from_response); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 394, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_5 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_10))) {
          __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
          if (likely(__pyx_t_5)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
            __Pyx_INCREF(__pyx_t_5);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_10, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_response};
          __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 394, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        }
        __Pyx_XDECREF_SET(__pyx_v_fixed_sql, __pyx_t_2);
        __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":395
 *                 # Extract SQL from response
 *                 fixed_sql = self._extract_sql_from_response(response)
 *                 explanation = self._extract_explanation(response)             # <<<<<<<<<<<<<<
 * 
 *                 if self.verbose:
 */
        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_extract_explanation); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 395, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_5 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_10))) {
          __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
          if (likely(__pyx_t_5)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
            __Pyx_INCREF(__pyx_t_5);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_10, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_response};
          __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 395, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        }
        __Pyx_XDECREF_SET(__pyx_v_explanation, __pyx_t_2);
        __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":397
 *                 explanation = self._extract_explanation(response)
 * 
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Generated fixed SQL: {fixed_sql}")
 * 
 */
        __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 397, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 397, __pyx_L8_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        if (__pyx_t_1) {

          /* "sQQideR/SQLBuilder.pyx":398
 * 
 *                 if self.verbose:
 *                     print(f"Generated fixed SQL: {fixed_sql}")             # <<<<<<<<<<<<<<
 * 
 *                 # Create a query dictionary
 */
          __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_fixed_sql, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 398, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Generated_fixed_SQL, __pyx_t_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 398, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
          __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_10); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 398, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

          /* "sQQideR/SQLBuilder.pyx":397
 *                 explanation = self._extract_explanation(response)
 * 
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Generated fixed SQL: {fixed_sql}")
 * 
 */
        }

        /* "sQQideR/SQLBuilder.pyx":402
 *                 # Create a query dictionary
 *                 fixed_query = {
 *                     "question": question,             # <<<<<<<<<<<<<<
 *                     "sql": fixed_sql,
 *                     "raw_ai_response": response,
 */
        __pyx_t_2 = __Pyx_PyDict_NewPresized(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 402, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_2);
        if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_question, __pyx_v_question) < 0) __PYX_ERR(0, 402, __pyx_L8_error)

        /* "sQQideR/SQLBuilder.pyx":403
 *                 fixed_query = {
 *                     "question": question,
 *                     "sql": fixed_sql,             # <<<<<<<<<<<<<<
 *                     "raw_ai_response": response,
 *                     "explanation": explanation,
 */
        if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_sql, __pyx_v_fixed_sql) < 0) __PYX_ERR(0, 402, __pyx_L8_error)

        /* "sQQideR/SQLBuilder.pyx":404
 *                     "question": question,
 *                     "sql": fixed_sql,
 *                     "raw_ai_response": response,             # <<<<<<<<<<<<<<
 *                     "explanation": explanation,
 *                     "source": f"ai_retry_attempt_{attempt+1}",
 */
        if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_raw_ai_response, __pyx_v_response) < 0) __PYX_ERR(0, 402, __pyx_L8_error)

        /* "sQQideR/SQLBuilder.pyx":405
 *                     "sql": fixed_sql,
 *                     "raw_ai_response": response,
 *                     "explanation": explanation,             # <<<<<<<<<<<<<<
 *                     "source": f"ai_retry_attempt_{attempt+1}",
 *                     "retry_attempt": attempt + 1
 */
        if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_explanation, __pyx_v_explanation) < 0) __PYX_ERR(0, 402, __pyx_L8_error)

        /* "sQQideR/SQLBuilder.pyx":406
 *                     "raw_ai_response": response,
 *                     "explanation": explanation,
 *                     "source": f"ai_retry_attempt_{attempt+1}",             # <<<<<<<<<<<<<<
 *                     "retry_attempt": attempt + 1
 *                 }
 */
        __pyx_t_10 = __Pyx_PyInt_AddObjC(__pyx_v_attempt, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 406, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_10, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 406, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_n_u_ai_retry_attempt, __pyx_t_5); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 406, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_source, __pyx_t_10) < 0) __PYX_ERR(0, 402, __pyx_L8_error)
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

        /* "sQQideR/SQLBuilder.pyx":407
 *                     "explanation": explanation,
 *                     "source": f"ai_retry_attempt_{attempt+1}",
 *                     "retry_attempt": attempt + 1             # <<<<<<<<<<<<<<
 *                 }
 * 
 */
        __pyx_t_10 = __Pyx_PyInt_AddObjC(__pyx_v_attempt, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 407, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_retry_attempt, __pyx_t_10) < 0) __PYX_ERR(0, 402, __pyx_L8_error)
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        __Pyx_XDECREF_SET(__pyx_v_fixed_query, __pyx_t_2);
        __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":411
 * 
 *                 # Test the fixed query
 *                 fixed_query = self.test_query(fixed_query)             # <<<<<<<<<<<<<<
 * 
 *                 # Store this attempt
 */
        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_test_query); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 411, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_5 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_10))) {
          __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
          if (likely(__pyx_t_5)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
            __Pyx_INCREF(__pyx_t_5);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_10, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_fixed_query};
          __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 411, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        }
        __Pyx_DECREF_SET(__pyx_v_fixed_query, __pyx_t_2);
        __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":414
 * 
 *                 # Store this attempt
 *                 attempts.append(fixed_query)             # <<<<<<<<<<<<<<
 * 
 *                 # If this attempt succeeded, we can stop
 */
        __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_attempts, __pyx_v_fixed_query); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 414, __pyx_L8_error)

        /* "sQQideR/SQLBuilder.pyx":417
 * 
 *                 # If this attempt succeeded, we can stop
 *                 if fixed_query.get("success", False):             # <<<<<<<<<<<<<<
 *                     if self.verbose:
 *                         print(f"Retry attempt #{attempt+1} succeeded!")
 */
        __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_fixed_query, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 417, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 417, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_10);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 417, __pyx_L8_error)
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        if (__pyx_t_1) {

          /* "sQQideR/SQLBuilder.pyx":418
 *                 # If this attempt succeeded, we can stop
 *                 if fixed_query.get("success", False):
 *                     if self.verbose:             # <<<<<<<<<<<<<<
 *                         print(f"Retry attempt #{attempt+1} succeeded!")
 *                     best_attempt = fixed_query
 */
          __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 418, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_10);
          __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 418, __pyx_L8_error)
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          if (__pyx_t_1) {

            /* "sQQideR/SQLBuilder.pyx":419
 *                 if fixed_query.get("success", False):
 *                     if self.verbose:
 *                         print(f"Retry attempt #{attempt+1} succeeded!")             # <<<<<<<<<<<<<<
 *                     best_attempt = fixed_query
 *                     result["success"] = True
 */
            __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 419, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_10);
            __pyx_t_14 = 0;
            __pyx_t_15 = 127;
            __Pyx_INCREF(__pyx_kp_u_Retry_attempt);
            __pyx_t_14 += 15;
            __Pyx_GIVEREF(__pyx_kp_u_Retry_attempt);
            PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_kp_u_Retry_attempt);
            __pyx_t_2 = __Pyx_PyInt_AddObjC(__pyx_v_attempt, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 419, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 419, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            __pyx_t_15 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_15) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_15;
            __pyx_t_14 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
            __Pyx_GIVEREF(__pyx_t_5);
            PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_5);
            __pyx_t_5 = 0;
            __Pyx_INCREF(__pyx_kp_u_succeeded);
            __pyx_t_14 += 11;
            __Pyx_GIVEREF(__pyx_kp_u_succeeded);
            PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_kp_u_succeeded);
            __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_10, 3, __pyx_t_14, __pyx_t_15); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 419, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
            __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_5); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 419, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_10);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

            /* "sQQideR/SQLBuilder.pyx":418
 *                 # If this attempt succeeded, we can stop
 *                 if fixed_query.get("success", False):
 *                     if self.verbose:             # <<<<<<<<<<<<<<
 *                         print(f"Retry attempt #{attempt+1} succeeded!")
 *                     best_attempt = fixed_query
 */
          }

          /* "sQQideR/SQLBuilder.pyx":420
 *                     if self.verbose:
 *                         print(f"Retry attempt #{attempt+1} succeeded!")
 *                     best_attempt = fixed_query             # <<<<<<<<<<<<<<
 *                     result["success"] = True
 *                     result["message"] = f"SQL fixed on attempt #{attempt+1}"
 */
          __Pyx_INCREF(__pyx_v_fixed_query);
          __Pyx_DECREF_SET(__pyx_v_best_attempt, __pyx_v_fixed_query);

          /* "sQQideR/SQLBuilder.pyx":421
 *                         print(f"Retry attempt #{attempt+1} succeeded!")
 *                     best_attempt = fixed_query
 *                     result["success"] = True             # <<<<<<<<<<<<<<
 *                     result["message"] = f"SQL fixed on attempt #{attempt+1}"
 * 
 */
          if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_success, Py_True) < 0))) __PYX_ERR(0, 421, __pyx_L8_error)

          /* "sQQideR/SQLBuilder.pyx":422
 *                     best_attempt = fixed_query
 *                     result["success"] = True
 *                     result["message"] = f"SQL fixed on attempt #{attempt+1}"             # <<<<<<<<<<<<<<
 * 
 *                     # Log the failed SQL and the working fix
 */
          __pyx_t_10 = __Pyx_PyInt_AddObjC(__pyx_v_attempt, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 422, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_10);
          __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_10, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 422, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_5);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_kp_u_SQL_fixed_on_attempt, __pyx_t_5); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 422, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_10);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_message, __pyx_t_10) < 0))) __PYX_ERR(0, 422, __pyx_L8_error)
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

          /* "sQQideR/SQLBuilder.pyx":425
 * 
 *                     # Log the failed SQL and the working fix
 *                     try:             # <<<<<<<<<<<<<<
 *                         import os
 *                         os.makedirs("data", exist_ok=True)
 */
          {
            __Pyx_PyThreadState_declare
            __Pyx_PyThreadState_assign
            __Pyx_ExceptionSave(&__pyx_t_17, &__pyx_t_18, &__pyx_t_19);
            __Pyx_XGOTREF(__pyx_t_17);
            __Pyx_XGOTREF(__pyx_t_18);
            __Pyx_XGOTREF(__pyx_t_19);
            /*try:*/ {

              /* "sQQideR/SQLBuilder.pyx":426
 *                     # Log the failed SQL and the working fix
 *                     try:
 *                         import os             # <<<<<<<<<<<<<<
 *                         os.makedirs("data", exist_ok=True)
 *                         file_path = os.path.join("data", "failed_sql.json")
 */
              __pyx_t_10 = __Pyx_ImportDottedModule(__pyx_n_s_os, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 426, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_10);
              __Pyx_XDECREF_SET(__pyx_v_os, __pyx_t_10);
              __pyx_t_10 = 0;

              /* "sQQideR/SQLBuilder.pyx":427
 *                     try:
 *                         import os
 *                         os.makedirs("data", exist_ok=True)             # <<<<<<<<<<<<<<
 *                         file_path = os.path.join("data", "failed_sql.json")
 * 
 */
              __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_os, __pyx_n_s_makedirs); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 427, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_10);
              __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 427, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_5);
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_exist_ok, Py_True) < 0) __PYX_ERR(0, 427, __pyx_L20_error)
              __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__10, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 427, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

              /* "sQQideR/SQLBuilder.pyx":428
 *                         import os
 *                         os.makedirs("data", exist_ok=True)
 *                         file_path = os.path.join("data", "failed_sql.json")             # <<<<<<<<<<<<<<
 * 
 *                         if os.path.exists(file_path):
 */
              __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_os, __pyx_n_s_path); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 428, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_2);
              __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_join); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 428, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_5);
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 428, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __Pyx_XDECREF_SET(__pyx_v_file_path, __pyx_t_2);
              __pyx_t_2 = 0;

              /* "sQQideR/SQLBuilder.pyx":430
 *                         file_path = os.path.join("data", "failed_sql.json")
 * 
 *                         if os.path.exists(file_path):             # <<<<<<<<<<<<<<
 *                             with open(file_path, "r", encoding="utf-8") as f:
 *                                 existing_logs = json.load(f)
 */
              __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_os, __pyx_n_s_path); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 430, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_5);
              __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_exists); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 430, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_10);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
              __pyx_t_5 = NULL;
              __pyx_t_7 = 0;
              #if CYTHON_UNPACK_METHODS
              if (likely(PyMethod_Check(__pyx_t_10))) {
                __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
                if (likely(__pyx_t_5)) {
                  PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
                  __Pyx_INCREF(__pyx_t_5);
                  __Pyx_INCREF(function);
                  __Pyx_DECREF_SET(__pyx_t_10, function);
                  __pyx_t_7 = 1;
                }
              }
              #endif
              {
                PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_file_path};
                __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
                __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 430, __pyx_L20_error)
                __Pyx_GOTREF(__pyx_t_2);
                __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
              }
              __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 430, __pyx_L20_error)
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
              if (__pyx_t_1) {

                /* "sQQideR/SQLBuilder.pyx":431
 * 
 *                         if os.path.exists(file_path):
 *                             with open(file_path, "r", encoding="utf-8") as f:             # <<<<<<<<<<<<<<
 *                                 existing_logs = json.load(f)
 *                         else:
 */
                /*with:*/ {
                  __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 431, __pyx_L20_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __Pyx_INCREF(__pyx_v_file_path);
                  __Pyx_GIVEREF(__pyx_v_file_path);
                  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_file_path)) __PYX_ERR(0, 431, __pyx_L20_error);
                  __Pyx_INCREF(__pyx_n_u_r);
                  __Pyx_GIVEREF(__pyx_n_u_r);
                  if (__Pyx_PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_n_u_r)) __PYX_ERR(0, 431, __pyx_L20_error);
                  __pyx_t_10 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 431, __pyx_L20_error)
                  __Pyx_GOTREF(__pyx_t_10);
                  if (PyDict_SetItem(__pyx_t_10, __pyx_n_s_encoding, __pyx_kp_u_utf_8) < 0) __PYX_ERR(0, 431, __pyx_L20_error)
                  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_2, __pyx_t_10); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 431, __pyx_L20_error)
                  __Pyx_GOTREF(__pyx_t_5);
                  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                  __pyx_t_20 = __Pyx_PyObject_LookupSpecial(__pyx_t_5, __pyx_n_s_exit); if (unlikely(!__pyx_t_20)) __PYX_ERR(0, 431, __pyx_L20_error)
                  __Pyx_GOTREF(__pyx_t_20);
                  __pyx_t_2 = __Pyx_PyObject_LookupSpecial(__pyx_t_5, __pyx_n_s_enter); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 431, __pyx_L29_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __pyx_t_21 = NULL;
                  __pyx_t_7 = 0;
                  #if CYTHON_UNPACK_METHODS
                  if (likely(PyMethod_Check(__pyx_t_2))) {
                    __pyx_t_21 = PyMethod_GET_SELF(__pyx_t_2);
                    if (likely(__pyx_t_21)) {
                      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
                      __Pyx_INCREF(__pyx_t_21);
                      __Pyx_INCREF(function);
                      __Pyx_DECREF_SET(__pyx_t_2, function);
                      __pyx_t_7 = 1;
                    }
                  }
                  #endif
                  {
                    PyObject *__pyx_callargs[2] = {__pyx_t_21, NULL};
                    __pyx_t_10 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
                    __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
                    if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 431, __pyx_L29_error)
                    __Pyx_GOTREF(__pyx_t_10);
                    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                  }
                  __pyx_t_2 = __pyx_t_10;
                  __pyx_t_10 = 0;
                  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                  /*try:*/ {
                    {
                      __Pyx_PyThreadState_declare
                      __Pyx_PyThreadState_assign
                      __Pyx_ExceptionSave(&__pyx_t_22, &__pyx_t_23, &__pyx_t_24);
                      __Pyx_XGOTREF(__pyx_t_22);
                      __Pyx_XGOTREF(__pyx_t_23);
                      __Pyx_XGOTREF(__pyx_t_24);
                      /*try:*/ {
                        __Pyx_XDECREF_SET(__pyx_v_f, __pyx_t_2);
                        __pyx_t_2 = 0;

                        /* "sQQideR/SQLBuilder.pyx":432
 *                         if os.path.exists(file_path):
 *                             with open(file_path, "r", encoding="utf-8") as f:
 *                                 existing_logs = json.load(f)             # <<<<<<<<<<<<<<
 *                         else:
 *                             existing_logs = []
 */
                        __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_json); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 432, __pyx_L35_error)
                        __Pyx_GOTREF(__pyx_t_5);
                        __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_load); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 432, __pyx_L35_error)
                        __Pyx_GOTREF(__pyx_t_10);
                        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                        __pyx_t_5 = NULL;
                        __pyx_t_7 = 0;
                        #if CYTHON_UNPACK_METHODS
                        if (unlikely(PyMethod_Check(__pyx_t_10))) {
                          __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
                          if (likely(__pyx_t_5)) {
                            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
                            __Pyx_INCREF(__pyx_t_5);
                            __Pyx_INCREF(function);
                            __Pyx_DECREF_SET(__pyx_t_10, function);
                            __pyx_t_7 = 1;
                          }
                        }
                        #endif
                        {
                          PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_f};
                          __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
                          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                          if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 432, __pyx_L35_error)
                          __Pyx_GOTREF(__pyx_t_2);
                          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                        }
                        __Pyx_XDECREF_SET(__pyx_v_existing_logs, __pyx_t_2);
                        __pyx_t_2 = 0;

                        /* "sQQideR/SQLBuilder.pyx":431
 * 
 *                         if os.path.exists(file_path):
 *                             with open(file_path, "r", encoding="utf-8") as f:             # <<<<<<<<<<<<<<
 *                                 existing_logs = json.load(f)
 *                         else:
 */
                      }
                      __Pyx_XDECREF(__pyx_t_22); __pyx_t_22 = 0;
                      __Pyx_XDECREF(__pyx_t_23); __pyx_t_23 = 0;
                      __Pyx_XDECREF(__pyx_t_24); __pyx_t_24 = 0;
                      goto __pyx_L42_try_end;
                      __pyx_L35_error:;
                      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
                      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
                      __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
                      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                      /*except:*/ {
                        __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.try_fix_failed_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
                        if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_10, &__pyx_t_5) < 0) __PYX_ERR(0, 431, __pyx_L37_except_error)
                        __Pyx_XGOTREF(__pyx_t_2);
                        __Pyx_XGOTREF(__pyx_t_10);
                        __Pyx_XGOTREF(__pyx_t_5);
                        __pyx_t_21 = PyTuple_Pack(3, __pyx_t_2, __pyx_t_10, __pyx_t_5); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 431, __pyx_L37_except_error)
                        __Pyx_GOTREF(__pyx_t_21);
                        __pyx_t_25 = __Pyx_PyObject_Call(__pyx_t_20, __pyx_t_21, NULL);
                        __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
                        __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
                        if (unlikely(!__pyx_t_25)) __PYX_ERR(0, 431, __pyx_L37_except_error)
                        __Pyx_GOTREF(__pyx_t_25);
                        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_25);
                        __Pyx_DECREF(__pyx_t_25); __pyx_t_25 = 0;
                        if (__pyx_t_1 < 0) __PYX_ERR(0, 431, __pyx_L37_except_error)
                        __pyx_t_3 = (!__pyx_t_1);
                        if (unlikely(__pyx_t_3)) {
                          __Pyx_GIVEREF(__pyx_t_2);
                          __Pyx_GIVEREF(__pyx_t_10);
                          __Pyx_XGIVEREF(__pyx_t_5);
                          __Pyx_ErrRestoreWithState(__pyx_t_2, __pyx_t_10, __pyx_t_5);
                          __pyx_t_2 = 0; __pyx_t_10 = 0; __pyx_t_5 = 0; 
                          __PYX_ERR(0, 431, __pyx_L37_except_error)
                        }
                        __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
                        __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
                        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                        goto __pyx_L36_exception_handled;
                      }
                      __pyx_L37_except_error:;
                      __Pyx_XGIVEREF(__pyx_t_22);
                      __Pyx_XGIVEREF(__pyx_t_23);
                      __Pyx_XGIVEREF(__pyx_t_24);
                      __Pyx_ExceptionReset(__pyx_t_22, __pyx_t_23, __pyx_t_24);
                      goto __pyx_L20_error;
                      __pyx_L36_exception_handled:;
                      __Pyx_XGIVEREF(__pyx_t_22);
                      __Pyx_XGIVEREF(__pyx_t_23);
                      __Pyx_XGIVEREF(__pyx_t_24);
                      __Pyx_ExceptionReset(__pyx_t_22, __pyx_t_23, __pyx_t_24);
                      __pyx_L42_try_end:;
                    }
                  }
                  /*finally:*/ {
                    /*normal exit:*/{
                      if (__pyx_t_20) {
                        __pyx_t_24 = __Pyx_PyObject_Call(__pyx_t_20, __pyx_tuple__3, NULL);
                        __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
                        if (unlikely(!__pyx_t_24)) __PYX_ERR(0, 431, __pyx_L20_error)
                        __Pyx_GOTREF(__pyx_t_24);
                        __Pyx_DECREF(__pyx_t_24); __pyx_t_24 = 0;
                      }
                      goto __pyx_L34;
                    }
                    __pyx_L34:;
                  }
                  goto __pyx_L46;
                  __pyx_L29_error:;
                  __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
                  goto __pyx_L20_error;
                  __pyx_L46:;
                }

                /* "sQQideR/SQLBuilder.pyx":430
 *                         file_path = os.path.join("data", "failed_sql.json")
 * 
 *                         if os.path.exists(file_path):             # <<<<<<<<<<<<<<
 *                             with open(file_path, "r", encoding="utf-8") as f:
 *                                 existing_logs = json.load(f)
 */
                goto __pyx_L28;
              }

              /* "sQQideR/SQLBuilder.pyx":434
 *                                 existing_logs = json.load(f)
 *                         else:
 *                             existing_logs = []             # <<<<<<<<<<<<<<
 * 
 *                         existing_logs.append({
 */
              /*else*/ {
                __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 434, __pyx_L20_error)
                __Pyx_GOTREF(__pyx_t_5);
                __Pyx_XDECREF_SET(__pyx_v_existing_logs, __pyx_t_5);
                __pyx_t_5 = 0;
              }
              __pyx_L28:;

              /* "sQQideR/SQLBuilder.pyx":436
 *                             existing_logs = []
 * 
 *                         existing_logs.append({             # <<<<<<<<<<<<<<
 *                             "question": question,
 *                             "failed_sql": original_sql,
 */
              if (unlikely(!__pyx_v_existing_logs)) { __Pyx_RaiseUnboundLocalError("existing_logs"); __PYX_ERR(0, 436, __pyx_L20_error) }

              /* "sQQideR/SQLBuilder.pyx":437
 * 
 *                         existing_logs.append({
 *                             "question": question,             # <<<<<<<<<<<<<<
 *                             "failed_sql": original_sql,
 *                             "error": original_error,
 */
              __pyx_t_5 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 437, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_5);
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_question, __pyx_v_question) < 0) __PYX_ERR(0, 437, __pyx_L20_error)

              /* "sQQideR/SQLBuilder.pyx":438
 *                         existing_logs.append({
 *                             "question": question,
 *                             "failed_sql": original_sql,             # <<<<<<<<<<<<<<
 *                             "error": original_error,
 *                             "working_sql": best_attempt.get("sql", "")
 */
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_failed_sql, __pyx_v_original_sql) < 0) __PYX_ERR(0, 437, __pyx_L20_error)

              /* "sQQideR/SQLBuilder.pyx":439
 *                             "question": question,
 *                             "failed_sql": original_sql,
 *                             "error": original_error,             # <<<<<<<<<<<<<<
 *                             "working_sql": best_attempt.get("sql", "")
 *                         })
 */
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_error, __pyx_v_original_error) < 0) __PYX_ERR(0, 437, __pyx_L20_error)

              /* "sQQideR/SQLBuilder.pyx":440
 *                             "failed_sql": original_sql,
 *                             "error": original_error,
 *                             "working_sql": best_attempt.get("sql", "")             # <<<<<<<<<<<<<<
 *                         })
 * 
 */
              __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_best_attempt, __pyx_n_s_get); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 440, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_10);
              __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 440, __pyx_L20_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
              if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_working_sql, __pyx_t_2) < 0) __PYX_ERR(0, 437, __pyx_L20_error)
              __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

              /* "sQQideR/SQLBuilder.pyx":436
 *                             existing_logs = []
 * 
 *                         existing_logs.append({             # <<<<<<<<<<<<<<
 *                             "question": question,
 *                             "failed_sql": original_sql,
 */
              __pyx_t_16 = __Pyx_PyObject_Append(__pyx_v_existing_logs, __pyx_t_5); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 436, __pyx_L20_error)
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

              /* "sQQideR/SQLBuilder.pyx":443
 *                         })
 * 
 *                         with open(file_path, "w", encoding="utf-8") as f:             # <<<<<<<<<<<<<<
 *                             json.dump(existing_logs, f, indent=2)
 * 
 */
              /*with:*/ {
                __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 443, __pyx_L20_error)
                __Pyx_GOTREF(__pyx_t_5);
                __Pyx_INCREF(__pyx_v_file_path);
                __Pyx_GIVEREF(__pyx_v_file_path);
                if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_file_path)) __PYX_ERR(0, 443, __pyx_L20_error);
                __Pyx_INCREF(__pyx_n_u_w);
                __Pyx_GIVEREF(__pyx_n_u_w);
                if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_n_u_w)) __PYX_ERR(0, 443, __pyx_L20_error);
                __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 443, __pyx_L20_error)
                __Pyx_GOTREF(__pyx_t_2);
                if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_encoding, __pyx_kp_u_utf_8) < 0) __PYX_ERR(0, 443, __pyx_L20_error)
                __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 443, __pyx_L20_error)
                __Pyx_GOTREF(__pyx_t_10);
                __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                __pyx_t_20 = __Pyx_PyObject_LookupSpecial(__pyx_t_10, __pyx_n_s_exit); if (unlikely(!__pyx_t_20)) __PYX_ERR(0, 443, __pyx_L20_error)
                __Pyx_GOTREF(__pyx_t_20);
                __pyx_t_5 = __Pyx_PyObject_LookupSpecial(__pyx_t_10, __pyx_n_s_enter); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 443, __pyx_L47_error)
                __Pyx_GOTREF(__pyx_t_5);
                __pyx_t_21 = NULL;
                __pyx_t_7 = 0;
                #if CYTHON_UNPACK_METHODS
                if (likely(PyMethod_Check(__pyx_t_5))) {
                  __pyx_t_21 = PyMethod_GET_SELF(__pyx_t_5);
                  if (likely(__pyx_t_21)) {
                    PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                    __Pyx_INCREF(__pyx_t_21);
                    __Pyx_INCREF(function);
                    __Pyx_DECREF_SET(__pyx_t_5, function);
                    __pyx_t_7 = 1;
                  }
                }
                #endif
                {
                  PyObject *__pyx_callargs[2] = {__pyx_t_21, NULL};
                  __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
                  __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
                  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 443, __pyx_L47_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                }
                __pyx_t_5 = __pyx_t_2;
                __pyx_t_2 = 0;
                __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                /*try:*/ {
                  {
                    __Pyx_PyThreadState_declare
                    __Pyx_PyThreadState_assign
                    __Pyx_ExceptionSave(&__pyx_t_24, &__pyx_t_23, &__pyx_t_22);
                    __Pyx_XGOTREF(__pyx_t_24);
                    __Pyx_XGOTREF(__pyx_t_23);
                    __Pyx_XGOTREF(__pyx_t_22);
                    /*try:*/ {
                      __Pyx_XDECREF_SET(__pyx_v_f, __pyx_t_5);
                      __pyx_t_5 = 0;

                      /* "sQQideR/SQLBuilder.pyx":444
 * 
 *                         with open(file_path, "w", encoding="utf-8") as f:
 *                             json.dump(existing_logs, f, indent=2)             # <<<<<<<<<<<<<<
 * 
 *                     except Exception as log_e:
 */
                      __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_json); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 444, __pyx_L53_error)
                      __Pyx_GOTREF(__pyx_t_5);
                      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_dump); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 444, __pyx_L53_error)
                      __Pyx_GOTREF(__pyx_t_10);
                      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                      if (unlikely(!__pyx_v_existing_logs)) { __Pyx_RaiseUnboundLocalError("existing_logs"); __PYX_ERR(0, 444, __pyx_L53_error) }
                      __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 444, __pyx_L53_error)
                      __Pyx_GOTREF(__pyx_t_5);
                      __Pyx_INCREF(__pyx_v_existing_logs);
                      __Pyx_GIVEREF(__pyx_v_existing_logs);
                      if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_existing_logs)) __PYX_ERR(0, 444, __pyx_L53_error);
                      __Pyx_INCREF(__pyx_v_f);
                      __Pyx_GIVEREF(__pyx_v_f);
                      if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_v_f)) __PYX_ERR(0, 444, __pyx_L53_error);
                      __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 444, __pyx_L53_error)
                      __Pyx_GOTREF(__pyx_t_2);
                      if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_indent, __pyx_int_2) < 0) __PYX_ERR(0, 444, __pyx_L53_error)
                      __pyx_t_21 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 444, __pyx_L53_error)
                      __Pyx_GOTREF(__pyx_t_21);
                      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                      __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;

                      /* "sQQideR/SQLBuilder.pyx":443
 *                         })
 * 
 *                         with open(file_path, "w", encoding="utf-8") as f:             # <<<<<<<<<<<<<<
 *                             json.dump(existing_logs, f, indent=2)
 * 
 */
                    }
                    __Pyx_XDECREF(__pyx_t_24); __pyx_t_24 = 0;
                    __Pyx_XDECREF(__pyx_t_23); __pyx_t_23 = 0;
                    __Pyx_XDECREF(__pyx_t_22); __pyx_t_22 = 0;
                    goto __pyx_L60_try_end;
                    __pyx_L53_error:;
                    __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
                    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
                    __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
                    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                    /*except:*/ {
                      __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.try_fix_failed_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
                      if (__Pyx_GetException(&__pyx_t_21, &__pyx_t_2, &__pyx_t_5) < 0) __PYX_ERR(0, 443, __pyx_L55_except_error)
                      __Pyx_XGOTREF(__pyx_t_21);
                      __Pyx_XGOTREF(__pyx_t_2);
                      __Pyx_XGOTREF(__pyx_t_5);
                      __pyx_t_10 = PyTuple_Pack(3, __pyx_t_21, __pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 443, __pyx_L55_except_error)
                      __Pyx_GOTREF(__pyx_t_10);
                      __pyx_t_25 = __Pyx_PyObject_Call(__pyx_t_20, __pyx_t_10, NULL);
                      __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
                      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                      if (unlikely(!__pyx_t_25)) __PYX_ERR(0, 443, __pyx_L55_except_error)
                      __Pyx_GOTREF(__pyx_t_25);
                      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_25);
                      __Pyx_DECREF(__pyx_t_25); __pyx_t_25 = 0;
                      if (__pyx_t_3 < 0) __PYX_ERR(0, 443, __pyx_L55_except_error)
                      __pyx_t_1 = (!__pyx_t_3);
                      if (unlikely(__pyx_t_1)) {
                        __Pyx_GIVEREF(__pyx_t_21);
                        __Pyx_GIVEREF(__pyx_t_2);
                        __Pyx_XGIVEREF(__pyx_t_5);
                        __Pyx_ErrRestoreWithState(__pyx_t_21, __pyx_t_2, __pyx_t_5);
                        __pyx_t_21 = 0; __pyx_t_2 = 0; __pyx_t_5 = 0; 
                        __PYX_ERR(0, 443, __pyx_L55_except_error)
                      }
                      __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
                      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
                      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                      goto __pyx_L54_exception_handled;
                    }
                    __pyx_L55_except_error:;
                    __Pyx_XGIVEREF(__pyx_t_24);
                    __Pyx_XGIVEREF(__pyx_t_23);
                    __Pyx_XGIVEREF(__pyx_t_22);
                    __Pyx_ExceptionReset(__pyx_t_24, __pyx_t_23, __pyx_t_22);
                    goto __pyx_L20_error;
                    __pyx_L54_exception_handled:;
                    __Pyx_XGIVEREF(__pyx_t_24);
                    __Pyx_XGIVEREF(__pyx_t_23);
                    __Pyx_XGIVEREF(__pyx_t_22);
                    __Pyx_ExceptionReset(__pyx_t_24, __pyx_t_23, __pyx_t_22);
                    __pyx_L60_try_end:;
                  }
                }
                /*finally:*/ {
                  /*normal exit:*/{
                    if (__pyx_t_20) {
                      __pyx_t_22 = __Pyx_PyObject_Call(__pyx_t_20, __pyx_tuple__3, NULL);
                      __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
                      if (unlikely(!__pyx_t_22)) __PYX_ERR(0, 443, __pyx_L20_error)
                      __Pyx_GOTREF(__pyx_t_22);
                      __Pyx_DECREF(__pyx_t_22); __pyx_t_22 = 0;
                    }
                    goto __pyx_L52;
                  }
                  __pyx_L52:;
                }
                goto __pyx_L64;
                __pyx_L47_error:;
                __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
                goto __pyx_L20_error;
                __pyx_L64:;
              }

              /* "sQQideR/SQLBuilder.pyx":425
 * 
 *                     # Log the failed SQL and the working fix
 *                     try:             # <<<<<<<<<<<<<<
 *                         import os
 *                         os.makedirs("data", exist_ok=True)
 */
            }
            __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
            __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
            __Pyx_XDECREF(__pyx_t_19); __pyx_t_19 = 0;
            goto __pyx_L27_try_end;
            __pyx_L20_error:;
            __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
            __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
            __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
            __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;

            /* "sQQideR/SQLBuilder.pyx":446
 *                             json.dump(existing_logs, f, indent=2)
 * 
 *                     except Exception as log_e:             # <<<<<<<<<<<<<<
 *                         if self.verbose:
 *                             print(f"Failed to log corrected SQL: {log_e}")
 */
            __pyx_t_26 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
            if (__pyx_t_26) {
              __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.try_fix_failed_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
              if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_2, &__pyx_t_21) < 0) __PYX_ERR(0, 446, __pyx_L22_except_error)
              __Pyx_XGOTREF(__pyx_t_5);
              __Pyx_XGOTREF(__pyx_t_2);
              __Pyx_XGOTREF(__pyx_t_21);
              __Pyx_INCREF(__pyx_t_2);
              __Pyx_XDECREF_SET(__pyx_v_log_e, __pyx_t_2);
              /*try:*/ {

                /* "sQQideR/SQLBuilder.pyx":447
 * 
 *                     except Exception as log_e:
 *                         if self.verbose:             # <<<<<<<<<<<<<<
 *                             print(f"Failed to log corrected SQL: {log_e}")
 * 
 */
                __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 447, __pyx_L70_error)
                __Pyx_GOTREF(__pyx_t_10);
                __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 447, __pyx_L70_error)
                __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                if (__pyx_t_1) {

                  /* "sQQideR/SQLBuilder.pyx":448
 *                     except Exception as log_e:
 *                         if self.verbose:
 *                             print(f"Failed to log corrected SQL: {log_e}")             # <<<<<<<<<<<<<<
 * 
 *                     break
 */
                  __pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_v_log_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 448, __pyx_L70_error)
                  __Pyx_GOTREF(__pyx_t_10);
                  __pyx_t_27 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Failed_to_log_corrected_SQL, __pyx_t_10); if (unlikely(!__pyx_t_27)) __PYX_ERR(0, 448, __pyx_L70_error)
                  __Pyx_GOTREF(__pyx_t_27);
                  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
                  __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_27); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 448, __pyx_L70_error)
                  __Pyx_GOTREF(__pyx_t_10);
                  __Pyx_DECREF(__pyx_t_27); __pyx_t_27 = 0;
                  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

                  /* "sQQideR/SQLBuilder.pyx":447
 * 
 *                     except Exception as log_e:
 *                         if self.verbose:             # <<<<<<<<<<<<<<
 *                             print(f"Failed to log corrected SQL: {log_e}")
 * 
 */
                }
              }

              /* "sQQideR/SQLBuilder.pyx":446
 *                             json.dump(existing_logs, f, indent=2)
 * 
 *                     except Exception as log_e:             # <<<<<<<<<<<<<<
 *                         if self.verbose:
 *                             print(f"Failed to log corrected SQL: {log_e}")
 */
              /*finally:*/ {
                /*normal exit:*/{
                  __Pyx_DECREF(__pyx_v_log_e); __pyx_v_log_e = 0;
                  goto __pyx_L71;
                }
                __pyx_L70_error:;
                /*exception exit:*/{
                  __Pyx_PyThreadState_declare
                  __Pyx_PyThreadState_assign
                  __pyx_t_20 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_30 = 0;
                  __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
                  __Pyx_XDECREF(__pyx_t_27); __pyx_t_27 = 0;
                  if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_24, &__pyx_t_25, &__pyx_t_30);
                  if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_20, &__pyx_t_22, &__pyx_t_23) < 0)) __Pyx_ErrFetch(&__pyx_t_20, &__pyx_t_22, &__pyx_t_23);
                  __Pyx_XGOTREF(__pyx_t_20);
                  __Pyx_XGOTREF(__pyx_t_22);
                  __Pyx_XGOTREF(__pyx_t_23);
                  __Pyx_XGOTREF(__pyx_t_24);
                  __Pyx_XGOTREF(__pyx_t_25);
                  __Pyx_XGOTREF(__pyx_t_30);
                  __pyx_t_26 = __pyx_lineno; __pyx_t_28 = __pyx_clineno; __pyx_t_29 = __pyx_filename;
                  {
                    __Pyx_DECREF(__pyx_v_log_e); __pyx_v_log_e = 0;
                  }
                  if (PY_MAJOR_VERSION >= 3) {
                    __Pyx_XGIVEREF(__pyx_t_24);
                    __Pyx_XGIVEREF(__pyx_t_25);
                    __Pyx_XGIVEREF(__pyx_t_30);
                    __Pyx_ExceptionReset(__pyx_t_24, __pyx_t_25, __pyx_t_30);
                  }
                  __Pyx_XGIVEREF(__pyx_t_20);
                  __Pyx_XGIVEREF(__pyx_t_22);
                  __Pyx_XGIVEREF(__pyx_t_23);
                  __Pyx_ErrRestore(__pyx_t_20, __pyx_t_22, __pyx_t_23);
                  __pyx_t_20 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_30 = 0;
                  __pyx_lineno = __pyx_t_26; __pyx_clineno = __pyx_t_28; __pyx_filename = __pyx_t_29;
                  goto __pyx_L22_except_error;
                }
                __pyx_L71:;
              }
              __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
              __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
              __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
              goto __pyx_L21_exception_handled;
            }
            goto __pyx_L22_except_error;

            /* "sQQideR/SQLBuilder.pyx":425
 * 
 *                     # Log the failed SQL and the working fix
 *                     try:             # <<<<<<<<<<<<<<
 *                         import os
 *                         os.makedirs("data", exist_ok=True)
 */
            __pyx_L22_except_error:;
            __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);
            goto __pyx_L8_error;
            __pyx_L21_exception_handled:;
            __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_L27_try_end:;
          }

          /* "sQQideR/SQLBuilder.pyx":450
 *                             print(f"Failed to log corrected SQL: {log_e}")
 * 
 *                     break             # <<<<<<<<<<<<<<
 * 
 *                 # If we continue, let's get more detailed schema info
 */
          goto __pyx_L13_try_break;

          /* "sQQideR/SQLBuilder.pyx":417
 * 
 *                 # If this attempt succeeded, we can stop
 *                 if fixed_query.get("success", False):             # <<<<<<<<<<<<<<
 *                     if self.verbose:
 *                         print(f"Retry attempt #{attempt+1} succeeded!")
 */
        }

        /* "sQQideR/SQLBuilder.pyx":453
 * 
 *                 # If we continue, let's get more detailed schema info
 *                 if attempt < max_attempts - 1:             # <<<<<<<<<<<<<<
 *                     # Get additional schema information based on the tables mentioned in the fixed SQL
 *                     table_names = self._extract_table_names(fixed_sql)
 */
        __pyx_t_21 = __Pyx_PyInt_SubtractObjC(__pyx_v_max_attempts, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 453, __pyx_L8_error)
        __Pyx_GOTREF(__pyx_t_21);
        __pyx_t_2 = PyObject_RichCompare(__pyx_v_attempt, __pyx_t_21, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 453, __pyx_L8_error)
        __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 453, __pyx_L8_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        if (__pyx_t_1) {

          /* "sQQideR/SQLBuilder.pyx":455
 *                 if attempt < max_attempts - 1:
 *                     # Get additional schema information based on the tables mentioned in the fixed SQL
 *                     table_names = self._extract_table_names(fixed_sql)             # <<<<<<<<<<<<<<
 *                     for table in table_names:
 *                         table_info = self._explore_table_schema(table)
 */
          __pyx_t_21 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_extract_table_names); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 455, __pyx_L8_error)
          __Pyx_GOTREF(__pyx_t_21);
          __pyx_t_5 = NULL;
          __pyx_t_7 = 0;
          #if CYTHON_UNPACK_METHODS
          if (likely(PyMethod_Check(__pyx_t_21))) {
            __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_21);
            if (likely(__pyx_t_5)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_21);
              __Pyx_INCREF(__pyx_t_5);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_21, function);
              __pyx_t_7 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_v_fixed_sql};
            __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_21, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
            __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
            if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 455, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
          }
          __Pyx_XDECREF_SET(__pyx_v_table_names, __pyx_t_2);
          __pyx_t_2 = 0;

          /* "sQQideR/SQLBuilder.pyx":456
 *                     # Get additional schema information based on the tables mentioned in the fixed SQL
 *                     table_names = self._extract_table_names(fixed_sql)
 *                     for table in table_names:             # <<<<<<<<<<<<<<
 *                         table_info = self._explore_table_schema(table)
 *                         if table_info and table_info not in schema_info:
 */
          if (likely(PyList_CheckExact(__pyx_v_table_names)) || PyTuple_CheckExact(__pyx_v_table_names)) {
            __pyx_t_2 = __pyx_v_table_names; __Pyx_INCREF(__pyx_t_2);
            __pyx_t_14 = 0;
            __pyx_t_31 = NULL;
          } else {
            __pyx_t_14 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_table_names); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 456, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_31 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_31)) __PYX_ERR(0, 456, __pyx_L8_error)
          }
          for (;;) {
            if (likely(!__pyx_t_31)) {
              if (likely(PyList_CheckExact(__pyx_t_2))) {
                {
                  Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2);
                  #if !CYTHON_ASSUME_SAFE_MACROS
                  if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 456, __pyx_L8_error)
                  #endif
                  if (__pyx_t_14 >= __pyx_temp) break;
                }
                #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
                __pyx_t_21 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_14); __Pyx_INCREF(__pyx_t_21); __pyx_t_14++; if (unlikely((0 < 0))) __PYX_ERR(0, 456, __pyx_L8_error)
                #else
                __pyx_t_21 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 456, __pyx_L8_error)
                __Pyx_GOTREF(__pyx_t_21);
                #endif
              } else {
                {
                  Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2);
                  #if !CYTHON_ASSUME_SAFE_MACROS
                  if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 456, __pyx_L8_error)
                  #endif
                  if (__pyx_t_14 >= __pyx_temp) break;
                }
                #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
                __pyx_t_21 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_14); __Pyx_INCREF(__pyx_t_21); __pyx_t_14++; if (unlikely((0 < 0))) __PYX_ERR(0, 456, __pyx_L8_error)
                #else
                __pyx_t_21 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 456, __pyx_L8_error)
                __Pyx_GOTREF(__pyx_t_21);
                #endif
              }
            } else {
              __pyx_t_21 = __pyx_t_31(__pyx_t_2);
              if (unlikely(!__pyx_t_21)) {
                PyObject* exc_type = PyErr_Occurred();
                if (exc_type) {
                  if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
                  else __PYX_ERR(0, 456, __pyx_L8_error)
                }
                break;
              }
              __Pyx_GOTREF(__pyx_t_21);
            }
            __Pyx_XDECREF_SET(__pyx_v_table, __pyx_t_21);
            __pyx_t_21 = 0;

            /* "sQQideR/SQLBuilder.pyx":457
 *                     table_names = self._extract_table_names(fixed_sql)
 *                     for table in table_names:
 *                         table_info = self._explore_table_schema(table)             # <<<<<<<<<<<<<<
 *                         if table_info and table_info not in schema_info:
 *                             schema_info.append(table_info)
 */
            __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_explore_table_schema); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 457, __pyx_L8_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_10 = NULL;
            __pyx_t_7 = 0;
            #if CYTHON_UNPACK_METHODS
            if (likely(PyMethod_Check(__pyx_t_5))) {
              __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_5);
              if (likely(__pyx_t_10)) {
                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                __Pyx_INCREF(__pyx_t_10);
                __Pyx_INCREF(function);
                __Pyx_DECREF_SET(__pyx_t_5, function);
                __pyx_t_7 = 1;
              }
            }
            #endif
            {
              PyObject *__pyx_callargs[2] = {__pyx_t_10, __pyx_v_table};
              __pyx_t_21 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
              __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
              if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 457, __pyx_L8_error)
              __Pyx_GOTREF(__pyx_t_21);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            }
            __Pyx_XDECREF_SET(__pyx_v_table_info, __pyx_t_21);
            __pyx_t_21 = 0;

            /* "sQQideR/SQLBuilder.pyx":458
 *                     for table in table_names:
 *                         table_info = self._explore_table_schema(table)
 *                         if table_info and table_info not in schema_info:             # <<<<<<<<<<<<<<
 *                             schema_info.append(table_info)
 * 
 */
            __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_table_info); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 458, __pyx_L8_error)
            if (__pyx_t_3) {
            } else {
              __pyx_t_1 = __pyx_t_3;
              goto __pyx_L81_bool_binop_done;
            }
            __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_v_table_info, __pyx_v_schema_info, Py_NE)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 458, __pyx_L8_error)
            __pyx_t_1 = __pyx_t_3;
            __pyx_L81_bool_binop_done:;
            if (__pyx_t_1) {

              /* "sQQideR/SQLBuilder.pyx":459
 *                         table_info = self._explore_table_schema(table)
 *                         if table_info and table_info not in schema_info:
 *                             schema_info.append(table_info)             # <<<<<<<<<<<<<<
 * 
 *             except Exception as e:
 */
              __pyx_t_16 = __Pyx_PyObject_Append(__pyx_v_schema_info, __pyx_v_table_info); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 459, __pyx_L8_error)

              /* "sQQideR/SQLBuilder.pyx":458
 *                     for table in table_names:
 *                         table_info = self._explore_table_schema(table)
 *                         if table_info and table_info not in schema_info:             # <<<<<<<<<<<<<<
 *                             schema_info.append(table_info)
 * 
 */
            }

            /* "sQQideR/SQLBuilder.pyx":456
 *                     # Get additional schema information based on the tables mentioned in the fixed SQL
 *                     table_names = self._extract_table_names(fixed_sql)
 *                     for table in table_names:             # <<<<<<<<<<<<<<
 *                         table_info = self._explore_table_schema(table)
 *                         if table_info and table_info not in schema_info:
 */
          }
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

          /* "sQQideR/SQLBuilder.pyx":453
 * 
 *                 # If we continue, let's get more detailed schema info
 *                 if attempt < max_attempts - 1:             # <<<<<<<<<<<<<<
 *                     # Get additional schema information based on the tables mentioned in the fixed SQL
 *                     table_names = self._extract_table_names(fixed_sql)
 */
        }

        /* "sQQideR/SQLBuilder.pyx":384
 *             )
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 # Get improved SQL from AI
 *                 if self.verbose:
 */
      }
      __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
      __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
      goto __pyx_L15_try_end;
      __pyx_L8_error:;
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
      __Pyx_XDECREF(__pyx_t_27); __pyx_t_27 = 0;
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":461
 *                             schema_info.append(table_info)
 * 
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Error during retry attempt #{attempt+1}: {e}")
 */
      __pyx_t_28 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
      if (__pyx_t_28) {
        __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.try_fix_failed_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
        if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_21, &__pyx_t_5) < 0) __PYX_ERR(0, 461, __pyx_L10_except_error)
        __Pyx_XGOTREF(__pyx_t_2);
        __Pyx_XGOTREF(__pyx_t_21);
        __Pyx_XGOTREF(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_21);
        __pyx_v_e = __pyx_t_21;
        /*try:*/ {

          /* "sQQideR/SQLBuilder.pyx":462
 * 
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Error during retry attempt #{attempt+1}: {e}")
 * 
 */
          __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 462, __pyx_L89_error)
          __Pyx_GOTREF(__pyx_t_10);
          __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 462, __pyx_L89_error)
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          if (__pyx_t_1) {

            /* "sQQideR/SQLBuilder.pyx":463
 *             except Exception as e:
 *                 if self.verbose:
 *                     print(f"Error during retry attempt #{attempt+1}: {e}")             # <<<<<<<<<<<<<<
 * 
 *                 # Record the failed attempt
 */
            __pyx_t_10 = PyTuple_New(4); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 463, __pyx_L89_error)
            __Pyx_GOTREF(__pyx_t_10);
            __pyx_t_14 = 0;
            __pyx_t_15 = 127;
            __Pyx_INCREF(__pyx_kp_u_Error_during_retry_attempt);
            __pyx_t_14 += 28;
            __Pyx_GIVEREF(__pyx_kp_u_Error_during_retry_attempt);
            PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_kp_u_Error_during_retry_attempt);
            __pyx_t_27 = __Pyx_PyInt_AddObjC(__pyx_v_attempt, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_27)) __PYX_ERR(0, 463, __pyx_L89_error)
            __Pyx_GOTREF(__pyx_t_27);
            __pyx_t_32 = __Pyx_PyObject_FormatSimple(__pyx_t_27, __pyx_empty_unicode); if (unlikely(!__pyx_t_32)) __PYX_ERR(0, 463, __pyx_L89_error)
            __Pyx_GOTREF(__pyx_t_32);
            __Pyx_DECREF(__pyx_t_27); __pyx_t_27 = 0;
            __pyx_t_15 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_32) > __pyx_t_15) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_32) : __pyx_t_15;
            __pyx_t_14 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_32);
            __Pyx_GIVEREF(__pyx_t_32);
            PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_32);
            __pyx_t_32 = 0;
            __Pyx_INCREF(__pyx_kp_u__13);
            __pyx_t_14 += 2;
            __Pyx_GIVEREF(__pyx_kp_u__13);
            PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_kp_u__13);
            __pyx_t_32 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_32)) __PYX_ERR(0, 463, __pyx_L89_error)
            __Pyx_GOTREF(__pyx_t_32);
            __pyx_t_15 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_32) > __pyx_t_15) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_32) : __pyx_t_15;
            __pyx_t_14 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_32);
            __Pyx_GIVEREF(__pyx_t_32);
            PyTuple_SET_ITEM(__pyx_t_10, 3, __pyx_t_32);
            __pyx_t_32 = 0;
            __pyx_t_32 = __Pyx_PyUnicode_Join(__pyx_t_10, 4, __pyx_t_14, __pyx_t_15); if (unlikely(!__pyx_t_32)) __PYX_ERR(0, 463, __pyx_L89_error)
            __Pyx_GOTREF(__pyx_t_32);
            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
            __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_32); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 463, __pyx_L89_error)
            __Pyx_GOTREF(__pyx_t_10);
            __Pyx_DECREF(__pyx_t_32); __pyx_t_32 = 0;
            __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

            /* "sQQideR/SQLBuilder.pyx":462
 * 
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Error during retry attempt #{attempt+1}: {e}")
 * 
 */
          }

          /* "sQQideR/SQLBuilder.pyx":467
 *                 # Record the failed attempt
 *                 attempts.append({
 *                     "success": False,             # <<<<<<<<<<<<<<
 *                     "execution_error": f"Error during AI retry: {str(e)}",
 *                     "retry_attempt": attempt + 1
 */
          __pyx_t_10 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 467, __pyx_L89_error)
          __Pyx_GOTREF(__pyx_t_10);
          if (PyDict_SetItem(__pyx_t_10, __pyx_n_u_success, Py_False) < 0) __PYX_ERR(0, 467, __pyx_L89_error)

          /* "sQQideR/SQLBuilder.pyx":468
 *                 attempts.append({
 *                     "success": False,
 *                     "execution_error": f"Error during AI retry: {str(e)}",             # <<<<<<<<<<<<<<
 *                     "retry_attempt": attempt + 1
 *                 })
 */
          __pyx_t_32 = __Pyx_PyObject_Unicode(__pyx_v_e); if (unlikely(!__pyx_t_32)) __PYX_ERR(0, 468, __pyx_L89_error)
          __Pyx_GOTREF(__pyx_t_32);
          __pyx_t_27 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_during_AI_retry, __pyx_t_32); if (unlikely(!__pyx_t_27)) __PYX_ERR(0, 468, __pyx_L89_error)
          __Pyx_GOTREF(__pyx_t_27);
          __Pyx_DECREF(__pyx_t_32); __pyx_t_32 = 0;
          if (PyDict_SetItem(__pyx_t_10, __pyx_n_u_execution_error, __pyx_t_27) < 0) __PYX_ERR(0, 467, __pyx_L89_error)
          __Pyx_DECREF(__pyx_t_27); __pyx_t_27 = 0;

          /* "sQQideR/SQLBuilder.pyx":469
 *                     "success": False,
 *                     "execution_error": f"Error during AI retry: {str(e)}",
 *                     "retry_attempt": attempt + 1             # <<<<<<<<<<<<<<
 *                 })
 * 
 */
          __pyx_t_27 = __Pyx_PyInt_AddObjC(__pyx_v_attempt, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_27)) __PYX_ERR(0, 469, __pyx_L89_error)
          __Pyx_GOTREF(__pyx_t_27);
          if (PyDict_SetItem(__pyx_t_10, __pyx_n_u_retry_attempt, __pyx_t_27) < 0) __PYX_ERR(0, 467, __pyx_L89_error)
          __Pyx_DECREF(__pyx_t_27); __pyx_t_27 = 0;

          /* "sQQideR/SQLBuilder.pyx":466
 * 
 *                 # Record the failed attempt
 *                 attempts.append({             # <<<<<<<<<<<<<<
 *                     "success": False,
 *                     "execution_error": f"Error during AI retry: {str(e)}",
 */
          __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_attempts, __pyx_t_10); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 466, __pyx_L89_error)
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        }

        /* "sQQideR/SQLBuilder.pyx":461
 *                             schema_info.append(table_info)
 * 
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Error during retry attempt #{attempt+1}: {e}")
 */
        /*finally:*/ {
          /*normal exit:*/{
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            goto __pyx_L90;
          }
          __pyx_L89_error:;
          /*exception exit:*/{
            __Pyx_PyThreadState_declare
            __Pyx_PyThreadState_assign
            __pyx_t_19 = 0; __pyx_t_18 = 0; __pyx_t_17 = 0; __pyx_t_30 = 0; __pyx_t_25 = 0; __pyx_t_24 = 0;
            __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
            __Pyx_XDECREF(__pyx_t_27); __pyx_t_27 = 0;
            __Pyx_XDECREF(__pyx_t_32); __pyx_t_32 = 0;
            if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_30, &__pyx_t_25, &__pyx_t_24);
            if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_19, &__pyx_t_18, &__pyx_t_17) < 0)) __Pyx_ErrFetch(&__pyx_t_19, &__pyx_t_18, &__pyx_t_17);
            __Pyx_XGOTREF(__pyx_t_19);
            __Pyx_XGOTREF(__pyx_t_18);
            __Pyx_XGOTREF(__pyx_t_17);
            __Pyx_XGOTREF(__pyx_t_30);
            __Pyx_XGOTREF(__pyx_t_25);
            __Pyx_XGOTREF(__pyx_t_24);
            __pyx_t_28 = __pyx_lineno; __pyx_t_26 = __pyx_clineno; __pyx_t_33 = __pyx_filename;
            {
              __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            }
            if (PY_MAJOR_VERSION >= 3) {
              __Pyx_XGIVEREF(__pyx_t_30);
              __Pyx_XGIVEREF(__pyx_t_25);
              __Pyx_XGIVEREF(__pyx_t_24);
              __Pyx_ExceptionReset(__pyx_t_30, __pyx_t_25, __pyx_t_24);
            }
            __Pyx_XGIVEREF(__pyx_t_19);
            __Pyx_XGIVEREF(__pyx_t_18);
            __Pyx_XGIVEREF(__pyx_t_17);
            __Pyx_ErrRestore(__pyx_t_19, __pyx_t_18, __pyx_t_17);
            __pyx_t_19 = 0; __pyx_t_18 = 0; __pyx_t_17 = 0; __pyx_t_30 = 0; __pyx_t_25 = 0; __pyx_t_24 = 0;
            __pyx_lineno = __pyx_t_28; __pyx_clineno = __pyx_t_26; __pyx_filename = __pyx_t_33;
            goto __pyx_L10_except_error;
          }
          __pyx_L90:;
        }
        __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
        __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        goto __pyx_L9_exception_handled;
      }
      goto __pyx_L10_except_error;

      /* "sQQideR/SQLBuilder.pyx":384
 *             )
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 # Get improved SQL from AI
 *                 if self.verbose:
 */
      __pyx_L10_except_error:;
      __Pyx_XGIVEREF(__pyx_t_11);
      __Pyx_XGIVEREF(__pyx_t_12);
      __Pyx_XGIVEREF(__pyx_t_13);
      __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
      goto __pyx_L1_error;
      __pyx_L13_try_break:;
      __Pyx_XGIVEREF(__pyx_t_11);
      __Pyx_XGIVEREF(__pyx_t_12);
      __Pyx_XGIVEREF(__pyx_t_13);
      __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
      goto __pyx_L7_break;
      __pyx_L9_exception_handled:;
      __Pyx_XGIVEREF(__pyx_t_11);
      __Pyx_XGIVEREF(__pyx_t_12);
      __Pyx_XGIVEREF(__pyx_t_13);
      __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
      __pyx_L15_try_end:;
    }

    /* "sQQideR/SQLBuilder.pyx":373
 *         schema_info = self._explore_database_schema()
 * 
 *         for attempt in range(max_attempts):             # <<<<<<<<<<<<<<
 *             # Build the prompt for the AI
 *             prompt = self._create_sql_correction_prompt(
 */
  }
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  goto __pyx_L96_for_end;
  __pyx_L7_break:;
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  goto __pyx_L96_for_end;
  __pyx_L96_for_end:;

  /* "sQQideR/SQLBuilder.pyx":473
 * 
 *         # Store the best attempt and all attempts in the result
 *         result["best_attempt"] = best_attempt             # <<<<<<<<<<<<<<
 *         result["attempts"] = attempts
 * 
 */
  if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_best_attempt, __pyx_v_best_attempt) < 0))) __PYX_ERR(0, 473, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":474
 *         # Store the best attempt and all attempts in the result
 *         result["best_attempt"] = best_attempt
 *         result["attempts"] = attempts             # <<<<<<<<<<<<<<
 * 
 *         if not result["success"]:
 */
  if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_attempts, __pyx_v_attempts) < 0))) __PYX_ERR(0, 474, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":476
 *         result["attempts"] = attempts
 * 
 *         if not result["success"]:             # <<<<<<<<<<<<<<
 *             result["message"] = f"Failed to fix SQL after {max_attempts} attempts. Original error: {original_error}"
 * 
 */
  __pyx_t_6 = __Pyx_PyDict_GetItem(__pyx_v_result, __pyx_n_u_success); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 476, __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(0, 476, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_3 = (!__pyx_t_1);
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":477
 * 
 *         if not result["success"]:
 *             result["message"] = f"Failed to fix SQL after {max_attempts} attempts. Original error: {original_error}"             # <<<<<<<<<<<<<<
 * 
 *         return result
 */
    __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 477, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_8 = 0;
    __pyx_t_15 = 127;
    __Pyx_INCREF(__pyx_kp_u_Failed_to_fix_SQL_after);
    __pyx_t_8 += 24;
    __Pyx_GIVEREF(__pyx_kp_u_Failed_to_fix_SQL_after);
    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_Failed_to_fix_SQL_after);
    __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_max_attempts, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 477, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_15 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_15) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_15;
    __pyx_t_8 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_5);
    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5);
    __pyx_t_5 = 0;
    __Pyx_INCREF(__pyx_kp_u_attempts_Original_error);
    __pyx_t_8 += 27;
    __Pyx_GIVEREF(__pyx_kp_u_attempts_Original_error);
    PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u_attempts_Original_error);
    __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_original_error, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 477, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_15 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_15) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_15;
    __pyx_t_8 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_5);
    PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_5);
    __pyx_t_5 = 0;
    __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_6, 4, __pyx_t_8, __pyx_t_15); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 477, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    if (unlikely((PyDict_SetItem(__pyx_v_result, __pyx_n_u_message, __pyx_t_5) < 0))) __PYX_ERR(0, 477, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":476
 *         result["attempts"] = attempts
 * 
 *         if not result["success"]:             # <<<<<<<<<<<<<<
 *             result["message"] = f"Failed to fix SQL after {max_attempts} attempts. Original error: {original_error}"
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":479
 *             result["message"] = f"Failed to fix SQL after {max_attempts} attempts. Original error: {original_error}"
 * 
 *         return result             # <<<<<<<<<<<<<<
 * 
 *     def _create_sql_correction_prompt(self, question: str, original_sql: str, error: str,
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_result);
  __pyx_r = __pyx_v_result;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":339
 *         return result
 * 
 *     def try_fix_failed_query(self, failed_query: Dict, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Try to fix a failed SQL query using AI assistance and schema exploration.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_XDECREF(__pyx_t_21);
  __Pyx_XDECREF(__pyx_t_27);
  __Pyx_XDECREF(__pyx_t_32);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.try_fix_failed_query", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_max_attempts);
  __Pyx_XDECREF(__pyx_v_attempts);
  __Pyx_XDECREF(__pyx_v_best_attempt);
  __Pyx_XDECREF(__pyx_v_original_error);
  __Pyx_XDECREF(__pyx_v_original_sql);
  __Pyx_XDECREF(__pyx_v_result);
  __Pyx_XDECREF(__pyx_v_schema_info);
  __Pyx_XDECREF(__pyx_v_attempt);
  __Pyx_XDECREF(__pyx_v_prompt);
  __Pyx_XDECREF(__pyx_v_response);
  __Pyx_XDECREF(__pyx_v_fixed_sql);
  __Pyx_XDECREF(__pyx_v_explanation);
  __Pyx_XDECREF(__pyx_v_fixed_query);
  __Pyx_XDECREF(__pyx_v_os);
  __Pyx_XDECREF(__pyx_v_file_path);
  __Pyx_XDECREF(__pyx_v_f);
  __Pyx_XDECREF(__pyx_v_existing_logs);
  __Pyx_XDECREF(__pyx_v_log_e);
  __Pyx_XDECREF(__pyx_v_table_names);
  __Pyx_XDECREF(__pyx_v_table);
  __Pyx_XDECREF(__pyx_v_table_info);
  __Pyx_XDECREF(__pyx_v_e);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":481
 *         return result
 * 
 *     def _create_sql_correction_prompt(self, question: str, original_sql: str, error: str,             # <<<<<<<<<<<<<<
 *                                       schema_info: List[Dict], previous_attempts: List[Dict],
 *                                       db_context: Dict) -> str:
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_17_create_sql_correction_prompt(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_16_create_sql_correction_prompt, "\n        Create a detailed prompt for SQL correction using the database error and schema info.\n        \n        Args:\n            question: The original question\n            original_sql: The SQL query that failed\n            error: The error message from the database\n            schema_info: Database schema information from exploration\n            previous_attempts: Previous correction attempts\n            db_context: The database context information\n            \n        Returns:\n            Formatted prompt string for the AI\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_17_create_sql_correction_prompt = {"_create_sql_correction_prompt", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_17_create_sql_correction_prompt, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_16_create_sql_correction_prompt};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_17_create_sql_correction_prompt(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_question = 0;
  PyObject *__pyx_v_original_sql = 0;
  PyObject *__pyx_v_error = 0;
  PyObject *__pyx_v_schema_info = 0;
  PyObject *__pyx_v_previous_attempts = 0;
  PyObject *__pyx_v_db_context = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[7] = {0,0,0,0,0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_create_sql_correction_prompt (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_question,&__pyx_n_s_original_sql,&__pyx_n_s_error,&__pyx_n_s_schema_info,&__pyx_n_s_previous_attempts,&__pyx_n_s_db_context,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  7: values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 481, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 481, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_correction_prompt", 1, 7, 7, 1); __PYX_ERR(0, 481, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_original_sql)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 481, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_correction_prompt", 1, 7, 7, 2); __PYX_ERR(0, 481, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_error)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[3]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 481, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_correction_prompt", 1, 7, 7, 3); __PYX_ERR(0, 481, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_schema_info)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[4]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 481, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_correction_prompt", 1, 7, 7, 4); __PYX_ERR(0, 481, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_previous_attempts)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[5]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 481, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_correction_prompt", 1, 7, 7, 5); __PYX_ERR(0, 481, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  6:
        if (likely((values[6] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_db_context)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[6]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 481, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_correction_prompt", 1, 7, 7, 6); __PYX_ERR(0, 481, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_create_sql_correction_prompt") < 0)) __PYX_ERR(0, 481, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 7)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
      values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
      values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4);
      values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5);
      values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6);
    }
    __pyx_v_self = values[0];
    __pyx_v_question = ((PyObject*)values[1]);
    __pyx_v_original_sql = ((PyObject*)values[2]);
    __pyx_v_error = ((PyObject*)values[3]);
    __pyx_v_schema_info = ((PyObject*)values[4]);
    __pyx_v_previous_attempts = ((PyObject*)values[5]);
    __pyx_v_db_context = ((PyObject*)values[6]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_create_sql_correction_prompt", 1, 7, 7, __pyx_nargs); __PYX_ERR(0, 481, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._create_sql_correction_prompt", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 481, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_original_sql), (&PyUnicode_Type), 0, "original_sql", 1))) __PYX_ERR(0, 481, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_error), (&PyUnicode_Type), 0, "error", 1))) __PYX_ERR(0, 481, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_schema_info), (&PyList_Type), 0, "schema_info", 1))) __PYX_ERR(0, 482, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_previous_attempts), (&PyList_Type), 0, "previous_attempts", 1))) __PYX_ERR(0, 482, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_db_context), (&PyDict_Type), 0, "db_context", 1))) __PYX_ERR(0, 483, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_16_create_sql_correction_prompt(__pyx_self, __pyx_v_self, __pyx_v_question, __pyx_v_original_sql, __pyx_v_error, __pyx_v_schema_info, __pyx_v_previous_attempts, __pyx_v_db_context);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_16_create_sql_correction_prompt(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_original_sql, PyObject *__pyx_v_error, PyObject *__pyx_v_schema_info, PyObject *__pyx_v_previous_attempts, PyObject *__pyx_v_db_context) {
  PyObject *__pyx_v_prompt = NULL;
  PyObject *__pyx_v_info = NULL;
  PyObject *__pyx_v_col = NULL;
  PyObject *__pyx_v_tables = NULL;
  PyObject *__pyx_v_table = NULL;
  PyObject *__pyx_v_relationships = NULL;
  PyObject *__pyx_v_rel = NULL;
  PyObject *__pyx_v_i = NULL;
  PyObject *__pyx_v_attempt = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  Py_ssize_t __pyx_t_2;
  Py_UCS4 __pyx_t_3;
  PyObject *__pyx_t_4 = NULL;
  int __pyx_t_5;
  Py_ssize_t __pyx_t_6;
  PyObject *__pyx_t_7 = NULL;
  PyObject *__pyx_t_8 = NULL;
  PyObject *(*__pyx_t_9)(PyObject *);
  Py_ssize_t __pyx_t_10;
  PyObject *__pyx_t_11 = NULL;
  int __pyx_t_12;
  PyObject *__pyx_t_13 = NULL;
  unsigned int __pyx_t_14;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_create_sql_correction_prompt", 1);

  /* "sQQideR/SQLBuilder.pyx":498
 *             Formatted prompt string for the AI
 *         """
 *         prompt = f"""You are an expert SQL developer tasked with fixing a failed SQL query.             # <<<<<<<<<<<<<<
 * 
 * ORIGINAL QUESTION: {question}
 */
  __pyx_t_1 = PyTuple_New(7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 498, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = 0;
  __pyx_t_3 = 127;
  __Pyx_INCREF(__pyx_kp_u_You_are_an_expert_SQL_developer);
  __pyx_t_2 += 91;
  __Pyx_GIVEREF(__pyx_kp_u_You_are_an_expert_SQL_developer);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_You_are_an_expert_SQL_developer);
  __Pyx_INCREF(__pyx_v_question);
  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_question) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_question) : __pyx_t_3;
  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_question);
  __Pyx_GIVEREF(__pyx_v_question);
  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_question);
  __Pyx_INCREF(__pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED);
  __pyx_t_2 += 34;
  __Pyx_GIVEREF(__pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED);
  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED);
  __Pyx_INCREF(__pyx_v_original_sql);
  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_original_sql) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_original_sql) : __pyx_t_3;
  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_original_sql);
  __Pyx_GIVEREF(__pyx_v_original_sql);
  PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_original_sql);
  __Pyx_INCREF(__pyx_kp_u_ERROR_MESSAGE);
  __pyx_t_2 += 17;
  __Pyx_GIVEREF(__pyx_kp_u_ERROR_MESSAGE);
  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u_ERROR_MESSAGE);
  __Pyx_INCREF(__pyx_v_error);
  __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_error) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_error) : __pyx_t_3;
  __pyx_t_2 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_error);
  __Pyx_GIVEREF(__pyx_v_error);
  PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_v_error);
  __Pyx_INCREF(__pyx_kp_u_DATABASE_SCHEMA_INFORMATION);
  __pyx_t_2 += 31;
  __Pyx_GIVEREF(__pyx_kp_u_DATABASE_SCHEMA_INFORMATION);
  PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_kp_u_DATABASE_SCHEMA_INFORMATION);
  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 7, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 498, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_prompt = ((PyObject*)__pyx_t_4);
  __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":512
 * 
 *         # Add schema information
 *         for info in schema_info:             # <<<<<<<<<<<<<<
 *             if "table_name" in info:
 *                 prompt += f"\nTable: {info['table_name']}\n"
 */
  __pyx_t_4 = __pyx_v_schema_info; __Pyx_INCREF(__pyx_t_4);
  __pyx_t_2 = 0;
  for (;;) {
    {
      Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_4);
      #if !CYTHON_ASSUME_SAFE_MACROS
      if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 512, __pyx_L1_error)
      #endif
      if (__pyx_t_2 >= __pyx_temp) break;
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 512, __pyx_L1_error)
    #else
    __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 512, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    #endif
    __Pyx_XDECREF_SET(__pyx_v_info, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":513
 *         # Add schema information
 *         for info in schema_info:
 *             if "table_name" in info:             # <<<<<<<<<<<<<<
 *                 prompt += f"\nTable: {info['table_name']}\n"
 *                 if "columns" in info:
 */
    __pyx_t_5 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_table_name, __pyx_v_info, Py_EQ)); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 513, __pyx_L1_error)
    if (__pyx_t_5) {

      /* "sQQideR/SQLBuilder.pyx":514
 *         for info in schema_info:
 *             if "table_name" in info:
 *                 prompt += f"\nTable: {info['table_name']}\n"             # <<<<<<<<<<<<<<
 *                 if "columns" in info:
 *                     prompt += "Columns:\n"
 */
      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 514, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_6 = 0;
      __pyx_t_3 = 127;
      __Pyx_INCREF(__pyx_kp_u_Table);
      __pyx_t_6 += 8;
      __Pyx_GIVEREF(__pyx_kp_u_Table);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Table);
      __pyx_t_7 = __Pyx_PyObject_Dict_GetItem(__pyx_v_info, __pyx_n_u_table_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 514, __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, 514, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_3;
      __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
      __Pyx_GIVEREF(__pyx_t_8);
      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_8);
      __pyx_t_8 = 0;
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_6 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__14);
      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__14);
      __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 514, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 514, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
      __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":515
 *             if "table_name" in info:
 *                 prompt += f"\nTable: {info['table_name']}\n"
 *                 if "columns" in info:             # <<<<<<<<<<<<<<
 *                     prompt += "Columns:\n"
 *                     for col in info["columns"]:
 */
      __pyx_t_5 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_columns, __pyx_v_info, Py_EQ)); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 515, __pyx_L1_error)
      if (__pyx_t_5) {

        /* "sQQideR/SQLBuilder.pyx":516
 *                 prompt += f"\nTable: {info['table_name']}\n"
 *                 if "columns" in info:
 *                     prompt += "Columns:\n"             # <<<<<<<<<<<<<<
 *                     for col in info["columns"]:
 *                         prompt += f"- {col['name']} ({col['type']})\n"
 */
        __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_Columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 516, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
        __pyx_t_1 = 0;

        /* "sQQideR/SQLBuilder.pyx":517
 *                 if "columns" in info:
 *                     prompt += "Columns:\n"
 *                     for col in info["columns"]:             # <<<<<<<<<<<<<<
 *                         prompt += f"- {col['name']} ({col['type']})\n"
 *                 if "sample_data" in info and info["sample_data"]:
 */
        __pyx_t_1 = __Pyx_PyObject_Dict_GetItem(__pyx_v_info, __pyx_n_u_columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 517, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
          __pyx_t_8 = __pyx_t_1; __Pyx_INCREF(__pyx_t_8);
          __pyx_t_6 = 0;
          __pyx_t_9 = NULL;
        } else {
          __pyx_t_6 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 517, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_8);
          __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 517, __pyx_L1_error)
        }
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        for (;;) {
          if (likely(!__pyx_t_9)) {
            if (likely(PyList_CheckExact(__pyx_t_8))) {
              {
                Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_8);
                #if !CYTHON_ASSUME_SAFE_MACROS
                if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 517, __pyx_L1_error)
                #endif
                if (__pyx_t_6 >= __pyx_temp) break;
              }
              #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
              __pyx_t_1 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_6); __Pyx_INCREF(__pyx_t_1); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 517, __pyx_L1_error)
              #else
              __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_8, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 517, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_1);
              #endif
            } else {
              {
                Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_8);
                #if !CYTHON_ASSUME_SAFE_MACROS
                if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 517, __pyx_L1_error)
                #endif
                if (__pyx_t_6 >= __pyx_temp) break;
              }
              #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
              __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_6); __Pyx_INCREF(__pyx_t_1); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 517, __pyx_L1_error)
              #else
              __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_8, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 517, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_1);
              #endif
            }
          } else {
            __pyx_t_1 = __pyx_t_9(__pyx_t_8);
            if (unlikely(!__pyx_t_1)) {
              PyObject* exc_type = PyErr_Occurred();
              if (exc_type) {
                if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
                else __PYX_ERR(0, 517, __pyx_L1_error)
              }
              break;
            }
            __Pyx_GOTREF(__pyx_t_1);
          }
          __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_1);
          __pyx_t_1 = 0;

          /* "sQQideR/SQLBuilder.pyx":518
 *                     prompt += "Columns:\n"
 *                     for col in info["columns"]:
 *                         prompt += f"- {col['name']} ({col['type']})\n"             # <<<<<<<<<<<<<<
 *                 if "sample_data" in info and info["sample_data"]:
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"
 */
          __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 518, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          __pyx_t_10 = 0;
          __pyx_t_3 = 127;
          __Pyx_INCREF(__pyx_kp_u__15);
          __pyx_t_10 += 2;
          __Pyx_GIVEREF(__pyx_kp_u__15);
          PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u__15);
          __pyx_t_7 = __Pyx_PyObject_Dict_GetItem(__pyx_v_col, __pyx_n_u_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 518, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __pyx_t_11 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_empty_unicode); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 518, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
          __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) : __pyx_t_3;
          __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_11);
          __Pyx_GIVEREF(__pyx_t_11);
          PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_11);
          __pyx_t_11 = 0;
          __Pyx_INCREF(__pyx_kp_u__16);
          __pyx_t_10 += 2;
          __Pyx_GIVEREF(__pyx_kp_u__16);
          PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__16);
          __pyx_t_11 = __Pyx_PyObject_Dict_GetItem(__pyx_v_col, __pyx_n_u_type); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 518, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_11, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 518, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
          __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_7) : __pyx_t_3;
          __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_7);
          __Pyx_GIVEREF(__pyx_t_7);
          PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_7);
          __pyx_t_7 = 0;
          __Pyx_INCREF(__pyx_kp_u__17);
          __pyx_t_10 += 2;
          __Pyx_GIVEREF(__pyx_kp_u__17);
          PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u__17);
          __pyx_t_7 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_10, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 518, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_7);
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 518, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
          __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
          __pyx_t_1 = 0;

          /* "sQQideR/SQLBuilder.pyx":517
 *                 if "columns" in info:
 *                     prompt += "Columns:\n"
 *                     for col in info["columns"]:             # <<<<<<<<<<<<<<
 *                         prompt += f"- {col['name']} ({col['type']})\n"
 *                 if "sample_data" in info and info["sample_data"]:
 */
        }
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

        /* "sQQideR/SQLBuilder.pyx":515
 *             if "table_name" in info:
 *                 prompt += f"\nTable: {info['table_name']}\n"
 *                 if "columns" in info:             # <<<<<<<<<<<<<<
 *                     prompt += "Columns:\n"
 *                     for col in info["columns"]:
 */
      }

      /* "sQQideR/SQLBuilder.pyx":519
 *                     for col in info["columns"]:
 *                         prompt += f"- {col['name']} ({col['type']})\n"
 *                 if "sample_data" in info and info["sample_data"]:             # <<<<<<<<<<<<<<
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"
 *             elif "sql" in info and "result" in info:
 */
      __pyx_t_12 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_sample_data, __pyx_v_info, Py_EQ)); if (unlikely((__pyx_t_12 < 0))) __PYX_ERR(0, 519, __pyx_L1_error)
      if (__pyx_t_12) {
      } else {
        __pyx_t_5 = __pyx_t_12;
        goto __pyx_L11_bool_binop_done;
      }
      __pyx_t_8 = __Pyx_PyObject_Dict_GetItem(__pyx_v_info, __pyx_n_u_sample_data); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 519, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_12 < 0))) __PYX_ERR(0, 519, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_5 = __pyx_t_12;
      __pyx_L11_bool_binop_done:;
      if (__pyx_t_5) {

        /* "sQQideR/SQLBuilder.pyx":520
 *                         prompt += f"- {col['name']} ({col['type']})\n"
 *                 if "sample_data" in info and info["sample_data"]:
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"             # <<<<<<<<<<<<<<
 *             elif "sql" in info and "result" in info:
 *                 prompt += f"\nQuery: {info['sql']}\n"
 */
        __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __pyx_t_6 = 0;
        __pyx_t_3 = 127;
        __Pyx_INCREF(__pyx_kp_u_Sample_data);
        __pyx_t_6 += 13;
        __Pyx_GIVEREF(__pyx_kp_u_Sample_data);
        PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_Sample_data);
        __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_json); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_dumps); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        __pyx_t_7 = __Pyx_PyObject_Dict_GetItem(__pyx_v_info, __pyx_n_u_sample_data); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __pyx_t_13 = __Pyx_PyObject_GetSlice(__pyx_t_7, 0, 3, NULL, NULL, &__pyx_slice__18, 0, 1, 1); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        __pyx_t_7 = NULL;
        __pyx_t_14 = 0;
        #if CYTHON_UNPACK_METHODS
        if (unlikely(PyMethod_Check(__pyx_t_11))) {
          __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_11);
          if (likely(__pyx_t_7)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
            __Pyx_INCREF(__pyx_t_7);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_11, function);
            __pyx_t_14 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_t_13};
          __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_11, __pyx_callargs+1-__pyx_t_14, 1+__pyx_t_14);
          __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
          __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
          if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 520, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        }
        __pyx_t_11 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) : __pyx_t_3;
        __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_11);
        __Pyx_GIVEREF(__pyx_t_11);
        PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_11);
        __pyx_t_11 = 0;
        __Pyx_INCREF(__pyx_kp_u__14);
        __pyx_t_6 += 1;
        __Pyx_GIVEREF(__pyx_kp_u__14);
        PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u__14);
        __pyx_t_11 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        __pyx_t_8 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_11); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 520, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_8));
        __pyx_t_8 = 0;

        /* "sQQideR/SQLBuilder.pyx":519
 *                     for col in info["columns"]:
 *                         prompt += f"- {col['name']} ({col['type']})\n"
 *                 if "sample_data" in info and info["sample_data"]:             # <<<<<<<<<<<<<<
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"
 *             elif "sql" in info and "result" in info:
 */
      }

      /* "sQQideR/SQLBuilder.pyx":513
 *         # Add schema information
 *         for info in schema_info:
 *             if "table_name" in info:             # <<<<<<<<<<<<<<
 *                 prompt += f"\nTable: {info['table_name']}\n"
 *                 if "columns" in info:
 */
      goto __pyx_L5;
    }

    /* "sQQideR/SQLBuilder.pyx":521
 *                 if "sample_data" in info and info["sample_data"]:
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"
 *             elif "sql" in info and "result" in info:             # <<<<<<<<<<<<<<
 *                 prompt += f"\nQuery: {info['sql']}\n"
 *                 prompt += f"Result: {json.dumps(info['result'])}\n"
 */
    __pyx_t_12 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_sql, __pyx_v_info, Py_EQ)); if (unlikely((__pyx_t_12 < 0))) __PYX_ERR(0, 521, __pyx_L1_error)
    if (__pyx_t_12) {
    } else {
      __pyx_t_5 = __pyx_t_12;
      goto __pyx_L13_bool_binop_done;
    }
    __pyx_t_12 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_result, __pyx_v_info, Py_EQ)); if (unlikely((__pyx_t_12 < 0))) __PYX_ERR(0, 521, __pyx_L1_error)
    __pyx_t_5 = __pyx_t_12;
    __pyx_L13_bool_binop_done:;
    if (__pyx_t_5) {

      /* "sQQideR/SQLBuilder.pyx":522
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"
 *             elif "sql" in info and "result" in info:
 *                 prompt += f"\nQuery: {info['sql']}\n"             # <<<<<<<<<<<<<<
 *                 prompt += f"Result: {json.dumps(info['result'])}\n"
 * 
 */
      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 522, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __pyx_t_6 = 0;
      __pyx_t_3 = 127;
      __Pyx_INCREF(__pyx_kp_u_Query);
      __pyx_t_6 += 8;
      __Pyx_GIVEREF(__pyx_kp_u_Query);
      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_Query);
      __pyx_t_11 = __Pyx_PyObject_Dict_GetItem(__pyx_v_info, __pyx_n_u_sql); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 522, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_11, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 522, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_3;
      __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_1);
      __pyx_t_1 = 0;
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_6 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__14);
      PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u__14);
      __pyx_t_1 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 522, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_8 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 522, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_8));
      __pyx_t_8 = 0;

      /* "sQQideR/SQLBuilder.pyx":523
 *             elif "sql" in info and "result" in info:
 *                 prompt += f"\nQuery: {info['sql']}\n"
 *                 prompt += f"Result: {json.dumps(info['result'])}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add database context
 */
      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __pyx_t_6 = 0;
      __pyx_t_3 = 127;
      __Pyx_INCREF(__pyx_kp_u_Result);
      __pyx_t_6 += 8;
      __Pyx_GIVEREF(__pyx_kp_u_Result);
      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_Result);
      __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_json); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_dumps); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __pyx_t_11 = __Pyx_PyObject_Dict_GetItem(__pyx_v_info, __pyx_n_u_result); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __pyx_t_7 = NULL;
      __pyx_t_14 = 0;
      #if CYTHON_UNPACK_METHODS
      if (unlikely(PyMethod_Check(__pyx_t_13))) {
        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_13);
        if (likely(__pyx_t_7)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_13);
          __Pyx_INCREF(__pyx_t_7);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_13, function);
          __pyx_t_14 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_t_11};
        __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_13, __pyx_callargs+1-__pyx_t_14, 1+__pyx_t_14);
        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 523, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      }
      __pyx_t_13 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_13) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_13) : __pyx_t_3;
      __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_13);
      __Pyx_GIVEREF(__pyx_t_13);
      PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_13);
      __pyx_t_13 = 0;
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_6 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__14);
      PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u__14);
      __pyx_t_13 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_8 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_13); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 523, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_8));
      __pyx_t_8 = 0;

      /* "sQQideR/SQLBuilder.pyx":521
 *                 if "sample_data" in info and info["sample_data"]:
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"
 *             elif "sql" in info and "result" in info:             # <<<<<<<<<<<<<<
 *                 prompt += f"\nQuery: {info['sql']}\n"
 *                 prompt += f"Result: {json.dumps(info['result'])}\n"
 */
    }
    __pyx_L5:;

    /* "sQQideR/SQLBuilder.pyx":512
 * 
 *         # Add schema information
 *         for info in schema_info:             # <<<<<<<<<<<<<<
 *             if "table_name" in info:
 *                 prompt += f"\nTable: {info['table_name']}\n"
 */
  }
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":526
 * 
 *         # Add database context
 *         if db_context:             # <<<<<<<<<<<<<<
 *             # Add tables information
 *             tables = db_context.get("database_objects", {}).get("tables", [])
 */
  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_db_context); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 526, __pyx_L1_error)
  if (__pyx_t_5) {

    /* "sQQideR/SQLBuilder.pyx":528
 *         if db_context:
 *             # Add tables information
 *             tables = db_context.get("database_objects", {}).get("tables", [])             # <<<<<<<<<<<<<<
 *             if tables:
 *                 prompt += "\nRelevant Tables in Context:\n"
 */
    __pyx_t_8 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 528, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __pyx_t_13 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_database_objects, __pyx_t_8); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 528, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_13);
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_get); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 528, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
    __pyx_t_13 = PyList_New(0); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 528, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_13);
    __pyx_t_1 = NULL;
    __pyx_t_14 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_8))) {
      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_8);
      if (likely(__pyx_t_1)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
        __Pyx_INCREF(__pyx_t_1);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_8, function);
        __pyx_t_14 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[3] = {__pyx_t_1, __pyx_n_u_tables, __pyx_t_13};
      __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_8, __pyx_callargs+1-__pyx_t_14, 2+__pyx_t_14);
      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 528, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    }
    __pyx_v_tables = __pyx_t_4;
    __pyx_t_4 = 0;

    /* "sQQideR/SQLBuilder.pyx":529
 *             # Add tables information
 *             tables = db_context.get("database_objects", {}).get("tables", [])
 *             if tables:             # <<<<<<<<<<<<<<
 *                 prompt += "\nRelevant Tables in Context:\n"
 *                 for table in tables:
 */
    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_tables); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 529, __pyx_L1_error)
    if (__pyx_t_5) {

      /* "sQQideR/SQLBuilder.pyx":530
 *             tables = db_context.get("database_objects", {}).get("tables", [])
 *             if tables:
 *                 prompt += "\nRelevant Tables in Context:\n"             # <<<<<<<<<<<<<<
 *                 for table in tables:
 *                     prompt += f"- {table['name']}: {table.get('description', 'No description')}\n"
 */
      __pyx_t_4 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_Relevant_Tables_in_Context); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 530, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_4));
      __pyx_t_4 = 0;

      /* "sQQideR/SQLBuilder.pyx":531
 *             if tables:
 *                 prompt += "\nRelevant Tables in Context:\n"
 *                 for table in tables:             # <<<<<<<<<<<<<<
 *                     prompt += f"- {table['name']}: {table.get('description', 'No description')}\n"
 * 
 */
      if (likely(PyList_CheckExact(__pyx_v_tables)) || PyTuple_CheckExact(__pyx_v_tables)) {
        __pyx_t_4 = __pyx_v_tables; __Pyx_INCREF(__pyx_t_4);
        __pyx_t_2 = 0;
        __pyx_t_9 = NULL;
      } else {
        __pyx_t_2 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tables); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 531, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_4); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 531, __pyx_L1_error)
      }
      for (;;) {
        if (likely(!__pyx_t_9)) {
          if (likely(PyList_CheckExact(__pyx_t_4))) {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_4);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 531, __pyx_L1_error)
              #endif
              if (__pyx_t_2 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_8 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_8); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 531, __pyx_L1_error)
            #else
            __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 531, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            #endif
          } else {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_4);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 531, __pyx_L1_error)
              #endif
              if (__pyx_t_2 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_8); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 531, __pyx_L1_error)
            #else
            __pyx_t_8 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 531, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            #endif
          }
        } else {
          __pyx_t_8 = __pyx_t_9(__pyx_t_4);
          if (unlikely(!__pyx_t_8)) {
            PyObject* exc_type = PyErr_Occurred();
            if (exc_type) {
              if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
              else __PYX_ERR(0, 531, __pyx_L1_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_8);
        }
        __Pyx_XDECREF_SET(__pyx_v_table, __pyx_t_8);
        __pyx_t_8 = 0;

        /* "sQQideR/SQLBuilder.pyx":532
 *                 prompt += "\nRelevant Tables in Context:\n"
 *                 for table in tables:
 *                     prompt += f"- {table['name']}: {table.get('description', 'No description')}\n"             # <<<<<<<<<<<<<<
 * 
 *             # Add relationships information
 */
        __pyx_t_8 = PyTuple_New(5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __pyx_t_6 = 0;
        __pyx_t_3 = 127;
        __Pyx_INCREF(__pyx_kp_u__15);
        __pyx_t_6 += 2;
        __Pyx_GIVEREF(__pyx_kp_u__15);
        PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u__15);
        __pyx_t_13 = __Pyx_PyObject_Dict_GetItem(__pyx_v_table, __pyx_n_u_name); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
        __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_3;
        __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_1);
        PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_INCREF(__pyx_kp_u__13);
        __pyx_t_6 += 2;
        __Pyx_GIVEREF(__pyx_kp_u__13);
        PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u__13);
        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_table, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
        __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_3;
        __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_1);
        PyTuple_SET_ITEM(__pyx_t_8, 3, __pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_INCREF(__pyx_kp_u__14);
        __pyx_t_6 += 1;
        __Pyx_GIVEREF(__pyx_kp_u__14);
        PyTuple_SET_ITEM(__pyx_t_8, 4, __pyx_kp_u__14);
        __pyx_t_1 = __Pyx_PyUnicode_Join(__pyx_t_8, 5, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        __pyx_t_8 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 532, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_8));
        __pyx_t_8 = 0;

        /* "sQQideR/SQLBuilder.pyx":531
 *             if tables:
 *                 prompt += "\nRelevant Tables in Context:\n"
 *                 for table in tables:             # <<<<<<<<<<<<<<
 *                     prompt += f"- {table['name']}: {table.get('description', 'No description')}\n"
 * 
 */
      }
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

      /* "sQQideR/SQLBuilder.pyx":529
 *             # Add tables information
 *             tables = db_context.get("database_objects", {}).get("tables", [])
 *             if tables:             # <<<<<<<<<<<<<<
 *                 prompt += "\nRelevant Tables in Context:\n"
 *                 for table in tables:
 */
    }

    /* "sQQideR/SQLBuilder.pyx":535
 * 
 *             # Add relationships information
 *             relationships = db_context.get("relationships", [])             # <<<<<<<<<<<<<<
 *             if relationships:
 *                 prompt += "\nTable Relationships in Context:\n"
 */
    __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 535, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_8 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_relationships, __pyx_t_4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 535, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_relationships = __pyx_t_8;
    __pyx_t_8 = 0;

    /* "sQQideR/SQLBuilder.pyx":536
 *             # Add relationships information
 *             relationships = db_context.get("relationships", [])
 *             if relationships:             # <<<<<<<<<<<<<<
 *                 prompt += "\nTable Relationships in Context:\n"
 *                 for rel in relationships:
 */
    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_relationships); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 536, __pyx_L1_error)
    if (__pyx_t_5) {

      /* "sQQideR/SQLBuilder.pyx":537
 *             relationships = db_context.get("relationships", [])
 *             if relationships:
 *                 prompt += "\nTable Relationships in Context:\n"             # <<<<<<<<<<<<<<
 *                 for rel in relationships:
 *                     prompt += f"- {rel.get('source', '')} to {rel.get('target', '')}: {rel.get('join_condition', '')}\n"
 */
      __pyx_t_8 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_Table_Relationships_in_Context); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 537, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_8));
      __pyx_t_8 = 0;

      /* "sQQideR/SQLBuilder.pyx":538
 *             if relationships:
 *                 prompt += "\nTable Relationships in Context:\n"
 *                 for rel in relationships:             # <<<<<<<<<<<<<<
 *                     prompt += f"- {rel.get('source', '')} to {rel.get('target', '')}: {rel.get('join_condition', '')}\n"
 * 
 */
      if (likely(PyList_CheckExact(__pyx_v_relationships)) || PyTuple_CheckExact(__pyx_v_relationships)) {
        __pyx_t_8 = __pyx_v_relationships; __Pyx_INCREF(__pyx_t_8);
        __pyx_t_2 = 0;
        __pyx_t_9 = NULL;
      } else {
        __pyx_t_2 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_v_relationships); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 538, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 538, __pyx_L1_error)
      }
      for (;;) {
        if (likely(!__pyx_t_9)) {
          if (likely(PyList_CheckExact(__pyx_t_8))) {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_8);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 538, __pyx_L1_error)
              #endif
              if (__pyx_t_2 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_4 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 538, __pyx_L1_error)
            #else
            __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_8, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 538, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            #endif
          } else {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_8);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 538, __pyx_L1_error)
              #endif
              if (__pyx_t_2 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_2); __Pyx_INCREF(__pyx_t_4); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 538, __pyx_L1_error)
            #else
            __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_8, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 538, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_4);
            #endif
          }
        } else {
          __pyx_t_4 = __pyx_t_9(__pyx_t_8);
          if (unlikely(!__pyx_t_4)) {
            PyObject* exc_type = PyErr_Occurred();
            if (exc_type) {
              if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
              else __PYX_ERR(0, 538, __pyx_L1_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_4);
        }
        __Pyx_XDECREF_SET(__pyx_v_rel, __pyx_t_4);
        __pyx_t_4 = 0;

        /* "sQQideR/SQLBuilder.pyx":539
 *                 prompt += "\nTable Relationships in Context:\n"
 *                 for rel in relationships:
 *                     prompt += f"- {rel.get('source', '')} to {rel.get('target', '')}: {rel.get('join_condition', '')}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add information about previous attempts if any
 */
        __pyx_t_4 = PyTuple_New(7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __pyx_t_6 = 0;
        __pyx_t_3 = 127;
        __Pyx_INCREF(__pyx_kp_u__15);
        __pyx_t_6 += 2;
        __Pyx_GIVEREF(__pyx_kp_u__15);
        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_kp_u__15);
        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_rel, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
        __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_3;
        __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_1);
        PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_INCREF(__pyx_kp_u_to);
        __pyx_t_6 += 4;
        __Pyx_GIVEREF(__pyx_kp_u_to);
        PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_kp_u_to);
        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_rel, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
        __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_3;
        __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_1);
        PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_INCREF(__pyx_kp_u__13);
        __pyx_t_6 += 2;
        __Pyx_GIVEREF(__pyx_kp_u__13);
        PyTuple_SET_ITEM(__pyx_t_4, 4, __pyx_kp_u__13);
        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_rel, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
        __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_3;
        __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_1);
        PyTuple_SET_ITEM(__pyx_t_4, 5, __pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_INCREF(__pyx_kp_u__14);
        __pyx_t_6 += 1;
        __Pyx_GIVEREF(__pyx_kp_u__14);
        PyTuple_SET_ITEM(__pyx_t_4, 6, __pyx_kp_u__14);
        __pyx_t_1 = __Pyx_PyUnicode_Join(__pyx_t_4, 7, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
        __pyx_t_4 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 539, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_4));
        __pyx_t_4 = 0;

        /* "sQQideR/SQLBuilder.pyx":538
 *             if relationships:
 *                 prompt += "\nTable Relationships in Context:\n"
 *                 for rel in relationships:             # <<<<<<<<<<<<<<
 *                     prompt += f"- {rel.get('source', '')} to {rel.get('target', '')}: {rel.get('join_condition', '')}\n"
 * 
 */
      }
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

      /* "sQQideR/SQLBuilder.pyx":536
 *             # Add relationships information
 *             relationships = db_context.get("relationships", [])
 *             if relationships:             # <<<<<<<<<<<<<<
 *                 prompt += "\nTable Relationships in Context:\n"
 *                 for rel in relationships:
 */
    }

    /* "sQQideR/SQLBuilder.pyx":526
 * 
 *         # Add database context
 *         if db_context:             # <<<<<<<<<<<<<<
 *             # Add tables information
 *             tables = db_context.get("database_objects", {}).get("tables", [])
 */
  }

  /* "sQQideR/SQLBuilder.pyx":542
 * 
 *         # Add information about previous attempts if any
 *         if previous_attempts:             # <<<<<<<<<<<<<<
 *             prompt += "\nPREVIOUS CORRECTION ATTEMPTS:\n"
 *             for i, attempt in enumerate(previous_attempts):
 */
  __pyx_t_5 = (PyList_GET_SIZE(__pyx_v_previous_attempts) != 0);
  if (__pyx_t_5) {

    /* "sQQideR/SQLBuilder.pyx":543
 *         # Add information about previous attempts if any
 *         if previous_attempts:
 *             prompt += "\nPREVIOUS CORRECTION ATTEMPTS:\n"             # <<<<<<<<<<<<<<
 *             for i, attempt in enumerate(previous_attempts):
 *                 prompt += f"\nAttempt #{i+1}:\n"
 */
    __pyx_t_8 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_PREVIOUS_CORRECTION_ATTEMPTS); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 543, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_8));
    __pyx_t_8 = 0;

    /* "sQQideR/SQLBuilder.pyx":544
 *         if previous_attempts:
 *             prompt += "\nPREVIOUS CORRECTION ATTEMPTS:\n"
 *             for i, attempt in enumerate(previous_attempts):             # <<<<<<<<<<<<<<
 *                 prompt += f"\nAttempt #{i+1}:\n"
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"
 */
    __Pyx_INCREF(__pyx_int_0);
    __pyx_t_8 = __pyx_int_0;
    __pyx_t_4 = __pyx_v_previous_attempts; __Pyx_INCREF(__pyx_t_4);
    __pyx_t_2 = 0;
    for (;;) {
      {
        Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_4);
        #if !CYTHON_ASSUME_SAFE_MACROS
        if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 544, __pyx_L1_error)
        #endif
        if (__pyx_t_2 >= __pyx_temp) break;
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_2); __Pyx_INCREF(__pyx_t_1); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 544, __pyx_L1_error)
      #else
      __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_4, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 544, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      #endif
      __Pyx_XDECREF_SET(__pyx_v_attempt, __pyx_t_1);
      __pyx_t_1 = 0;
      __Pyx_INCREF(__pyx_t_8);
      __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_8);
      __pyx_t_1 = __Pyx_PyInt_AddObjC(__pyx_t_8, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 544, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_8);
      __pyx_t_8 = __pyx_t_1;
      __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":545
 *             prompt += "\nPREVIOUS CORRECTION ATTEMPTS:\n"
 *             for i, attempt in enumerate(previous_attempts):
 *                 prompt += f"\nAttempt #{i+1}:\n"             # <<<<<<<<<<<<<<
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"
 *                 if not attempt.get("success", False):
 */
      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 545, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_6 = 0;
      __pyx_t_3 = 127;
      __Pyx_INCREF(__pyx_kp_u_Attempt);
      __pyx_t_6 += 10;
      __Pyx_GIVEREF(__pyx_kp_u_Attempt);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Attempt);
      __pyx_t_13 = __Pyx_PyInt_AddObjC(__pyx_v_i, __pyx_int_1, 1, 0, 0); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 545, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __pyx_t_11 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 545, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) : __pyx_t_3;
      __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_11);
      __Pyx_GIVEREF(__pyx_t_11);
      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_11);
      __pyx_t_11 = 0;
      __Pyx_INCREF(__pyx_kp_u__23);
      __pyx_t_6 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__23);
      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__23);
      __pyx_t_11 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 545, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 545, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
      __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":546
 *             for i, attempt in enumerate(previous_attempts):
 *                 prompt += f"\nAttempt #{i+1}:\n"
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"             # <<<<<<<<<<<<<<
 *                 if not attempt.get("success", False):
 *                     prompt += f"Error: {attempt.get('execution_error', 'Unknown error')}\n"
 */
      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 546, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_6 = 0;
      __pyx_t_3 = 127;
      __Pyx_INCREF(__pyx_kp_u_SQL);
      __pyx_t_6 += 5;
      __Pyx_GIVEREF(__pyx_kp_u_SQL);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_SQL);
      __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_attempt, __pyx_n_s_get); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 546, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 546, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_13);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __pyx_t_11 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 546, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
      __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_11) : __pyx_t_3;
      __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_11);
      __Pyx_GIVEREF(__pyx_t_11);
      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_11);
      __pyx_t_11 = 0;
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_6 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__14);
      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__14);
      __pyx_t_11 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 546, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 546, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
      __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":547
 *                 prompt += f"\nAttempt #{i+1}:\n"
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"
 *                 if not attempt.get("success", False):             # <<<<<<<<<<<<<<
 *                     prompt += f"Error: {attempt.get('execution_error', 'Unknown error')}\n"
 * 
 */
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_attempt, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 547, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 547, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 547, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __pyx_t_12 = (!__pyx_t_5);
      if (__pyx_t_12) {

        /* "sQQideR/SQLBuilder.pyx":548
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"
 *                 if not attempt.get("success", False):
 *                     prompt += f"Error: {attempt.get('execution_error', 'Unknown error')}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add instructions for fixing the query
 */
        __pyx_t_11 = PyTuple_New(3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 548, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
        __pyx_t_6 = 0;
        __pyx_t_3 = 127;
        __Pyx_INCREF(__pyx_kp_u_Error);
        __pyx_t_6 += 7;
        __Pyx_GIVEREF(__pyx_kp_u_Error);
        PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_kp_u_Error);
        __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_attempt, __pyx_n_s_get); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 548, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 548, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_13);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_13, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 548, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
        __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_3;
        __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
        __Pyx_GIVEREF(__pyx_t_1);
        PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_1);
        __pyx_t_1 = 0;
        __Pyx_INCREF(__pyx_kp_u__14);
        __pyx_t_6 += 1;
        __Pyx_GIVEREF(__pyx_kp_u__14);
        PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_kp_u__14);
        __pyx_t_1 = __Pyx_PyUnicode_Join(__pyx_t_11, 3, __pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 548, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        __pyx_t_11 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 548, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_11);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_11));
        __pyx_t_11 = 0;

        /* "sQQideR/SQLBuilder.pyx":547
 *                 prompt += f"\nAttempt #{i+1}:\n"
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"
 *                 if not attempt.get("success", False):             # <<<<<<<<<<<<<<
 *                     prompt += f"Error: {attempt.get('execution_error', 'Unknown error')}\n"
 * 
 */
      }

      /* "sQQideR/SQLBuilder.pyx":544
 *         if previous_attempts:
 *             prompt += "\nPREVIOUS CORRECTION ATTEMPTS:\n"
 *             for i, attempt in enumerate(previous_attempts):             # <<<<<<<<<<<<<<
 *                 prompt += f"\nAttempt #{i+1}:\n"
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"
 */
    }
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

    /* "sQQideR/SQLBuilder.pyx":542
 * 
 *         # Add information about previous attempts if any
 *         if previous_attempts:             # <<<<<<<<<<<<<<
 *             prompt += "\nPREVIOUS CORRECTION ATTEMPTS:\n"
 *             for i, attempt in enumerate(previous_attempts):
 */
  }

  /* "sQQideR/SQLBuilder.pyx":551
 * 
 *         # Add instructions for fixing the query
 *         prompt += """             # <<<<<<<<<<<<<<
 * TASK:
 * 1. Analyze the error message and schema information carefully
 */
  __pyx_t_8 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_TASK_1_Analyze_the_error_messag); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 551, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_8));
  __pyx_t_8 = 0;

  /* "sQQideR/SQLBuilder.pyx":570
 * """
 * 
 *         return prompt             # <<<<<<<<<<<<<<
 * 
 *     def _explore_database_schema(self) -> List[Dict]:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_prompt);
  __pyx_r = __pyx_v_prompt;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":481
 *         return result
 * 
 *     def _create_sql_correction_prompt(self, question: str, original_sql: str, error: str,             # <<<<<<<<<<<<<<
 *                                       schema_info: List[Dict], previous_attempts: List[Dict],
 *                                       db_context: Dict) -> str:
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_XDECREF(__pyx_t_13);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._create_sql_correction_prompt", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_prompt);
  __Pyx_XDECREF(__pyx_v_info);
  __Pyx_XDECREF(__pyx_v_col);
  __Pyx_XDECREF(__pyx_v_tables);
  __Pyx_XDECREF(__pyx_v_table);
  __Pyx_XDECREF(__pyx_v_relationships);
  __Pyx_XDECREF(__pyx_v_rel);
  __Pyx_XDECREF(__pyx_v_i);
  __Pyx_XDECREF(__pyx_v_attempt);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":572
 *         return prompt
 * 
 *     def _explore_database_schema(self) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Explore the database schema to gather information for SQL correction.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_19_explore_database_schema(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_18_explore_database_schema, "\n        Explore the database schema to gather information for SQL correction.\n        \n        Returns:\n            List of dictionaries with schema information\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_19_explore_database_schema = {"_explore_database_schema", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_19_explore_database_schema, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_18_explore_database_schema};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_19_explore_database_schema(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[1] = {0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_explore_database_schema (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 572, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_explore_database_schema") < 0)) __PYX_ERR(0, 572, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 1)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
    }
    __pyx_v_self = values[0];
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_explore_database_schema", 1, 1, 1, __pyx_nargs); __PYX_ERR(0, 572, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._explore_database_schema", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_18_explore_database_schema(__pyx_self, __pyx_v_self);

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_18_explore_database_schema(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
  PyObject *__pyx_v_schema_info = NULL;
  PyObject *__pyx_v_tables_query = NULL;
  PyObject *__pyx_v_tables_df = NULL;
  PyObject *__pyx_v_table_name = NULL;
  PyObject *__pyx_v_table_info = NULL;
  PyObject *__pyx_v_e = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  int __pyx_t_2;
  int __pyx_t_3;
  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;
  unsigned int __pyx_t_10;
  int __pyx_t_11;
  Py_ssize_t __pyx_t_12;
  PyObject *(*__pyx_t_13)(PyObject *);
  int __pyx_t_14;
  PyObject *__pyx_t_15 = NULL;
  int __pyx_t_16;
  char const *__pyx_t_17;
  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;
  PyObject *__pyx_t_23 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_explore_database_schema", 1);

  /* "sQQideR/SQLBuilder.pyx":579
 *             List of dictionaries with schema information
 *         """
 *         if not self.conn:             # <<<<<<<<<<<<<<
 *             return []
 * 
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 579, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 579, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = (!__pyx_t_2);
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":580
 *         """
 *         if not self.conn:
 *             return []             # <<<<<<<<<<<<<<
 * 
 *         schema_info = []
 */
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 580, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_r = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":579
 *             List of dictionaries with schema information
 *         """
 *         if not self.conn:             # <<<<<<<<<<<<<<
 *             return []
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":582
 *             return []
 * 
 *         schema_info = []             # <<<<<<<<<<<<<<
 * 
 *         try:
 */
  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 582, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_v_schema_info = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":584
 *         schema_info = []
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Get list of all tables
 *             tables_query = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"
 */
  {
    __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:*/ {

      /* "sQQideR/SQLBuilder.pyx":586
 *         try:
 *             # Get list of all tables
 *             tables_query = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"             # <<<<<<<<<<<<<<
 *             tables_df = pd.read_sql_query(tables_query, self.conn)
 * 
 */
      __Pyx_INCREF(__pyx_kp_u_SELECT_name_FROM_sqlite_master_W);
      __pyx_v_tables_query = __pyx_kp_u_SELECT_name_FROM_sqlite_master_W;

      /* "sQQideR/SQLBuilder.pyx":587
 *             # Get list of all tables
 *             tables_query = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"
 *             tables_df = pd.read_sql_query(tables_query, self.conn)             # <<<<<<<<<<<<<<
 * 
 *             # Add the query and result to schema info
 */
      __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_pd); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 587, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_7);
      __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_read_sql_query); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 587, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 587, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_7);
      __pyx_t_9 = NULL;
      __pyx_t_10 = 0;
      #if CYTHON_UNPACK_METHODS
      if (unlikely(PyMethod_Check(__pyx_t_8))) {
        __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8);
        if (likely(__pyx_t_9)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
          __Pyx_INCREF(__pyx_t_9);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_8, function);
          __pyx_t_10 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[3] = {__pyx_t_9, __pyx_v_tables_query, __pyx_t_7};
        __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_8, __pyx_callargs+1-__pyx_t_10, 2+__pyx_t_10);
        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 587, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      }
      __pyx_v_tables_df = __pyx_t_1;
      __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":591
 *             # Add the query and result to schema info
 *             schema_info.append({
 *                 "sql": tables_query,             # <<<<<<<<<<<<<<
 *                 "result": tables_df.to_dict(orient="records")
 *             })
 */
      __pyx_t_1 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 591, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_sql, __pyx_v_tables_query) < 0) __PYX_ERR(0, 591, __pyx_L4_error)

      /* "sQQideR/SQLBuilder.pyx":592
 *             schema_info.append({
 *                 "sql": tables_query,
 *                 "result": tables_df.to_dict(orient="records")             # <<<<<<<<<<<<<<
 *             })
 * 
 */
      __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_tables_df, __pyx_n_s_to_dict); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 592, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_8);
      __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 592, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_7);
      if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_orient, __pyx_n_u_records) < 0) __PYX_ERR(0, 592, __pyx_L4_error)
      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_empty_tuple, __pyx_t_7); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 592, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_result, __pyx_t_9) < 0) __PYX_ERR(0, 591, __pyx_L4_error)
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;

      /* "sQQideR/SQLBuilder.pyx":590
 * 
 *             # Add the query and result to schema info
 *             schema_info.append({             # <<<<<<<<<<<<<<
 *                 "sql": tables_query,
 *                 "result": tables_df.to_dict(orient="records")
 */
      __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_schema_info, __pyx_t_1); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 590, __pyx_L4_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":596
 * 
 *             # For each table, get its schema and sample data (limited to 5 tables to avoid huge prompts)
 *             for table_name in tables_df['name'].head(5):             # <<<<<<<<<<<<<<
 *                 table_info = self._explore_table_schema(table_name)
 *                 if table_info:
 */
      __pyx_t_9 = __Pyx_PyObject_Dict_GetItem(__pyx_v_tables_df, __pyx_n_u_name); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 596, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_9);
      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_head); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 596, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __pyx_t_9 = NULL;
      __pyx_t_10 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_7))) {
        __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_7);
        if (likely(__pyx_t_9)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
          __Pyx_INCREF(__pyx_t_9);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_7, function);
          __pyx_t_10 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_int_5};
        __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_7, __pyx_callargs+1-__pyx_t_10, 1+__pyx_t_10);
        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
        if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 596, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      }
      if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
        __pyx_t_7 = __pyx_t_1; __Pyx_INCREF(__pyx_t_7);
        __pyx_t_12 = 0;
        __pyx_t_13 = NULL;
      } else {
        __pyx_t_12 = -1; __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 596, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_7);
        __pyx_t_13 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 596, __pyx_L4_error)
      }
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      for (;;) {
        if (likely(!__pyx_t_13)) {
          if (likely(PyList_CheckExact(__pyx_t_7))) {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_7);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 596, __pyx_L4_error)
              #endif
              if (__pyx_t_12 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_1 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely((0 < 0))) __PYX_ERR(0, 596, __pyx_L4_error)
            #else
            __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_7, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 596, __pyx_L4_error)
            __Pyx_GOTREF(__pyx_t_1);
            #endif
          } else {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_7);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 596, __pyx_L4_error)
              #endif
              if (__pyx_t_12 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_7, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely((0 < 0))) __PYX_ERR(0, 596, __pyx_L4_error)
            #else
            __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_7, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 596, __pyx_L4_error)
            __Pyx_GOTREF(__pyx_t_1);
            #endif
          }
        } else {
          __pyx_t_1 = __pyx_t_13(__pyx_t_7);
          if (unlikely(!__pyx_t_1)) {
            PyObject* exc_type = PyErr_Occurred();
            if (exc_type) {
              if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
              else __PYX_ERR(0, 596, __pyx_L4_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_1);
        }
        __Pyx_XDECREF_SET(__pyx_v_table_name, __pyx_t_1);
        __pyx_t_1 = 0;

        /* "sQQideR/SQLBuilder.pyx":597
 *             # For each table, get its schema and sample data (limited to 5 tables to avoid huge prompts)
 *             for table_name in tables_df['name'].head(5):
 *                 table_info = self._explore_table_schema(table_name)             # <<<<<<<<<<<<<<
 *                 if table_info:
 *                     schema_info.append(table_info)
 */
        __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_explore_table_schema); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 597, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_9);
        __pyx_t_8 = NULL;
        __pyx_t_10 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_9))) {
          __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_9);
          if (likely(__pyx_t_8)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
            __Pyx_INCREF(__pyx_t_8);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_9, function);
            __pyx_t_10 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_8, __pyx_v_table_name};
          __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_9, __pyx_callargs+1-__pyx_t_10, 1+__pyx_t_10);
          __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
          if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 597, __pyx_L4_error)
          __Pyx_GOTREF(__pyx_t_1);
          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
        }
        __Pyx_XDECREF_SET(__pyx_v_table_info, __pyx_t_1);
        __pyx_t_1 = 0;

        /* "sQQideR/SQLBuilder.pyx":598
 *             for table_name in tables_df['name'].head(5):
 *                 table_info = self._explore_table_schema(table_name)
 *                 if table_info:             # <<<<<<<<<<<<<<
 *                     schema_info.append(table_info)
 * 
 */
        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_table_info); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 598, __pyx_L4_error)
        if (__pyx_t_3) {

          /* "sQQideR/SQLBuilder.pyx":599
 *                 table_info = self._explore_table_schema(table_name)
 *                 if table_info:
 *                     schema_info.append(table_info)             # <<<<<<<<<<<<<<
 * 
 *         except Exception as e:
 */
          __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_schema_info, __pyx_v_table_info); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 599, __pyx_L4_error)

          /* "sQQideR/SQLBuilder.pyx":598
 *             for table_name in tables_df['name'].head(5):
 *                 table_info = self._explore_table_schema(table_name)
 *                 if table_info:             # <<<<<<<<<<<<<<
 *                     schema_info.append(table_info)
 * 
 */
        }

        /* "sQQideR/SQLBuilder.pyx":596
 * 
 *             # For each table, get its schema and sample data (limited to 5 tables to avoid huge prompts)
 *             for table_name in tables_df['name'].head(5):             # <<<<<<<<<<<<<<
 *                 table_info = self._explore_table_schema(table_name)
 *                 if table_info:
 */
      }
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;

      /* "sQQideR/SQLBuilder.pyx":584
 *         schema_info = []
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Get list of all tables
 *             tables_query = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"
 */
    }
    __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;
    goto __pyx_L9_try_end;
    __pyx_L4_error:;
    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;

    /* "sQQideR/SQLBuilder.pyx":601
 *                     schema_info.append(table_info)
 * 
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error exploring database schema: {e}")
 */
    __pyx_t_14 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
    if (__pyx_t_14) {
      __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._explore_database_schema", __pyx_clineno, __pyx_lineno, __pyx_filename);
      if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_1, &__pyx_t_9) < 0) __PYX_ERR(0, 601, __pyx_L6_except_error)
      __Pyx_XGOTREF(__pyx_t_7);
      __Pyx_XGOTREF(__pyx_t_1);
      __Pyx_XGOTREF(__pyx_t_9);
      __Pyx_INCREF(__pyx_t_1);
      __pyx_v_e = __pyx_t_1;
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":602
 * 
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error exploring database schema: {e}")
 * 
 */
        __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 602, __pyx_L19_error)
        __Pyx_GOTREF(__pyx_t_8);
        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 602, __pyx_L19_error)
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        if (__pyx_t_3) {

          /* "sQQideR/SQLBuilder.pyx":603
 *         except Exception as e:
 *             if self.verbose:
 *                 print(f"Error exploring database schema: {e}")             # <<<<<<<<<<<<<<
 * 
 *         return schema_info
 */
          __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 603, __pyx_L19_error)
          __Pyx_GOTREF(__pyx_t_8);
          __pyx_t_15 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_exploring_database_schema, __pyx_t_8); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 603, __pyx_L19_error)
          __Pyx_GOTREF(__pyx_t_15);
          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
          __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_15); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 603, __pyx_L19_error)
          __Pyx_GOTREF(__pyx_t_8);
          __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

          /* "sQQideR/SQLBuilder.pyx":602
 * 
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error exploring database schema: {e}")
 * 
 */
        }
      }

      /* "sQQideR/SQLBuilder.pyx":601
 *                     schema_info.append(table_info)
 * 
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error exploring database schema: {e}")
 */
      /*finally:*/ {
        /*normal exit:*/{
          __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          goto __pyx_L20;
        }
        __pyx_L19_error:;
        /*exception exit:*/{
          __Pyx_PyThreadState_declare
          __Pyx_PyThreadState_assign
          __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0;
          __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
          __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
          if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_21, &__pyx_t_22, &__pyx_t_23);
          if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20) < 0)) __Pyx_ErrFetch(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20);
          __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_XGOTREF(__pyx_t_23);
          __pyx_t_14 = __pyx_lineno; __pyx_t_16 = __pyx_clineno; __pyx_t_17 = __pyx_filename;
          {
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          }
          if (PY_MAJOR_VERSION >= 3) {
            __Pyx_XGIVEREF(__pyx_t_21);
            __Pyx_XGIVEREF(__pyx_t_22);
            __Pyx_XGIVEREF(__pyx_t_23);
            __Pyx_ExceptionReset(__pyx_t_21, __pyx_t_22, __pyx_t_23);
          }
          __Pyx_XGIVEREF(__pyx_t_18);
          __Pyx_XGIVEREF(__pyx_t_19);
          __Pyx_XGIVEREF(__pyx_t_20);
          __Pyx_ErrRestore(__pyx_t_18, __pyx_t_19, __pyx_t_20);
          __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0;
          __pyx_lineno = __pyx_t_14; __pyx_clineno = __pyx_t_16; __pyx_filename = __pyx_t_17;
          goto __pyx_L6_except_error;
        }
        __pyx_L20:;
      }
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      goto __pyx_L5_exception_handled;
    }
    goto __pyx_L6_except_error;

    /* "sQQideR/SQLBuilder.pyx":584
 *         schema_info = []
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Get list of all tables
 *             tables_query = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';"
 */
    __pyx_L6_except_error:;
    __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_L5_exception_handled:;
    __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);
    __pyx_L9_try_end:;
  }

  /* "sQQideR/SQLBuilder.pyx":605
 *                 print(f"Error exploring database schema: {e}")
 * 
 *         return schema_info             # <<<<<<<<<<<<<<
 * 
 *     def _explore_table_schema(self, table_name: str) -> Dict:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_schema_info);
  __pyx_r = __pyx_v_schema_info;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":572
 *         return prompt
 * 
 *     def _explore_database_schema(self) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Explore the database schema to gather information for SQL correction.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_15);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._explore_database_schema", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_schema_info);
  __Pyx_XDECREF(__pyx_v_tables_query);
  __Pyx_XDECREF(__pyx_v_tables_df);
  __Pyx_XDECREF(__pyx_v_table_name);
  __Pyx_XDECREF(__pyx_v_table_info);
  __Pyx_XDECREF(__pyx_v_e);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":607
 *         return schema_info
 * 
 *     def _explore_table_schema(self, table_name: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Explore a specific table's schema and sample data.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_21_explore_table_schema(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_20_explore_table_schema, "\n        Explore a specific table's schema and sample data.\n        \n        Args:\n            table_name: Name of the table to explore\n            \n        Returns:\n            Dictionary with table schema information\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_21_explore_table_schema = {"_explore_table_schema", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_21_explore_table_schema, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_20_explore_table_schema};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_21_explore_table_schema(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_table_name = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_explore_table_schema (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_table_name,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 607, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_table_name)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 607, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_explore_table_schema", 1, 2, 2, 1); __PYX_ERR(0, 607, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_explore_table_schema") < 0)) __PYX_ERR(0, 607, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_table_name = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_explore_table_schema", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 607, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._explore_table_schema", __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), 0, "table_name", 1))) __PYX_ERR(0, 607, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_20_explore_table_schema(__pyx_self, __pyx_v_self, __pyx_v_table_name);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_20_explore_table_schema(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_table_name) {
  PyObject *__pyx_v_pragma_query = NULL;
  PyObject *__pyx_v_columns_df = NULL;
  PyObject *__pyx_v_sample_query = NULL;
  PyObject *__pyx_v_sample_df = NULL;
  PyObject *__pyx_v_sample_data = NULL;
  PyObject *__pyx_v_columns = NULL;
  CYTHON_UNUSED PyObject *__pyx_v__ = NULL;
  PyObject *__pyx_v_row = NULL;
  PyObject *__pyx_v_e = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  int __pyx_t_2;
  int __pyx_t_3;
  PyObject *__pyx_t_4 = NULL;
  PyObject *__pyx_t_5 = NULL;
  PyObject *__pyx_t_6 = NULL;
  Py_ssize_t __pyx_t_7;
  Py_UCS4 __pyx_t_8;
  PyObject *__pyx_t_9 = NULL;
  PyObject *__pyx_t_10 = NULL;
  PyObject *__pyx_t_11 = NULL;
  unsigned int __pyx_t_12;
  PyObject *__pyx_t_13 = NULL;
  PyObject *__pyx_t_14 = NULL;
  PyObject *__pyx_t_15 = NULL;
  int __pyx_t_16;
  PyObject *(*__pyx_t_17)(PyObject *);
  PyObject *__pyx_t_18 = NULL;
  PyObject *(*__pyx_t_19)(PyObject *);
  int __pyx_t_20;
  int __pyx_t_21;
  char const *__pyx_t_22;
  PyObject *__pyx_t_23 = NULL;
  PyObject *__pyx_t_24 = NULL;
  PyObject *__pyx_t_25 = NULL;
  PyObject *__pyx_t_26 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_explore_table_schema", 1);

  /* "sQQideR/SQLBuilder.pyx":617
 *             Dictionary with table schema information
 *         """
 *         if not self.conn:             # <<<<<<<<<<<<<<
 *             return {}
 * 
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 617, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 617, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = (!__pyx_t_2);
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":618
 *         """
 *         if not self.conn:
 *             return {}             # <<<<<<<<<<<<<<
 * 
 *         try:
 */
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 618, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_r = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":617
 *             Dictionary with table schema information
 *         """
 *         if not self.conn:             # <<<<<<<<<<<<<<
 *             return {}
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":620
 *             return {}
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Get table schema
 *             pragma_query = f"PRAGMA table_info({table_name});"
 */
  {
    __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:*/ {

      /* "sQQideR/SQLBuilder.pyx":622
 *         try:
 *             # Get table schema
 *             pragma_query = f"PRAGMA table_info({table_name});"             # <<<<<<<<<<<<<<
 *             columns_df = pd.read_sql_query(pragma_query, self.conn)
 * 
 */
      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 622, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_7 = 0;
      __pyx_t_8 = 127;
      __Pyx_INCREF(__pyx_kp_u_PRAGMA_table_info);
      __pyx_t_7 += 18;
      __Pyx_GIVEREF(__pyx_kp_u_PRAGMA_table_info);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_PRAGMA_table_info);
      __Pyx_INCREF(__pyx_v_table_name);
      __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_table_name) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_table_name) : __pyx_t_8;
      __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_table_name);
      __Pyx_GIVEREF(__pyx_v_table_name);
      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_table_name);
      __Pyx_INCREF(__pyx_kp_u__26);
      __pyx_t_7 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__26);
      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__26);
      __pyx_t_9 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 622, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_v_pragma_query = ((PyObject*)__pyx_t_9);
      __pyx_t_9 = 0;

      /* "sQQideR/SQLBuilder.pyx":623
 *             # Get table schema
 *             pragma_query = f"PRAGMA table_info({table_name});"
 *             columns_df = pd.read_sql_query(pragma_query, self.conn)             # <<<<<<<<<<<<<<
 * 
 *             # Get sample data (first 3 rows)
 */
      __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pd); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 623, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_read_sql_query); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 623, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 623, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_11 = NULL;
      __pyx_t_12 = 0;
      #if CYTHON_UNPACK_METHODS
      if (unlikely(PyMethod_Check(__pyx_t_10))) {
        __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_10);
        if (likely(__pyx_t_11)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
          __Pyx_INCREF(__pyx_t_11);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_10, function);
          __pyx_t_12 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[3] = {__pyx_t_11, __pyx_v_pragma_query, __pyx_t_1};
        __pyx_t_9 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_12, 2+__pyx_t_12);
        __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 623, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_9);
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      }
      __pyx_v_columns_df = __pyx_t_9;
      __pyx_t_9 = 0;

      /* "sQQideR/SQLBuilder.pyx":626
 * 
 *             # Get sample data (first 3 rows)
 *             sample_query = f"SELECT * FROM {table_name} LIMIT 3;"             # <<<<<<<<<<<<<<
 *             try:
 *                 sample_df = pd.read_sql_query(sample_query, self.conn)
 */
      __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 626, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_9);
      __pyx_t_7 = 0;
      __pyx_t_8 = 127;
      __Pyx_INCREF(__pyx_kp_u_SELECT_FROM);
      __pyx_t_7 += 14;
      __Pyx_GIVEREF(__pyx_kp_u_SELECT_FROM);
      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_SELECT_FROM);
      __Pyx_INCREF(__pyx_v_table_name);
      __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_table_name) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_table_name) : __pyx_t_8;
      __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_table_name);
      __Pyx_GIVEREF(__pyx_v_table_name);
      PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_table_name);
      __Pyx_INCREF(__pyx_kp_u_LIMIT_3);
      __pyx_t_7 += 9;
      __Pyx_GIVEREF(__pyx_kp_u_LIMIT_3);
      PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u_LIMIT_3);
      __pyx_t_10 = __Pyx_PyUnicode_Join(__pyx_t_9, 3, __pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 626, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __pyx_v_sample_query = ((PyObject*)__pyx_t_10);
      __pyx_t_10 = 0;

      /* "sQQideR/SQLBuilder.pyx":627
 *             # Get sample data (first 3 rows)
 *             sample_query = f"SELECT * FROM {table_name} LIMIT 3;"
 *             try:             # <<<<<<<<<<<<<<
 *                 sample_df = pd.read_sql_query(sample_query, self.conn)
 *                 sample_data = sample_df.to_dict(orient="records")
 */
      {
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        __Pyx_ExceptionSave(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15);
        __Pyx_XGOTREF(__pyx_t_13);
        __Pyx_XGOTREF(__pyx_t_14);
        __Pyx_XGOTREF(__pyx_t_15);
        /*try:*/ {

          /* "sQQideR/SQLBuilder.pyx":628
 *             sample_query = f"SELECT * FROM {table_name} LIMIT 3;"
 *             try:
 *                 sample_df = pd.read_sql_query(sample_query, self.conn)             # <<<<<<<<<<<<<<
 *                 sample_data = sample_df.to_dict(orient="records")
 *             except Exception:
 */
          __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_pd); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 628, __pyx_L10_error)
          __Pyx_GOTREF(__pyx_t_9);
          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_read_sql_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L10_error)
          __Pyx_GOTREF(__pyx_t_1);
          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
          __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 628, __pyx_L10_error)
          __Pyx_GOTREF(__pyx_t_9);
          __pyx_t_11 = NULL;
          __pyx_t_12 = 0;
          #if CYTHON_UNPACK_METHODS
          if (unlikely(PyMethod_Check(__pyx_t_1))) {
            __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_1);
            if (likely(__pyx_t_11)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
              __Pyx_INCREF(__pyx_t_11);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_1, function);
              __pyx_t_12 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[3] = {__pyx_t_11, __pyx_v_sample_query, __pyx_t_9};
            __pyx_t_10 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_12, 2+__pyx_t_12);
            __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
            __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
            if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 628, __pyx_L10_error)
            __Pyx_GOTREF(__pyx_t_10);
            __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          }
          __pyx_v_sample_df = __pyx_t_10;
          __pyx_t_10 = 0;

          /* "sQQideR/SQLBuilder.pyx":629
 *             try:
 *                 sample_df = pd.read_sql_query(sample_query, self.conn)
 *                 sample_data = sample_df.to_dict(orient="records")             # <<<<<<<<<<<<<<
 *             except Exception:
 *                 # Table might exist but query could still fail
 */
          __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample_df, __pyx_n_s_to_dict); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 629, __pyx_L10_error)
          __Pyx_GOTREF(__pyx_t_10);
          __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 629, __pyx_L10_error)
          __Pyx_GOTREF(__pyx_t_1);
          if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_orient, __pyx_n_u_records) < 0) __PYX_ERR(0, 629, __pyx_L10_error)
          __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 629, __pyx_L10_error)
          __Pyx_GOTREF(__pyx_t_9);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
          __pyx_v_sample_data = __pyx_t_9;
          __pyx_t_9 = 0;

          /* "sQQideR/SQLBuilder.pyx":627
 *             # Get sample data (first 3 rows)
 *             sample_query = f"SELECT * FROM {table_name} LIMIT 3;"
 *             try:             # <<<<<<<<<<<<<<
 *                 sample_df = pd.read_sql_query(sample_query, self.conn)
 *                 sample_data = sample_df.to_dict(orient="records")
 */
        }
        __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
        __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
        __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
        goto __pyx_L15_try_end;
        __pyx_L10_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_9); __pyx_t_9 = 0;

        /* "sQQideR/SQLBuilder.pyx":630
 *                 sample_df = pd.read_sql_query(sample_query, self.conn)
 *                 sample_data = sample_df.to_dict(orient="records")
 *             except Exception:             # <<<<<<<<<<<<<<
 *                 # Table might exist but query could still fail
 *                 sample_data = []
 */
        __pyx_t_16 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
        if (__pyx_t_16) {
          __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._explore_table_schema", __pyx_clineno, __pyx_lineno, __pyx_filename);
          if (__Pyx_GetException(&__pyx_t_9, &__pyx_t_1, &__pyx_t_10) < 0) __PYX_ERR(0, 630, __pyx_L12_except_error)
          __Pyx_XGOTREF(__pyx_t_9);
          __Pyx_XGOTREF(__pyx_t_1);
          __Pyx_XGOTREF(__pyx_t_10);

          /* "sQQideR/SQLBuilder.pyx":632
 *             except Exception:
 *                 # Table might exist but query could still fail
 *                 sample_data = []             # <<<<<<<<<<<<<<
 * 
 *             # Format column information
 */
          __pyx_t_11 = PyList_New(0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 632, __pyx_L12_except_error)
          __Pyx_GOTREF(__pyx_t_11);
          __Pyx_XDECREF_SET(__pyx_v_sample_data, __pyx_t_11);
          __pyx_t_11 = 0;
          __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
          __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
          __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
          goto __pyx_L11_exception_handled;
        }
        goto __pyx_L12_except_error;

        /* "sQQideR/SQLBuilder.pyx":627
 *             # Get sample data (first 3 rows)
 *             sample_query = f"SELECT * FROM {table_name} LIMIT 3;"
 *             try:             # <<<<<<<<<<<<<<
 *                 sample_df = pd.read_sql_query(sample_query, self.conn)
 *                 sample_data = sample_df.to_dict(orient="records")
 */
        __pyx_L12_except_error:;
        __Pyx_XGIVEREF(__pyx_t_13);
        __Pyx_XGIVEREF(__pyx_t_14);
        __Pyx_XGIVEREF(__pyx_t_15);
        __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15);
        goto __pyx_L4_error;
        __pyx_L11_exception_handled:;
        __Pyx_XGIVEREF(__pyx_t_13);
        __Pyx_XGIVEREF(__pyx_t_14);
        __Pyx_XGIVEREF(__pyx_t_15);
        __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15);
        __pyx_L15_try_end:;
      }

      /* "sQQideR/SQLBuilder.pyx":635
 * 
 *             # Format column information
 *             columns = []             # <<<<<<<<<<<<<<
 *             for _, row in columns_df.iterrows():
 *                 columns.append({
 */
      __pyx_t_10 = PyList_New(0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 635, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_v_columns = ((PyObject*)__pyx_t_10);
      __pyx_t_10 = 0;

      /* "sQQideR/SQLBuilder.pyx":636
 *             # Format column information
 *             columns = []
 *             for _, row in columns_df.iterrows():             # <<<<<<<<<<<<<<
 *                 columns.append({
 *                     "name": row["name"],
 */
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_columns_df, __pyx_n_s_iterrows); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 636, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_9 = NULL;
      __pyx_t_12 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_1))) {
        __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_1);
        if (likely(__pyx_t_9)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
          __Pyx_INCREF(__pyx_t_9);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_1, function);
          __pyx_t_12 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_9, NULL};
        __pyx_t_10 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_12, 0+__pyx_t_12);
        __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 636, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_10);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      }
      if (likely(PyList_CheckExact(__pyx_t_10)) || PyTuple_CheckExact(__pyx_t_10)) {
        __pyx_t_1 = __pyx_t_10; __Pyx_INCREF(__pyx_t_1);
        __pyx_t_7 = 0;
        __pyx_t_17 = NULL;
      } else {
        __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 636, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_17 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 636, __pyx_L4_error)
      }
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      for (;;) {
        if (likely(!__pyx_t_17)) {
          if (likely(PyList_CheckExact(__pyx_t_1))) {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 636, __pyx_L4_error)
              #endif
              if (__pyx_t_7 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_10 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_10); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 636, __pyx_L4_error)
            #else
            __pyx_t_10 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 636, __pyx_L4_error)
            __Pyx_GOTREF(__pyx_t_10);
            #endif
          } else {
            {
              Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
              #if !CYTHON_ASSUME_SAFE_MACROS
              if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 636, __pyx_L4_error)
              #endif
              if (__pyx_t_7 >= __pyx_temp) break;
            }
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_10); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 636, __pyx_L4_error)
            #else
            __pyx_t_10 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 636, __pyx_L4_error)
            __Pyx_GOTREF(__pyx_t_10);
            #endif
          }
        } else {
          __pyx_t_10 = __pyx_t_17(__pyx_t_1);
          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(0, 636, __pyx_L4_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_10);
        }
        if ((likely(PyTuple_CheckExact(__pyx_t_10))) || (PyList_CheckExact(__pyx_t_10))) {
          PyObject* sequence = __pyx_t_10;
          Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
          if (unlikely(size != 2)) {
            if (size > 2) __Pyx_RaiseTooManyValuesError(2);
            else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
            __PYX_ERR(0, 636, __pyx_L4_error)
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          if (likely(PyTuple_CheckExact(sequence))) {
            __pyx_t_9 = PyTuple_GET_ITEM(sequence, 0); 
            __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); 
          } else {
            __pyx_t_9 = PyList_GET_ITEM(sequence, 0); 
            __pyx_t_11 = PyList_GET_ITEM(sequence, 1); 
          }
          __Pyx_INCREF(__pyx_t_9);
          __Pyx_INCREF(__pyx_t_11);
          #else
          __pyx_t_9 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 636, __pyx_L4_error)
          __Pyx_GOTREF(__pyx_t_9);
          __pyx_t_11 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 636, __pyx_L4_error)
          __Pyx_GOTREF(__pyx_t_11);
          #endif
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        } else {
          Py_ssize_t index = -1;
          __pyx_t_18 = PyObject_GetIter(__pyx_t_10); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 636, __pyx_L4_error)
          __Pyx_GOTREF(__pyx_t_18);
          __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
          __pyx_t_19 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_18);
          index = 0; __pyx_t_9 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_9)) goto __pyx_L20_unpacking_failed;
          __Pyx_GOTREF(__pyx_t_9);
          index = 1; __pyx_t_11 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_11)) goto __pyx_L20_unpacking_failed;
          __Pyx_GOTREF(__pyx_t_11);
          if (__Pyx_IternextUnpackEndCheck(__pyx_t_19(__pyx_t_18), 2) < 0) __PYX_ERR(0, 636, __pyx_L4_error)
          __pyx_t_19 = NULL;
          __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
          goto __pyx_L21_unpacking_done;
          __pyx_L20_unpacking_failed:;
          __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
          __pyx_t_19 = NULL;
          if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
          __PYX_ERR(0, 636, __pyx_L4_error)
          __pyx_L21_unpacking_done:;
        }
        __Pyx_XDECREF_SET(__pyx_v__, __pyx_t_9);
        __pyx_t_9 = 0;
        __Pyx_XDECREF_SET(__pyx_v_row, __pyx_t_11);
        __pyx_t_11 = 0;

        /* "sQQideR/SQLBuilder.pyx":638
 *             for _, row in columns_df.iterrows():
 *                 columns.append({
 *                     "name": row["name"],             # <<<<<<<<<<<<<<
 *                     "type": row["type"],
 *                     "notnull": bool(row["notnull"]),
 */
        __pyx_t_10 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 638, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_10);
        __pyx_t_11 = __Pyx_PyObject_Dict_GetItem(__pyx_v_row, __pyx_n_u_name); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 638, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_11);
        if (PyDict_SetItem(__pyx_t_10, __pyx_n_u_name, __pyx_t_11) < 0) __PYX_ERR(0, 638, __pyx_L4_error)
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;

        /* "sQQideR/SQLBuilder.pyx":639
 *                 columns.append({
 *                     "name": row["name"],
 *                     "type": row["type"],             # <<<<<<<<<<<<<<
 *                     "notnull": bool(row["notnull"]),
 *                     "pk": bool(row["pk"])
 */
        __pyx_t_11 = __Pyx_PyObject_Dict_GetItem(__pyx_v_row, __pyx_n_u_type); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 639, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_11);
        if (PyDict_SetItem(__pyx_t_10, __pyx_n_u_type, __pyx_t_11) < 0) __PYX_ERR(0, 638, __pyx_L4_error)
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;

        /* "sQQideR/SQLBuilder.pyx":640
 *                     "name": row["name"],
 *                     "type": row["type"],
 *                     "notnull": bool(row["notnull"]),             # <<<<<<<<<<<<<<
 *                     "pk": bool(row["pk"])
 *                 })
 */
        __pyx_t_11 = __Pyx_PyObject_Dict_GetItem(__pyx_v_row, __pyx_n_u_notnull); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 640, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_11);
        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 640, __pyx_L4_error)
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        __pyx_t_11 = __Pyx_PyBool_FromLong((!(!__pyx_t_3))); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 640, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_11);
        if (PyDict_SetItem(__pyx_t_10, __pyx_n_u_notnull, __pyx_t_11) < 0) __PYX_ERR(0, 638, __pyx_L4_error)
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;

        /* "sQQideR/SQLBuilder.pyx":641
 *                     "type": row["type"],
 *                     "notnull": bool(row["notnull"]),
 *                     "pk": bool(row["pk"])             # <<<<<<<<<<<<<<
 *                 })
 * 
 */
        __pyx_t_11 = __Pyx_PyObject_Dict_GetItem(__pyx_v_row, __pyx_n_u_pk); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 641, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_11);
        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 641, __pyx_L4_error)
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        __pyx_t_11 = __Pyx_PyBool_FromLong((!(!__pyx_t_3))); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 641, __pyx_L4_error)
        __Pyx_GOTREF(__pyx_t_11);
        if (PyDict_SetItem(__pyx_t_10, __pyx_n_u_pk, __pyx_t_11) < 0) __PYX_ERR(0, 638, __pyx_L4_error)
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;

        /* "sQQideR/SQLBuilder.pyx":637
 *             columns = []
 *             for _, row in columns_df.iterrows():
 *                 columns.append({             # <<<<<<<<<<<<<<
 *                     "name": row["name"],
 *                     "type": row["type"],
 */
        __pyx_t_20 = __Pyx_PyList_Append(__pyx_v_columns, __pyx_t_10); if (unlikely(__pyx_t_20 == ((int)-1))) __PYX_ERR(0, 637, __pyx_L4_error)
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;

        /* "sQQideR/SQLBuilder.pyx":636
 *             # Format column information
 *             columns = []
 *             for _, row in columns_df.iterrows():             # <<<<<<<<<<<<<<
 *                 columns.append({
 *                     "name": row["name"],
 */
      }
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

      /* "sQQideR/SQLBuilder.pyx":644
 *                 })
 * 
 *             return {             # <<<<<<<<<<<<<<
 *                 "table_name": table_name,
 *                 "columns": columns,
 */
      __Pyx_XDECREF(__pyx_r);

      /* "sQQideR/SQLBuilder.pyx":645
 * 
 *             return {
 *                 "table_name": table_name,             # <<<<<<<<<<<<<<
 *                 "columns": columns,
 *                 "sample_data": sample_data
 */
      __pyx_t_1 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 645, __pyx_L4_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_table_name, __pyx_v_table_name) < 0) __PYX_ERR(0, 645, __pyx_L4_error)

      /* "sQQideR/SQLBuilder.pyx":646
 *             return {
 *                 "table_name": table_name,
 *                 "columns": columns,             # <<<<<<<<<<<<<<
 *                 "sample_data": sample_data
 *             }
 */
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_columns, __pyx_v_columns) < 0) __PYX_ERR(0, 645, __pyx_L4_error)

      /* "sQQideR/SQLBuilder.pyx":647
 *                 "table_name": table_name,
 *                 "columns": columns,
 *                 "sample_data": sample_data             # <<<<<<<<<<<<<<
 *             }
 *         except Exception as e:
 */
      if (PyDict_SetItem(__pyx_t_1, __pyx_n_u_sample_data, __pyx_v_sample_data) < 0) __PYX_ERR(0, 645, __pyx_L4_error)
      __pyx_r = ((PyObject*)__pyx_t_1);
      __pyx_t_1 = 0;
      goto __pyx_L8_try_return;

      /* "sQQideR/SQLBuilder.pyx":620
 *             return {}
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Get table schema
 *             pragma_query = f"PRAGMA table_info({table_name});"
 */
    }
    __pyx_L4_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_18); __pyx_t_18 = 0;
    __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;

    /* "sQQideR/SQLBuilder.pyx":649
 *                 "sample_data": sample_data
 *             }
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error exploring table {table_name}: {e}")
 */
    __pyx_t_16 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
    if (__pyx_t_16) {
      __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._explore_table_schema", __pyx_clineno, __pyx_lineno, __pyx_filename);
      if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_10, &__pyx_t_11) < 0) __PYX_ERR(0, 649, __pyx_L6_except_error)
      __Pyx_XGOTREF(__pyx_t_1);
      __Pyx_XGOTREF(__pyx_t_10);
      __Pyx_XGOTREF(__pyx_t_11);
      __Pyx_INCREF(__pyx_t_10);
      __pyx_v_e = __pyx_t_10;
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":650
 *             }
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error exploring table {table_name}: {e}")
 *             return {}
 */
        __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 650, __pyx_L28_error)
        __Pyx_GOTREF(__pyx_t_9);
        __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 650, __pyx_L28_error)
        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
        if (__pyx_t_3) {

          /* "sQQideR/SQLBuilder.pyx":651
 *         except Exception as e:
 *             if self.verbose:
 *                 print(f"Error exploring table {table_name}: {e}")             # <<<<<<<<<<<<<<
 *             return {}
 * 
 */
          __pyx_t_9 = PyTuple_New(4); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 651, __pyx_L28_error)
          __Pyx_GOTREF(__pyx_t_9);
          __pyx_t_7 = 0;
          __pyx_t_8 = 127;
          __Pyx_INCREF(__pyx_kp_u_Error_exploring_table);
          __pyx_t_7 += 22;
          __Pyx_GIVEREF(__pyx_kp_u_Error_exploring_table);
          PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_kp_u_Error_exploring_table);
          __Pyx_INCREF(__pyx_v_table_name);
          __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_table_name) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_table_name) : __pyx_t_8;
          __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_table_name);
          __Pyx_GIVEREF(__pyx_v_table_name);
          PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_table_name);
          __Pyx_INCREF(__pyx_kp_u__13);
          __pyx_t_7 += 2;
          __Pyx_GIVEREF(__pyx_kp_u__13);
          PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_kp_u__13);
          __pyx_t_18 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 651, __pyx_L28_error)
          __Pyx_GOTREF(__pyx_t_18);
          __pyx_t_8 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_18) > __pyx_t_8) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_18) : __pyx_t_8;
          __pyx_t_7 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_18);
          __Pyx_GIVEREF(__pyx_t_18);
          PyTuple_SET_ITEM(__pyx_t_9, 3, __pyx_t_18);
          __pyx_t_18 = 0;
          __pyx_t_18 = __Pyx_PyUnicode_Join(__pyx_t_9, 4, __pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 651, __pyx_L28_error)
          __Pyx_GOTREF(__pyx_t_18);
          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
          __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_18); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 651, __pyx_L28_error)
          __Pyx_GOTREF(__pyx_t_9);
          __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
          __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;

          /* "sQQideR/SQLBuilder.pyx":650
 *             }
 *         except Exception as e:
 *             if self.verbose:             # <<<<<<<<<<<<<<
 *                 print(f"Error exploring table {table_name}: {e}")
 *             return {}
 */
        }

        /* "sQQideR/SQLBuilder.pyx":652
 *             if self.verbose:
 *                 print(f"Error exploring table {table_name}: {e}")
 *             return {}             # <<<<<<<<<<<<<<
 * 
 *     def _extract_table_names(self, sql: str) -> List[str]:
 */
        __Pyx_XDECREF(__pyx_r);
        __pyx_t_9 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 652, __pyx_L28_error)
        __Pyx_GOTREF(__pyx_t_9);
        __pyx_r = ((PyObject*)__pyx_t_9);
        __pyx_t_9 = 0;
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
        goto __pyx_L27_return;
      }

      /* "sQQideR/SQLBuilder.pyx":649
 *                 "sample_data": sample_data
 *             }
 *         except Exception as e:             # <<<<<<<<<<<<<<
 *             if self.verbose:
 *                 print(f"Error exploring table {table_name}: {e}")
 */
      /*finally:*/ {
        __pyx_L28_error:;
        /*exception exit:*/{
          __Pyx_PyThreadState_declare
          __Pyx_PyThreadState_assign
          __pyx_t_15 = 0; __pyx_t_14 = 0; __pyx_t_13 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0;
          __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
          __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
          if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_23, &__pyx_t_24, &__pyx_t_25);
          if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_15, &__pyx_t_14, &__pyx_t_13) < 0)) __Pyx_ErrFetch(&__pyx_t_15, &__pyx_t_14, &__pyx_t_13);
          __Pyx_XGOTREF(__pyx_t_15);
          __Pyx_XGOTREF(__pyx_t_14);
          __Pyx_XGOTREF(__pyx_t_13);
          __Pyx_XGOTREF(__pyx_t_23);
          __Pyx_XGOTREF(__pyx_t_24);
          __Pyx_XGOTREF(__pyx_t_25);
          __pyx_t_16 = __pyx_lineno; __pyx_t_21 = __pyx_clineno; __pyx_t_22 = __pyx_filename;
          {
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          }
          if (PY_MAJOR_VERSION >= 3) {
            __Pyx_XGIVEREF(__pyx_t_23);
            __Pyx_XGIVEREF(__pyx_t_24);
            __Pyx_XGIVEREF(__pyx_t_25);
            __Pyx_ExceptionReset(__pyx_t_23, __pyx_t_24, __pyx_t_25);
          }
          __Pyx_XGIVEREF(__pyx_t_15);
          __Pyx_XGIVEREF(__pyx_t_14);
          __Pyx_XGIVEREF(__pyx_t_13);
          __Pyx_ErrRestore(__pyx_t_15, __pyx_t_14, __pyx_t_13);
          __pyx_t_15 = 0; __pyx_t_14 = 0; __pyx_t_13 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0;
          __pyx_lineno = __pyx_t_16; __pyx_clineno = __pyx_t_21; __pyx_filename = __pyx_t_22;
          goto __pyx_L6_except_error;
        }
        __pyx_L27_return: {
          __pyx_t_26 = __pyx_r;
          __pyx_r = 0;
          __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
          __pyx_r = __pyx_t_26;
          __pyx_t_26 = 0;
          goto __pyx_L7_except_return;
        }
      }
    }
    goto __pyx_L6_except_error;

    /* "sQQideR/SQLBuilder.pyx":620
 *             return {}
 * 
 *         try:             # <<<<<<<<<<<<<<
 *             # Get table schema
 *             pragma_query = f"PRAGMA table_info({table_name});"
 */
    __pyx_L6_except_error:;
    __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_L8_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;
    __pyx_L7_except_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;
  }

  /* "sQQideR/SQLBuilder.pyx":607
 *         return schema_info
 * 
 *     def _explore_table_schema(self, table_name: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Explore a specific table's schema and sample data.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_XDECREF(__pyx_t_18);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._explore_table_schema", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_pragma_query);
  __Pyx_XDECREF(__pyx_v_columns_df);
  __Pyx_XDECREF(__pyx_v_sample_query);
  __Pyx_XDECREF(__pyx_v_sample_df);
  __Pyx_XDECREF(__pyx_v_sample_data);
  __Pyx_XDECREF(__pyx_v_columns);
  __Pyx_XDECREF(__pyx_v__);
  __Pyx_XDECREF(__pyx_v_row);
  __Pyx_XDECREF(__pyx_v_e);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":654
 *             return {}
 * 
 *     def _extract_table_names(self, sql: str) -> List[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Extract table names from a SQL query.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_23_extract_table_names(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_22_extract_table_names, "\n        Extract table names from a SQL query.\n        \n        Args:\n            sql: SQL query string\n            \n        Returns:\n            List of table names\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_23_extract_table_names = {"_extract_table_names", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_23_extract_table_names, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_22_extract_table_names};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_23_extract_table_names(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_sql = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_extract_table_names (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_sql,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 654, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_sql)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 654, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_extract_table_names", 1, 2, 2, 1); __PYX_ERR(0, 654, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_extract_table_names") < 0)) __PYX_ERR(0, 654, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_sql = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_extract_table_names", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 654, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._extract_table_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sql), (&PyUnicode_Type), 0, "sql", 1))) __PYX_ERR(0, 654, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_22_extract_table_names(__pyx_self, __pyx_v_self, __pyx_v_sql);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_22_extract_table_names(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_sql) {
  PyObject *__pyx_v_from_pattern = NULL;
  PyObject *__pyx_v_join_pattern = NULL;
  PyObject *__pyx_v_table_names = NULL;
  PyObject *__pyx_v_from_matches = NULL;
  PyObject *__pyx_v_match = NULL;
  PyObject *__pyx_v_join_matches = NULL;
  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;
  unsigned int __pyx_t_5;
  Py_ssize_t __pyx_t_6;
  PyObject *(*__pyx_t_7)(PyObject *);
  int __pyx_t_8;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_extract_table_names", 1);

  /* "sQQideR/SQLBuilder.pyx":666
 *         # Simple regex-based extraction - might not catch all cases
 *         # Looks for table names in FROM and JOIN clauses
 *         from_pattern = r'FROM\s+([a-zA-Z0-9_]+)'             # <<<<<<<<<<<<<<
 *         join_pattern = r'JOIN\s+([a-zA-Z0-9_]+)'
 * 
 */
  __Pyx_INCREF(__pyx_kp_u_FROM_s_a_zA_Z0_9);
  __pyx_v_from_pattern = __pyx_kp_u_FROM_s_a_zA_Z0_9;

  /* "sQQideR/SQLBuilder.pyx":667
 *         # Looks for table names in FROM and JOIN clauses
 *         from_pattern = r'FROM\s+([a-zA-Z0-9_]+)'
 *         join_pattern = r'JOIN\s+([a-zA-Z0-9_]+)'             # <<<<<<<<<<<<<<
 * 
 *         table_names = set()
 */
  __Pyx_INCREF(__pyx_kp_u_JOIN_s_a_zA_Z0_9);
  __pyx_v_join_pattern = __pyx_kp_u_JOIN_s_a_zA_Z0_9;

  /* "sQQideR/SQLBuilder.pyx":669
 *         join_pattern = r'JOIN\s+([a-zA-Z0-9_]+)'
 * 
 *         table_names = set()             # <<<<<<<<<<<<<<
 * 
 *         # Extract from FROM clause
 */
  __pyx_t_1 = PySet_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 669, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_v_table_names = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":672
 * 
 *         # Extract from FROM clause
 *         from_matches = re.finditer(from_pattern, sql, re.IGNORECASE)             # <<<<<<<<<<<<<<
 *         for match in from_matches:
 *             table_names.add(match.group(1))
 */
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 672, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_finditer); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 672, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 672, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_IGNORECASE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 672, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  __pyx_t_5 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(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_5 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_from_pattern, __pyx_v_sql, __pyx_t_4};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 3+__pyx_t_5);
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 672, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  }
  __pyx_v_from_matches = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":673
 *         # Extract from FROM clause
 *         from_matches = re.finditer(from_pattern, sql, re.IGNORECASE)
 *         for match in from_matches:             # <<<<<<<<<<<<<<
 *             table_names.add(match.group(1))
 * 
 */
  if (likely(PyList_CheckExact(__pyx_v_from_matches)) || PyTuple_CheckExact(__pyx_v_from_matches)) {
    __pyx_t_1 = __pyx_v_from_matches; __Pyx_INCREF(__pyx_t_1);
    __pyx_t_6 = 0;
    __pyx_t_7 = NULL;
  } else {
    __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_from_matches); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 673, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 673, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_7)) {
      if (likely(PyList_CheckExact(__pyx_t_1))) {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 673, __pyx_L1_error)
          #endif
          if (__pyx_t_6 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 673, __pyx_L1_error)
        #else
        __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 673, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        #endif
      } else {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 673, __pyx_L1_error)
          #endif
          if (__pyx_t_6 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 673, __pyx_L1_error)
        #else
        __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 673, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        #endif
      }
    } else {
      __pyx_t_3 = __pyx_t_7(__pyx_t_1);
      if (unlikely(!__pyx_t_3)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 673, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_3);
    }
    __Pyx_XDECREF_SET(__pyx_v_match, __pyx_t_3);
    __pyx_t_3 = 0;

    /* "sQQideR/SQLBuilder.pyx":674
 *         from_matches = re.finditer(from_pattern, sql, re.IGNORECASE)
 *         for match in from_matches:
 *             table_names.add(match.group(1))             # <<<<<<<<<<<<<<
 * 
 *         # Extract from JOIN clauses
 */
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 674, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_2 = NULL;
    __pyx_t_5 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_4))) {
      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4);
      if (likely(__pyx_t_2)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_4, function);
        __pyx_t_5 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_int_1};
      __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5);
      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 674, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
    __pyx_t_8 = PySet_Add(__pyx_v_table_names, __pyx_t_3); if (unlikely(__pyx_t_8 == ((int)-1))) __PYX_ERR(0, 674, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;

    /* "sQQideR/SQLBuilder.pyx":673
 *         # Extract from FROM clause
 *         from_matches = re.finditer(from_pattern, sql, re.IGNORECASE)
 *         for match in from_matches:             # <<<<<<<<<<<<<<
 *             table_names.add(match.group(1))
 * 
 */
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":677
 * 
 *         # Extract from JOIN clauses
 *         join_matches = re.finditer(join_pattern, sql, re.IGNORECASE)             # <<<<<<<<<<<<<<
 *         for match in join_matches:
 *             table_names.add(match.group(1))
 */
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_re); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 677, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_finditer); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 677, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_re); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 677, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_IGNORECASE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 677, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  __pyx_t_5 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
      __pyx_t_5 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[4] = {__pyx_t_3, __pyx_v_join_pattern, __pyx_v_sql, __pyx_t_2};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 3+__pyx_t_5);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 677, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  }
  __pyx_v_join_matches = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":678
 *         # Extract from JOIN clauses
 *         join_matches = re.finditer(join_pattern, sql, re.IGNORECASE)
 *         for match in join_matches:             # <<<<<<<<<<<<<<
 *             table_names.add(match.group(1))
 * 
 */
  if (likely(PyList_CheckExact(__pyx_v_join_matches)) || PyTuple_CheckExact(__pyx_v_join_matches)) {
    __pyx_t_1 = __pyx_v_join_matches; __Pyx_INCREF(__pyx_t_1);
    __pyx_t_6 = 0;
    __pyx_t_7 = NULL;
  } else {
    __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_join_matches); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 678, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_7 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 678, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_7)) {
      if (likely(PyList_CheckExact(__pyx_t_1))) {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 678, __pyx_L1_error)
          #endif
          if (__pyx_t_6 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 678, __pyx_L1_error)
        #else
        __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 678, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      } else {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 678, __pyx_L1_error)
          #endif
          if (__pyx_t_6 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_4); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 678, __pyx_L1_error)
        #else
        __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 678, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      }
    } else {
      __pyx_t_4 = __pyx_t_7(__pyx_t_1);
      if (unlikely(!__pyx_t_4)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 678, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_4);
    }
    __Pyx_XDECREF_SET(__pyx_v_match, __pyx_t_4);
    __pyx_t_4 = 0;

    /* "sQQideR/SQLBuilder.pyx":679
 *         join_matches = re.finditer(join_pattern, sql, re.IGNORECASE)
 *         for match in join_matches:
 *             table_names.add(match.group(1))             # <<<<<<<<<<<<<<
 * 
 *         return list(table_names)
 */
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 679, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = NULL;
    __pyx_t_5 = 0;
    #if CYTHON_UNPACK_METHODS
    if (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_5 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_int_1};
      __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5);
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 679, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    }
    __pyx_t_8 = PySet_Add(__pyx_v_table_names, __pyx_t_4); if (unlikely(__pyx_t_8 == ((int)-1))) __PYX_ERR(0, 679, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

    /* "sQQideR/SQLBuilder.pyx":678
 *         # Extract from JOIN clauses
 *         join_matches = re.finditer(join_pattern, sql, re.IGNORECASE)
 *         for match in join_matches:             # <<<<<<<<<<<<<<
 *             table_names.add(match.group(1))
 * 
 */
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":681
 *             table_names.add(match.group(1))
 * 
 *         return list(table_names)             # <<<<<<<<<<<<<<
 * 
 *     def generate_additional_explorations(self, question: str, main_query: Dict, db_context: Dict) -> List[Dict]:
 */
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = PySequence_List(__pyx_v_table_names); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 681, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":654
 *             return {}
 * 
 *     def _extract_table_names(self, sql: str) -> List[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Extract table names from a SQL query.
 */

  /* 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_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._extract_table_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_from_pattern);
  __Pyx_XDECREF(__pyx_v_join_pattern);
  __Pyx_XDECREF(__pyx_v_table_names);
  __Pyx_XDECREF(__pyx_v_from_matches);
  __Pyx_XDECREF(__pyx_v_match);
  __Pyx_XDECREF(__pyx_v_join_matches);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":683
 *         return list(table_names)
 * 
 *     def generate_additional_explorations(self, question: str, main_query: Dict, db_context: Dict) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Generate and execute additional SQL queries to explore related aspects of the main query.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_25generate_additional_explorations(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_24generate_additional_explorations, "\n        Generate and execute additional SQL queries to explore related aspects of the main query.\n        \n        This provides additional context about the question by exploring related data\n        that might be interesting but wasn't explicitly asked for.\n        \n        Args:\n            question: The natural language question\n            main_query: The main query dictionary with results\n            db_context: Database context information\n            \n        Returns:\n            List of exploration query results\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_25generate_additional_explorations = {"generate_additional_explorations", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_25generate_additional_explorations, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_24generate_additional_explorations};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_25generate_additional_explorations(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_question = 0;
  PyObject *__pyx_v_main_query = 0;
  PyObject *__pyx_v_db_context = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[4] = {0,0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("generate_additional_explorations (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_question,&__pyx_n_s_main_query,&__pyx_n_s_db_context,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 683, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 683, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("generate_additional_explorations", 1, 4, 4, 1); __PYX_ERR(0, 683, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_main_query)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 683, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("generate_additional_explorations", 1, 4, 4, 2); __PYX_ERR(0, 683, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_db_context)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[3]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 683, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("generate_additional_explorations", 1, 4, 4, 3); __PYX_ERR(0, 683, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "generate_additional_explorations") < 0)) __PYX_ERR(0, 683, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 4)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
      values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3);
    }
    __pyx_v_self = values[0];
    __pyx_v_question = ((PyObject*)values[1]);
    __pyx_v_main_query = ((PyObject*)values[2]);
    __pyx_v_db_context = ((PyObject*)values[3]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("generate_additional_explorations", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 683, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_additional_explorations", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 683, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_main_query), (&PyDict_Type), 0, "main_query", 1))) __PYX_ERR(0, 683, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_db_context), (&PyDict_Type), 0, "db_context", 1))) __PYX_ERR(0, 683, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_24generate_additional_explorations(__pyx_self, __pyx_v_self, __pyx_v_question, __pyx_v_main_query, __pyx_v_db_context);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
static PyObject *__pyx_gb_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */

/* "sQQideR/SQLBuilder.pyx":806
 *         # 4. If the question relates to relationships, explore relationship counts
 *         relationship_keywords = ["relation", "connect", "join", "link", "between"]
 *         if any(keyword in question.lower() for keyword in relationship_keywords) and len(tables_used) > 1:             # <<<<<<<<<<<<<<
 *             # Find relationships between the used tables from context
 *             for rel in db_context.get("relationships", []):
 */

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_genexpr(PyObject *__pyx_self, PyObject *__pyx_genexpr_arg_0) {
  struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_cur_scope = (struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *)__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr(__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 806, __pyx_L1_error)
  } else {
    __Pyx_GOTREF((PyObject *)__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *) __pyx_self;
  __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_outer_scope);
  __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_outer_scope);
  __pyx_cur_scope->__pyx_genexpr_arg_0 = __pyx_genexpr_arg_0;
  __Pyx_INCREF(__pyx_cur_scope->__pyx_genexpr_arg_0);
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_genexpr_arg_0);
  {
    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_2generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_SQLBuilder_generate_additional_e, __pyx_n_s_sQQideR_SQLBuilder); if (unlikely(!gen)) __PYX_ERR(0, 806, __pyx_L1_error)
    __Pyx_DECREF(__pyx_cur_scope);
    __Pyx_RefNannyFinishContext();
    return (PyObject *) gen;
  }

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_additional_explorations.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __Pyx_DECREF((PyObject *)__pyx_cur_scope);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_gb_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
{
  struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *)__pyx_generator->closure);
  PyObject *__pyx_r = NULL;
  PyObject *__pyx_t_1 = NULL;
  Py_ssize_t __pyx_t_2;
  PyObject *__pyx_t_3 = NULL;
  int __pyx_t_4;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  switch (__pyx_generator->resume_label) {
    case 0: goto __pyx_L3_first_run;
    default: /* CPython raises the right error here */
    __Pyx_RefNannyFinishContext();
    return NULL;
  }
  __pyx_L3_first_run:;
  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 806, __pyx_L1_error)
  if (unlikely(!__pyx_cur_scope->__pyx_genexpr_arg_0)) { __Pyx_RaiseUnboundLocalError(".0"); __PYX_ERR(0, 806, __pyx_L1_error) }
  __pyx_t_1 = __pyx_cur_scope->__pyx_genexpr_arg_0; __Pyx_INCREF(__pyx_t_1);
  __pyx_t_2 = 0;
  for (;;) {
    {
      Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
      #if !CYTHON_ASSUME_SAFE_MACROS
      if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 806, __pyx_L1_error)
      #endif
      if (__pyx_t_2 >= __pyx_temp) break;
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely((0 < 0))) __PYX_ERR(0, 806, __pyx_L1_error)
    #else
    __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 806, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    #endif
    __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_keyword);
    __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_keyword, __pyx_t_3);
    __Pyx_GIVEREF(__pyx_t_3);
    __pyx_t_3 = 0;
    if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_question)) { __Pyx_RaiseClosureNameError("question"); __PYX_ERR(0, 806, __pyx_L1_error) }
    __pyx_t_3 = __Pyx_CallUnboundCMethod0(&__pyx_umethod_PyUnicode_Type_lower, __pyx_cur_scope->__pyx_outer_scope->__pyx_v_question); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 806, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = (__Pyx_PySequence_ContainsTF(__pyx_cur_scope->__pyx_v_keyword, __pyx_t_3, Py_EQ)); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 806, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (__pyx_t_4) {
      __Pyx_XDECREF(__pyx_r);
      __Pyx_INCREF(Py_True);
      __pyx_r = Py_True;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      goto __pyx_L0;
    }
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  /*else*/ {
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(Py_False);
    __pyx_r = Py_False;
    goto __pyx_L0;
  }
  CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_Generator_Replace_StopIteration(0);
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  #if !CYTHON_USE_EXC_INFO_STACK
  __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
  #endif
  __pyx_generator->resume_label = -1;
  __Pyx_Coroutine_clear((PyObject*)__pyx_generator);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":683
 *         return list(table_names)
 * 
 *     def generate_additional_explorations(self, question: str, main_query: Dict, db_context: Dict) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Generate and execute additional SQL queries to explore related aspects of the main query.
 */

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_24generate_additional_explorations(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_main_query, PyObject *__pyx_v_db_context) {
  struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *__pyx_cur_scope;
  PyObject *__pyx_v_explorations = NULL;
  PyObject *__pyx_v_main_sql = NULL;
  PyObject *__pyx_v_tables_used = NULL;
  PyObject *__pyx_v_table_obj = NULL;
  PyObject *__pyx_v_table_name = NULL;
  PyObject *__pyx_v_table = NULL;
  PyObject *__pyx_v_count_query = NULL;
  PyObject *__pyx_v_df = NULL;
  PyObject *__pyx_v_e = NULL;
  PyObject *__pyx_v_date_columns = NULL;
  PyObject *__pyx_v_column_obj = NULL;
  PyObject *__pyx_v_col_name = NULL;
  CYTHON_UNUSED PyObject *__pyx_v_data_type = NULL;
  PyObject *__pyx_v_date_col = NULL;
  PyObject *__pyx_v_time_query = NULL;
  PyObject *__pyx_v_numeric_columns = NULL;
  PyObject *__pyx_v_first_result = NULL;
  PyObject *__pyx_v_col = NULL;
  PyObject *__pyx_v_val = NULL;
  PyObject *__pyx_v_stats_query_dict = NULL;
  PyObject *__pyx_v_agg_parts = NULL;
  PyObject *__pyx_v_sql = NULL;
  PyObject *__pyx_v_tested_query = NULL;
  PyObject *__pyx_v_retry_info = NULL;
  PyObject *__pyx_v_relationship_keywords = NULL;
  PyObject *__pyx_v_rel = NULL;
  PyObject *__pyx_v_source = NULL;
  PyObject *__pyx_v_target = NULL;
  PyObject *__pyx_v_join_condition = NULL;
  PyObject *__pyx_v_parts = NULL;
  PyObject *__pyx_v_left_side = NULL;
  CYTHON_UNUSED PyObject *__pyx_v_right_side = NULL;
  PyObject *__pyx_v_relationship_query = NULL;
  PyObject *__pyx_gb_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_2generator = 0;
  PyObject *__pyx_r = NULL;
  __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;
  unsigned int __pyx_t_7;
  PyObject *__pyx_t_8 = NULL;
  Py_ssize_t __pyx_t_9;
  PyObject *(*__pyx_t_10)(PyObject *);
  int __pyx_t_11;
  Py_ssize_t __pyx_t_12;
  Py_UCS4 __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;
  int __pyx_t_19;
  int __pyx_t_20;
  char const *__pyx_t_21;
  PyObject *__pyx_t_22 = NULL;
  PyObject *__pyx_t_23 = NULL;
  PyObject *__pyx_t_24 = NULL;
  PyObject *__pyx_t_25 = NULL;
  PyObject *__pyx_t_26 = NULL;
  PyObject *__pyx_t_27 = NULL;
  PyObject *(*__pyx_t_28)(PyObject *);
  char const *__pyx_t_29;
  int __pyx_t_30;
  int __pyx_t_31;
  char const *__pyx_t_32;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("generate_additional_explorations", 0);
  __pyx_cur_scope = (struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *)__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations(__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 683, __pyx_L1_error)
  } else {
    __Pyx_GOTREF((PyObject *)__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_v_question = __pyx_v_question;
  __Pyx_INCREF(__pyx_cur_scope->__pyx_v_question);
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_question);

  /* "sQQideR/SQLBuilder.pyx":698
 *             List of exploration query results
 *         """
 *         if not self.conn or not main_query.get("success", False):             # <<<<<<<<<<<<<<
 *             return []
 * 
 */
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 698, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 698, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_4 = (!__pyx_t_3);
  if (!__pyx_t_4) {
  } else {
    __pyx_t_1 = __pyx_t_4;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_main_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 698, __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(0, 698, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_3 = (!__pyx_t_4);
  __pyx_t_1 = __pyx_t_3;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {

    /* "sQQideR/SQLBuilder.pyx":699
 *         """
 *         if not self.conn or not main_query.get("success", False):
 *             return []             # <<<<<<<<<<<<<<
 * 
 *         explorations = []
 */
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 699, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_r = ((PyObject*)__pyx_t_2);
    __pyx_t_2 = 0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":698
 *             List of exploration query results
 *         """
 *         if not self.conn or not main_query.get("success", False):             # <<<<<<<<<<<<<<
 *             return []
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":701
 *             return []
 * 
 *         explorations = []             # <<<<<<<<<<<<<<
 * 
 *         # Extract tables and columns used in the main query
 */
  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 701, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_v_explorations = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":704
 * 
 *         # Extract tables and columns used in the main query
 *         main_sql = main_query.get("sql", "").lower()             # <<<<<<<<<<<<<<
 *         tables_used = []
 * 
 */
  __pyx_t_5 = __Pyx_PyDict_GetItemDefault(__pyx_v_main_query, __pyx_n_u_sql, __pyx_kp_u__7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_lower); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 704, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (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_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 704, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  }
  __pyx_v_main_sql = __pyx_t_2;
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":705
 *         # Extract tables and columns used in the main query
 *         main_sql = main_query.get("sql", "").lower()
 *         tables_used = []             # <<<<<<<<<<<<<<
 * 
 *         # Extract table names from the main SQL query
 */
  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 705, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_v_tables_used = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":708
 * 
 *         # Extract table names from the main SQL query
 *         for table_obj in db_context.get("database_objects", {}).get("tables", []):             # <<<<<<<<<<<<<<
 *             table_name = table_obj.get("name", "").lower()
 *             if table_name and table_name in main_sql:
 */
  __pyx_t_6 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 708, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_5 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_database_objects, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 708, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_get); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 708, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 708, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_8 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_6))) {
    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_6);
    if (likely(__pyx_t_8)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
      __Pyx_INCREF(__pyx_t_8);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_6, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[3] = {__pyx_t_8, __pyx_n_u_tables, __pyx_t_5};
    __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 708, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  }
  if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) {
    __pyx_t_6 = __pyx_t_2; __Pyx_INCREF(__pyx_t_6);
    __pyx_t_9 = 0;
    __pyx_t_10 = NULL;
  } else {
    __pyx_t_9 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 708, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_10 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 708, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  for (;;) {
    if (likely(!__pyx_t_10)) {
      if (likely(PyList_CheckExact(__pyx_t_6))) {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 708, __pyx_L1_error)
          #endif
          if (__pyx_t_9 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_9); __Pyx_INCREF(__pyx_t_2); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 708, __pyx_L1_error)
        #else
        __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 708, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        #endif
      } else {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 708, __pyx_L1_error)
          #endif
          if (__pyx_t_9 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_9); __Pyx_INCREF(__pyx_t_2); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 708, __pyx_L1_error)
        #else
        __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 708, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        #endif
      }
    } else {
      __pyx_t_2 = __pyx_t_10(__pyx_t_6);
      if (unlikely(!__pyx_t_2)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 708, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_2);
    }
    __Pyx_XDECREF_SET(__pyx_v_table_obj, __pyx_t_2);
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":709
 *         # Extract table names from the main SQL query
 *         for table_obj in db_context.get("database_objects", {}).get("tables", []):
 *             table_name = table_obj.get("name", "").lower()             # <<<<<<<<<<<<<<
 *             if table_name and table_name in main_sql:
 *                 tables_used.append(table_name)
 */
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_table_obj, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 709, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 709, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_lower); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 709, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __pyx_t_8 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_8)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_8);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_8, NULL};
      __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 709, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __Pyx_XDECREF_SET(__pyx_v_table_name, __pyx_t_2);
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":710
 *         for table_obj in db_context.get("database_objects", {}).get("tables", []):
 *             table_name = table_obj.get("name", "").lower()
 *             if table_name and table_name in main_sql:             # <<<<<<<<<<<<<<
 *                 tables_used.append(table_name)
 * 
 */
    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_table_name); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 710, __pyx_L1_error)
    if (__pyx_t_3) {
    } else {
      __pyx_t_1 = __pyx_t_3;
      goto __pyx_L9_bool_binop_done;
    }
    __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_v_table_name, __pyx_v_main_sql, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 710, __pyx_L1_error)
    __pyx_t_1 = __pyx_t_3;
    __pyx_L9_bool_binop_done:;
    if (__pyx_t_1) {

      /* "sQQideR/SQLBuilder.pyx":711
 *             table_name = table_obj.get("name", "").lower()
 *             if table_name and table_name in main_sql:
 *                 tables_used.append(table_name)             # <<<<<<<<<<<<<<
 * 
 *         # 1. For each table in the main query, get a count exploration
 */
      __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_tables_used, __pyx_v_table_name); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 711, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":710
 *         for table_obj in db_context.get("database_objects", {}).get("tables", []):
 *             table_name = table_obj.get("name", "").lower()
 *             if table_name and table_name in main_sql:             # <<<<<<<<<<<<<<
 *                 tables_used.append(table_name)
 * 
 */
    }

    /* "sQQideR/SQLBuilder.pyx":708
 * 
 *         # Extract table names from the main SQL query
 *         for table_obj in db_context.get("database_objects", {}).get("tables", []):             # <<<<<<<<<<<<<<
 *             table_name = table_obj.get("name", "").lower()
 *             if table_name and table_name in main_sql:
 */
  }
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

  /* "sQQideR/SQLBuilder.pyx":714
 * 
 *         # 1. For each table in the main query, get a count exploration
 *         for table in tables_used:             # <<<<<<<<<<<<<<
 *             count_query = {
 *                 "name": f"Count records in {table}",
 */
  __pyx_t_6 = __pyx_v_tables_used; __Pyx_INCREF(__pyx_t_6);
  __pyx_t_9 = 0;
  for (;;) {
    {
      Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6);
      #if !CYTHON_ASSUME_SAFE_MACROS
      if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 714, __pyx_L1_error)
      #endif
      if (__pyx_t_9 >= __pyx_temp) break;
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    __pyx_t_2 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_9); __Pyx_INCREF(__pyx_t_2); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 714, __pyx_L1_error)
    #else
    __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    #endif
    __Pyx_XDECREF_SET(__pyx_v_table, __pyx_t_2);
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":716
 *         for table in tables_used:
 *             count_query = {
 *                 "name": f"Count records in {table}",             # <<<<<<<<<<<<<<
 *                 "description": f"Shows the total number of records in the {table} table",
 *                 "sql": f"SELECT COUNT(*) AS record_count FROM {table}"
 */
    __pyx_t_2 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_table, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Count_records_in, __pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_name, __pyx_t_8) < 0) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

    /* "sQQideR/SQLBuilder.pyx":717
 *             count_query = {
 *                 "name": f"Count records in {table}",
 *                 "description": f"Shows the total number of records in the {table} table",             # <<<<<<<<<<<<<<
 *                 "sql": f"SELECT COUNT(*) AS record_count FROM {table}"
 *             }
 */
    __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 717, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __pyx_t_12 = 0;
    __pyx_t_13 = 127;
    __Pyx_INCREF(__pyx_kp_u_Shows_the_total_number_of_record);
    __pyx_t_12 += 41;
    __Pyx_GIVEREF(__pyx_kp_u_Shows_the_total_number_of_record);
    PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_Shows_the_total_number_of_record);
    __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_table, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 717, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_13;
    __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_5);
    PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_5);
    __pyx_t_5 = 0;
    __Pyx_INCREF(__pyx_kp_u_table);
    __pyx_t_12 += 6;
    __Pyx_GIVEREF(__pyx_kp_u_table);
    PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u_table);
    __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_8, 3, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 717, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_description, __pyx_t_5) < 0) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":718
 *                 "name": f"Count records in {table}",
 *                 "description": f"Shows the total number of records in the {table} table",
 *                 "sql": f"SELECT COUNT(*) AS record_count FROM {table}"             # <<<<<<<<<<<<<<
 *             }
 * 
 */
    __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_table, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 718, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_kp_u_SELECT_COUNT_AS_record_count_FRO, __pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 718, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_sql, __pyx_t_8) < 0) __PYX_ERR(0, 716, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_XDECREF_SET(__pyx_v_count_query, ((PyObject*)__pyx_t_2));
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":721
 *             }
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 df = pd.read_sql_query(count_query["sql"], self.conn)
 *                 count_query["success"] = True
 */
    {
      __Pyx_PyThreadState_declare
      __Pyx_PyThreadState_assign
      __Pyx_ExceptionSave(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16);
      __Pyx_XGOTREF(__pyx_t_14);
      __Pyx_XGOTREF(__pyx_t_15);
      __Pyx_XGOTREF(__pyx_t_16);
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":722
 * 
 *             try:
 *                 df = pd.read_sql_query(count_query["sql"], self.conn)             # <<<<<<<<<<<<<<
 *                 count_query["success"] = True
 *                 count_query["results"] = df.to_dict(orient="records")
 */
        __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_pd); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 722, __pyx_L14_error)
        __Pyx_GOTREF(__pyx_t_8);
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_read_sql_query); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 722, __pyx_L14_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
        __pyx_t_8 = __Pyx_PyDict_GetItem(__pyx_v_count_query, __pyx_n_u_sql); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 722, __pyx_L14_error)
        __Pyx_GOTREF(__pyx_t_8);
        __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 722, __pyx_L14_error)
        __Pyx_GOTREF(__pyx_t_17);
        __pyx_t_18 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (unlikely(PyMethod_Check(__pyx_t_5))) {
          __pyx_t_18 = PyMethod_GET_SELF(__pyx_t_5);
          if (likely(__pyx_t_18)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
            __Pyx_INCREF(__pyx_t_18);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_5, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[3] = {__pyx_t_18, __pyx_t_8, __pyx_t_17};
          __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
          __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
          if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 722, __pyx_L14_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        }
        __Pyx_XDECREF_SET(__pyx_v_df, __pyx_t_2);
        __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":723
 *             try:
 *                 df = pd.read_sql_query(count_query["sql"], self.conn)
 *                 count_query["success"] = True             # <<<<<<<<<<<<<<
 *                 count_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(count_query)
 */
        if (unlikely((PyDict_SetItem(__pyx_v_count_query, __pyx_n_u_success, Py_True) < 0))) __PYX_ERR(0, 723, __pyx_L14_error)

        /* "sQQideR/SQLBuilder.pyx":724
 *                 df = pd.read_sql_query(count_query["sql"], self.conn)
 *                 count_query["success"] = True
 *                 count_query["results"] = df.to_dict(orient="records")             # <<<<<<<<<<<<<<
 *                 explorations.append(count_query)
 *             except Exception as e:
 */
        __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_to_dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 724, __pyx_L14_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 724, __pyx_L14_error)
        __Pyx_GOTREF(__pyx_t_5);
        if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_orient, __pyx_n_u_records) < 0) __PYX_ERR(0, 724, __pyx_L14_error)
        __pyx_t_17 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 724, __pyx_L14_error)
        __Pyx_GOTREF(__pyx_t_17);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        if (unlikely((PyDict_SetItem(__pyx_v_count_query, __pyx_n_u_results, __pyx_t_17) < 0))) __PYX_ERR(0, 724, __pyx_L14_error)
        __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;

        /* "sQQideR/SQLBuilder.pyx":725
 *                 count_query["success"] = True
 *                 count_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(count_query)             # <<<<<<<<<<<<<<
 *             except Exception as e:
 *                 if self.verbose:
 */
        __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_explorations, __pyx_v_count_query); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 725, __pyx_L14_error)

        /* "sQQideR/SQLBuilder.pyx":721
 *             }
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 df = pd.read_sql_query(count_query["sql"], self.conn)
 *                 count_query["success"] = True
 */
      }
      __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
      __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
      __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
      goto __pyx_L21_try_end;
      __pyx_L14_error:;
      __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
      __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;

      /* "sQQideR/SQLBuilder.pyx":726
 *                 count_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(count_query)
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Error executing count exploration: {e}")
 */
      __pyx_t_19 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
      if (__pyx_t_19) {
        __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_additional_explorations", __pyx_clineno, __pyx_lineno, __pyx_filename);
        if (__Pyx_GetException(&__pyx_t_17, &__pyx_t_5, &__pyx_t_2) < 0) __PYX_ERR(0, 726, __pyx_L16_except_error)
        __Pyx_XGOTREF(__pyx_t_17);
        __Pyx_XGOTREF(__pyx_t_5);
        __Pyx_XGOTREF(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_5);
        __pyx_v_e = __pyx_t_5;
        /*try:*/ {

          /* "sQQideR/SQLBuilder.pyx":727
 *                 explorations.append(count_query)
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Error executing count exploration: {e}")
 * 
 */
          __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 727, __pyx_L27_error)
          __Pyx_GOTREF(__pyx_t_8);
          __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 727, __pyx_L27_error)
          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
          if (__pyx_t_1) {

            /* "sQQideR/SQLBuilder.pyx":728
 *             except Exception as e:
 *                 if self.verbose:
 *                     print(f"Error executing count exploration: {e}")             # <<<<<<<<<<<<<<
 * 
 *         # 2. For tables with time/date columns, add a time distribution exploration
 */
            __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 728, __pyx_L27_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_18 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_executing_count_exploratio, __pyx_t_8); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 728, __pyx_L27_error)
            __Pyx_GOTREF(__pyx_t_18);
            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
            __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_18); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 728, __pyx_L27_error)
            __Pyx_GOTREF(__pyx_t_8);
            __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

            /* "sQQideR/SQLBuilder.pyx":727
 *                 explorations.append(count_query)
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Error executing count exploration: {e}")
 * 
 */
          }
        }

        /* "sQQideR/SQLBuilder.pyx":726
 *                 count_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(count_query)
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Error executing count exploration: {e}")
 */
        /*finally:*/ {
          /*normal exit:*/{
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            goto __pyx_L28;
          }
          __pyx_L27_error:;
          /*exception exit:*/{
            __Pyx_PyThreadState_declare
            __Pyx_PyThreadState_assign
            __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_26 = 0; __pyx_t_27 = 0;
            __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
            __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
            if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_25, &__pyx_t_26, &__pyx_t_27);
            if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_22, &__pyx_t_23, &__pyx_t_24) < 0)) __Pyx_ErrFetch(&__pyx_t_22, &__pyx_t_23, &__pyx_t_24);
            __Pyx_XGOTREF(__pyx_t_22);
            __Pyx_XGOTREF(__pyx_t_23);
            __Pyx_XGOTREF(__pyx_t_24);
            __Pyx_XGOTREF(__pyx_t_25);
            __Pyx_XGOTREF(__pyx_t_26);
            __Pyx_XGOTREF(__pyx_t_27);
            __pyx_t_19 = __pyx_lineno; __pyx_t_20 = __pyx_clineno; __pyx_t_21 = __pyx_filename;
            {
              __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            }
            if (PY_MAJOR_VERSION >= 3) {
              __Pyx_XGIVEREF(__pyx_t_25);
              __Pyx_XGIVEREF(__pyx_t_26);
              __Pyx_XGIVEREF(__pyx_t_27);
              __Pyx_ExceptionReset(__pyx_t_25, __pyx_t_26, __pyx_t_27);
            }
            __Pyx_XGIVEREF(__pyx_t_22);
            __Pyx_XGIVEREF(__pyx_t_23);
            __Pyx_XGIVEREF(__pyx_t_24);
            __Pyx_ErrRestore(__pyx_t_22, __pyx_t_23, __pyx_t_24);
            __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_26 = 0; __pyx_t_27 = 0;
            __pyx_lineno = __pyx_t_19; __pyx_clineno = __pyx_t_20; __pyx_filename = __pyx_t_21;
            goto __pyx_L16_except_error;
          }
          __pyx_L28:;
        }
        __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
        goto __pyx_L15_exception_handled;
      }
      goto __pyx_L16_except_error;

      /* "sQQideR/SQLBuilder.pyx":721
 *             }
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 df = pd.read_sql_query(count_query["sql"], self.conn)
 *                 count_query["success"] = True
 */
      __pyx_L16_except_error:;
      __Pyx_XGIVEREF(__pyx_t_14);
      __Pyx_XGIVEREF(__pyx_t_15);
      __Pyx_XGIVEREF(__pyx_t_16);
      __Pyx_ExceptionReset(__pyx_t_14, __pyx_t_15, __pyx_t_16);
      goto __pyx_L1_error;
      __pyx_L15_exception_handled:;
      __Pyx_XGIVEREF(__pyx_t_14);
      __Pyx_XGIVEREF(__pyx_t_15);
      __Pyx_XGIVEREF(__pyx_t_16);
      __Pyx_ExceptionReset(__pyx_t_14, __pyx_t_15, __pyx_t_16);
      __pyx_L21_try_end:;
    }

    /* "sQQideR/SQLBuilder.pyx":714
 * 
 *         # 1. For each table in the main query, get a count exploration
 *         for table in tables_used:             # <<<<<<<<<<<<<<
 *             count_query = {
 *                 "name": f"Count records in {table}",
 */
  }
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

  /* "sQQideR/SQLBuilder.pyx":731
 * 
 *         # 2. For tables with time/date columns, add a time distribution exploration
 *         date_columns = []             # <<<<<<<<<<<<<<
 *         for column_obj in db_context.get("database_objects", {}).get("columns", []):
 *             col_name = column_obj.get("name", "").lower()
 */
  __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 731, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_v_date_columns = ((PyObject*)__pyx_t_6);
  __pyx_t_6 = 0;

  /* "sQQideR/SQLBuilder.pyx":732
 *         # 2. For tables with time/date columns, add a time distribution exploration
 *         date_columns = []
 *         for column_obj in db_context.get("database_objects", {}).get("columns", []):             # <<<<<<<<<<<<<<
 *             col_name = column_obj.get("name", "").lower()
 *             data_type = column_obj.get("data_type", "").lower()
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 732, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_database_objects, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 732, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 732, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 732, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_17 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_17)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_17);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[3] = {__pyx_t_17, __pyx_n_u_columns, __pyx_t_5};
    __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 732, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  }
  if (likely(PyList_CheckExact(__pyx_t_6)) || PyTuple_CheckExact(__pyx_t_6)) {
    __pyx_t_2 = __pyx_t_6; __Pyx_INCREF(__pyx_t_2);
    __pyx_t_9 = 0;
    __pyx_t_10 = NULL;
  } else {
    __pyx_t_9 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 732, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_10 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 732, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  for (;;) {
    if (likely(!__pyx_t_10)) {
      if (likely(PyList_CheckExact(__pyx_t_2))) {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 732, __pyx_L1_error)
          #endif
          if (__pyx_t_9 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_9); __Pyx_INCREF(__pyx_t_6); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 732, __pyx_L1_error)
        #else
        __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 732, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        #endif
      } else {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_2);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 732, __pyx_L1_error)
          #endif
          if (__pyx_t_9 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_6 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_9); __Pyx_INCREF(__pyx_t_6); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 732, __pyx_L1_error)
        #else
        __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 732, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        #endif
      }
    } else {
      __pyx_t_6 = __pyx_t_10(__pyx_t_2);
      if (unlikely(!__pyx_t_6)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 732, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_6);
    }
    __Pyx_XDECREF_SET(__pyx_v_column_obj, __pyx_t_6);
    __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":733
 *         date_columns = []
 *         for column_obj in db_context.get("database_objects", {}).get("columns", []):
 *             col_name = column_obj.get("name", "").lower()             # <<<<<<<<<<<<<<
 *             data_type = column_obj.get("data_type", "").lower()
 * 
 */
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_column_obj, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 733, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_17 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 733, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_17, __pyx_n_s_lower); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 733, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
    __pyx_t_17 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_17)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_17);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_17, NULL};
      __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
      if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 733, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __Pyx_XDECREF_SET(__pyx_v_col_name, __pyx_t_6);
    __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":734
 *         for column_obj in db_context.get("database_objects", {}).get("columns", []):
 *             col_name = column_obj.get("name", "").lower()
 *             data_type = column_obj.get("data_type", "").lower()             # <<<<<<<<<<<<<<
 * 
 *             # Check if column is date/time related
 */
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_column_obj, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 734, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_17 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 734, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_17, __pyx_n_s_lower); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 734, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
    __pyx_t_17 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_17)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_17);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_17, NULL};
      __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
      if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 734, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __Pyx_XDECREF_SET(__pyx_v_data_type, __pyx_t_6);
    __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":737
 * 
 *             # Check if column is date/time related
 *             if ("date" in col_name or "time" in col_name or "day" in col_name) and col_name.split(".")[-1] in main_sql:             # <<<<<<<<<<<<<<
 *                 table_name = col_name.split(".")[0] if "." in col_name else None
 *                 if table_name and table_name in tables_used:
 */
    __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_date, __pyx_v_col_name, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 737, __pyx_L1_error)
    if (!__pyx_t_3) {
    } else {
      goto __pyx_L39_next_and;
    }
    __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_time, __pyx_v_col_name, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 737, __pyx_L1_error)
    if (!__pyx_t_3) {
    } else {
      goto __pyx_L39_next_and;
    }
    __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_day, __pyx_v_col_name, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 737, __pyx_L1_error)
    if (__pyx_t_3) {
    } else {
      __pyx_t_1 = __pyx_t_3;
      goto __pyx_L38_bool_binop_done;
    }
    __pyx_L39_next_and:;
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_col_name, __pyx_n_s_split); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 737, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_17 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_17)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_17);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_17, __pyx_kp_u__29};
      __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
      if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 737, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_6, -1L, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 737, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_t_5, __pyx_v_main_sql, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 737, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_1 = __pyx_t_3;
    __pyx_L38_bool_binop_done:;
    if (__pyx_t_1) {

      /* "sQQideR/SQLBuilder.pyx":738
 *             # Check if column is date/time related
 *             if ("date" in col_name or "time" in col_name or "day" in col_name) and col_name.split(".")[-1] in main_sql:
 *                 table_name = col_name.split(".")[0] if "." in col_name else None             # <<<<<<<<<<<<<<
 *                 if table_name and table_name in tables_used:
 *                     date_columns.append((table_name, col_name.split(".")[-1]))
 */
      __pyx_t_1 = (__Pyx_PySequence_ContainsTF(__pyx_kp_u__29, __pyx_v_col_name, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 738, __pyx_L1_error)
      if (__pyx_t_1) {
        __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_v_col_name, __pyx_n_s_split); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 738, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_17);
        __pyx_t_8 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_17))) {
          __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_17);
          if (likely(__pyx_t_8)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_17);
            __Pyx_INCREF(__pyx_t_8);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_17, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_8, __pyx_kp_u__29};
          __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_17, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
          if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 738, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_6);
          __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
        }
        __pyx_t_17 = __Pyx_GetItemInt(__pyx_t_6, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 738, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_17);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        __pyx_t_5 = __pyx_t_17;
        __pyx_t_17 = 0;
      } else {
        __Pyx_INCREF(Py_None);
        __pyx_t_5 = Py_None;
      }
      __Pyx_XDECREF_SET(__pyx_v_table_name, __pyx_t_5);
      __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":739
 *             if ("date" in col_name or "time" in col_name or "day" in col_name) and col_name.split(".")[-1] in main_sql:
 *                 table_name = col_name.split(".")[0] if "." in col_name else None
 *                 if table_name and table_name in tables_used:             # <<<<<<<<<<<<<<
 *                     date_columns.append((table_name, col_name.split(".")[-1]))
 * 
 */
      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_table_name); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 739, __pyx_L1_error)
      if (__pyx_t_3) {
      } else {
        __pyx_t_1 = __pyx_t_3;
        goto __pyx_L43_bool_binop_done;
      }
      __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_v_table_name, __pyx_v_tables_used, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 739, __pyx_L1_error)
      __pyx_t_1 = __pyx_t_3;
      __pyx_L43_bool_binop_done:;
      if (__pyx_t_1) {

        /* "sQQideR/SQLBuilder.pyx":740
 *                 table_name = col_name.split(".")[0] if "." in col_name else None
 *                 if table_name and table_name in tables_used:
 *                     date_columns.append((table_name, col_name.split(".")[-1]))             # <<<<<<<<<<<<<<
 * 
 *         # Create time-based explorations
 */
        __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_v_col_name, __pyx_n_s_split); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 740, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_17);
        __pyx_t_6 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_17))) {
          __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_17);
          if (likely(__pyx_t_6)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_17);
            __Pyx_INCREF(__pyx_t_6);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_17, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_kp_u__29};
          __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_17, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
          if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 740, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
        }
        __pyx_t_17 = __Pyx_GetItemInt(__pyx_t_5, -1L, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 740, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_17);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 740, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_INCREF(__pyx_v_table_name);
        __Pyx_GIVEREF(__pyx_v_table_name);
        if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_table_name)) __PYX_ERR(0, 740, __pyx_L1_error);
        __Pyx_GIVEREF(__pyx_t_17);
        if (__Pyx_PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_17)) __PYX_ERR(0, 740, __pyx_L1_error);
        __pyx_t_17 = 0;
        __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_date_columns, __pyx_t_5); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 740, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

        /* "sQQideR/SQLBuilder.pyx":739
 *             if ("date" in col_name or "time" in col_name or "day" in col_name) and col_name.split(".")[-1] in main_sql:
 *                 table_name = col_name.split(".")[0] if "." in col_name else None
 *                 if table_name and table_name in tables_used:             # <<<<<<<<<<<<<<
 *                     date_columns.append((table_name, col_name.split(".")[-1]))
 * 
 */
      }

      /* "sQQideR/SQLBuilder.pyx":737
 * 
 *             # Check if column is date/time related
 *             if ("date" in col_name or "time" in col_name or "day" in col_name) and col_name.split(".")[-1] in main_sql:             # <<<<<<<<<<<<<<
 *                 table_name = col_name.split(".")[0] if "." in col_name else None
 *                 if table_name and table_name in tables_used:
 */
    }

    /* "sQQideR/SQLBuilder.pyx":732
 *         # 2. For tables with time/date columns, add a time distribution exploration
 *         date_columns = []
 *         for column_obj in db_context.get("database_objects", {}).get("columns", []):             # <<<<<<<<<<<<<<
 *             col_name = column_obj.get("name", "").lower()
 *             data_type = column_obj.get("data_type", "").lower()
 */
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":743
 * 
 *         # Create time-based explorations
 *         for table, date_col in date_columns:             # <<<<<<<<<<<<<<
 *             time_query = {
 *                 "name": f"Time distribution for {table}.{date_col}",
 */
  __pyx_t_2 = __pyx_v_date_columns; __Pyx_INCREF(__pyx_t_2);
  __pyx_t_9 = 0;
  for (;;) {
    {
      Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_2);
      #if !CYTHON_ASSUME_SAFE_MACROS
      if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 743, __pyx_L1_error)
      #endif
      if (__pyx_t_9 >= __pyx_temp) break;
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_9); __Pyx_INCREF(__pyx_t_5); __pyx_t_9++; if (unlikely((0 < 0))) __PYX_ERR(0, 743, __pyx_L1_error)
    #else
    __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_2, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 743, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    #endif
    if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) {
      PyObject* sequence = __pyx_t_5;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 2)) {
        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 743, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_17 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
      } else {
        __pyx_t_17 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
      }
      __Pyx_INCREF(__pyx_t_17);
      __Pyx_INCREF(__pyx_t_6);
      #else
      __pyx_t_17 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 743, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_17);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 743, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      #endif
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_8 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 743, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_28 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_8);
      index = 0; __pyx_t_17 = __pyx_t_28(__pyx_t_8); if (unlikely(!__pyx_t_17)) goto __pyx_L48_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_17);
      index = 1; __pyx_t_6 = __pyx_t_28(__pyx_t_8); if (unlikely(!__pyx_t_6)) goto __pyx_L48_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_28(__pyx_t_8), 2) < 0) __PYX_ERR(0, 743, __pyx_L1_error)
      __pyx_t_28 = NULL;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      goto __pyx_L49_unpacking_done;
      __pyx_L48_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_28 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 743, __pyx_L1_error)
      __pyx_L49_unpacking_done:;
    }
    __Pyx_XDECREF_SET(__pyx_v_table, __pyx_t_17);
    __pyx_t_17 = 0;
    __Pyx_XDECREF_SET(__pyx_v_date_col, __pyx_t_6);
    __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":745
 *         for table, date_col in date_columns:
 *             time_query = {
 *                 "name": f"Time distribution for {table}.{date_col}",             # <<<<<<<<<<<<<<
 *                 "description": f"Shows the distribution of values in the {date_col} column",
 *                 "sql": f"SELECT {date_col}, COUNT(*) as count FROM {table} GROUP BY {date_col} ORDER BY COUNT(*) DESC LIMIT 5"
 */
    __pyx_t_5 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_12 = 0;
    __pyx_t_13 = 127;
    __Pyx_INCREF(__pyx_kp_u_Time_distribution_for);
    __pyx_t_12 += 22;
    __Pyx_GIVEREF(__pyx_kp_u_Time_distribution_for);
    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_Time_distribution_for);
    __pyx_t_17 = __Pyx_PyObject_FormatSimple(__pyx_v_table, __pyx_empty_unicode); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) : __pyx_t_13;
    __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_17);
    __Pyx_GIVEREF(__pyx_t_17);
    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_17);
    __pyx_t_17 = 0;
    __Pyx_INCREF(__pyx_kp_u__29);
    __pyx_t_12 += 1;
    __Pyx_GIVEREF(__pyx_kp_u__29);
    PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u__29);
    __pyx_t_17 = __Pyx_PyObject_FormatSimple(__pyx_v_date_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) : __pyx_t_13;
    __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_17);
    __Pyx_GIVEREF(__pyx_t_17);
    PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_17);
    __pyx_t_17 = 0;
    __pyx_t_17 = __Pyx_PyUnicode_Join(__pyx_t_6, 4, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_name, __pyx_t_17) < 0) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;

    /* "sQQideR/SQLBuilder.pyx":746
 *             time_query = {
 *                 "name": f"Time distribution for {table}.{date_col}",
 *                 "description": f"Shows the distribution of values in the {date_col} column",             # <<<<<<<<<<<<<<
 *                 "sql": f"SELECT {date_col}, COUNT(*) as count FROM {table} GROUP BY {date_col} ORDER BY COUNT(*) DESC LIMIT 5"
 *             }
 */
    __pyx_t_17 = PyTuple_New(3); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 746, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __pyx_t_12 = 0;
    __pyx_t_13 = 127;
    __Pyx_INCREF(__pyx_kp_u_Shows_the_distribution_of_values);
    __pyx_t_12 += 40;
    __Pyx_GIVEREF(__pyx_kp_u_Shows_the_distribution_of_values);
    PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_kp_u_Shows_the_distribution_of_values);
    __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_date_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 746, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_13;
    __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_6);
    PyTuple_SET_ITEM(__pyx_t_17, 1, __pyx_t_6);
    __pyx_t_6 = 0;
    __Pyx_INCREF(__pyx_kp_u_column);
    __pyx_t_12 += 7;
    __Pyx_GIVEREF(__pyx_kp_u_column);
    PyTuple_SET_ITEM(__pyx_t_17, 2, __pyx_kp_u_column);
    __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_17, 3, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 746, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
    if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_description, __pyx_t_6) < 0) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":747
 *                 "name": f"Time distribution for {table}.{date_col}",
 *                 "description": f"Shows the distribution of values in the {date_col} column",
 *                 "sql": f"SELECT {date_col}, COUNT(*) as count FROM {table} GROUP BY {date_col} ORDER BY COUNT(*) DESC LIMIT 5"             # <<<<<<<<<<<<<<
 *             }
 * 
 */
    __pyx_t_6 = PyTuple_New(7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 747, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_12 = 0;
    __pyx_t_13 = 127;
    __Pyx_INCREF(__pyx_kp_u_SELECT);
    __pyx_t_12 += 7;
    __Pyx_GIVEREF(__pyx_kp_u_SELECT);
    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_SELECT);
    __pyx_t_17 = __Pyx_PyObject_FormatSimple(__pyx_v_date_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 747, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) : __pyx_t_13;
    __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_17);
    __Pyx_GIVEREF(__pyx_t_17);
    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_17);
    __pyx_t_17 = 0;
    __Pyx_INCREF(__pyx_kp_u_COUNT_as_count_FROM);
    __pyx_t_12 += 25;
    __Pyx_GIVEREF(__pyx_kp_u_COUNT_as_count_FROM);
    PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u_COUNT_as_count_FROM);
    __pyx_t_17 = __Pyx_PyObject_FormatSimple(__pyx_v_table, __pyx_empty_unicode); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 747, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) : __pyx_t_13;
    __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_17);
    __Pyx_GIVEREF(__pyx_t_17);
    PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_17);
    __pyx_t_17 = 0;
    __Pyx_INCREF(__pyx_kp_u_GROUP_BY);
    __pyx_t_12 += 10;
    __Pyx_GIVEREF(__pyx_kp_u_GROUP_BY);
    PyTuple_SET_ITEM(__pyx_t_6, 4, __pyx_kp_u_GROUP_BY);
    __pyx_t_17 = __Pyx_PyObject_FormatSimple(__pyx_v_date_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 747, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_17) : __pyx_t_13;
    __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_17);
    __Pyx_GIVEREF(__pyx_t_17);
    PyTuple_SET_ITEM(__pyx_t_6, 5, __pyx_t_17);
    __pyx_t_17 = 0;
    __Pyx_INCREF(__pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5);
    __pyx_t_12 += 31;
    __Pyx_GIVEREF(__pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5);
    PyTuple_SET_ITEM(__pyx_t_6, 6, __pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5);
    __pyx_t_17 = __Pyx_PyUnicode_Join(__pyx_t_6, 7, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 747, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_17);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_sql, __pyx_t_17) < 0) __PYX_ERR(0, 745, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
    __Pyx_XDECREF_SET(__pyx_v_time_query, ((PyObject*)__pyx_t_5));
    __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":750
 *             }
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 df = pd.read_sql_query(time_query["sql"], self.conn)
 *                 time_query["success"] = True
 */
    {
      __Pyx_PyThreadState_declare
      __Pyx_PyThreadState_assign
      __Pyx_ExceptionSave(&__pyx_t_16, &__pyx_t_15, &__pyx_t_14);
      __Pyx_XGOTREF(__pyx_t_16);
      __Pyx_XGOTREF(__pyx_t_15);
      __Pyx_XGOTREF(__pyx_t_14);
      /*try:*/ {

        /* "sQQideR/SQLBuilder.pyx":751
 * 
 *             try:
 *                 df = pd.read_sql_query(time_query["sql"], self.conn)             # <<<<<<<<<<<<<<
 *                 time_query["success"] = True
 *                 time_query["results"] = df.to_dict(orient="records")
 */
        __Pyx_GetModuleGlobalName(__pyx_t_17, __pyx_n_s_pd); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 751, __pyx_L50_error)
        __Pyx_GOTREF(__pyx_t_17);
        __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_17, __pyx_n_s_read_sql_query); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 751, __pyx_L50_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
        __pyx_t_17 = __Pyx_PyDict_GetItem(__pyx_v_time_query, __pyx_n_u_sql); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 751, __pyx_L50_error)
        __Pyx_GOTREF(__pyx_t_17);
        __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 751, __pyx_L50_error)
        __Pyx_GOTREF(__pyx_t_8);
        __pyx_t_18 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (unlikely(PyMethod_Check(__pyx_t_6))) {
          __pyx_t_18 = PyMethod_GET_SELF(__pyx_t_6);
          if (likely(__pyx_t_18)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
            __Pyx_INCREF(__pyx_t_18);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_6, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[3] = {__pyx_t_18, __pyx_t_17, __pyx_t_8};
          __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
          __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
          __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
          if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 751, __pyx_L50_error)
          __Pyx_GOTREF(__pyx_t_5);
          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        }
        __Pyx_XDECREF_SET(__pyx_v_df, __pyx_t_5);
        __pyx_t_5 = 0;

        /* "sQQideR/SQLBuilder.pyx":752
 *             try:
 *                 df = pd.read_sql_query(time_query["sql"], self.conn)
 *                 time_query["success"] = True             # <<<<<<<<<<<<<<
 *                 time_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(time_query)
 */
        if (unlikely((PyDict_SetItem(__pyx_v_time_query, __pyx_n_u_success, Py_True) < 0))) __PYX_ERR(0, 752, __pyx_L50_error)

        /* "sQQideR/SQLBuilder.pyx":753
 *                 df = pd.read_sql_query(time_query["sql"], self.conn)
 *                 time_query["success"] = True
 *                 time_query["results"] = df.to_dict(orient="records")             # <<<<<<<<<<<<<<
 *                 explorations.append(time_query)
 *             except Exception as e:
 */
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_to_dict); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 753, __pyx_L50_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 753, __pyx_L50_error)
        __Pyx_GOTREF(__pyx_t_6);
        if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_orient, __pyx_n_u_records) < 0) __PYX_ERR(0, 753, __pyx_L50_error)
        __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 753, __pyx_L50_error)
        __Pyx_GOTREF(__pyx_t_8);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        if (unlikely((PyDict_SetItem(__pyx_v_time_query, __pyx_n_u_results, __pyx_t_8) < 0))) __PYX_ERR(0, 753, __pyx_L50_error)
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

        /* "sQQideR/SQLBuilder.pyx":754
 *                 time_query["success"] = True
 *                 time_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(time_query)             # <<<<<<<<<<<<<<
 *             except Exception as e:
 *                 if self.verbose:
 */
        __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_explorations, __pyx_v_time_query); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 754, __pyx_L50_error)

        /* "sQQideR/SQLBuilder.pyx":750
 *             }
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 df = pd.read_sql_query(time_query["sql"], self.conn)
 *                 time_query["success"] = True
 */
      }
      __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
      __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
      __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
      goto __pyx_L57_try_end;
      __pyx_L50_error:;
      __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
      __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;

      /* "sQQideR/SQLBuilder.pyx":755
 *                 time_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(time_query)
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Error executing time exploration: {e}")
 */
      __pyx_t_20 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
      if (__pyx_t_20) {
        __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_additional_explorations", __pyx_clineno, __pyx_lineno, __pyx_filename);
        if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_6, &__pyx_t_5) < 0) __PYX_ERR(0, 755, __pyx_L52_except_error)
        __Pyx_XGOTREF(__pyx_t_8);
        __Pyx_XGOTREF(__pyx_t_6);
        __Pyx_XGOTREF(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_6);
        __pyx_v_e = __pyx_t_6;
        /*try:*/ {

          /* "sQQideR/SQLBuilder.pyx":756
 *                 explorations.append(time_query)
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Error executing time exploration: {e}")
 * 
 */
          __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 756, __pyx_L63_error)
          __Pyx_GOTREF(__pyx_t_17);
          __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_17); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 756, __pyx_L63_error)
          __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
          if (__pyx_t_1) {

            /* "sQQideR/SQLBuilder.pyx":757
 *             except Exception as e:
 *                 if self.verbose:
 *                     print(f"Error executing time exploration: {e}")             # <<<<<<<<<<<<<<
 * 
 *         # 3. If the main query has numeric results, add a statistical summary
 */
            __pyx_t_17 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 757, __pyx_L63_error)
            __Pyx_GOTREF(__pyx_t_17);
            __pyx_t_18 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_executing_time_exploration, __pyx_t_17); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 757, __pyx_L63_error)
            __Pyx_GOTREF(__pyx_t_18);
            __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
            __pyx_t_17 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_18); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 757, __pyx_L63_error)
            __Pyx_GOTREF(__pyx_t_17);
            __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
            __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;

            /* "sQQideR/SQLBuilder.pyx":756
 *                 explorations.append(time_query)
 *             except Exception as e:
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Error executing time exploration: {e}")
 * 
 */
          }
        }

        /* "sQQideR/SQLBuilder.pyx":755
 *                 time_query["results"] = df.to_dict(orient="records")
 *                 explorations.append(time_query)
 *             except Exception as e:             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Error executing time exploration: {e}")
 */
        /*finally:*/ {
          /*normal exit:*/{
            __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            goto __pyx_L64;
          }
          __pyx_L63_error:;
          /*exception exit:*/{
            __Pyx_PyThreadState_declare
            __Pyx_PyThreadState_assign
            __pyx_t_27 = 0; __pyx_t_26 = 0; __pyx_t_25 = 0; __pyx_t_24 = 0; __pyx_t_23 = 0; __pyx_t_22 = 0;
            __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
            __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
            if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_24, &__pyx_t_23, &__pyx_t_22);
            if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_27, &__pyx_t_26, &__pyx_t_25) < 0)) __Pyx_ErrFetch(&__pyx_t_27, &__pyx_t_26, &__pyx_t_25);
            __Pyx_XGOTREF(__pyx_t_27);
            __Pyx_XGOTREF(__pyx_t_26);
            __Pyx_XGOTREF(__pyx_t_25);
            __Pyx_XGOTREF(__pyx_t_24);
            __Pyx_XGOTREF(__pyx_t_23);
            __Pyx_XGOTREF(__pyx_t_22);
            __pyx_t_20 = __pyx_lineno; __pyx_t_19 = __pyx_clineno; __pyx_t_29 = __pyx_filename;
            {
              __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
            }
            if (PY_MAJOR_VERSION >= 3) {
              __Pyx_XGIVEREF(__pyx_t_24);
              __Pyx_XGIVEREF(__pyx_t_23);
              __Pyx_XGIVEREF(__pyx_t_22);
              __Pyx_ExceptionReset(__pyx_t_24, __pyx_t_23, __pyx_t_22);
            }
            __Pyx_XGIVEREF(__pyx_t_27);
            __Pyx_XGIVEREF(__pyx_t_26);
            __Pyx_XGIVEREF(__pyx_t_25);
            __Pyx_ErrRestore(__pyx_t_27, __pyx_t_26, __pyx_t_25);
            __pyx_t_27 = 0; __pyx_t_26 = 0; __pyx_t_25 = 0; __pyx_t_24 = 0; __pyx_t_23 = 0; __pyx_t_22 = 0;
            __pyx_lineno = __pyx_t_20; __pyx_clineno = __pyx_t_19; __pyx_filename = __pyx_t_29;
            goto __pyx_L52_except_error;
          }
          __pyx_L64:;
        }
        __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
        goto __pyx_L51_exception_handled;
      }
      goto __pyx_L52_except_error;

      /* "sQQideR/SQLBuilder.pyx":750
 *             }
 * 
 *             try:             # <<<<<<<<<<<<<<
 *                 df = pd.read_sql_query(time_query["sql"], self.conn)
 *                 time_query["success"] = True
 */
      __pyx_L52_except_error:;
      __Pyx_XGIVEREF(__pyx_t_16);
      __Pyx_XGIVEREF(__pyx_t_15);
      __Pyx_XGIVEREF(__pyx_t_14);
      __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_15, __pyx_t_14);
      goto __pyx_L1_error;
      __pyx_L51_exception_handled:;
      __Pyx_XGIVEREF(__pyx_t_16);
      __Pyx_XGIVEREF(__pyx_t_15);
      __Pyx_XGIVEREF(__pyx_t_14);
      __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_15, __pyx_t_14);
      __pyx_L57_try_end:;
    }

    /* "sQQideR/SQLBuilder.pyx":743
 * 
 *         # Create time-based explorations
 *         for table, date_col in date_columns:             # <<<<<<<<<<<<<<
 *             time_query = {
 *                 "name": f"Time distribution for {table}.{date_col}",
 */
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":760
 * 
 *         # 3. If the main query has numeric results, add a statistical summary
 *         if main_query.get("results") and len(main_query["results"]) > 0:             # <<<<<<<<<<<<<<
 *             numeric_columns = []
 *             first_result = main_query["results"][0]
 */
  __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_main_query, __pyx_n_u_results, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 760, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 760, __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_L72_bool_binop_done;
  }
  __pyx_t_2 = __Pyx_PyDict_GetItem(__pyx_v_main_query, __pyx_n_u_results); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 760, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_9 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_9 == ((Py_ssize_t)-1))) __PYX_ERR(0, 760, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_3 = (__pyx_t_9 > 0);
  __pyx_t_1 = __pyx_t_3;
  __pyx_L72_bool_binop_done:;
  if (__pyx_t_1) {

    /* "sQQideR/SQLBuilder.pyx":761
 *         # 3. If the main query has numeric results, add a statistical summary
 *         if main_query.get("results") and len(main_query["results"]) > 0:
 *             numeric_columns = []             # <<<<<<<<<<<<<<
 *             first_result = main_query["results"][0]
 * 
 */
    __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 761, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_v_numeric_columns = ((PyObject*)__pyx_t_2);
    __pyx_t_2 = 0;

    /* "sQQideR/SQLBuilder.pyx":762
 *         if main_query.get("results") and len(main_query["results"]) > 0:
 *             numeric_columns = []
 *             first_result = main_query["results"][0]             # <<<<<<<<<<<<<<
 * 
 *             for col, val in first_result.items():
 */
    __pyx_t_2 = __Pyx_PyDict_GetItem(__pyx_v_main_query, __pyx_n_u_results); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 762, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 762, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_v_first_result = __pyx_t_5;
    __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":764
 *             first_result = main_query["results"][0]
 * 
 *             for col, val in first_result.items():             # <<<<<<<<<<<<<<
 *                 if isinstance(val, (int, float)) and not isinstance(val, bool):
 *                     numeric_columns.append(col)
 */
    __pyx_t_9 = 0;
    if (unlikely(__pyx_v_first_result == Py_None)) {
      PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items");
      __PYX_ERR(0, 764, __pyx_L1_error)
    }
    __pyx_t_2 = __Pyx_dict_iterator(__pyx_v_first_result, 0, __pyx_n_s_items, (&__pyx_t_12), (&__pyx_t_19)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 764, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_XDECREF(__pyx_t_5);
    __pyx_t_5 = __pyx_t_2;
    __pyx_t_2 = 0;
    while (1) {
      __pyx_t_20 = __Pyx_dict_iter_next(__pyx_t_5, __pyx_t_12, &__pyx_t_9, &__pyx_t_2, &__pyx_t_6, NULL, __pyx_t_19);
      if (unlikely(__pyx_t_20 == 0)) break;
      if (unlikely(__pyx_t_20 == -1)) __PYX_ERR(0, 764, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_2);
      __pyx_t_2 = 0;
      __Pyx_XDECREF_SET(__pyx_v_val, __pyx_t_6);
      __pyx_t_6 = 0;

      /* "sQQideR/SQLBuilder.pyx":765
 * 
 *             for col, val in first_result.items():
 *                 if isinstance(val, (int, float)) and not isinstance(val, bool):             # <<<<<<<<<<<<<<
 *                     numeric_columns.append(col)
 * 
 */
      __pyx_t_4 = PyInt_Check(__pyx_v_val); 
      if (!__pyx_t_4) {
      } else {
        __pyx_t_3 = __pyx_t_4;
        goto __pyx_L79_bool_binop_done;
      }
      __pyx_t_4 = PyFloat_Check(__pyx_v_val); 
      __pyx_t_3 = __pyx_t_4;
      __pyx_L79_bool_binop_done:;
      if (__pyx_t_3) {
      } else {
        __pyx_t_1 = __pyx_t_3;
        goto __pyx_L77_bool_binop_done;
      }
      __pyx_t_6 = ((PyObject*)&PyBool_Type);
      __Pyx_INCREF(__pyx_t_6);
      __pyx_t_3 = PyObject_IsInstance(__pyx_v_val, __pyx_t_6); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 765, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __pyx_t_4 = (!__pyx_t_3);
      __pyx_t_1 = __pyx_t_4;
      __pyx_L77_bool_binop_done:;
      if (__pyx_t_1) {

        /* "sQQideR/SQLBuilder.pyx":766
 *             for col, val in first_result.items():
 *                 if isinstance(val, (int, float)) and not isinstance(val, bool):
 *                     numeric_columns.append(col)             # <<<<<<<<<<<<<<
 * 
 *             if numeric_columns and tables_used:
 */
        __pyx_t_11 = __Pyx_PyList_Append(__pyx_v_numeric_columns, __pyx_v_col); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 766, __pyx_L1_error)

        /* "sQQideR/SQLBuilder.pyx":765
 * 
 *             for col, val in first_result.items():
 *                 if isinstance(val, (int, float)) and not isinstance(val, bool):             # <<<<<<<<<<<<<<
 *                     numeric_columns.append(col)
 * 
 */
      }
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":768
 *                     numeric_columns.append(col)
 * 
 *             if numeric_columns and tables_used:             # <<<<<<<<<<<<<<
 *                 stats_query_dict = {
 *                     "name": "Statistical summary",
 */
    __pyx_t_4 = (PyList_GET_SIZE(__pyx_v_numeric_columns) != 0);
    if (__pyx_t_4) {
    } else {
      __pyx_t_1 = __pyx_t_4;
      goto __pyx_L82_bool_binop_done;
    }
    __pyx_t_4 = (PyList_GET_SIZE(__pyx_v_tables_used) != 0);
    __pyx_t_1 = __pyx_t_4;
    __pyx_L82_bool_binop_done:;
    if (__pyx_t_1) {

      /* "sQQideR/SQLBuilder.pyx":770
 *             if numeric_columns and tables_used:
 *                 stats_query_dict = {
 *                     "name": "Statistical summary",             # <<<<<<<<<<<<<<
 *                     "description": "Statistical summary of numeric values from the main query",
 *                     "source": "exploration_stats",
 */
      __pyx_t_5 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 770, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_name, __pyx_kp_u_Statistical_summary) < 0) __PYX_ERR(0, 770, __pyx_L1_error)
      if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_description, __pyx_kp_u_Statistical_summary_of_numeric_v) < 0) __PYX_ERR(0, 770, __pyx_L1_error)
      if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_source, __pyx_n_u_exploration_stats) < 0) __PYX_ERR(0, 770, __pyx_L1_error)

      /* "sQQideR/SQLBuilder.pyx":773
 *                     "description": "Statistical summary of numeric values from the main query",
 *                     "source": "exploration_stats",
 *                     "question": f"Statistical summary for {question}"             # <<<<<<<<<<<<<<
 *                 }
 * 
 */
      __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Statistical_summary_for, __pyx_cur_scope->__pyx_v_question); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 773, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      if (PyDict_SetItem(__pyx_t_5, __pyx_n_u_question, __pyx_t_6) < 0) __PYX_ERR(0, 770, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __pyx_v_stats_query_dict = ((PyObject*)__pyx_t_5);
      __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":777
 * 
 *                 # Build the statistical aggregation part of the query
 *                 agg_parts = []             # <<<<<<<<<<<<<<
 *                 for col in numeric_columns:
 *                     agg_parts.extend([
 */
      __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 777, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_v_agg_parts = ((PyObject*)__pyx_t_5);
      __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":778
 *                 # Build the statistical aggregation part of the query
 *                 agg_parts = []
 *                 for col in numeric_columns:             # <<<<<<<<<<<<<<
 *                     agg_parts.extend([
 *                         f"MIN({col}) AS min_{col}",
 */
      __pyx_t_5 = __pyx_v_numeric_columns; __Pyx_INCREF(__pyx_t_5);
      __pyx_t_12 = 0;
      for (;;) {
        {
          Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5);
          #if !CYTHON_ASSUME_SAFE_MACROS
          if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 778, __pyx_L1_error)
          #endif
          if (__pyx_t_12 >= __pyx_temp) break;
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_6 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_12); __Pyx_INCREF(__pyx_t_6); __pyx_t_12++; if (unlikely((0 < 0))) __PYX_ERR(0, 778, __pyx_L1_error)
        #else
        __pyx_t_6 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 778, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        #endif
        __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_6);
        __pyx_t_6 = 0;

        /* "sQQideR/SQLBuilder.pyx":780
 *                 for col in numeric_columns:
 *                     agg_parts.extend([
 *                         f"MIN({col}) AS min_{col}",             # <<<<<<<<<<<<<<
 *                         f"MAX({col}) AS max_{col}",
 *                         f"AVG({col}) AS avg_{col}"
 */
        __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 780, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_9 = 0;
        __pyx_t_13 = 127;
        __Pyx_INCREF(__pyx_kp_u_MIN);
        __pyx_t_9 += 4;
        __Pyx_GIVEREF(__pyx_kp_u_MIN);
        PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_MIN);
        __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 780, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_13;
        __pyx_t_9 += __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_AS_min);
        __pyx_t_9 += 9;
        __Pyx_GIVEREF(__pyx_kp_u_AS_min);
        PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u_AS_min);
        __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 780, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_13;
        __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2);
        __Pyx_GIVEREF(__pyx_t_2);
        PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_2);
        __pyx_t_2 = 0;
        __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_6, 4, __pyx_t_9, __pyx_t_13); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 780, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

        /* "sQQideR/SQLBuilder.pyx":779
 *                 agg_parts = []
 *                 for col in numeric_columns:
 *                     agg_parts.extend([             # <<<<<<<<<<<<<<
 *                         f"MIN({col}) AS min_{col}",
 *                         f"MAX({col}) AS max_{col}",
 */
        __pyx_t_11 = __Pyx_ListComp_Append(__pyx_v_agg_parts, __pyx_t_2); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 779, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":781
 *                     agg_parts.extend([
 *                         f"MIN({col}) AS min_{col}",
 *                         f"MAX({col}) AS max_{col}",             # <<<<<<<<<<<<<<
 *                         f"AVG({col}) AS avg_{col}"
 *                     ])
 */
        __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 781, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_9 = 0;
        __pyx_t_13 = 127;
        __Pyx_INCREF(__pyx_kp_u_MAX);
        __pyx_t_9 += 4;
        __Pyx_GIVEREF(__pyx_kp_u_MAX);
        PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_MAX);
        __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 781, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_13;
        __pyx_t_9 += __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_AS_max);
        __pyx_t_9 += 9;
        __Pyx_GIVEREF(__pyx_kp_u_AS_max);
        PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u_AS_max);
        __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 781, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_13;
        __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
        __Pyx_GIVEREF(__pyx_t_6);
        PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_6);
        __pyx_t_6 = 0;
        __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_2, 4, __pyx_t_9, __pyx_t_13); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 781, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":779
 *                 agg_parts = []
 *                 for col in numeric_columns:
 *                     agg_parts.extend([             # <<<<<<<<<<<<<<
 *                         f"MIN({col}) AS min_{col}",
 *                         f"MAX({col}) AS max_{col}",
 */
        __pyx_t_30 = __Pyx_ListComp_Append(__pyx_v_agg_parts, __pyx_t_6); if (unlikely(__pyx_t_30 == ((int)-1))) __PYX_ERR(0, 779, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

        /* "sQQideR/SQLBuilder.pyx":782
 *                         f"MIN({col}) AS min_{col}",
 *                         f"MAX({col}) AS max_{col}",
 *                         f"AVG({col}) AS avg_{col}"             # <<<<<<<<<<<<<<
 *                     ])
 * 
 */
        __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 782, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_9 = 0;
        __pyx_t_13 = 127;
        __Pyx_INCREF(__pyx_kp_u_AVG);
        __pyx_t_9 += 4;
        __Pyx_GIVEREF(__pyx_kp_u_AVG);
        PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_kp_u_AVG);
        __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_13;
        __pyx_t_9 += __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_AS_avg);
        __pyx_t_9 += 9;
        __Pyx_GIVEREF(__pyx_kp_u_AS_avg);
        PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_kp_u_AS_avg);
        __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_v_col, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_13;
        __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2);
        __Pyx_GIVEREF(__pyx_t_2);
        PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_2);
        __pyx_t_2 = 0;
        __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_6, 4, __pyx_t_9, __pyx_t_13); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

        /* "sQQideR/SQLBuilder.pyx":779
 *                 agg_parts = []
 *                 for col in numeric_columns:
 *                     agg_parts.extend([             # <<<<<<<<<<<<<<
 *                         f"MIN({col}) AS min_{col}",
 *                         f"MAX({col}) AS max_{col}",
 */
        __pyx_t_31 = __Pyx_PyList_Append(__pyx_v_agg_parts, __pyx_t_2); if (unlikely(__pyx_t_31 == ((int)-1))) __PYX_ERR(0, 779, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        (void)((__pyx_t_11 | (__pyx_t_30 | __pyx_t_31)));

        /* "sQQideR/SQLBuilder.pyx":778
 *                 # Build the statistical aggregation part of the query
 *                 agg_parts = []
 *                 for col in numeric_columns:             # <<<<<<<<<<<<<<
 *                     agg_parts.extend([
 *                         f"MIN({col}) AS min_{col}",
 */
      }
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":785
 *                     ])
 * 
 *                 if agg_parts:             # <<<<<<<<<<<<<<
 *                     sql = f"SELECT {', '.join(agg_parts)} FROM {tables_used[0]}"
 *                     stats_query_dict["sql"] = sql
 */
      __pyx_t_1 = (PyList_GET_SIZE(__pyx_v_agg_parts) != 0);
      if (__pyx_t_1) {

        /* "sQQideR/SQLBuilder.pyx":786
 * 
 *                 if agg_parts:
 *                     sql = f"SELECT {', '.join(agg_parts)} FROM {tables_used[0]}"             # <<<<<<<<<<<<<<
 *                     stats_query_dict["sql"] = sql
 * 
 */
        __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 786, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_12 = 0;
        __pyx_t_13 = 127;
        __Pyx_INCREF(__pyx_kp_u_SELECT);
        __pyx_t_12 += 7;
        __Pyx_GIVEREF(__pyx_kp_u_SELECT);
        PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_SELECT);
        __pyx_t_2 = PyUnicode_Join(__pyx_kp_u__30, __pyx_v_agg_parts); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 786, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_13;
        __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2);
        __Pyx_GIVEREF(__pyx_t_2);
        PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
        __pyx_t_2 = 0;
        __Pyx_INCREF(__pyx_kp_u_FROM);
        __pyx_t_12 += 6;
        __Pyx_GIVEREF(__pyx_kp_u_FROM);
        PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_FROM);
        __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_tables_used, 0, long, 1, __Pyx_PyInt_From_long, 1, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 786, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 786, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_13;
        __pyx_t_12 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
        __Pyx_GIVEREF(__pyx_t_6);
        PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_6);
        __pyx_t_6 = 0;
        __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_5, 4, __pyx_t_12, __pyx_t_13); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 786, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __pyx_v_sql = ((PyObject*)__pyx_t_6);
        __pyx_t_6 = 0;

        /* "sQQideR/SQLBuilder.pyx":787
 *                 if agg_parts:
 *                     sql = f"SELECT {', '.join(agg_parts)} FROM {tables_used[0]}"
 *                     stats_query_dict["sql"] = sql             # <<<<<<<<<<<<<<
 * 
 *                     # Test the query
 */
        if (unlikely((PyDict_SetItem(__pyx_v_stats_query_dict, __pyx_n_u_sql, __pyx_v_sql) < 0))) __PYX_ERR(0, 787, __pyx_L1_error)

        /* "sQQideR/SQLBuilder.pyx":790
 * 
 *                     # Test the query
 *                     tested_query = self.test_query(stats_query_dict)             # <<<<<<<<<<<<<<
 * 
 *                     # If the query failed, try to fix it
 */
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_test_query); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 790, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_2 = NULL;
        __pyx_t_7 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_5))) {
          __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5);
          if (likely(__pyx_t_2)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
            __Pyx_INCREF(__pyx_t_2);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_5, function);
            __pyx_t_7 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_v_stats_query_dict};
          __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
          __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
          if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 790, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_6);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        }
        __pyx_v_tested_query = __pyx_t_6;
        __pyx_t_6 = 0;

        /* "sQQideR/SQLBuilder.pyx":793
 * 
 *                     # If the query failed, try to fix it
 *                     if not tested_query.get("success", False):             # <<<<<<<<<<<<<<
 *                         retry_info = self.try_fix_failed_query(tested_query, stats_query_dict["question"], db_context)
 *                         if retry_info["best_attempt"]:
 */
        __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_tested_query, __pyx_n_s_get); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 793, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 793, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 793, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __pyx_t_4 = (!__pyx_t_1);
        if (__pyx_t_4) {

          /* "sQQideR/SQLBuilder.pyx":794
 *                     # If the query failed, try to fix it
 *                     if not tested_query.get("success", False):
 *                         retry_info = self.try_fix_failed_query(tested_query, stats_query_dict["question"], db_context)             # <<<<<<<<<<<<<<
 *                         if retry_info["best_attempt"]:
 *                             tested_query = retry_info["best_attempt"]
 */
          __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_try_fix_failed_query); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 794, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_6);
          __pyx_t_2 = __Pyx_PyDict_GetItem(__pyx_v_stats_query_dict, __pyx_n_u_question); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 794, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          __pyx_t_8 = NULL;
          __pyx_t_7 = 0;
          #if CYTHON_UNPACK_METHODS
          if (likely(PyMethod_Check(__pyx_t_6))) {
            __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_6);
            if (likely(__pyx_t_8)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
              __Pyx_INCREF(__pyx_t_8);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_6, function);
              __pyx_t_7 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[4] = {__pyx_t_8, __pyx_v_tested_query, __pyx_t_2, __pyx_v_db_context};
            __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 3+__pyx_t_7);
            __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
            __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
            if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 794, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
          }
          __pyx_v_retry_info = __pyx_t_5;
          __pyx_t_5 = 0;

          /* "sQQideR/SQLBuilder.pyx":795
 *                     if not tested_query.get("success", False):
 *                         retry_info = self.try_fix_failed_query(tested_query, stats_query_dict["question"], db_context)
 *                         if retry_info["best_attempt"]:             # <<<<<<<<<<<<<<
 *                             tested_query = retry_info["best_attempt"]
 * 
 */
          __pyx_t_5 = __Pyx_PyObject_Dict_GetItem(__pyx_v_retry_info, __pyx_n_u_best_attempt); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 795, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 795, __pyx_L1_error)
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          if (__pyx_t_4) {

            /* "sQQideR/SQLBuilder.pyx":796
 *                         retry_info = self.try_fix_failed_query(tested_query, stats_query_dict["question"], db_context)
 *                         if retry_info["best_attempt"]:
 *                             tested_query = retry_info["best_attempt"]             # <<<<<<<<<<<<<<
 * 
 *                     # Only add successful queries
 */
            __pyx_t_5 = __Pyx_PyObject_Dict_GetItem(__pyx_v_retry_info, __pyx_n_u_best_attempt); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 796, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF_SET(__pyx_v_tested_query, __pyx_t_5);
            __pyx_t_5 = 0;

            /* "sQQideR/SQLBuilder.pyx":795
 *                     if not tested_query.get("success", False):
 *                         retry_info = self.try_fix_failed_query(tested_query, stats_query_dict["question"], db_context)
 *                         if retry_info["best_attempt"]:             # <<<<<<<<<<<<<<
 *                             tested_query = retry_info["best_attempt"]
 * 
 */
          }

          /* "sQQideR/SQLBuilder.pyx":793
 * 
 *                     # If the query failed, try to fix it
 *                     if not tested_query.get("success", False):             # <<<<<<<<<<<<<<
 *                         retry_info = self.try_fix_failed_query(tested_query, stats_query_dict["question"], db_context)
 *                         if retry_info["best_attempt"]:
 */
        }

        /* "sQQideR/SQLBuilder.pyx":799
 * 
 *                     # Only add successful queries
 *                     if tested_query.get("success", False):             # <<<<<<<<<<<<<<
 *                         explorations.append(tested_query)
 *                     elif self.verbose:
 */
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_tested_query, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 799, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 799, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 799, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        if (__pyx_t_4) {

          /* "sQQideR/SQLBuilder.pyx":800
 *                     # Only add successful queries
 *                     if tested_query.get("success", False):
 *                         explorations.append(tested_query)             # <<<<<<<<<<<<<<
 *                     elif self.verbose:
 *                         print(f"Stats exploration failed and couldn't be fixed: {tested_query.get('execution_error')}")
 */
          __pyx_t_31 = __Pyx_PyList_Append(__pyx_v_explorations, __pyx_v_tested_query); if (unlikely(__pyx_t_31 == ((int)-1))) __PYX_ERR(0, 800, __pyx_L1_error)

          /* "sQQideR/SQLBuilder.pyx":799
 * 
 *                     # Only add successful queries
 *                     if tested_query.get("success", False):             # <<<<<<<<<<<<<<
 *                         explorations.append(tested_query)
 *                     elif self.verbose:
 */
          goto __pyx_L90;
        }

        /* "sQQideR/SQLBuilder.pyx":801
 *                     if tested_query.get("success", False):
 *                         explorations.append(tested_query)
 *                     elif self.verbose:             # <<<<<<<<<<<<<<
 *                         print(f"Stats exploration failed and couldn't be fixed: {tested_query.get('execution_error')}")
 * 
 */
        __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 801, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 801, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        if (__pyx_t_4) {

          /* "sQQideR/SQLBuilder.pyx":802
 *                         explorations.append(tested_query)
 *                     elif self.verbose:
 *                         print(f"Stats exploration failed and couldn't be fixed: {tested_query.get('execution_error')}")             # <<<<<<<<<<<<<<
 * 
 *         # 4. If the question relates to relationships, explore relationship counts
 */
          __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_tested_query, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 802, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_2 = NULL;
          __pyx_t_7 = 0;
          #if CYTHON_UNPACK_METHODS
          if (likely(PyMethod_Check(__pyx_t_5))) {
            __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5);
            if (likely(__pyx_t_2)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
              __Pyx_INCREF(__pyx_t_2);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_5, function);
              __pyx_t_7 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_n_u_execution_error};
            __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
            __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
            if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 802, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_6);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          }
          __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_6, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 802, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
          __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Stats_exploration_failed_and_cou, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 802, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_6);
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 802, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
          __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

          /* "sQQideR/SQLBuilder.pyx":801
 *                     if tested_query.get("success", False):
 *                         explorations.append(tested_query)
 *                     elif self.verbose:             # <<<<<<<<<<<<<<
 *                         print(f"Stats exploration failed and couldn't be fixed: {tested_query.get('execution_error')}")
 * 
 */
        }
        __pyx_L90:;

        /* "sQQideR/SQLBuilder.pyx":785
 *                     ])
 * 
 *                 if agg_parts:             # <<<<<<<<<<<<<<
 *                     sql = f"SELECT {', '.join(agg_parts)} FROM {tables_used[0]}"
 *                     stats_query_dict["sql"] = sql
 */
      }

      /* "sQQideR/SQLBuilder.pyx":768
 *                     numeric_columns.append(col)
 * 
 *             if numeric_columns and tables_used:             # <<<<<<<<<<<<<<
 *                 stats_query_dict = {
 *                     "name": "Statistical summary",
 */
    }

    /* "sQQideR/SQLBuilder.pyx":760
 * 
 *         # 3. If the main query has numeric results, add a statistical summary
 *         if main_query.get("results") and len(main_query["results"]) > 0:             # <<<<<<<<<<<<<<
 *             numeric_columns = []
 *             first_result = main_query["results"][0]
 */
  }

  /* "sQQideR/SQLBuilder.pyx":805
 * 
 *         # 4. If the question relates to relationships, explore relationship counts
 *         relationship_keywords = ["relation", "connect", "join", "link", "between"]             # <<<<<<<<<<<<<<
 *         if any(keyword in question.lower() for keyword in relationship_keywords) and len(tables_used) > 1:
 *             # Find relationships between the used tables from context
 */
  __pyx_t_5 = PyList_New(5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 805, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_INCREF(__pyx_n_u_relation);
  __Pyx_GIVEREF(__pyx_n_u_relation);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 0, __pyx_n_u_relation)) __PYX_ERR(0, 805, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_u_connect);
  __Pyx_GIVEREF(__pyx_n_u_connect);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 1, __pyx_n_u_connect)) __PYX_ERR(0, 805, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_u_join);
  __Pyx_GIVEREF(__pyx_n_u_join);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 2, __pyx_n_u_join)) __PYX_ERR(0, 805, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_u_link);
  __Pyx_GIVEREF(__pyx_n_u_link);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 3, __pyx_n_u_link)) __PYX_ERR(0, 805, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_u_between);
  __Pyx_GIVEREF(__pyx_n_u_between);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_5, 4, __pyx_n_u_between)) __PYX_ERR(0, 805, __pyx_L1_error);
  __pyx_v_relationship_keywords = ((PyObject*)__pyx_t_5);
  __pyx_t_5 = 0;

  /* "sQQideR/SQLBuilder.pyx":806
 *         # 4. If the question relates to relationships, explore relationship counts
 *         relationship_keywords = ["relation", "connect", "join", "link", "between"]
 *         if any(keyword in question.lower() for keyword in relationship_keywords) and len(tables_used) > 1:             # <<<<<<<<<<<<<<
 *             # Find relationships between the used tables from context
 *             for rel in db_context.get("relationships", []):
 */
  __pyx_t_5 = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_genexpr(((PyObject*)__pyx_cur_scope), __pyx_v_relationship_keywords); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 806, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = __Pyx_Generator_Next(__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 806, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 806, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  if (__pyx_t_1) {
  } else {
    __pyx_t_4 = __pyx_t_1;
    goto __pyx_L92_bool_binop_done;
  }
  __pyx_t_12 = __Pyx_PyList_GET_SIZE(__pyx_v_tables_used); if (unlikely(__pyx_t_12 == ((Py_ssize_t)-1))) __PYX_ERR(0, 806, __pyx_L1_error)
  __pyx_t_1 = (__pyx_t_12 > 1);
  __pyx_t_4 = __pyx_t_1;
  __pyx_L92_bool_binop_done:;
  if (__pyx_t_4) {

    /* "sQQideR/SQLBuilder.pyx":808
 *         if any(keyword in question.lower() for keyword in relationship_keywords) and len(tables_used) > 1:
 *             # Find relationships between the used tables from context
 *             for rel in db_context.get("relationships", []):             # <<<<<<<<<<<<<<
 *                 source = rel.get("source", "").lower()
 *                 target = rel.get("target", "").lower()
 */
    __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 808, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_5 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_relationships, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 808, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
      __pyx_t_6 = __pyx_t_5; __Pyx_INCREF(__pyx_t_6);
      __pyx_t_12 = 0;
      __pyx_t_10 = NULL;
    } else {
      __pyx_t_12 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 808, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_10 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_6); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 808, __pyx_L1_error)
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    for (;;) {
      if (likely(!__pyx_t_10)) {
        if (likely(PyList_CheckExact(__pyx_t_6))) {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_6);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 808, __pyx_L1_error)
            #endif
            if (__pyx_t_12 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_5 = PyList_GET_ITEM(__pyx_t_6, __pyx_t_12); __Pyx_INCREF(__pyx_t_5); __pyx_t_12++; if (unlikely((0 < 0))) __PYX_ERR(0, 808, __pyx_L1_error)
          #else
          __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 808, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          #endif
        } else {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_6);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 808, __pyx_L1_error)
            #endif
            if (__pyx_t_12 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_6, __pyx_t_12); __Pyx_INCREF(__pyx_t_5); __pyx_t_12++; if (unlikely((0 < 0))) __PYX_ERR(0, 808, __pyx_L1_error)
          #else
          __pyx_t_5 = __Pyx_PySequence_ITEM(__pyx_t_6, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 808, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          #endif
        }
      } else {
        __pyx_t_5 = __pyx_t_10(__pyx_t_6);
        if (unlikely(!__pyx_t_5)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 808, __pyx_L1_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_5);
      }
      __Pyx_XDECREF_SET(__pyx_v_rel, __pyx_t_5);
      __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":809
 *             # Find relationships between the used tables from context
 *             for rel in db_context.get("relationships", []):
 *                 source = rel.get("source", "").lower()             # <<<<<<<<<<<<<<
 *                 target = rel.get("target", "").lower()
 * 
 */
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_rel, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 809, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 809, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_lower); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 809, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_8 = NULL;
      __pyx_t_7 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(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_7 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_8, NULL};
        __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
        __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
        if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 809, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      }
      __Pyx_XDECREF_SET(__pyx_v_source, __pyx_t_5);
      __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":810
 *             for rel in db_context.get("relationships", []):
 *                 source = rel.get("source", "").lower()
 *                 target = rel.get("target", "").lower()             # <<<<<<<<<<<<<<
 * 
 *                 if source in tables_used and target in tables_used:
 */
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_rel, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 810, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 810, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_lower); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 810, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __pyx_t_8 = NULL;
      __pyx_t_7 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(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_7 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_8, NULL};
        __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
        __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
        if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 810, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      }
      __Pyx_XDECREF_SET(__pyx_v_target, __pyx_t_5);
      __pyx_t_5 = 0;

      /* "sQQideR/SQLBuilder.pyx":812
 *                 target = rel.get("target", "").lower()
 * 
 *                 if source in tables_used and target in tables_used:             # <<<<<<<<<<<<<<
 *                     join_condition = rel.get("join_condition", "")
 *                     if join_condition:
 */
      __pyx_t_1 = (__Pyx_PySequence_ContainsTF(__pyx_v_source, __pyx_v_tables_used, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 812, __pyx_L1_error)
      if (__pyx_t_1) {
      } else {
        __pyx_t_4 = __pyx_t_1;
        goto __pyx_L97_bool_binop_done;
      }
      __pyx_t_1 = (__Pyx_PySequence_ContainsTF(__pyx_v_target, __pyx_v_tables_used, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 812, __pyx_L1_error)
      __pyx_t_4 = __pyx_t_1;
      __pyx_L97_bool_binop_done:;
      if (__pyx_t_4) {

        /* "sQQideR/SQLBuilder.pyx":813
 * 
 *                 if source in tables_used and target in tables_used:
 *                     join_condition = rel.get("join_condition", "")             # <<<<<<<<<<<<<<
 *                     if join_condition:
 *                         parts = join_condition.split("=")
 */
        __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_rel, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 813, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 813, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_XDECREF_SET(__pyx_v_join_condition, __pyx_t_2);
        __pyx_t_2 = 0;

        /* "sQQideR/SQLBuilder.pyx":814
 *                 if source in tables_used and target in tables_used:
 *                     join_condition = rel.get("join_condition", "")
 *                     if join_condition:             # <<<<<<<<<<<<<<
 *                         parts = join_condition.split("=")
 *                         if len(parts) == 2:
 */
        __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_join_condition); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 814, __pyx_L1_error)
        if (__pyx_t_4) {

          /* "sQQideR/SQLBuilder.pyx":815
 *                     join_condition = rel.get("join_condition", "")
 *                     if join_condition:
 *                         parts = join_condition.split("=")             # <<<<<<<<<<<<<<
 *                         if len(parts) == 2:
 *                             left_side = parts[0].strip()
 */
          __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_join_condition, __pyx_n_s_split); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 815, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_5);
          __pyx_t_8 = NULL;
          __pyx_t_7 = 0;
          #if CYTHON_UNPACK_METHODS
          if (likely(PyMethod_Check(__pyx_t_5))) {
            __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_5);
            if (likely(__pyx_t_8)) {
              PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
              __Pyx_INCREF(__pyx_t_8);
              __Pyx_INCREF(function);
              __Pyx_DECREF_SET(__pyx_t_5, function);
              __pyx_t_7 = 1;
            }
          }
          #endif
          {
            PyObject *__pyx_callargs[2] = {__pyx_t_8, __pyx_kp_u__31};
            __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
            __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
            if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 815, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
          }
          __Pyx_XDECREF_SET(__pyx_v_parts, __pyx_t_2);
          __pyx_t_2 = 0;

          /* "sQQideR/SQLBuilder.pyx":816
 *                     if join_condition:
 *                         parts = join_condition.split("=")
 *                         if len(parts) == 2:             # <<<<<<<<<<<<<<
 *                             left_side = parts[0].strip()
 *                             right_side = parts[1].strip()
 */
          __pyx_t_9 = PyObject_Length(__pyx_v_parts); if (unlikely(__pyx_t_9 == ((Py_ssize_t)-1))) __PYX_ERR(0, 816, __pyx_L1_error)
          __pyx_t_4 = (__pyx_t_9 == 2);
          if (__pyx_t_4) {

            /* "sQQideR/SQLBuilder.pyx":817
 *                         parts = join_condition.split("=")
 *                         if len(parts) == 2:
 *                             left_side = parts[0].strip()             # <<<<<<<<<<<<<<
 *                             right_side = parts[1].strip()
 * 
 */
            __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_parts, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 817, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_strip); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 817, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            __pyx_t_5 = NULL;
            __pyx_t_7 = 0;
            #if CYTHON_UNPACK_METHODS
            if (likely(PyMethod_Check(__pyx_t_8))) {
              __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_8);
              if (likely(__pyx_t_5)) {
                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
                __Pyx_INCREF(__pyx_t_5);
                __Pyx_INCREF(function);
                __Pyx_DECREF_SET(__pyx_t_8, function);
                __pyx_t_7 = 1;
              }
            }
            #endif
            {
              PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL};
              __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_8, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
              __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
              if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 817, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
            }
            __Pyx_XDECREF_SET(__pyx_v_left_side, __pyx_t_2);
            __pyx_t_2 = 0;

            /* "sQQideR/SQLBuilder.pyx":818
 *                         if len(parts) == 2:
 *                             left_side = parts[0].strip()
 *                             right_side = parts[1].strip()             # <<<<<<<<<<<<<<
 * 
 *                             relationship_query = {
 */
            __pyx_t_8 = __Pyx_GetItemInt(__pyx_v_parts, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 818, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_strip); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 818, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
            __pyx_t_8 = NULL;
            __pyx_t_7 = 0;
            #if CYTHON_UNPACK_METHODS
            if (likely(PyMethod_Check(__pyx_t_5))) {
              __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_5);
              if (likely(__pyx_t_8)) {
                PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                __Pyx_INCREF(__pyx_t_8);
                __Pyx_INCREF(function);
                __Pyx_DECREF_SET(__pyx_t_5, function);
                __pyx_t_7 = 1;
              }
            }
            #endif
            {
              PyObject *__pyx_callargs[2] = {__pyx_t_8, NULL};
              __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
              __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
              if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 818, __pyx_L1_error)
              __Pyx_GOTREF(__pyx_t_2);
              __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            }
            __Pyx_XDECREF_SET(__pyx_v_right_side, __pyx_t_2);
            __pyx_t_2 = 0;

            /* "sQQideR/SQLBuilder.pyx":821
 * 
 *                             relationship_query = {
 *                                 "name": f"Relationship count between {source} and {target}",             # <<<<<<<<<<<<<<
 *                                 "description": f"Shows the number of connections between {source} and {target}",
 *                                 "sql": f"SELECT COUNT(DISTINCT {left_side}) as distinct_connections FROM {source} JOIN {target} ON {join_condition}"
 */
            __pyx_t_2 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_2);
            __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_9 = 0;
            __pyx_t_13 = 127;
            __Pyx_INCREF(__pyx_kp_u_Relationship_count_between);
            __pyx_t_9 += 27;
            __Pyx_GIVEREF(__pyx_kp_u_Relationship_count_between);
            PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Relationship_count_between);
            __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_source, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
            __Pyx_GIVEREF(__pyx_t_8);
            PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_8);
            __pyx_t_8 = 0;
            __Pyx_INCREF(__pyx_kp_u_and);
            __pyx_t_9 += 5;
            __Pyx_GIVEREF(__pyx_kp_u_and);
            PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_and);
            __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_target, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
            __Pyx_GIVEREF(__pyx_t_8);
            PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_8);
            __pyx_t_8 = 0;
            __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_5, 4, __pyx_t_9, __pyx_t_13); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_name, __pyx_t_8) < 0) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

            /* "sQQideR/SQLBuilder.pyx":822
 *                             relationship_query = {
 *                                 "name": f"Relationship count between {source} and {target}",
 *                                 "description": f"Shows the number of connections between {source} and {target}",             # <<<<<<<<<<<<<<
 *                                 "sql": f"SELECT COUNT(DISTINCT {left_side}) as distinct_connections FROM {source} JOIN {target} ON {join_condition}"
 *                             }
 */
            __pyx_t_8 = PyTuple_New(4); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 822, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_9 = 0;
            __pyx_t_13 = 127;
            __Pyx_INCREF(__pyx_kp_u_Shows_the_number_of_connections);
            __pyx_t_9 += 40;
            __Pyx_GIVEREF(__pyx_kp_u_Shows_the_number_of_connections);
            PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_kp_u_Shows_the_number_of_connections);
            __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_source, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 822, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
            __Pyx_GIVEREF(__pyx_t_5);
            PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_5);
            __pyx_t_5 = 0;
            __Pyx_INCREF(__pyx_kp_u_and);
            __pyx_t_9 += 5;
            __Pyx_GIVEREF(__pyx_kp_u_and);
            PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_kp_u_and);
            __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_target, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 822, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
            __Pyx_GIVEREF(__pyx_t_5);
            PyTuple_SET_ITEM(__pyx_t_8, 3, __pyx_t_5);
            __pyx_t_5 = 0;
            __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_8, 4, __pyx_t_9, __pyx_t_13); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 822, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
            if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_description, __pyx_t_5) < 0) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

            /* "sQQideR/SQLBuilder.pyx":823
 *                                 "name": f"Relationship count between {source} and {target}",
 *                                 "description": f"Shows the number of connections between {source} and {target}",
 *                                 "sql": f"SELECT COUNT(DISTINCT {left_side}) as distinct_connections FROM {source} JOIN {target} ON {join_condition}"             # <<<<<<<<<<<<<<
 *                             }
 * 
 */
            __pyx_t_5 = PyTuple_New(8); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 823, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_5);
            __pyx_t_9 = 0;
            __pyx_t_13 = 127;
            __Pyx_INCREF(__pyx_kp_u_SELECT_COUNT_DISTINCT);
            __pyx_t_9 += 22;
            __Pyx_GIVEREF(__pyx_kp_u_SELECT_COUNT_DISTINCT);
            PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_SELECT_COUNT_DISTINCT);
            __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_left_side, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 823, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
            __Pyx_GIVEREF(__pyx_t_8);
            PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_8);
            __pyx_t_8 = 0;
            __Pyx_INCREF(__pyx_kp_u_as_distinct_connections_FROM);
            __pyx_t_9 += 31;
            __Pyx_GIVEREF(__pyx_kp_u_as_distinct_connections_FROM);
            PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_as_distinct_connections_FROM);
            __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_source, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 823, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
            __Pyx_GIVEREF(__pyx_t_8);
            PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_8);
            __pyx_t_8 = 0;
            __Pyx_INCREF(__pyx_kp_u_JOIN);
            __pyx_t_9 += 6;
            __Pyx_GIVEREF(__pyx_kp_u_JOIN);
            PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_kp_u_JOIN);
            __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_target, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 823, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
            __Pyx_GIVEREF(__pyx_t_8);
            PyTuple_SET_ITEM(__pyx_t_5, 5, __pyx_t_8);
            __pyx_t_8 = 0;
            __Pyx_INCREF(__pyx_kp_u_ON);
            __pyx_t_9 += 4;
            __Pyx_GIVEREF(__pyx_kp_u_ON);
            PyTuple_SET_ITEM(__pyx_t_5, 6, __pyx_kp_u_ON);
            __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_join_condition, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 823, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __pyx_t_13 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) > __pyx_t_13) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_8) : __pyx_t_13;
            __pyx_t_9 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_8);
            __Pyx_GIVEREF(__pyx_t_8);
            PyTuple_SET_ITEM(__pyx_t_5, 7, __pyx_t_8);
            __pyx_t_8 = 0;
            __pyx_t_8 = __Pyx_PyUnicode_Join(__pyx_t_5, 8, __pyx_t_9, __pyx_t_13); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 823, __pyx_L1_error)
            __Pyx_GOTREF(__pyx_t_8);
            __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
            if (PyDict_SetItem(__pyx_t_2, __pyx_n_u_sql, __pyx_t_8) < 0) __PYX_ERR(0, 821, __pyx_L1_error)
            __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
            __Pyx_XDECREF_SET(__pyx_v_relationship_query, ((PyObject*)__pyx_t_2));
            __pyx_t_2 = 0;

            /* "sQQideR/SQLBuilder.pyx":826
 *                             }
 * 
 *                             try:             # <<<<<<<<<<<<<<
 *                                 df = pd.read_sql_query(relationship_query["sql"], self.conn)
 *                                 relationship_query["success"] = True
 */
            {
              __Pyx_PyThreadState_declare
              __Pyx_PyThreadState_assign
              __Pyx_ExceptionSave(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16);
              __Pyx_XGOTREF(__pyx_t_14);
              __Pyx_XGOTREF(__pyx_t_15);
              __Pyx_XGOTREF(__pyx_t_16);
              /*try:*/ {

                /* "sQQideR/SQLBuilder.pyx":827
 * 
 *                             try:
 *                                 df = pd.read_sql_query(relationship_query["sql"], self.conn)             # <<<<<<<<<<<<<<
 *                                 relationship_query["success"] = True
 *                                 relationship_query["results"] = df.to_dict(orient="records")
 */
                __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_pd); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 827, __pyx_L101_error)
                __Pyx_GOTREF(__pyx_t_8);
                __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_read_sql_query); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 827, __pyx_L101_error)
                __Pyx_GOTREF(__pyx_t_5);
                __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
                __pyx_t_8 = __Pyx_PyDict_GetItem(__pyx_v_relationship_query, __pyx_n_u_sql); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 827, __pyx_L101_error)
                __Pyx_GOTREF(__pyx_t_8);
                __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_conn); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 827, __pyx_L101_error)
                __Pyx_GOTREF(__pyx_t_17);
                __pyx_t_18 = NULL;
                __pyx_t_7 = 0;
                #if CYTHON_UNPACK_METHODS
                if (unlikely(PyMethod_Check(__pyx_t_5))) {
                  __pyx_t_18 = PyMethod_GET_SELF(__pyx_t_5);
                  if (likely(__pyx_t_18)) {
                    PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
                    __Pyx_INCREF(__pyx_t_18);
                    __Pyx_INCREF(function);
                    __Pyx_DECREF_SET(__pyx_t_5, function);
                    __pyx_t_7 = 1;
                  }
                }
                #endif
                {
                  PyObject *__pyx_callargs[3] = {__pyx_t_18, __pyx_t_8, __pyx_t_17};
                  __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7);
                  __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
                  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
                  __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
                  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 827, __pyx_L101_error)
                  __Pyx_GOTREF(__pyx_t_2);
                  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                }
                __Pyx_XDECREF_SET(__pyx_v_df, __pyx_t_2);
                __pyx_t_2 = 0;

                /* "sQQideR/SQLBuilder.pyx":828
 *                             try:
 *                                 df = pd.read_sql_query(relationship_query["sql"], self.conn)
 *                                 relationship_query["success"] = True             # <<<<<<<<<<<<<<
 *                                 relationship_query["results"] = df.to_dict(orient="records")
 *                                 explorations.append(relationship_query)
 */
                if (unlikely((PyDict_SetItem(__pyx_v_relationship_query, __pyx_n_u_success, Py_True) < 0))) __PYX_ERR(0, 828, __pyx_L101_error)

                /* "sQQideR/SQLBuilder.pyx":829
 *                                 df = pd.read_sql_query(relationship_query["sql"], self.conn)
 *                                 relationship_query["success"] = True
 *                                 relationship_query["results"] = df.to_dict(orient="records")             # <<<<<<<<<<<<<<
 *                                 explorations.append(relationship_query)
 *                             except Exception as e:
 */
                __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_to_dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 829, __pyx_L101_error)
                __Pyx_GOTREF(__pyx_t_2);
                __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 829, __pyx_L101_error)
                __Pyx_GOTREF(__pyx_t_5);
                if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_orient, __pyx_n_u_records) < 0) __PYX_ERR(0, 829, __pyx_L101_error)
                __pyx_t_17 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 829, __pyx_L101_error)
                __Pyx_GOTREF(__pyx_t_17);
                __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
                __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
                if (unlikely((PyDict_SetItem(__pyx_v_relationship_query, __pyx_n_u_results, __pyx_t_17) < 0))) __PYX_ERR(0, 829, __pyx_L101_error)
                __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;

                /* "sQQideR/SQLBuilder.pyx":830
 *                                 relationship_query["success"] = True
 *                                 relationship_query["results"] = df.to_dict(orient="records")
 *                                 explorations.append(relationship_query)             # <<<<<<<<<<<<<<
 *                             except Exception as e:
 *                                 if self.verbose:
 */
                __pyx_t_31 = __Pyx_PyList_Append(__pyx_v_explorations, __pyx_v_relationship_query); if (unlikely(__pyx_t_31 == ((int)-1))) __PYX_ERR(0, 830, __pyx_L101_error)

                /* "sQQideR/SQLBuilder.pyx":826
 *                             }
 * 
 *                             try:             # <<<<<<<<<<<<<<
 *                                 df = pd.read_sql_query(relationship_query["sql"], self.conn)
 *                                 relationship_query["success"] = True
 */
              }
              __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
              __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
              __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
              goto __pyx_L108_try_end;
              __pyx_L101_error:;
              __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
              __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
              __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
              __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
              __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;

              /* "sQQideR/SQLBuilder.pyx":831
 *                                 relationship_query["results"] = df.to_dict(orient="records")
 *                                 explorations.append(relationship_query)
 *                             except Exception as e:             # <<<<<<<<<<<<<<
 *                                 if self.verbose:
 *                                     print(f"Error executing relationship exploration: {e}")
 */
              __pyx_t_19 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
              if (__pyx_t_19) {
                __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_additional_explorations", __pyx_clineno, __pyx_lineno, __pyx_filename);
                if (__Pyx_GetException(&__pyx_t_17, &__pyx_t_5, &__pyx_t_2) < 0) __PYX_ERR(0, 831, __pyx_L103_except_error)
                __Pyx_XGOTREF(__pyx_t_17);
                __Pyx_XGOTREF(__pyx_t_5);
                __Pyx_XGOTREF(__pyx_t_2);
                __Pyx_INCREF(__pyx_t_5);
                __pyx_v_e = __pyx_t_5;
                /*try:*/ {

                  /* "sQQideR/SQLBuilder.pyx":832
 *                                 explorations.append(relationship_query)
 *                             except Exception as e:
 *                                 if self.verbose:             # <<<<<<<<<<<<<<
 *                                     print(f"Error executing relationship exploration: {e}")
 * 
 */
                  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 832, __pyx_L114_error)
                  __Pyx_GOTREF(__pyx_t_8);
                  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely((__pyx_t_4 < 0))) __PYX_ERR(0, 832, __pyx_L114_error)
                  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
                  if (__pyx_t_4) {

                    /* "sQQideR/SQLBuilder.pyx":833
 *                             except Exception as e:
 *                                 if self.verbose:
 *                                     print(f"Error executing relationship exploration: {e}")             # <<<<<<<<<<<<<<
 * 
 *         return explorations
 */
                    __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_v_e, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 833, __pyx_L114_error)
                    __Pyx_GOTREF(__pyx_t_8);
                    __pyx_t_18 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Error_executing_relationship_exp, __pyx_t_8); if (unlikely(!__pyx_t_18)) __PYX_ERR(0, 833, __pyx_L114_error)
                    __Pyx_GOTREF(__pyx_t_18);
                    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
                    __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_18); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 833, __pyx_L114_error)
                    __Pyx_GOTREF(__pyx_t_8);
                    __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
                    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;

                    /* "sQQideR/SQLBuilder.pyx":832
 *                                 explorations.append(relationship_query)
 *                             except Exception as e:
 *                                 if self.verbose:             # <<<<<<<<<<<<<<
 *                                     print(f"Error executing relationship exploration: {e}")
 * 
 */
                  }
                }

                /* "sQQideR/SQLBuilder.pyx":831
 *                                 relationship_query["results"] = df.to_dict(orient="records")
 *                                 explorations.append(relationship_query)
 *                             except Exception as e:             # <<<<<<<<<<<<<<
 *                                 if self.verbose:
 *                                     print(f"Error executing relationship exploration: {e}")
 */
                /*finally:*/ {
                  /*normal exit:*/{
                    __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
                    goto __pyx_L115;
                  }
                  __pyx_L114_error:;
                  /*exception exit:*/{
                    __Pyx_PyThreadState_declare
                    __Pyx_PyThreadState_assign
                    __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_26 = 0; __pyx_t_27 = 0;
                    __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0;
                    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
                    if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_25, &__pyx_t_26, &__pyx_t_27);
                    if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_22, &__pyx_t_23, &__pyx_t_24) < 0)) __Pyx_ErrFetch(&__pyx_t_22, &__pyx_t_23, &__pyx_t_24);
                    __Pyx_XGOTREF(__pyx_t_22);
                    __Pyx_XGOTREF(__pyx_t_23);
                    __Pyx_XGOTREF(__pyx_t_24);
                    __Pyx_XGOTREF(__pyx_t_25);
                    __Pyx_XGOTREF(__pyx_t_26);
                    __Pyx_XGOTREF(__pyx_t_27);
                    __pyx_t_19 = __pyx_lineno; __pyx_t_20 = __pyx_clineno; __pyx_t_32 = __pyx_filename;
                    {
                      __Pyx_DECREF(__pyx_v_e); __pyx_v_e = 0;
                    }
                    if (PY_MAJOR_VERSION >= 3) {
                      __Pyx_XGIVEREF(__pyx_t_25);
                      __Pyx_XGIVEREF(__pyx_t_26);
                      __Pyx_XGIVEREF(__pyx_t_27);
                      __Pyx_ExceptionReset(__pyx_t_25, __pyx_t_26, __pyx_t_27);
                    }
                    __Pyx_XGIVEREF(__pyx_t_22);
                    __Pyx_XGIVEREF(__pyx_t_23);
                    __Pyx_XGIVEREF(__pyx_t_24);
                    __Pyx_ErrRestore(__pyx_t_22, __pyx_t_23, __pyx_t_24);
                    __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_26 = 0; __pyx_t_27 = 0;
                    __pyx_lineno = __pyx_t_19; __pyx_clineno = __pyx_t_20; __pyx_filename = __pyx_t_32;
                    goto __pyx_L103_except_error;
                  }
                  __pyx_L115:;
                }
                __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
                __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
                __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
                goto __pyx_L102_exception_handled;
              }
              goto __pyx_L103_except_error;

              /* "sQQideR/SQLBuilder.pyx":826
 *                             }
 * 
 *                             try:             # <<<<<<<<<<<<<<
 *                                 df = pd.read_sql_query(relationship_query["sql"], self.conn)
 *                                 relationship_query["success"] = True
 */
              __pyx_L103_except_error:;
              __Pyx_XGIVEREF(__pyx_t_14);
              __Pyx_XGIVEREF(__pyx_t_15);
              __Pyx_XGIVEREF(__pyx_t_16);
              __Pyx_ExceptionReset(__pyx_t_14, __pyx_t_15, __pyx_t_16);
              goto __pyx_L1_error;
              __pyx_L102_exception_handled:;
              __Pyx_XGIVEREF(__pyx_t_14);
              __Pyx_XGIVEREF(__pyx_t_15);
              __Pyx_XGIVEREF(__pyx_t_16);
              __Pyx_ExceptionReset(__pyx_t_14, __pyx_t_15, __pyx_t_16);
              __pyx_L108_try_end:;
            }

            /* "sQQideR/SQLBuilder.pyx":816
 *                     if join_condition:
 *                         parts = join_condition.split("=")
 *                         if len(parts) == 2:             # <<<<<<<<<<<<<<
 *                             left_side = parts[0].strip()
 *                             right_side = parts[1].strip()
 */
          }

          /* "sQQideR/SQLBuilder.pyx":814
 *                 if source in tables_used and target in tables_used:
 *                     join_condition = rel.get("join_condition", "")
 *                     if join_condition:             # <<<<<<<<<<<<<<
 *                         parts = join_condition.split("=")
 *                         if len(parts) == 2:
 */
        }

        /* "sQQideR/SQLBuilder.pyx":812
 *                 target = rel.get("target", "").lower()
 * 
 *                 if source in tables_used and target in tables_used:             # <<<<<<<<<<<<<<
 *                     join_condition = rel.get("join_condition", "")
 *                     if join_condition:
 */
      }

      /* "sQQideR/SQLBuilder.pyx":808
 *         if any(keyword in question.lower() for keyword in relationship_keywords) and len(tables_used) > 1:
 *             # Find relationships between the used tables from context
 *             for rel in db_context.get("relationships", []):             # <<<<<<<<<<<<<<
 *                 source = rel.get("source", "").lower()
 *                 target = rel.get("target", "").lower()
 */
    }
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":806
 *         # 4. If the question relates to relationships, explore relationship counts
 *         relationship_keywords = ["relation", "connect", "join", "link", "between"]
 *         if any(keyword in question.lower() for keyword in relationship_keywords) and len(tables_used) > 1:             # <<<<<<<<<<<<<<
 *             # Find relationships between the used tables from context
 *             for rel in db_context.get("relationships", []):
 */
  }

  /* "sQQideR/SQLBuilder.pyx":835
 *                                     print(f"Error executing relationship exploration: {e}")
 * 
 *         return explorations             # <<<<<<<<<<<<<<
 * 
 *     def _create_sql_generation_prompt(self, question: str, db_context: Dict) -> str:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_explorations);
  __pyx_r = __pyx_v_explorations;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":683
 *         return list(table_names)
 * 
 *     def generate_additional_explorations(self, question: str, main_query: Dict, db_context: Dict) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Generate and execute additional SQL queries to explore related aspects of the main query.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_17);
  __Pyx_XDECREF(__pyx_t_18);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder.generate_additional_explorations", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_explorations);
  __Pyx_XDECREF(__pyx_v_main_sql);
  __Pyx_XDECREF(__pyx_v_tables_used);
  __Pyx_XDECREF(__pyx_v_table_obj);
  __Pyx_XDECREF(__pyx_v_table_name);
  __Pyx_XDECREF(__pyx_v_table);
  __Pyx_XDECREF(__pyx_v_count_query);
  __Pyx_XDECREF(__pyx_v_df);
  __Pyx_XDECREF(__pyx_v_e);
  __Pyx_XDECREF(__pyx_v_date_columns);
  __Pyx_XDECREF(__pyx_v_column_obj);
  __Pyx_XDECREF(__pyx_v_col_name);
  __Pyx_XDECREF(__pyx_v_data_type);
  __Pyx_XDECREF(__pyx_v_date_col);
  __Pyx_XDECREF(__pyx_v_time_query);
  __Pyx_XDECREF(__pyx_v_numeric_columns);
  __Pyx_XDECREF(__pyx_v_first_result);
  __Pyx_XDECREF(__pyx_v_col);
  __Pyx_XDECREF(__pyx_v_val);
  __Pyx_XDECREF(__pyx_v_stats_query_dict);
  __Pyx_XDECREF(__pyx_v_agg_parts);
  __Pyx_XDECREF(__pyx_v_sql);
  __Pyx_XDECREF(__pyx_v_tested_query);
  __Pyx_XDECREF(__pyx_v_retry_info);
  __Pyx_XDECREF(__pyx_v_relationship_keywords);
  __Pyx_XDECREF(__pyx_v_rel);
  __Pyx_XDECREF(__pyx_v_source);
  __Pyx_XDECREF(__pyx_v_target);
  __Pyx_XDECREF(__pyx_v_join_condition);
  __Pyx_XDECREF(__pyx_v_parts);
  __Pyx_XDECREF(__pyx_v_left_side);
  __Pyx_XDECREF(__pyx_v_right_side);
  __Pyx_XDECREF(__pyx_v_relationship_query);
  __Pyx_XDECREF(__pyx_gb_7sQQideR_10SQLBuilder_10SQLBuilder_32generate_additional_explorations_2generator);
  __Pyx_DECREF((PyObject *)__pyx_cur_scope);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":837
 *         return explorations
 * 
 *     def _create_sql_generation_prompt(self, question: str, db_context: Dict) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Create a detailed prompt for SQL generation using the database context.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_27_create_sql_generation_prompt(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_26_create_sql_generation_prompt, "\n        Create a detailed prompt for SQL generation using the database context.\n        \n        Args:\n            question: The natural language question\n            db_context: Database context information\n            \n        Returns:\n            Formatted prompt string for the AI\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_27_create_sql_generation_prompt = {"_create_sql_generation_prompt", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_27_create_sql_generation_prompt, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_26_create_sql_generation_prompt};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_27_create_sql_generation_prompt(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_question = 0;
  PyObject *__pyx_v_db_context = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[3] = {0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_create_sql_generation_prompt (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_question,&__pyx_n_s_db_context,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 837, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 837, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_generation_prompt", 1, 3, 3, 1); __PYX_ERR(0, 837, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_db_context)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 837, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_create_sql_generation_prompt", 1, 3, 3, 2); __PYX_ERR(0, 837, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_create_sql_generation_prompt") < 0)) __PYX_ERR(0, 837, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 3)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
    }
    __pyx_v_self = values[0];
    __pyx_v_question = ((PyObject*)values[1]);
    __pyx_v_db_context = ((PyObject*)values[2]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_create_sql_generation_prompt", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 837, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._create_sql_generation_prompt", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 837, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_db_context), (&PyDict_Type), 0, "db_context", 1))) __PYX_ERR(0, 837, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_26_create_sql_generation_prompt(__pyx_self, __pyx_v_self, __pyx_v_question, __pyx_v_db_context);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_26_create_sql_generation_prompt(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_question, PyObject *__pyx_v_db_context) {
  PyObject *__pyx_v_tables = NULL;
  PyObject *__pyx_v_columns = NULL;
  PyObject *__pyx_v_relationships = NULL;
  PyObject *__pyx_v_prompt = NULL;
  PyObject *__pyx_v_table = NULL;
  PyObject *__pyx_v_col = NULL;
  PyObject *__pyx_v_name_parts = NULL;
  PyObject *__pyx_v_column = NULL;
  PyObject *__pyx_v_rel = NULL;
  PyObject *__pyx_v_prev = NULL;
  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;
  unsigned int __pyx_t_5;
  Py_ssize_t __pyx_t_6;
  Py_UCS4 __pyx_t_7;
  int __pyx_t_8;
  PyObject *(*__pyx_t_9)(PyObject *);
  Py_ssize_t __pyx_t_10;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_create_sql_generation_prompt", 1);

  /* "sQQideR/SQLBuilder.pyx":849
 *         """
 *         # Extract key information from db_context
 *         tables = db_context.get("database_objects", {}).get("tables", [])             # <<<<<<<<<<<<<<
 *         columns = db_context.get("database_objects", {}).get("columns", [])
 *         relationships = db_context.get("relationships", [])
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 849, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_database_objects, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 849, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 849, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 849, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = NULL;
  __pyx_t_5 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(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_5 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_n_u_tables, __pyx_t_3};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 2+__pyx_t_5);
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 849, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  }
  __pyx_v_tables = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":850
 *         # Extract key information from db_context
 *         tables = db_context.get("database_objects", {}).get("tables", [])
 *         columns = db_context.get("database_objects", {}).get("columns", [])             # <<<<<<<<<<<<<<
 *         relationships = db_context.get("relationships", [])
 * 
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 850, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_database_objects, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 850, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 850, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 850, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = NULL;
  __pyx_t_5 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(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_5 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_n_u_columns, __pyx_t_3};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 2+__pyx_t_5);
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 850, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  }
  __pyx_v_columns = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":851
 *         tables = db_context.get("database_objects", {}).get("tables", [])
 *         columns = db_context.get("database_objects", {}).get("columns", [])
 *         relationships = db_context.get("relationships", [])             # <<<<<<<<<<<<<<
 * 
 *         # Build a structured prompt
 */
  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 851, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyDict_GetItemDefault(__pyx_v_db_context, __pyx_n_u_relationships, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 851, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_relationships = __pyx_t_2;
  __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":854
 * 
 *         # Build a structured prompt
 *         prompt = f"""You are an expert SQL developer. Generate a SQL query to answer the following question:             # <<<<<<<<<<<<<<
 * 
 * QUESTION: {question}
 */
  __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 854, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_6 = 0;
  __pyx_t_7 = 127;
  __Pyx_INCREF(__pyx_kp_u_You_are_an_expert_SQL_developer_2);
  __pyx_t_6 += 99;
  __Pyx_GIVEREF(__pyx_kp_u_You_are_an_expert_SQL_developer_2);
  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u_You_are_an_expert_SQL_developer_2);
  __Pyx_INCREF(__pyx_v_question);
  __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_question) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_question) : __pyx_t_7;
  __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_v_question);
  __Pyx_GIVEREF(__pyx_v_question);
  PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_question);
  __Pyx_INCREF(__pyx_kp_u_DATABASE_CONTEXT);
  __pyx_t_6 += 20;
  __Pyx_GIVEREF(__pyx_kp_u_DATABASE_CONTEXT);
  PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u_DATABASE_CONTEXT);
  __pyx_t_1 = __Pyx_PyUnicode_Join(__pyx_t_2, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 854, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_prompt = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":862
 * 
 *         # Add tables information
 *         if tables:             # <<<<<<<<<<<<<<
 *             prompt += "\nRelevant Tables:\n"
 *             for table in tables:
 */
  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_tables); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 862, __pyx_L1_error)
  if (__pyx_t_8) {

    /* "sQQideR/SQLBuilder.pyx":863
 *         # Add tables information
 *         if tables:
 *             prompt += "\nRelevant Tables:\n"             # <<<<<<<<<<<<<<
 *             for table in tables:
 *                 prompt += f"- {table['name']}: {table['description']}\n"
 */
    __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_Relevant_Tables); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 863, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":864
 *         if tables:
 *             prompt += "\nRelevant Tables:\n"
 *             for table in tables:             # <<<<<<<<<<<<<<
 *                 prompt += f"- {table['name']}: {table['description']}\n"
 * 
 */
    if (likely(PyList_CheckExact(__pyx_v_tables)) || PyTuple_CheckExact(__pyx_v_tables)) {
      __pyx_t_1 = __pyx_v_tables; __Pyx_INCREF(__pyx_t_1);
      __pyx_t_6 = 0;
      __pyx_t_9 = NULL;
    } else {
      __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_tables); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 864, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 864, __pyx_L1_error)
    }
    for (;;) {
      if (likely(!__pyx_t_9)) {
        if (likely(PyList_CheckExact(__pyx_t_1))) {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 864, __pyx_L1_error)
            #endif
            if (__pyx_t_6 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 864, __pyx_L1_error)
          #else
          __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 864, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          #endif
        } else {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 864, __pyx_L1_error)
            #endif
            if (__pyx_t_6 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 864, __pyx_L1_error)
          #else
          __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 864, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          #endif
        }
      } else {
        __pyx_t_2 = __pyx_t_9(__pyx_t_1);
        if (unlikely(!__pyx_t_2)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 864, __pyx_L1_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_2);
      }
      __Pyx_XDECREF_SET(__pyx_v_table, __pyx_t_2);
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":865
 *             prompt += "\nRelevant Tables:\n"
 *             for table in tables:
 *                 prompt += f"- {table['name']}: {table['description']}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add columns information
 */
      __pyx_t_2 = PyTuple_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 865, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_10 = 0;
      __pyx_t_7 = 127;
      __Pyx_INCREF(__pyx_kp_u__15);
      __pyx_t_10 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__15);
      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u__15);
      __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_v_table, __pyx_n_u_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 865, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_3, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 865, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
      __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
      __pyx_t_4 = 0;
      __Pyx_INCREF(__pyx_kp_u__13);
      __pyx_t_10 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__13);
      PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__13);
      __pyx_t_4 = __Pyx_PyObject_Dict_GetItem(__pyx_v_table, __pyx_n_u_description); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 865, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 865, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __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_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
      __pyx_t_3 = 0;
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_10 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__14);
      PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_kp_u__14);
      __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_2, 5, __pyx_t_10, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 865, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 865, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_2));
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":864
 *         if tables:
 *             prompt += "\nRelevant Tables:\n"
 *             for table in tables:             # <<<<<<<<<<<<<<
 *                 prompt += f"- {table['name']}: {table['description']}\n"
 * 
 */
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":862
 * 
 *         # Add tables information
 *         if tables:             # <<<<<<<<<<<<<<
 *             prompt += "\nRelevant Tables:\n"
 *             for table in tables:
 */
  }

  /* "sQQideR/SQLBuilder.pyx":868
 * 
 *         # Add columns information
 *         if columns:             # <<<<<<<<<<<<<<
 *             prompt += "\nRelevant Columns:\n"
 *             for col in columns:
 */
  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_columns); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 868, __pyx_L1_error)
  if (__pyx_t_8) {

    /* "sQQideR/SQLBuilder.pyx":869
 *         # Add columns information
 *         if columns:
 *             prompt += "\nRelevant Columns:\n"             # <<<<<<<<<<<<<<
 *             for col in columns:
 *                 name_parts = col['name'].split('.')
 */
    __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_Relevant_Columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 869, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":870
 *         if columns:
 *             prompt += "\nRelevant Columns:\n"
 *             for col in columns:             # <<<<<<<<<<<<<<
 *                 name_parts = col['name'].split('.')
 *                 table = name_parts[0] if len(name_parts) > 1 else "Unknown"
 */
    if (likely(PyList_CheckExact(__pyx_v_columns)) || PyTuple_CheckExact(__pyx_v_columns)) {
      __pyx_t_1 = __pyx_v_columns; __Pyx_INCREF(__pyx_t_1);
      __pyx_t_6 = 0;
      __pyx_t_9 = NULL;
    } else {
      __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 870, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 870, __pyx_L1_error)
    }
    for (;;) {
      if (likely(!__pyx_t_9)) {
        if (likely(PyList_CheckExact(__pyx_t_1))) {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 870, __pyx_L1_error)
            #endif
            if (__pyx_t_6 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 870, __pyx_L1_error)
          #else
          __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 870, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          #endif
        } else {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 870, __pyx_L1_error)
            #endif
            if (__pyx_t_6 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 870, __pyx_L1_error)
          #else
          __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 870, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          #endif
        }
      } else {
        __pyx_t_2 = __pyx_t_9(__pyx_t_1);
        if (unlikely(!__pyx_t_2)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 870, __pyx_L1_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_2);
      }
      __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_2);
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":871
 *             prompt += "\nRelevant Columns:\n"
 *             for col in columns:
 *                 name_parts = col['name'].split('.')             # <<<<<<<<<<<<<<
 *                 table = name_parts[0] if len(name_parts) > 1 else "Unknown"
 *                 column = name_parts[1] if len(name_parts) > 1 else name_parts[0]
 */
      __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_v_col, __pyx_n_u_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 871, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_split); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 871, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_3 = NULL;
      __pyx_t_5 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_4))) {
        __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
        if (likely(__pyx_t_3)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
          __Pyx_INCREF(__pyx_t_3);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_4, function);
          __pyx_t_5 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_kp_u__29};
        __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_4, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5);
        __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
        if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 871, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      }
      __Pyx_XDECREF_SET(__pyx_v_name_parts, __pyx_t_2);
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":872
 *             for col in columns:
 *                 name_parts = col['name'].split('.')
 *                 table = name_parts[0] if len(name_parts) > 1 else "Unknown"             # <<<<<<<<<<<<<<
 *                 column = name_parts[1] if len(name_parts) > 1 else name_parts[0]
 *                 prompt += f"- {table}.{column} ({col['data_type']}): {col['description']}\n"
 */
      __pyx_t_10 = PyObject_Length(__pyx_v_name_parts); if (unlikely(__pyx_t_10 == ((Py_ssize_t)-1))) __PYX_ERR(0, 872, __pyx_L1_error)
      __pyx_t_8 = (__pyx_t_10 > 1);
      if (__pyx_t_8) {
        __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_name_parts, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 872, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __pyx_t_2 = __pyx_t_4;
        __pyx_t_4 = 0;
      } else {
        __Pyx_INCREF(__pyx_n_u_Unknown);
        __pyx_t_2 = __pyx_n_u_Unknown;
      }
      __Pyx_XDECREF_SET(__pyx_v_table, __pyx_t_2);
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":873
 *                 name_parts = col['name'].split('.')
 *                 table = name_parts[0] if len(name_parts) > 1 else "Unknown"
 *                 column = name_parts[1] if len(name_parts) > 1 else name_parts[0]             # <<<<<<<<<<<<<<
 *                 prompt += f"- {table}.{column} ({col['data_type']}): {col['description']}\n"
 * 
 */
      __pyx_t_10 = PyObject_Length(__pyx_v_name_parts); if (unlikely(__pyx_t_10 == ((Py_ssize_t)-1))) __PYX_ERR(0, 873, __pyx_L1_error)
      __pyx_t_8 = (__pyx_t_10 > 1);
      if (__pyx_t_8) {
        __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_name_parts, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 873, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __pyx_t_2 = __pyx_t_4;
        __pyx_t_4 = 0;
      } else {
        __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_name_parts, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 873, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __pyx_t_2 = __pyx_t_4;
        __pyx_t_4 = 0;
      }
      __Pyx_XDECREF_SET(__pyx_v_column, __pyx_t_2);
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":874
 *                 table = name_parts[0] if len(name_parts) > 1 else "Unknown"
 *                 column = name_parts[1] if len(name_parts) > 1 else name_parts[0]
 *                 prompt += f"- {table}.{column} ({col['data_type']}): {col['description']}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add relationships
 */
      __pyx_t_2 = PyTuple_New(9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_10 = 0;
      __pyx_t_7 = 127;
      __Pyx_INCREF(__pyx_kp_u__15);
      __pyx_t_10 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__15);
      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u__15);
      __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_v_table, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
      __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
      __pyx_t_4 = 0;
      __Pyx_INCREF(__pyx_kp_u__29);
      __pyx_t_10 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__29);
      PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u__29);
      __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_v_column, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
      __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_4);
      __pyx_t_4 = 0;
      __Pyx_INCREF(__pyx_kp_u__16);
      __pyx_t_10 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__16);
      PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_kp_u__16);
      __pyx_t_4 = __Pyx_PyObject_Dict_GetItem(__pyx_v_col, __pyx_n_u_data_type); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __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_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_t_3);
      __pyx_t_3 = 0;
      __Pyx_INCREF(__pyx_kp_u__32);
      __pyx_t_10 += 3;
      __Pyx_GIVEREF(__pyx_kp_u__32);
      PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_kp_u__32);
      __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_v_col, __pyx_n_u_description); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_3, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
      __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_2, 7, __pyx_t_4);
      __pyx_t_4 = 0;
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_10 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__14);
      PyTuple_SET_ITEM(__pyx_t_2, 8, __pyx_kp_u__14);
      __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_2, 9, __pyx_t_10, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 874, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_2));
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":870
 *         if columns:
 *             prompt += "\nRelevant Columns:\n"
 *             for col in columns:             # <<<<<<<<<<<<<<
 *                 name_parts = col['name'].split('.')
 *                 table = name_parts[0] if len(name_parts) > 1 else "Unknown"
 */
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":868
 * 
 *         # Add columns information
 *         if columns:             # <<<<<<<<<<<<<<
 *             prompt += "\nRelevant Columns:\n"
 *             for col in columns:
 */
  }

  /* "sQQideR/SQLBuilder.pyx":877
 * 
 *         # Add relationships
 *         if relationships:             # <<<<<<<<<<<<<<
 *             prompt += "\nTable Relationships:\n"
 *             for rel in relationships:
 */
  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_relationships); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 877, __pyx_L1_error)
  if (__pyx_t_8) {

    /* "sQQideR/SQLBuilder.pyx":878
 *         # Add relationships
 *         if relationships:
 *             prompt += "\nTable Relationships:\n"             # <<<<<<<<<<<<<<
 *             for rel in relationships:
 *                 prompt += f"- {rel['source']} to {rel['target']}: {rel['join_condition']}\n"
 */
    __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_Table_Relationships); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 878, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":879
 *         if relationships:
 *             prompt += "\nTable Relationships:\n"
 *             for rel in relationships:             # <<<<<<<<<<<<<<
 *                 prompt += f"- {rel['source']} to {rel['target']}: {rel['join_condition']}\n"
 * 
 */
    if (likely(PyList_CheckExact(__pyx_v_relationships)) || PyTuple_CheckExact(__pyx_v_relationships)) {
      __pyx_t_1 = __pyx_v_relationships; __Pyx_INCREF(__pyx_t_1);
      __pyx_t_6 = 0;
      __pyx_t_9 = NULL;
    } else {
      __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_relationships); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 879, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 879, __pyx_L1_error)
    }
    for (;;) {
      if (likely(!__pyx_t_9)) {
        if (likely(PyList_CheckExact(__pyx_t_1))) {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 879, __pyx_L1_error)
            #endif
            if (__pyx_t_6 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 879, __pyx_L1_error)
          #else
          __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 879, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          #endif
        } else {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 879, __pyx_L1_error)
            #endif
            if (__pyx_t_6 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely((0 < 0))) __PYX_ERR(0, 879, __pyx_L1_error)
          #else
          __pyx_t_2 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 879, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          #endif
        }
      } else {
        __pyx_t_2 = __pyx_t_9(__pyx_t_1);
        if (unlikely(!__pyx_t_2)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 879, __pyx_L1_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_2);
      }
      __Pyx_XDECREF_SET(__pyx_v_rel, __pyx_t_2);
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":880
 *             prompt += "\nTable Relationships:\n"
 *             for rel in relationships:
 *                 prompt += f"- {rel['source']} to {rel['target']}: {rel['join_condition']}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add previously run query information if available
 */
      __pyx_t_2 = PyTuple_New(7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_10 = 0;
      __pyx_t_7 = 127;
      __Pyx_INCREF(__pyx_kp_u__15);
      __pyx_t_10 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__15);
      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_kp_u__15);
      __pyx_t_4 = __Pyx_PyObject_Dict_GetItem(__pyx_v_rel, __pyx_n_u_source); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __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_10 += __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_to);
      __pyx_t_10 += 4;
      __Pyx_GIVEREF(__pyx_kp_u_to);
      PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_kp_u_to);
      __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_v_rel, __pyx_n_u_target); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_3, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_7;
      __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_4);
      __pyx_t_4 = 0;
      __Pyx_INCREF(__pyx_kp_u__13);
      __pyx_t_10 += 2;
      __Pyx_GIVEREF(__pyx_kp_u__13);
      PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_kp_u__13);
      __pyx_t_4 = __Pyx_PyObject_Dict_GetItem(__pyx_v_rel, __pyx_n_u_join_condition); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __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_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_t_3);
      __pyx_t_3 = 0;
      __Pyx_INCREF(__pyx_kp_u__14);
      __pyx_t_10 += 1;
      __Pyx_GIVEREF(__pyx_kp_u__14);
      PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_kp_u__14);
      __pyx_t_3 = __Pyx_PyUnicode_Join(__pyx_t_2, 7, __pyx_t_10, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 880, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_2));
      __pyx_t_2 = 0;

      /* "sQQideR/SQLBuilder.pyx":879
 *         if relationships:
 *             prompt += "\nTable Relationships:\n"
 *             for rel in relationships:             # <<<<<<<<<<<<<<
 *                 prompt += f"- {rel['source']} to {rel['target']}: {rel['join_condition']}\n"
 * 
 */
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":877
 * 
 *         # Add relationships
 *         if relationships:             # <<<<<<<<<<<<<<
 *             prompt += "\nTable Relationships:\n"
 *             for rel in relationships:
 */
  }

  /* "sQQideR/SQLBuilder.pyx":883
 * 
 *         # Add previously run query information if available
 *         if "previously_run_query" in db_context:             # <<<<<<<<<<<<<<
 *             prev = db_context["previously_run_query"]
 *             prompt += f"\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n"
 */
  __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_previously_run_query, __pyx_v_db_context, Py_EQ)); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 883, __pyx_L1_error)
  if (__pyx_t_8) {

    /* "sQQideR/SQLBuilder.pyx":884
 *         # Add previously run query information if available
 *         if "previously_run_query" in db_context:
 *             prev = db_context["previously_run_query"]             # <<<<<<<<<<<<<<
 *             prompt += f"\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n"
 *             prompt += f"Question: {prev.get('question', '')}\n"
 */
    __pyx_t_1 = __Pyx_PyDict_GetItem(__pyx_v_db_context, __pyx_n_u_previously_run_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 884, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_v_prev = __pyx_t_1;
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":885
 *         if "previously_run_query" in db_context:
 *             prev = db_context["previously_run_query"]
 *             prompt += f"\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n"             # <<<<<<<<<<<<<<
 *             prompt += f"Question: {prev.get('question', '')}\n"
 *             prompt += f"SQL: {prev.get('sql', '')}\n\n"
 */
    __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_PREVIOUSLY_RUN_QUERY_FOR_SIMILA); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 885, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":886
 *             prev = db_context["previously_run_query"]
 *             prompt += f"\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n"
 *             prompt += f"Question: {prev.get('question', '')}\n"             # <<<<<<<<<<<<<<
 *             prompt += f"SQL: {prev.get('sql', '')}\n\n"
 *             prompt += "You should strongly consider using this previous query as a starting point, but adapt it to the current question if needed.\n"
 */
    __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 886, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_6 = 0;
    __pyx_t_7 = 127;
    __Pyx_INCREF(__pyx_kp_u_Question);
    __pyx_t_6 += 10;
    __Pyx_GIVEREF(__pyx_kp_u_Question);
    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Question);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_prev, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 886, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 886, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_t_3, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 886, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_7;
    __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2);
    __Pyx_GIVEREF(__pyx_t_2);
    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
    __pyx_t_2 = 0;
    __Pyx_INCREF(__pyx_kp_u__14);
    __pyx_t_6 += 1;
    __Pyx_GIVEREF(__pyx_kp_u__14);
    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__14);
    __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 886, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 886, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":887
 *             prompt += f"\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n"
 *             prompt += f"Question: {prev.get('question', '')}\n"
 *             prompt += f"SQL: {prev.get('sql', '')}\n\n"             # <<<<<<<<<<<<<<
 *             prompt += "You should strongly consider using this previous query as a starting point, but adapt it to the current question if needed.\n"
 * 
 */
    __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 887, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_6 = 0;
    __pyx_t_7 = 127;
    __Pyx_INCREF(__pyx_kp_u_SQL);
    __pyx_t_6 += 5;
    __Pyx_GIVEREF(__pyx_kp_u_SQL);
    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_SQL);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_prev, __pyx_n_s_get); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 887, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 887, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_t_3, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 887, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_7 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) > __pyx_t_7) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_2) : __pyx_t_7;
    __pyx_t_6 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_2);
    __Pyx_GIVEREF(__pyx_t_2);
    PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
    __pyx_t_2 = 0;
    __Pyx_INCREF(__pyx_kp_u__34);
    __pyx_t_6 += 2;
    __Pyx_GIVEREF(__pyx_kp_u__34);
    PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__34);
    __pyx_t_2 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 887, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 887, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":888
 *             prompt += f"Question: {prev.get('question', '')}\n"
 *             prompt += f"SQL: {prev.get('sql', '')}\n\n"
 *             prompt += "You should strongly consider using this previous query as a starting point, but adapt it to the current question if needed.\n"             # <<<<<<<<<<<<<<
 * 
 *         # Final instructions
 */
    __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_You_should_strongly_consider_usi); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 888, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":883
 * 
 *         # Add previously run query information if available
 *         if "previously_run_query" in db_context:             # <<<<<<<<<<<<<<
 *             prev = db_context["previously_run_query"]
 *             prompt += f"\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n"
 */
  }

  /* "sQQideR/SQLBuilder.pyx":891
 * 
 *         # Final instructions
 *         prompt += """             # <<<<<<<<<<<<<<
 * INSTRUCTIONS:
 * 1. Generate a valid SQL query that answers the question using the provided database context
 */
  __pyx_t_1 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_prompt, __pyx_kp_u_INSTRUCTIONS_1_Generate_a_valid); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 891, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF_SET(__pyx_v_prompt, ((PyObject*)__pyx_t_1));
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":901
 * """
 * 
 *         return prompt             # <<<<<<<<<<<<<<
 * 
 *     def _extract_sql_from_response(self, response: str) -> str:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_prompt);
  __pyx_r = __pyx_v_prompt;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":837
 *         return explorations
 * 
 *     def _create_sql_generation_prompt(self, question: str, db_context: Dict) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Create a detailed prompt for SQL generation using the database context.
 */

  /* 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_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._create_sql_generation_prompt", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_tables);
  __Pyx_XDECREF(__pyx_v_columns);
  __Pyx_XDECREF(__pyx_v_relationships);
  __Pyx_XDECREF(__pyx_v_prompt);
  __Pyx_XDECREF(__pyx_v_table);
  __Pyx_XDECREF(__pyx_v_col);
  __Pyx_XDECREF(__pyx_v_name_parts);
  __Pyx_XDECREF(__pyx_v_column);
  __Pyx_XDECREF(__pyx_v_rel);
  __Pyx_XDECREF(__pyx_v_prev);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":903
 *         return prompt
 * 
 *     def _extract_sql_from_response(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the SQL query from the AI response.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_29_extract_sql_from_response(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_28_extract_sql_from_response, "\n        Extract the SQL query from the AI response.\n        \n        Args:\n            response: Raw AI response text\n            \n        Returns:\n            Extracted SQL query\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_29_extract_sql_from_response = {"_extract_sql_from_response", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_29_extract_sql_from_response, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_28_extract_sql_from_response};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_29_extract_sql_from_response(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_response = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_extract_sql_from_response (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_response,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 903, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_response)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 903, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_extract_sql_from_response", 1, 2, 2, 1); __PYX_ERR(0, 903, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_extract_sql_from_response") < 0)) __PYX_ERR(0, 903, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_response = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_extract_sql_from_response", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 903, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._extract_sql_from_response", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_response), (&PyUnicode_Type), 0, "response", 1))) __PYX_ERR(0, 903, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_28_extract_sql_from_response(__pyx_self, __pyx_v_self, __pyx_v_response);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_28_extract_sql_from_response(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_response) {
  PyObject *__pyx_v_code_block_pattern = NULL;
  PyObject *__pyx_v_code_blocks = NULL;
  PyObject *__pyx_v_block = NULL;
  PyObject *__pyx_v_direct_sql_pattern = NULL;
  PyObject *__pyx_v_direct_matches = NULL;
  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;
  unsigned int __pyx_t_5;
  int __pyx_t_6;
  Py_ssize_t __pyx_t_7;
  PyObject *(*__pyx_t_8)(PyObject *);
  PyObject *__pyx_t_9 = NULL;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_extract_sql_from_response", 1);

  /* "sQQideR/SQLBuilder.pyx":914
 *         """
 *         # Look for SQL within code blocks
 *         code_block_pattern = r"```(?:sql)?\s*(.*?)```"             # <<<<<<<<<<<<<<
 *         code_blocks = re.findall(code_block_pattern, response, re.DOTALL)
 * 
 */
  __Pyx_INCREF(__pyx_kp_u_sql_s);
  __pyx_v_code_block_pattern = __pyx_kp_u_sql_s;

  /* "sQQideR/SQLBuilder.pyx":915
 *         # Look for SQL within code blocks
 *         code_block_pattern = r"```(?:sql)?\s*(.*?)```"
 *         code_blocks = re.findall(code_block_pattern, response, re.DOTALL)             # <<<<<<<<<<<<<<
 * 
 *         if code_blocks:
 */
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 915, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_findall); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 915, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 915, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_DOTALL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 915, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  __pyx_t_5 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(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_5 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[4] = {__pyx_t_2, __pyx_v_code_block_pattern, __pyx_v_response, __pyx_t_4};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 3+__pyx_t_5);
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 915, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  }
  __pyx_v_code_blocks = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":917
 *         code_blocks = re.findall(code_block_pattern, response, re.DOTALL)
 * 
 *         if code_blocks:             # <<<<<<<<<<<<<<
 *             # Use the first code block that looks like SQL
 *             for block in code_blocks:
 */
  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_code_blocks); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 917, __pyx_L1_error)
  if (__pyx_t_6) {

    /* "sQQideR/SQLBuilder.pyx":919
 *         if code_blocks:
 *             # Use the first code block that looks like SQL
 *             for block in code_blocks:             # <<<<<<<<<<<<<<
 *                 if re.search(r"\bSELECT\b", block, re.IGNORECASE):
 *                     return block.strip()
 */
    if (likely(PyList_CheckExact(__pyx_v_code_blocks)) || PyTuple_CheckExact(__pyx_v_code_blocks)) {
      __pyx_t_1 = __pyx_v_code_blocks; __Pyx_INCREF(__pyx_t_1);
      __pyx_t_7 = 0;
      __pyx_t_8 = NULL;
    } else {
      __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_code_blocks); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 919, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 919, __pyx_L1_error)
    }
    for (;;) {
      if (likely(!__pyx_t_8)) {
        if (likely(PyList_CheckExact(__pyx_t_1))) {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 919, __pyx_L1_error)
            #endif
            if (__pyx_t_7 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 919, __pyx_L1_error)
          #else
          __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 919, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          #endif
        } else {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 919, __pyx_L1_error)
            #endif
            if (__pyx_t_7 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely((0 < 0))) __PYX_ERR(0, 919, __pyx_L1_error)
          #else
          __pyx_t_3 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 919, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          #endif
        }
      } else {
        __pyx_t_3 = __pyx_t_8(__pyx_t_1);
        if (unlikely(!__pyx_t_3)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 919, __pyx_L1_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_3);
      }
      __Pyx_XDECREF_SET(__pyx_v_block, __pyx_t_3);
      __pyx_t_3 = 0;

      /* "sQQideR/SQLBuilder.pyx":920
 *             # Use the first code block that looks like SQL
 *             for block in code_blocks:
 *                 if re.search(r"\bSELECT\b", block, re.IGNORECASE):             # <<<<<<<<<<<<<<
 *                     return block.strip()
 * 
 */
      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_re); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 920, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_search); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 920, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_re); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 920, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_IGNORECASE); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 920, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __pyx_t_4 = NULL;
      __pyx_t_5 = 0;
      #if CYTHON_UNPACK_METHODS
      if (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_5 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[4] = {__pyx_t_4, __pyx_kp_u_bSELECT_b, __pyx_v_block, __pyx_t_9};
        __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 3+__pyx_t_5);
        __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
        if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 920, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_3);
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      }
      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 920, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      if (__pyx_t_6) {

        /* "sQQideR/SQLBuilder.pyx":921
 *             for block in code_blocks:
 *                 if re.search(r"\bSELECT\b", block, re.IGNORECASE):
 *                     return block.strip()             # <<<<<<<<<<<<<<
 * 
 *         # If no code blocks with SQL, look for direct SQL
 */
        __Pyx_XDECREF(__pyx_r);
        __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_block, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 921, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        __pyx_t_9 = NULL;
        __pyx_t_5 = 0;
        #if CYTHON_UNPACK_METHODS
        if (likely(PyMethod_Check(__pyx_t_2))) {
          __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_2);
          if (likely(__pyx_t_9)) {
            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
            __Pyx_INCREF(__pyx_t_9);
            __Pyx_INCREF(function);
            __Pyx_DECREF_SET(__pyx_t_2, function);
            __pyx_t_5 = 1;
          }
        }
        #endif
        {
          PyObject *__pyx_callargs[2] = {__pyx_t_9, NULL};
          __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 0+__pyx_t_5);
          __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
          if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 921, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_3);
          __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
        }
        if (!(likely(PyUnicode_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None) || __Pyx_RaiseUnexpectedTypeError("unicode", __pyx_t_3))) __PYX_ERR(0, 921, __pyx_L1_error)
        __pyx_r = ((PyObject*)__pyx_t_3);
        __pyx_t_3 = 0;
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        goto __pyx_L0;

        /* "sQQideR/SQLBuilder.pyx":920
 *             # Use the first code block that looks like SQL
 *             for block in code_blocks:
 *                 if re.search(r"\bSELECT\b", block, re.IGNORECASE):             # <<<<<<<<<<<<<<
 *                     return block.strip()
 * 
 */
      }

      /* "sQQideR/SQLBuilder.pyx":919
 *         if code_blocks:
 *             # Use the first code block that looks like SQL
 *             for block in code_blocks:             # <<<<<<<<<<<<<<
 *                 if re.search(r"\bSELECT\b", block, re.IGNORECASE):
 *                     return block.strip()
 */
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":917
 *         code_blocks = re.findall(code_block_pattern, response, re.DOTALL)
 * 
 *         if code_blocks:             # <<<<<<<<<<<<<<
 *             # Use the first code block that looks like SQL
 *             for block in code_blocks:
 */
  }

  /* "sQQideR/SQLBuilder.pyx":924
 * 
 *         # If no code blocks with SQL, look for direct SQL
 *         direct_sql_pattern = r"(?:^|\n)(SELECT\s+.*?)((?:\n\n)|$|(?:\nEXPLANATION:))"             # <<<<<<<<<<<<<<
 *         direct_matches = re.search(direct_sql_pattern, response, re.DOTALL | re.IGNORECASE)
 * 
 */
  __Pyx_INCREF(__pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION);
  __pyx_v_direct_sql_pattern = __pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION;

  /* "sQQideR/SQLBuilder.pyx":925
 *         # If no code blocks with SQL, look for direct SQL
 *         direct_sql_pattern = r"(?:^|\n)(SELECT\s+.*?)((?:\n\n)|$|(?:\nEXPLANATION:))"
 *         direct_matches = re.search(direct_sql_pattern, response, re.DOTALL | re.IGNORECASE)             # <<<<<<<<<<<<<<
 * 
 *         if direct_matches:
 */
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_re); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_search); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 925, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_re); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_DOTALL); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 925, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_9);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_re); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_IGNORECASE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 925, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = PyNumber_Or(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  __pyx_t_5 = 0;
  #if CYTHON_UNPACK_METHODS
  if (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_5 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[4] = {__pyx_t_4, __pyx_v_direct_sql_pattern, __pyx_v_response, __pyx_t_3};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_5, 3+__pyx_t_5);
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 925, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  }
  __pyx_v_direct_matches = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":927
 *         direct_matches = re.search(direct_sql_pattern, response, re.DOTALL | re.IGNORECASE)
 * 
 *         if direct_matches:             # <<<<<<<<<<<<<<
 *             return direct_matches.group(1).strip()
 * 
 */
  __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_direct_matches); if (unlikely((__pyx_t_6 < 0))) __PYX_ERR(0, 927, __pyx_L1_error)
  if (__pyx_t_6) {

    /* "sQQideR/SQLBuilder.pyx":928
 * 
 *         if direct_matches:
 *             return direct_matches.group(1).strip()             # <<<<<<<<<<<<<<
 * 
 *         # Fallback: just return the whole response
 */
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_direct_matches, __pyx_n_s_group); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 928, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = NULL;
    __pyx_t_5 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(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_5 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_int_1};
      __pyx_t_2 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 1+__pyx_t_5);
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 928, __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_strip); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 928, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = NULL;
    __pyx_t_5 = 0;
    #if CYTHON_UNPACK_METHODS
    if (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_5 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_5, 0+__pyx_t_5);
      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 928, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    }
    if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None) || __Pyx_RaiseUnexpectedTypeError("unicode", __pyx_t_1))) __PYX_ERR(0, 928, __pyx_L1_error)
    __pyx_r = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":927
 *         direct_matches = re.search(direct_sql_pattern, response, re.DOTALL | re.IGNORECASE)
 * 
 *         if direct_matches:             # <<<<<<<<<<<<<<
 *             return direct_matches.group(1).strip()
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":931
 * 
 *         # Fallback: just return the whole response
 *         return response.strip()             # <<<<<<<<<<<<<<
 * 
 *     def _extract_explanation(self, response: str) -> str:
 */
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __Pyx_CallUnboundCMethod0(&__pyx_umethod_PyUnicode_Type_strip, __pyx_v_response); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 931, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None) || __Pyx_RaiseUnexpectedTypeError("unicode", __pyx_t_1))) __PYX_ERR(0, 931, __pyx_L1_error)
  __pyx_r = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":903
 *         return prompt
 * 
 *     def _extract_sql_from_response(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the SQL query from the AI response.
 */

  /* 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_9);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._extract_sql_from_response", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_code_block_pattern);
  __Pyx_XDECREF(__pyx_v_code_blocks);
  __Pyx_XDECREF(__pyx_v_block);
  __Pyx_XDECREF(__pyx_v_direct_sql_pattern);
  __Pyx_XDECREF(__pyx_v_direct_matches);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":933
 *         return response.strip()
 * 
 *     def _extract_explanation(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the explanation part from the AI response.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_31_extract_explanation(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_30_extract_explanation, "\n        Extract the explanation part from the AI response.\n        \n        Args:\n            response: Raw AI response text\n            \n        Returns:\n            Extracted explanation or empty string\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_31_extract_explanation = {"_extract_explanation", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_31_extract_explanation, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_30_extract_explanation};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_31_extract_explanation(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_response = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_extract_explanation (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_response,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 933, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_response)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 933, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_extract_explanation", 1, 2, 2, 1); __PYX_ERR(0, 933, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_extract_explanation") < 0)) __PYX_ERR(0, 933, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_response = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_extract_explanation", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 933, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._extract_explanation", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_response), (&PyUnicode_Type), 0, "response", 1))) __PYX_ERR(0, 933, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_30_extract_explanation(__pyx_self, __pyx_v_self, __pyx_v_response);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_30_extract_explanation(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_response) {
  PyObject *__pyx_v_explanation_pattern = NULL;
  PyObject *__pyx_v_explanation_match = NULL;
  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;
  unsigned int __pyx_t_6;
  int __pyx_t_7;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_extract_explanation", 1);

  /* "sQQideR/SQLBuilder.pyx":943
 *             Extracted explanation or empty string
 *         """
 *         explanation_pattern = r"EXPLANATION:(.*?)(?:$|```)"             # <<<<<<<<<<<<<<
 *         explanation_match = re.search(explanation_pattern, response, re.DOTALL | re.IGNORECASE)
 * 
 */
  __Pyx_INCREF(__pyx_kp_u_EXPLANATION);
  __pyx_v_explanation_pattern = __pyx_kp_u_EXPLANATION;

  /* "sQQideR/SQLBuilder.pyx":944
 *         """
 *         explanation_pattern = r"EXPLANATION:(.*?)(?:$|```)"
 *         explanation_match = re.search(explanation_pattern, response, re.DOTALL | re.IGNORECASE)             # <<<<<<<<<<<<<<
 * 
 *         if explanation_match:
 */
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 944, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_search); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 944, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 944, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_DOTALL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 944, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 944, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_IGNORECASE); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 944, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyNumber_Or(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 944, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  __pyx_t_6 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
      __pyx_t_6 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[4] = {__pyx_t_5, __pyx_v_explanation_pattern, __pyx_v_response, __pyx_t_2};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_6, 3+__pyx_t_6);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 944, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  }
  __pyx_v_explanation_match = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":946
 *         explanation_match = re.search(explanation_pattern, response, re.DOTALL | re.IGNORECASE)
 * 
 *         if explanation_match:             # <<<<<<<<<<<<<<
 *             return explanation_match.group(1).strip()
 * 
 */
  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_v_explanation_match); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 946, __pyx_L1_error)
  if (__pyx_t_7) {

    /* "sQQideR/SQLBuilder.pyx":947
 * 
 *         if explanation_match:
 *             return explanation_match.group(1).strip()             # <<<<<<<<<<<<<<
 * 
 *         return ""
 */
    __Pyx_XDECREF(__pyx_r);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_explanation_match, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 947, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(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;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_int_1};
      __pyx_t_3 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 1+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 947, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    }
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 947, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_3 = NULL;
    __pyx_t_6 = 0;
    #if CYTHON_UNPACK_METHODS
    if (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_6 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_6, 0+__pyx_t_6);
      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 947, __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) || __Pyx_RaiseUnexpectedTypeError("unicode", __pyx_t_1))) __PYX_ERR(0, 947, __pyx_L1_error)
    __pyx_r = ((PyObject*)__pyx_t_1);
    __pyx_t_1 = 0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":946
 *         explanation_match = re.search(explanation_pattern, response, re.DOTALL | re.IGNORECASE)
 * 
 *         if explanation_match:             # <<<<<<<<<<<<<<
 *             return explanation_match.group(1).strip()
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":949
 *             return explanation_match.group(1).strip()
 * 
 *         return ""             # <<<<<<<<<<<<<<
 * 
 *     def _generate_result_summary(self, df: pd.DataFrame) -> str:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_kp_u__7);
  __pyx_r = __pyx_kp_u__7;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":933
 *         return response.strip()
 * 
 *     def _extract_explanation(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the explanation part from the AI response.
 */

  /* 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_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._extract_explanation", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_explanation_pattern);
  __Pyx_XDECREF(__pyx_v_explanation_match);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":951
 *         return ""
 * 
 *     def _generate_result_summary(self, df: pd.DataFrame) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Generate a human-readable summary of query results.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_33_generate_result_summary(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_32_generate_result_summary, "\n        Generate a human-readable summary of query results.\n        \n        Args:\n            df: DataFrame containing query results\n            \n        Returns:\n            Summary string\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_33_generate_result_summary = {"_generate_result_summary", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_33_generate_result_summary, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_32_generate_result_summary};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_33_generate_result_summary(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_df = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_generate_result_summary (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_df,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 951, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_df)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 951, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_generate_result_summary", 1, 2, 2, 1); __PYX_ERR(0, 951, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_generate_result_summary") < 0)) __PYX_ERR(0, 951, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_df = values[1];
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_generate_result_summary", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 951, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._generate_result_summary", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_32_generate_result_summary(__pyx_self, __pyx_v_self, __pyx_v_df);

  /* function exit code */
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_32_generate_result_summary(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_df) {
  PyObject *__pyx_v_num_rows = NULL;
  Py_ssize_t __pyx_v_num_cols;
  PyObject *__pyx_v_summary = NULL;
  PyObject *__pyx_v_sample = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  int __pyx_t_2;
  Py_ssize_t __pyx_t_3;
  Py_UCS4 __pyx_t_4;
  PyObject *__pyx_t_5 = NULL;
  PyObject *__pyx_t_6 = NULL;
  PyObject *__pyx_t_7 = NULL;
  unsigned int __pyx_t_8;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_generate_result_summary", 1);

  /* "sQQideR/SQLBuilder.pyx":961
 *             Summary string
 *         """
 *         if df.empty:             # <<<<<<<<<<<<<<
 *             return "Query returned no results."
 * 
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 961, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 961, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_2) {

    /* "sQQideR/SQLBuilder.pyx":962
 *         """
 *         if df.empty:
 *             return "Query returned no results."             # <<<<<<<<<<<<<<
 * 
 *         num_rows = len(df)
 */
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_kp_u_Query_returned_no_results);
    __pyx_r = __pyx_kp_u_Query_returned_no_results;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":961
 *             Summary string
 *         """
 *         if df.empty:             # <<<<<<<<<<<<<<
 *             return "Query returned no results."
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":964
 *             return "Query returned no results."
 * 
 *         num_rows = len(df)             # <<<<<<<<<<<<<<
 *         num_cols = len(df.columns)
 * 
 */
  __pyx_t_3 = PyObject_Length(__pyx_v_df); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(0, 964, __pyx_L1_error)
  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 964, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_v_num_rows = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":965
 * 
 *         num_rows = len(df)
 *         num_cols = len(df.columns)             # <<<<<<<<<<<<<<
 * 
 *         summary = f"Query returned {num_rows} row(s) with {num_cols} column(s)."
 */
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_columns); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 965, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(0, 965, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_num_cols = __pyx_t_3;

  /* "sQQideR/SQLBuilder.pyx":967
 *         num_cols = len(df.columns)
 * 
 *         summary = f"Query returned {num_rows} row(s) with {num_cols} column(s)."             # <<<<<<<<<<<<<<
 * 
 *         # If small result set, add more details
 */
  __pyx_t_1 = PyTuple_New(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 967, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = 0;
  __pyx_t_4 = 127;
  __Pyx_INCREF(__pyx_kp_u_Query_returned);
  __pyx_t_3 += 15;
  __Pyx_GIVEREF(__pyx_kp_u_Query_returned);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Query_returned);
  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_num_rows, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 967, __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_3 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_5);
  __Pyx_GIVEREF(__pyx_t_5);
  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_5);
  __pyx_t_5 = 0;
  __Pyx_INCREF(__pyx_kp_u_row_s_with);
  __pyx_t_3 += 13;
  __Pyx_GIVEREF(__pyx_kp_u_row_s_with);
  PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_row_s_with);
  __pyx_t_5 = __Pyx_PyUnicode_From_Py_ssize_t(__pyx_v_num_cols, 0, ' ', 'd'); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 967, __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_1, 3, __pyx_t_5);
  __pyx_t_5 = 0;
  __Pyx_INCREF(__pyx_kp_u_column_s);
  __pyx_t_3 += 11;
  __Pyx_GIVEREF(__pyx_kp_u_column_s);
  PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_kp_u_column_s);
  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 5, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 967, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_summary = ((PyObject*)__pyx_t_5);
  __pyx_t_5 = 0;

  /* "sQQideR/SQLBuilder.pyx":970
 * 
 *         # If small result set, add more details
 *         if num_rows <= 5:             # <<<<<<<<<<<<<<
 *             sample = df.head().to_string()
 *             summary += f"\n\nResults:\n{sample}"
 */
  __pyx_t_5 = PyObject_RichCompare(__pyx_v_num_rows, __pyx_int_5, Py_LE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 970, __pyx_L1_error)
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 970, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (__pyx_t_2) {

    /* "sQQideR/SQLBuilder.pyx":971
 *         # If small result set, add more details
 *         if num_rows <= 5:
 *             sample = df.head().to_string()             # <<<<<<<<<<<<<<
 *             summary += f"\n\nResults:\n{sample}"
 *         else:
 */
    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_head); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 971, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_7 = NULL;
    __pyx_t_8 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_6))) {
      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
      if (likely(__pyx_t_7)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
        __Pyx_INCREF(__pyx_t_7);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_6, function);
        __pyx_t_8 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_7, NULL};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_8, 0+__pyx_t_8);
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 971, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    }
    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_to_string); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 971, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = NULL;
    __pyx_t_8 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_6))) {
      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_6);
      if (likely(__pyx_t_1)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
        __Pyx_INCREF(__pyx_t_1);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_6, function);
        __pyx_t_8 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_1, NULL};
      __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_8, 0+__pyx_t_8);
      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 971, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    }
    __pyx_v_sample = __pyx_t_5;
    __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":972
 *         if num_rows <= 5:
 *             sample = df.head().to_string()
 *             summary += f"\n\nResults:\n{sample}"             # <<<<<<<<<<<<<<
 *         else:
 *             sample = df.head(3).to_string()
 */
    __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_v_sample, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 972, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Results, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 972, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_summary, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 972, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF_SET(__pyx_v_summary, ((PyObject*)__pyx_t_5));
    __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":970
 * 
 *         # If small result set, add more details
 *         if num_rows <= 5:             # <<<<<<<<<<<<<<
 *             sample = df.head().to_string()
 *             summary += f"\n\nResults:\n{sample}"
 */
    goto __pyx_L4;
  }

  /* "sQQideR/SQLBuilder.pyx":974
 *             summary += f"\n\nResults:\n{sample}"
 *         else:
 *             sample = df.head(3).to_string()             # <<<<<<<<<<<<<<
 *             summary += f"\n\nSample of first 3 rows:\n{sample}\n...\n(plus {num_rows-3} more rows)"
 * 
 */
  /*else*/ {
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_df, __pyx_n_s_head); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 974, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_7 = NULL;
    __pyx_t_8 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_7)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_7);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
        __pyx_t_8 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_int_3};
      __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_8, 1+__pyx_t_8);
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 974, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    }
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_to_string); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 974, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_6 = NULL;
    __pyx_t_8 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_6)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_6);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
        __pyx_t_8 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_6, NULL};
      __pyx_t_5 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_8, 0+__pyx_t_8);
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 974, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    }
    __pyx_v_sample = __pyx_t_5;
    __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":975
 *         else:
 *             sample = df.head(3).to_string()
 *             summary += f"\n\nSample of first 3 rows:\n{sample}\n...\n(plus {num_rows-3} more rows)"             # <<<<<<<<<<<<<<
 * 
 *         return summary
 */
    __pyx_t_5 = PyTuple_New(5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 975, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_3 = 0;
    __pyx_t_4 = 127;
    __Pyx_INCREF(__pyx_kp_u_Sample_of_first_3_rows);
    __pyx_t_3 += 26;
    __Pyx_GIVEREF(__pyx_kp_u_Sample_of_first_3_rows);
    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_kp_u_Sample_of_first_3_rows);
    __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_v_sample, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 975, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_1) : __pyx_t_4;
    __pyx_t_3 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_1);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1);
    __pyx_t_1 = 0;
    __Pyx_INCREF(__pyx_kp_u_plus);
    __pyx_t_3 += 11;
    __Pyx_GIVEREF(__pyx_kp_u_plus);
    PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u_plus);
    __pyx_t_1 = __Pyx_PyInt_SubtractObjC(__pyx_v_num_rows, __pyx_int_3, 3, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 975, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 975, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_4 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_4) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_4;
    __pyx_t_3 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_6);
    PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_6);
    __pyx_t_6 = 0;
    __Pyx_INCREF(__pyx_kp_u_more_rows);
    __pyx_t_3 += 11;
    __Pyx_GIVEREF(__pyx_kp_u_more_rows);
    PyTuple_SET_ITEM(__pyx_t_5, 4, __pyx_kp_u_more_rows);
    __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_5, 5, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 975, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = __Pyx_PyUnicode_ConcatInPlace(__pyx_v_summary, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 975, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF_SET(__pyx_v_summary, ((PyObject*)__pyx_t_5));
    __pyx_t_5 = 0;
  }
  __pyx_L4:;

  /* "sQQideR/SQLBuilder.pyx":977
 *             summary += f"\n\nSample of first 3 rows:\n{sample}\n...\n(plus {num_rows-3} more rows)"
 * 
 *         return summary             # <<<<<<<<<<<<<<
 * 
 *     def _evaluate_query_relevance(self, query: Dict, question: str) -> float:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_summary);
  __pyx_r = __pyx_v_summary;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":951
 *         return ""
 * 
 *     def _generate_result_summary(self, df: pd.DataFrame) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Generate a human-readable summary of query results.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._generate_result_summary", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_num_rows);
  __Pyx_XDECREF(__pyx_v_summary);
  __Pyx_XDECREF(__pyx_v_sample);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":979
 *         return summary
 * 
 *     def _evaluate_query_relevance(self, query: Dict, question: str) -> float:             # <<<<<<<<<<<<<<
 *         """
 *         Evaluate how relevant a query's results are to the original question.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_35_evaluate_query_relevance(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_34_evaluate_query_relevance, "\n        Evaluate how relevant a query's results are to the original question.\n        \n        This is a simple heuristic-based evaluation. In a production system,\n        you might want to use an AI model to evaluate relevance.\n        \n        Args:\n            query: Query dictionary with results\n            question: Original natural language question\n            \n        Returns:\n            Relevance score (0-10)\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_35_evaluate_query_relevance = {"_evaluate_query_relevance", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_35_evaluate_query_relevance, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_34_evaluate_query_relevance};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_35_evaluate_query_relevance(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_query = 0;
  PyObject *__pyx_v_question = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[3] = {0,0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_evaluate_query_relevance (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_query,&__pyx_n_s_question,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 979, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_query)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 979, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_evaluate_query_relevance", 1, 3, 3, 1); __PYX_ERR(0, 979, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_question)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[2]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 979, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_evaluate_query_relevance", 1, 3, 3, 2); __PYX_ERR(0, 979, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_evaluate_query_relevance") < 0)) __PYX_ERR(0, 979, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 3)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
      values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2);
    }
    __pyx_v_self = values[0];
    __pyx_v_query = ((PyObject*)values[1]);
    __pyx_v_question = ((PyObject*)values[2]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_evaluate_query_relevance", 1, 3, 3, __pyx_nargs); __PYX_ERR(0, 979, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._evaluate_query_relevance", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), (&PyDict_Type), 0, "query", 1))) __PYX_ERR(0, 979, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_question), (&PyUnicode_Type), 0, "question", 1))) __PYX_ERR(0, 979, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_34_evaluate_query_relevance(__pyx_self, __pyx_v_self, __pyx_v_query, __pyx_v_question);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_34_evaluate_query_relevance(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_query, PyObject *__pyx_v_question) {
  PyObject *__pyx_v_score = NULL;
  PyObject *__pyx_v_row_count = NULL;
  PyObject *__pyx_v_question_keywords = NULL;
  PyObject *__pyx_v_columns = NULL;
  PyObject *__pyx_v_column_keywords = NULL;
  PyObject *__pyx_v_col = NULL;
  PyObject *__pyx_v_overlap = NULL;
  PyObject *__pyx_v_sql = NULL;
  PyObject *__pyx_v_conditions = NULL;
  PyObject *__pyx_8genexpr1__pyx_v_col = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  int __pyx_t_2;
  int __pyx_t_3;
  PyObject *__pyx_t_4 = NULL;
  PyObject *__pyx_t_5 = NULL;
  PyObject *__pyx_t_6 = NULL;
  unsigned int __pyx_t_7;
  Py_ssize_t __pyx_t_8;
  PyObject *(*__pyx_t_9)(PyObject *);
  PyObject *__pyx_t_10 = NULL;
  long __pyx_t_11;
  Py_ssize_t __pyx_t_12;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_evaluate_query_relevance", 1);

  /* "sQQideR/SQLBuilder.pyx":993
 *             Relevance score (0-10)
 *         """
 *         score = 5.0  # Start with neutral score             # <<<<<<<<<<<<<<
 * 
 *         # If query failed, low relevance
 */
  __Pyx_INCREF(__pyx_float_5_0);
  __pyx_v_score = __pyx_float_5_0;

  /* "sQQideR/SQLBuilder.pyx":996
 * 
 *         # If query failed, low relevance
 *         if not query.get("success", False):             # <<<<<<<<<<<<<<
 *             return 0.0
 * 
 */
  __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_query, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 996, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 996, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = (!__pyx_t_2);
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":997
 *         # If query failed, low relevance
 *         if not query.get("success", False):
 *             return 0.0             # <<<<<<<<<<<<<<
 * 
 *         # More results might indicate better coverage (up to a point)
 */
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_float_0_0);
    __pyx_r = __pyx_float_0_0;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":996
 * 
 *         # If query failed, low relevance
 *         if not query.get("success", False):             # <<<<<<<<<<<<<<
 *             return 0.0
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":1000
 * 
 *         # More results might indicate better coverage (up to a point)
 *         row_count = query.get("row_count", 0)             # <<<<<<<<<<<<<<
 *         if row_count == 0:
 *             score -= 2  # Empty results are usually not helpful
 */
  __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_query, __pyx_n_u_row_count, __pyx_int_0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1000, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_v_row_count = __pyx_t_1;
  __pyx_t_1 = 0;

  /* "sQQideR/SQLBuilder.pyx":1001
 *         # More results might indicate better coverage (up to a point)
 *         row_count = query.get("row_count", 0)
 *         if row_count == 0:             # <<<<<<<<<<<<<<
 *             score -= 2  # Empty results are usually not helpful
 *         elif 1 <= row_count <= 20:
 */
  __pyx_t_3 = (__Pyx_PyInt_BoolEqObjC(__pyx_v_row_count, __pyx_int_0, 0, 0)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1001, __pyx_L1_error)
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":1002
 *         row_count = query.get("row_count", 0)
 *         if row_count == 0:
 *             score -= 2  # Empty results are usually not helpful             # <<<<<<<<<<<<<<
 *         elif 1 <= row_count <= 20:
 *             score += 1  # A reasonable number of results is good
 */
    __pyx_t_1 = __Pyx_PyInt_SubtractObjC(__pyx_v_score, __pyx_int_2, 2, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1002, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_score, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":1001
 *         # More results might indicate better coverage (up to a point)
 *         row_count = query.get("row_count", 0)
 *         if row_count == 0:             # <<<<<<<<<<<<<<
 *             score -= 2  # Empty results are usually not helpful
 *         elif 1 <= row_count <= 20:
 */
    goto __pyx_L4;
  }

  /* "sQQideR/SQLBuilder.pyx":1003
 *         if row_count == 0:
 *             score -= 2  # Empty results are usually not helpful
 *         elif 1 <= row_count <= 20:             # <<<<<<<<<<<<<<
 *             score += 1  # A reasonable number of results is good
 *         elif row_count > 100:
 */
  __pyx_t_1 = PyObject_RichCompare(__pyx_int_1, __pyx_v_row_count, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1003, __pyx_L1_error)
  if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
    __Pyx_DECREF(__pyx_t_1);
    __pyx_t_1 = PyObject_RichCompare(__pyx_v_row_count, __pyx_int_20, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1003, __pyx_L1_error)
  }
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1003, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":1004
 *             score -= 2  # Empty results are usually not helpful
 *         elif 1 <= row_count <= 20:
 *             score += 1  # A reasonable number of results is good             # <<<<<<<<<<<<<<
 *         elif row_count > 100:
 *             score -= 1  # Too many results might be too broad
 */
    __pyx_t_1 = __Pyx_PyInt_AddObjC(__pyx_v_score, __pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1004, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_score, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":1003
 *         if row_count == 0:
 *             score -= 2  # Empty results are usually not helpful
 *         elif 1 <= row_count <= 20:             # <<<<<<<<<<<<<<
 *             score += 1  # A reasonable number of results is good
 *         elif row_count > 100:
 */
    goto __pyx_L4;
  }

  /* "sQQideR/SQLBuilder.pyx":1005
 *         elif 1 <= row_count <= 20:
 *             score += 1  # A reasonable number of results is good
 *         elif row_count > 100:             # <<<<<<<<<<<<<<
 *             score -= 1  # Too many results might be too broad
 * 
 */
  __pyx_t_1 = PyObject_RichCompare(__pyx_v_row_count, __pyx_int_100, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1005, __pyx_L1_error)
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1005, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":1006
 *             score += 1  # A reasonable number of results is good
 *         elif row_count > 100:
 *             score -= 1  # Too many results might be too broad             # <<<<<<<<<<<<<<
 * 
 *         # Check if column names relate to question keywords
 */
    __pyx_t_1 = __Pyx_PyInt_SubtractObjC(__pyx_v_score, __pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1006, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF_SET(__pyx_v_score, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":1005
 *         elif 1 <= row_count <= 20:
 *             score += 1  # A reasonable number of results is good
 *         elif row_count > 100:             # <<<<<<<<<<<<<<
 *             score -= 1  # Too many results might be too broad
 * 
 */
  }
  __pyx_L4:;

  /* "sQQideR/SQLBuilder.pyx":1009
 * 
 *         # Check if column names relate to question keywords
 *         question_keywords = set(re.findall(r'\b\w{4,}\b', question.lower()))             # <<<<<<<<<<<<<<
 *         columns = [col.lower() for col in query.get("columns", [])]
 *         column_keywords = set()
 */
  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_re); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1009, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_findall); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_CallUnboundCMethod0(&__pyx_umethod_PyUnicode_Type_lower, __pyx_v_question); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1009, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[3] = {__pyx_t_6, __pyx_kp_u_b_w_4_b, __pyx_t_4};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1009, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __pyx_t_5 = PySet_New(__pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_question_keywords = ((PyObject*)__pyx_t_5);
  __pyx_t_5 = 0;

  /* "sQQideR/SQLBuilder.pyx":1010
 *         # Check if column names relate to question keywords
 *         question_keywords = set(re.findall(r'\b\w{4,}\b', question.lower()))
 *         columns = [col.lower() for col in query.get("columns", [])]             # <<<<<<<<<<<<<<
 *         column_keywords = set()
 *         for col in columns:
 */
  { /* enter inner scope */
    __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1010, __pyx_L7_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1010, __pyx_L7_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = __Pyx_PyDict_GetItemDefault(__pyx_v_query, __pyx_n_u_columns, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1010, __pyx_L7_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (likely(PyList_CheckExact(__pyx_t_4)) || PyTuple_CheckExact(__pyx_t_4)) {
      __pyx_t_1 = __pyx_t_4; __Pyx_INCREF(__pyx_t_1);
      __pyx_t_8 = 0;
      __pyx_t_9 = NULL;
    } else {
      __pyx_t_8 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1010, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_9 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1010, __pyx_L7_error)
    }
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    for (;;) {
      if (likely(!__pyx_t_9)) {
        if (likely(PyList_CheckExact(__pyx_t_1))) {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1010, __pyx_L7_error)
            #endif
            if (__pyx_t_8 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_4); __pyx_t_8++; if (unlikely((0 < 0))) __PYX_ERR(0, 1010, __pyx_L7_error)
          #else
          __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1010, __pyx_L7_error)
          __Pyx_GOTREF(__pyx_t_4);
          #endif
        } else {
          {
            Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_1);
            #if !CYTHON_ASSUME_SAFE_MACROS
            if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1010, __pyx_L7_error)
            #endif
            if (__pyx_t_8 >= __pyx_temp) break;
          }
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_8); __Pyx_INCREF(__pyx_t_4); __pyx_t_8++; if (unlikely((0 < 0))) __PYX_ERR(0, 1010, __pyx_L7_error)
          #else
          __pyx_t_4 = __Pyx_PySequence_ITEM(__pyx_t_1, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1010, __pyx_L7_error)
          __Pyx_GOTREF(__pyx_t_4);
          #endif
        }
      } else {
        __pyx_t_4 = __pyx_t_9(__pyx_t_1);
        if (unlikely(!__pyx_t_4)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 1010, __pyx_L7_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_4);
      }
      __Pyx_XDECREF_SET(__pyx_8genexpr1__pyx_v_col, __pyx_t_4);
      __pyx_t_4 = 0;
      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr1__pyx_v_col, __pyx_n_s_lower); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1010, __pyx_L7_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_10 = NULL;
      __pyx_t_7 = 0;
      #if CYTHON_UNPACK_METHODS
      if (likely(PyMethod_Check(__pyx_t_6))) {
        __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_6);
        if (likely(__pyx_t_10)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
          __Pyx_INCREF(__pyx_t_10);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_6, function);
          __pyx_t_7 = 1;
        }
      }
      #endif
      {
        PyObject *__pyx_callargs[2] = {__pyx_t_10, NULL};
        __pyx_t_4 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
        __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
        if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1010, __pyx_L7_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      }
      if (unlikely(__Pyx_ListComp_Append(__pyx_t_5, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 1010, __pyx_L7_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_col); __pyx_8genexpr1__pyx_v_col = 0;
    goto __pyx_L11_exit_scope;
    __pyx_L7_error:;
    __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_col); __pyx_8genexpr1__pyx_v_col = 0;
    goto __pyx_L1_error;
    __pyx_L11_exit_scope:;
  } /* exit inner scope */
  __pyx_v_columns = ((PyObject*)__pyx_t_5);
  __pyx_t_5 = 0;

  /* "sQQideR/SQLBuilder.pyx":1011
 *         question_keywords = set(re.findall(r'\b\w{4,}\b', question.lower()))
 *         columns = [col.lower() for col in query.get("columns", [])]
 *         column_keywords = set()             # <<<<<<<<<<<<<<
 *         for col in columns:
 *             column_keywords.update(re.findall(r'\b\w{4,}\b', col))
 */
  __pyx_t_5 = PySet_New(0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1011, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_v_column_keywords = ((PyObject*)__pyx_t_5);
  __pyx_t_5 = 0;

  /* "sQQideR/SQLBuilder.pyx":1012
 *         columns = [col.lower() for col in query.get("columns", [])]
 *         column_keywords = set()
 *         for col in columns:             # <<<<<<<<<<<<<<
 *             column_keywords.update(re.findall(r'\b\w{4,}\b', col))
 * 
 */
  __pyx_t_5 = __pyx_v_columns; __Pyx_INCREF(__pyx_t_5);
  __pyx_t_8 = 0;
  for (;;) {
    {
      Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_5);
      #if !CYTHON_ASSUME_SAFE_MACROS
      if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1012, __pyx_L1_error)
      #endif
      if (__pyx_t_8 >= __pyx_temp) break;
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_8); __Pyx_INCREF(__pyx_t_1); __pyx_t_8++; if (unlikely((0 < 0))) __PYX_ERR(0, 1012, __pyx_L1_error)
    #else
    __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_5, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1012, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    #endif
    __Pyx_XDECREF_SET(__pyx_v_col, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":1013
 *         column_keywords = set()
 *         for col in columns:
 *             column_keywords.update(re.findall(r'\b\w{4,}\b', col))             # <<<<<<<<<<<<<<
 * 
 *         # Calculate keyword overlap
 */
    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_re); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1013, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_findall); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1013, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_t_4 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (unlikely(PyMethod_Check(__pyx_t_6))) {
      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_6);
      if (likely(__pyx_t_4)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
        __Pyx_INCREF(__pyx_t_4);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_6, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_kp_u_b_w_4_b, __pyx_v_col};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_7, 2+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1013, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    }
    __pyx_t_6 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PySet_Type_update, __pyx_v_column_keywords, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1013, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":1012
 *         columns = [col.lower() for col in query.get("columns", [])]
 *         column_keywords = set()
 *         for col in columns:             # <<<<<<<<<<<<<<
 *             column_keywords.update(re.findall(r'\b\w{4,}\b', col))
 * 
 */
  }
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;

  /* "sQQideR/SQLBuilder.pyx":1016
 * 
 *         # Calculate keyword overlap
 *         overlap = question_keywords.intersection(column_keywords)             # <<<<<<<<<<<<<<
 *         if overlap:
 *             score += min(len(overlap), 3)  # Up to +3 for keyword matches
 */
  __pyx_t_5 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PySet_Type_intersection, __pyx_v_question_keywords, __pyx_v_column_keywords); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1016, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_v_overlap = __pyx_t_5;
  __pyx_t_5 = 0;

  /* "sQQideR/SQLBuilder.pyx":1017
 *         # Calculate keyword overlap
 *         overlap = question_keywords.intersection(column_keywords)
 *         if overlap:             # <<<<<<<<<<<<<<
 *             score += min(len(overlap), 3)  # Up to +3 for keyword matches
 * 
 */
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_overlap); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1017, __pyx_L1_error)
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":1018
 *         overlap = question_keywords.intersection(column_keywords)
 *         if overlap:
 *             score += min(len(overlap), 3)  # Up to +3 for keyword matches             # <<<<<<<<<<<<<<
 * 
 *         # Prefer queries that include more specific filters
 */
    __pyx_t_11 = 3;
    __pyx_t_8 = PyObject_Length(__pyx_v_overlap); if (unlikely(__pyx_t_8 == ((Py_ssize_t)-1))) __PYX_ERR(0, 1018, __pyx_L1_error)
    __pyx_t_3 = (__pyx_t_11 < __pyx_t_8);
    if (__pyx_t_3) {
      __pyx_t_12 = __pyx_t_11;
    } else {
      __pyx_t_12 = __pyx_t_8;
    }
    __pyx_t_5 = PyInt_FromSsize_t(__pyx_t_12); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1018, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = PyNumber_InPlaceAdd(__pyx_v_score, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1018, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF_SET(__pyx_v_score, __pyx_t_6);
    __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":1017
 *         # Calculate keyword overlap
 *         overlap = question_keywords.intersection(column_keywords)
 *         if overlap:             # <<<<<<<<<<<<<<
 *             score += min(len(overlap), 3)  # Up to +3 for keyword matches
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":1021
 * 
 *         # Prefer queries that include more specific filters
 *         sql = query.get("sql", "").lower()             # <<<<<<<<<<<<<<
 *         if "where" in sql:
 *             score += 1  # Having a WHERE clause is good
 */
  __pyx_t_5 = __Pyx_PyDict_GetItemDefault(__pyx_v_query, __pyx_n_u_sql, __pyx_kp_u__7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1021, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_lower); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1021, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = NULL;
  __pyx_t_7 = 0;
  #if CYTHON_UNPACK_METHODS
  if (likely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
      __pyx_t_7 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL};
    __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_7, 0+__pyx_t_7);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1021, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  }
  __pyx_v_sql = __pyx_t_6;
  __pyx_t_6 = 0;

  /* "sQQideR/SQLBuilder.pyx":1022
 *         # Prefer queries that include more specific filters
 *         sql = query.get("sql", "").lower()
 *         if "where" in sql:             # <<<<<<<<<<<<<<
 *             score += 1  # Having a WHERE clause is good
 *             # Count filter conditions
 */
  __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_n_u_where, __pyx_v_sql, Py_EQ)); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1022, __pyx_L1_error)
  if (__pyx_t_3) {

    /* "sQQideR/SQLBuilder.pyx":1023
 *         sql = query.get("sql", "").lower()
 *         if "where" in sql:
 *             score += 1  # Having a WHERE clause is good             # <<<<<<<<<<<<<<
 *             # Count filter conditions
 *             conditions = sql.count(" and ") + sql.count(" or ")
 */
    __pyx_t_6 = __Pyx_PyInt_AddObjC(__pyx_v_score, __pyx_int_1, 1, 1, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1023, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF_SET(__pyx_v_score, __pyx_t_6);
    __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":1025
 *             score += 1  # Having a WHERE clause is good
 *             # Count filter conditions
 *             conditions = sql.count(" and ") + sql.count(" or ")             # <<<<<<<<<<<<<<
 *             score += min(conditions, 2) * 0.5  # Up to +1 for multiple conditions
 * 
 */
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_sql, __pyx_n_s_count); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1025, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_5 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_5)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_5, __pyx_kp_u_and};
      __pyx_t_6 = __Pyx_PyObject_FastCall(__pyx_t_1, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1025, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    }
    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_sql, __pyx_n_s_count); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1025, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_4 = NULL;
    __pyx_t_7 = 0;
    #if CYTHON_UNPACK_METHODS
    if (likely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_4)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_4);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
        __pyx_t_7 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_4, __pyx_kp_u_or};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_5, __pyx_callargs+1-__pyx_t_7, 1+__pyx_t_7);
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1025, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __pyx_t_5 = PyNumber_Add(__pyx_t_6, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1025, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_v_conditions = __pyx_t_5;
    __pyx_t_5 = 0;

    /* "sQQideR/SQLBuilder.pyx":1026
 *             # Count filter conditions
 *             conditions = sql.count(" and ") + sql.count(" or ")
 *             score += min(conditions, 2) * 0.5  # Up to +1 for multiple conditions             # <<<<<<<<<<<<<<
 * 
 *         # Cap score between 0 and 10
 */
    __pyx_t_11 = 2;
    __Pyx_INCREF(__pyx_v_conditions);
    __pyx_t_5 = __pyx_v_conditions;
    __pyx_t_6 = __Pyx_PyInt_From_long(__pyx_t_11); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1026, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_4 = PyObject_RichCompare(__pyx_t_6, __pyx_t_5, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1026, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1026, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (__pyx_t_3) {
      __pyx_t_4 = __Pyx_PyInt_From_long(__pyx_t_11); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1026, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_1 = __pyx_t_4;
      __pyx_t_4 = 0;
    } else {
      __Pyx_INCREF(__pyx_t_5);
      __pyx_t_1 = __pyx_t_5;
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = PyNumber_Multiply(__pyx_t_1, __pyx_float_0_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1026, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_score, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1026, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF_SET(__pyx_v_score, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":1022
 *         # Prefer queries that include more specific filters
 *         sql = query.get("sql", "").lower()
 *         if "where" in sql:             # <<<<<<<<<<<<<<
 *             score += 1  # Having a WHERE clause is good
 *             # Count filter conditions
 */
  }

  /* "sQQideR/SQLBuilder.pyx":1029
 * 
 *         # Cap score between 0 and 10
 *         return max(0, min(10, score))             # <<<<<<<<<<<<<<
 * 
 *     def _validate_safe_sql(self, sql: str) -> Optional[str]:
 */
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_score);
  __pyx_t_1 = __pyx_v_score;
  __pyx_t_11 = 10;
  __pyx_t_4 = __Pyx_PyInt_From_long(__pyx_t_11); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1029, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = PyObject_RichCompare(__pyx_t_1, __pyx_t_4, Py_LT); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1029, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1029, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  if (__pyx_t_3) {
    __Pyx_INCREF(__pyx_t_1);
    __pyx_t_5 = __pyx_t_1;
  } else {
    __pyx_t_6 = __Pyx_PyInt_From_long(__pyx_t_11); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1029, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_5 = __pyx_t_6;
    __pyx_t_6 = 0;
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_INCREF(__pyx_t_5);
  __pyx_t_1 = __pyx_t_5;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_11 = 0;
  __pyx_t_6 = __Pyx_PyInt_From_long(__pyx_t_11); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1029, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_6, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1029, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_3 < 0))) __PYX_ERR(0, 1029, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__pyx_t_3) {
    __Pyx_INCREF(__pyx_t_1);
    __pyx_t_5 = __pyx_t_1;
  } else {
    __pyx_t_4 = __Pyx_PyInt_From_long(__pyx_t_11); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1029, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_5 = __pyx_t_4;
    __pyx_t_4 = 0;
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_INCREF(__pyx_t_5);
  __pyx_r = __pyx_t_5;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":979
 *         return summary
 * 
 *     def _evaluate_query_relevance(self, query: Dict, question: str) -> float:             # <<<<<<<<<<<<<<
 *         """
 *         Evaluate how relevant a query's results are to the original question.
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._evaluate_query_relevance", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_score);
  __Pyx_XDECREF(__pyx_v_row_count);
  __Pyx_XDECREF(__pyx_v_question_keywords);
  __Pyx_XDECREF(__pyx_v_columns);
  __Pyx_XDECREF(__pyx_v_column_keywords);
  __Pyx_XDECREF(__pyx_v_col);
  __Pyx_XDECREF(__pyx_v_overlap);
  __Pyx_XDECREF(__pyx_v_sql);
  __Pyx_XDECREF(__pyx_v_conditions);
  __Pyx_XDECREF(__pyx_8genexpr1__pyx_v_col);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":1031
 *         return max(0, min(10, score))
 * 
 *     def _validate_safe_sql(self, sql: str) -> Optional[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Validate that SQL doesn't contain destructive operations.
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_37_validate_safe_sql(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
PyDoc_STRVAR(__pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_36_validate_safe_sql, "\n        Validate that SQL doesn't contain destructive operations.\n        \n        Args:\n            sql: SQL query string to validate\n            \n        Returns:\n            Error message if SQL contains destructive operations, None if safe\n        ");
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_37_validate_safe_sql = {"_validate_safe_sql", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_37_validate_safe_sql, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_7sQQideR_10SQLBuilder_10SQLBuilder_36_validate_safe_sql};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_37_validate_safe_sql(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_sql = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_validate_safe_sql (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_sql,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1031, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_sql)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1031, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_validate_safe_sql", 1, 2, 2, 1); __PYX_ERR(0, 1031, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_validate_safe_sql") < 0)) __PYX_ERR(0, 1031, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_sql = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_validate_safe_sql", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1031, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._validate_safe_sql", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sql), (&PyUnicode_Type), 0, "sql", 1))) __PYX_ERR(0, 1031, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_36_validate_safe_sql(__pyx_self, __pyx_v_self, __pyx_v_sql);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_36_validate_safe_sql(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_sql) {
  PyObject *__pyx_v_normalized_sql = NULL;
  PyObject *__pyx_v_dangerous_operations = NULL;
  PyObject *__pyx_v_operation = NULL;
  PyObject *__pyx_v_error_msg = NULL;
  PyObject *__pyx_v_pattern = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  PyObject *__pyx_t_1 = NULL;
  PyObject *__pyx_t_2 = NULL;
  PyObject *__pyx_t_3 = NULL;
  unsigned int __pyx_t_4;
  Py_ssize_t __pyx_t_5;
  PyObject *__pyx_t_6 = NULL;
  PyObject *__pyx_t_7 = NULL;
  PyObject *(*__pyx_t_8)(PyObject *);
  int __pyx_t_9;
  Py_ssize_t __pyx_t_10;
  Py_UCS4 __pyx_t_11;
  int __pyx_t_12;
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  __Pyx_RefNannySetupContext("_validate_safe_sql", 1);

  /* "sQQideR/SQLBuilder.pyx":1042
 *         """
 *         # Normalize SQL for consistent checking (remove extra whitespace, case-insensitive)
 *         normalized_sql = " ".join(sql.lower().split())             # <<<<<<<<<<<<<<
 * 
 *         # List of dangerous SQL operations to check for
 */
  __pyx_t_2 = __Pyx_CallUnboundCMethod0(&__pyx_umethod_PyUnicode_Type_lower, __pyx_v_sql); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1042, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_split); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1042, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  __pyx_t_4 = 0;
  #if CYTHON_UNPACK_METHODS
  if (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_4 = 1;
    }
  }
  #endif
  {
    PyObject *__pyx_callargs[2] = {__pyx_t_2, NULL};
    __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_3, __pyx_callargs+1-__pyx_t_4, 0+__pyx_t_4);
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1042, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  }
  __pyx_t_3 = PyUnicode_Join(__pyx_kp_u__35, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1042, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_normalized_sql = ((PyObject*)__pyx_t_3);
  __pyx_t_3 = 0;

  /* "sQQideR/SQLBuilder.pyx":1045
 * 
 *         # List of dangerous SQL operations to check for
 *         dangerous_operations = [             # <<<<<<<<<<<<<<
 *             ("delete", "DELETE operations are not allowed"),
 *             ("drop", "DROP operations are not allowed"),
 */
  __pyx_t_3 = PyList_New(11); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1045, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_INCREF(__pyx_tuple__36);
  __Pyx_GIVEREF(__pyx_tuple__36);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 0, __pyx_tuple__36)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__37);
  __Pyx_GIVEREF(__pyx_tuple__37);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 1, __pyx_tuple__37)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__38);
  __Pyx_GIVEREF(__pyx_tuple__38);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 2, __pyx_tuple__38)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__39);
  __Pyx_GIVEREF(__pyx_tuple__39);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 3, __pyx_tuple__39)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__40);
  __Pyx_GIVEREF(__pyx_tuple__40);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 4, __pyx_tuple__40)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__41);
  __Pyx_GIVEREF(__pyx_tuple__41);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 5, __pyx_tuple__41)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__42);
  __Pyx_GIVEREF(__pyx_tuple__42);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 6, __pyx_tuple__42)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__43);
  __Pyx_GIVEREF(__pyx_tuple__43);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 7, __pyx_tuple__43)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__44);
  __Pyx_GIVEREF(__pyx_tuple__44);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 8, __pyx_tuple__44)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__45);
  __Pyx_GIVEREF(__pyx_tuple__45);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 9, __pyx_tuple__45)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __Pyx_INCREF(__pyx_tuple__46);
  __Pyx_GIVEREF(__pyx_tuple__46);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_3, 10, __pyx_tuple__46)) __PYX_ERR(0, 1045, __pyx_L1_error);
  __pyx_v_dangerous_operations = ((PyObject*)__pyx_t_3);
  __pyx_t_3 = 0;

  /* "sQQideR/SQLBuilder.pyx":1060
 * 
 *         # Check for each dangerous operation
 *         for operation, error_msg in dangerous_operations:             # <<<<<<<<<<<<<<
 *             # Use regex with word boundaries to avoid false positives
 *             pattern = r'\b' + re.escape(operation) + r'\b'
 */
  __pyx_t_3 = __pyx_v_dangerous_operations; __Pyx_INCREF(__pyx_t_3);
  __pyx_t_5 = 0;
  for (;;) {
    {
      Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_3);
      #if !CYTHON_ASSUME_SAFE_MACROS
      if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 1060, __pyx_L1_error)
      #endif
      if (__pyx_t_5 >= __pyx_temp) break;
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    __pyx_t_1 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_5); __Pyx_INCREF(__pyx_t_1); __pyx_t_5++; if (unlikely((0 < 0))) __PYX_ERR(0, 1060, __pyx_L1_error)
    #else
    __pyx_t_1 = __Pyx_PySequence_ITEM(__pyx_t_3, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1060, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    #endif
    if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
      PyObject* sequence = __pyx_t_1;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 2)) {
        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 1060, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
      } else {
        __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
      }
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_6);
      #else
      __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1060, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1060, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      #endif
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_7 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1060, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_8 = __Pyx_PyObject_GetIterNextFunc(__pyx_t_7);
      index = 0; __pyx_t_2 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_2);
      index = 1; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L5_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_6);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 2) < 0) __PYX_ERR(0, 1060, __pyx_L1_error)
      __pyx_t_8 = NULL;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      goto __pyx_L6_unpacking_done;
      __pyx_L5_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_8 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 1060, __pyx_L1_error)
      __pyx_L6_unpacking_done:;
    }
    __Pyx_XDECREF_SET(__pyx_v_operation, __pyx_t_2);
    __pyx_t_2 = 0;
    __Pyx_XDECREF_SET(__pyx_v_error_msg, __pyx_t_6);
    __pyx_t_6 = 0;

    /* "sQQideR/SQLBuilder.pyx":1062
 *         for operation, error_msg in dangerous_operations:
 *             # Use regex with word boundaries to avoid false positives
 *             pattern = r'\b' + re.escape(operation) + r'\b'             # <<<<<<<<<<<<<<
 *             if re.search(pattern, normalized_sql):
 *                 if self.verbose:
 */
    __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_re); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1062, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_escape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1062, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_6 = NULL;
    __pyx_t_4 = 0;
    #if CYTHON_UNPACK_METHODS
    if (unlikely(PyMethod_Check(__pyx_t_2))) {
      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
      if (likely(__pyx_t_6)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_6);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_2, function);
        __pyx_t_4 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[2] = {__pyx_t_6, __pyx_v_operation};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_2, __pyx_callargs+1-__pyx_t_4, 1+__pyx_t_4);
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1062, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    }
    __pyx_t_2 = PyNumber_Add(__pyx_kp_u_b, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1062, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_1 = PyNumber_Add(__pyx_t_2, __pyx_kp_u_b); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1062, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_XDECREF_SET(__pyx_v_pattern, __pyx_t_1);
    __pyx_t_1 = 0;

    /* "sQQideR/SQLBuilder.pyx":1063
 *             # Use regex with word boundaries to avoid false positives
 *             pattern = r'\b' + re.escape(operation) + r'\b'
 *             if re.search(pattern, normalized_sql):             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Blocked dangerous SQL operation: {operation}")
 */
    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_re); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1063, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_search); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1063, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = NULL;
    __pyx_t_4 = 0;
    #if CYTHON_UNPACK_METHODS
    if (unlikely(PyMethod_Check(__pyx_t_6))) {
      __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_6);
      if (likely(__pyx_t_2)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
        __Pyx_INCREF(__pyx_t_2);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_6, function);
        __pyx_t_4 = 1;
      }
    }
    #endif
    {
      PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_v_pattern, __pyx_v_normalized_sql};
      __pyx_t_1 = __Pyx_PyObject_FastCall(__pyx_t_6, __pyx_callargs+1-__pyx_t_4, 2+__pyx_t_4);
      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
      if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1063, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    }
    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 1063, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (__pyx_t_9) {

      /* "sQQideR/SQLBuilder.pyx":1064
 *             pattern = r'\b' + re.escape(operation) + r'\b'
 *             if re.search(pattern, normalized_sql):
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Blocked dangerous SQL operation: {operation}")
 *                 return f"Security restriction: {error_msg}. SQL Query Builder only supports SELECT operations."
 */
      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_verbose); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1064, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 1064, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      if (__pyx_t_9) {

        /* "sQQideR/SQLBuilder.pyx":1065
 *             if re.search(pattern, normalized_sql):
 *                 if self.verbose:
 *                     print(f"Blocked dangerous SQL operation: {operation}")             # <<<<<<<<<<<<<<
 *                 return f"Security restriction: {error_msg}. SQL Query Builder only supports SELECT operations."
 * 
 */
        __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_v_operation, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1065, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __pyx_t_6 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Blocked_dangerous_SQL_operation, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1065, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_print, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1065, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;

        /* "sQQideR/SQLBuilder.pyx":1064
 *             pattern = r'\b' + re.escape(operation) + r'\b'
 *             if re.search(pattern, normalized_sql):
 *                 if self.verbose:             # <<<<<<<<<<<<<<
 *                     print(f"Blocked dangerous SQL operation: {operation}")
 *                 return f"Security restriction: {error_msg}. SQL Query Builder only supports SELECT operations."
 */
      }

      /* "sQQideR/SQLBuilder.pyx":1066
 *                 if self.verbose:
 *                     print(f"Blocked dangerous SQL operation: {operation}")
 *                 return f"Security restriction: {error_msg}. SQL Query Builder only supports SELECT operations."             # <<<<<<<<<<<<<<
 * 
 *         # Verify the SQL begins with SELECT to ensure it's a read-only operation
 */
      __Pyx_XDECREF(__pyx_r);
      __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1066, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_10 = 0;
      __pyx_t_11 = 127;
      __Pyx_INCREF(__pyx_kp_u_Security_restriction);
      __pyx_t_10 += 22;
      __Pyx_GIVEREF(__pyx_kp_u_Security_restriction);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Security_restriction);
      __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_error_msg, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1066, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_11;
      __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_6);
      __pyx_t_6 = 0;
      __Pyx_INCREF(__pyx_kp_u_SQL_Query_Builder_only_supports);
      __pyx_t_10 += 52;
      __Pyx_GIVEREF(__pyx_kp_u_SQL_Query_Builder_only_supports);
      PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u_SQL_Query_Builder_only_supports);
      __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1066, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_r = ((PyObject*)__pyx_t_6);
      __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      goto __pyx_L0;

      /* "sQQideR/SQLBuilder.pyx":1063
 *             # Use regex with word boundaries to avoid false positives
 *             pattern = r'\b' + re.escape(operation) + r'\b'
 *             if re.search(pattern, normalized_sql):             # <<<<<<<<<<<<<<
 *                 if self.verbose:
 *                     print(f"Blocked dangerous SQL operation: {operation}")
 */
    }

    /* "sQQideR/SQLBuilder.pyx":1060
 * 
 *         # Check for each dangerous operation
 *         for operation, error_msg in dangerous_operations:             # <<<<<<<<<<<<<<
 *             # Use regex with word boundaries to avoid false positives
 *             pattern = r'\b' + re.escape(operation) + r'\b'
 */
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;

  /* "sQQideR/SQLBuilder.pyx":1069
 * 
 *         # Verify the SQL begins with SELECT to ensure it's a read-only operation
 *         if not normalized_sql.startswith("select "):             # <<<<<<<<<<<<<<
 *             return "Security restriction: Only SELECT operations are allowed."
 * 
 */
  if (unlikely(__pyx_v_normalized_sql == Py_None)) {
    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "startswith");
    __PYX_ERR(0, 1069, __pyx_L1_error)
  }
  __pyx_t_9 = __Pyx_PyUnicode_Tailmatch(__pyx_v_normalized_sql, __pyx_kp_u_select, 0, PY_SSIZE_T_MAX, -1); if (unlikely(__pyx_t_9 == ((int)-1))) __PYX_ERR(0, 1069, __pyx_L1_error)
  __pyx_t_12 = (!__pyx_t_9);
  if (__pyx_t_12) {

    /* "sQQideR/SQLBuilder.pyx":1070
 *         # Verify the SQL begins with SELECT to ensure it's a read-only operation
 *         if not normalized_sql.startswith("select "):
 *             return "Security restriction: Only SELECT operations are allowed."             # <<<<<<<<<<<<<<
 * 
 *         return None  # SQL is safe
 */
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_kp_u_Security_restriction_Only_SELECT);
    __pyx_r = __pyx_kp_u_Security_restriction_Only_SELECT;
    goto __pyx_L0;

    /* "sQQideR/SQLBuilder.pyx":1069
 * 
 *         # Verify the SQL begins with SELECT to ensure it's a read-only operation
 *         if not normalized_sql.startswith("select "):             # <<<<<<<<<<<<<<
 *             return "Security restriction: Only SELECT operations are allowed."
 * 
 */
  }

  /* "sQQideR/SQLBuilder.pyx":1072
 *             return "Security restriction: Only SELECT operations are allowed."
 * 
 *         return None  # SQL is safe             # <<<<<<<<<<<<<<
 * 
 *     def _clean_text(self, text: str) -> str:
 */
  __Pyx_XDECREF(__pyx_r);
  __pyx_r = ((PyObject*)Py_None); __Pyx_INCREF(Py_None);
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":1031
 *         return max(0, min(10, score))
 * 
 *     def _validate_safe_sql(self, sql: str) -> Optional[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Validate that SQL doesn't contain destructive operations.
 */

  /* 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_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._validate_safe_sql", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_normalized_sql);
  __Pyx_XDECREF(__pyx_v_dangerous_operations);
  __Pyx_XDECREF(__pyx_v_operation);
  __Pyx_XDECREF(__pyx_v_error_msg);
  __Pyx_XDECREF(__pyx_v_pattern);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* "sQQideR/SQLBuilder.pyx":1074
 *         return None  # SQL is safe
 * 
 *     def _clean_text(self, text: str) -> str:             # <<<<<<<<<<<<<<
 *         # Remove newline characters and extra spaces for downstream system compatibility
 *         return " ".join(text.split())
 */

/* Python wrapper */
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_39_clean_text(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
); /*proto*/
static PyMethodDef __pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_39_clean_text = {"_clean_text", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_39_clean_text, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_7sQQideR_10SQLBuilder_10SQLBuilder_39_clean_text(PyObject *__pyx_self, 
#if CYTHON_METH_FASTCALL
PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds
#else
PyObject *__pyx_args, PyObject *__pyx_kwds
#endif
) {
  CYTHON_UNUSED PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_text = 0;
  #if !CYTHON_METH_FASTCALL
  CYTHON_UNUSED Py_ssize_t __pyx_nargs;
  #endif
  CYTHON_UNUSED PyObject *const *__pyx_kwvalues;
  PyObject* values[2] = {0,0};
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_clean_text (wrapper)", 0);
  #if !CYTHON_METH_FASTCALL
  #if CYTHON_ASSUME_SAFE_MACROS
  __pyx_nargs = PyTuple_GET_SIZE(__pyx_args);
  #else
  __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL;
  #endif
  #endif
  __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs);
  {
    PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_text,0};
    if (__pyx_kwds) {
      Py_ssize_t kw_args;
      switch (__pyx_nargs) {
        case  2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds);
      switch (__pyx_nargs) {
        case  0:
        if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_self)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[0]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1074, __pyx_L3_error)
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_text)) != 0)) {
          (void)__Pyx_Arg_NewRef_FASTCALL(values[1]);
          kw_args--;
        }
        else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1074, __pyx_L3_error)
        else {
          __Pyx_RaiseArgtupleInvalid("_clean_text", 1, 2, 2, 1); __PYX_ERR(0, 1074, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        const Py_ssize_t kwd_pos_args = __pyx_nargs;
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "_clean_text") < 0)) __PYX_ERR(0, 1074, __pyx_L3_error)
      }
    } else if (unlikely(__pyx_nargs != 2)) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0);
      values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1);
    }
    __pyx_v_self = values[0];
    __pyx_v_text = ((PyObject*)values[1]);
  }
  goto __pyx_L6_skip;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_clean_text", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 1074, __pyx_L3_error)
  __pyx_L6_skip:;
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L3_error:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._clean_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_text), (&PyUnicode_Type), 0, "text", 1))) __PYX_ERR(0, 1074, __pyx_L1_error)
  __pyx_r = __pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_38_clean_text(__pyx_self, __pyx_v_self, __pyx_v_text);

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  {
    Py_ssize_t __pyx_temp;
    for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) {
      __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]);
    }
  }
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_7sQQideR_10SQLBuilder_10SQLBuilder_38_clean_text(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_text) {
  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("_clean_text", 1);

  /* "sQQideR/SQLBuilder.pyx":1076
 *     def _clean_text(self, text: str) -> str:
 *         # Remove newline characters and extra spaces for downstream system compatibility
 *         return " ".join(text.split())             # <<<<<<<<<<<<<<
 */
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = PyUnicode_Split(__pyx_v_text, ((PyObject *)NULL), -1L); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1076, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = PyUnicode_Join(__pyx_kp_u__35, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1076, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_r = ((PyObject*)__pyx_t_2);
  __pyx_t_2 = 0;
  goto __pyx_L0;

  /* "sQQideR/SQLBuilder.pyx":1074
 *         return None  # SQL is safe
 * 
 *     def _clean_text(self, text: str) -> str:             # <<<<<<<<<<<<<<
 *         # Remove newline characters and extra spaces for downstream system compatibility
 *         return " ".join(text.split())
 */

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_AddTraceback("sQQideR.SQLBuilder.SQLBuilder._clean_text", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

#if CYTHON_USE_FREELISTS
static struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *__pyx_freelist_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations[8];
static int __pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations = 0;
#endif

static PyObject *__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
  PyObject *o;
  #if CYTHON_COMPILING_IN_LIMITED_API
  allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc);
  o = alloc_func(t, 0);
  #else
  #if CYTHON_USE_FREELISTS
  if (likely((int)(__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations)))) {
    o = (PyObject*)__pyx_freelist_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations[--__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations];
    memset(o, 0, sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations));
    (void) PyObject_INIT(o, t);
  } else
  #endif
  {
    o = (*t->tp_alloc)(t, 0);
    if (unlikely(!o)) return 0;
  }
  #endif
  return o;
}

static void __pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations(PyObject *o) {
  struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *p = (struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *)o;
  #if CYTHON_USE_TP_FINALIZE
  if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && (!PyType_IS_GC(Py_TYPE(o)) || !__Pyx_PyObject_GC_IsFinalized(o))) {
    if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations) {
      if (PyObject_CallFinalizerFromDealloc(o)) return;
    }
  }
  #endif
  Py_CLEAR(p->__pyx_v_question);
  #if CYTHON_USE_FREELISTS
  if (((int)(__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations)))) {
    __pyx_freelist_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations[__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations++] = ((struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations *)o);
  } else
  #endif
  {
    #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY
    (*Py_TYPE(o)->tp_free)(o);
    #else
    {
      freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free);
      if (tp_free) tp_free(o);
    }
    #endif
  }
}
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations_slots[] = {
  {Py_tp_dealloc, (void *)__pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations},
  {Py_tp_new, (void *)__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations},
  {0, 0},
};
static PyType_Spec __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations_spec = {
  "sQQideR.SQLBuilder.__pyx_scope_struct__generate_additional_explorations",
  sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations),
  0,
  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_FINALIZE,
  __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations_slots,
};
#else

static PyTypeObject __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations = {
  PyVarObject_HEAD_INIT(0, 0)
  "sQQideR.SQLBuilder.""__pyx_scope_struct__generate_additional_explorations", /*tp_name*/
  sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations), /*tp_basicsize*/
  0, /*tp_itemsize*/
  __pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations, /*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_HAVE_FINALIZE, /*tp_flags*/
  0, /*tp_doc*/
  0, /*tp_traverse*/
  0, /*tp_clear*/
  0, /*tp_richcompare*/
  0, /*tp_weaklistoffset*/
  0, /*tp_iter*/
  0, /*tp_iternext*/
  0, /*tp_methods*/
  0, /*tp_members*/
  0, /*tp_getset*/
  0, /*tp_base*/
  0, /*tp_dict*/
  0, /*tp_descr_get*/
  0, /*tp_descr_set*/
  #if !CYTHON_USE_TYPE_SPECS
  0, /*tp_dictoffset*/
  #endif
  0, /*tp_init*/
  0, /*tp_alloc*/
  __pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations, /*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
  #if CYTHON_USE_TP_FINALIZE
  0, /*tp_finalize*/
  #else
  NULL, /*tp_finalize*/
  #endif
  #endif
  #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800)
  0, /*tp_vectorcall*/
  #endif
  #if __PYX_NEED_TP_PRINT_SLOT == 1
  0, /*tp_print*/
  #endif
  #if PY_VERSION_HEX >= 0x030C0000
  0, /*tp_watched*/
  #endif
  #if PY_VERSION_HEX >= 0x030d00A4
  0, /*tp_versions_used*/
  #endif
  #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
  0, /*tp_pypy_flags*/
  #endif
};
#endif

#if CYTHON_USE_FREELISTS
static struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *__pyx_freelist_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr[8];
static int __pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr = 0;
#endif

static PyObject *__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
  PyObject *o;
  #if CYTHON_COMPILING_IN_LIMITED_API
  allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc);
  o = alloc_func(t, 0);
  #else
  #if CYTHON_USE_FREELISTS
  if (likely((int)(__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr)))) {
    o = (PyObject*)__pyx_freelist_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr[--__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr];
    memset(o, 0, sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr));
    (void) PyObject_INIT(o, t);
    PyObject_GC_Track(o);
  } else
  #endif
  {
    o = (*t->tp_alloc)(t, 0);
    if (unlikely(!o)) return 0;
  }
  #endif
  return o;
}

static void __pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr(PyObject *o) {
  struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *)o;
  #if CYTHON_USE_TP_FINALIZE
  if (unlikely((PY_VERSION_HEX >= 0x03080000 || __Pyx_PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE)) && __Pyx_PyObject_GetSlot(o, tp_finalize, destructor)) && !__Pyx_PyObject_GC_IsFinalized(o)) {
    if (__Pyx_PyObject_GetSlot(o, tp_dealloc, destructor) == __pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr) {
      if (PyObject_CallFinalizerFromDealloc(o)) return;
    }
  }
  #endif
  PyObject_GC_UnTrack(o);
  Py_CLEAR(p->__pyx_outer_scope);
  Py_CLEAR(p->__pyx_genexpr_arg_0);
  Py_CLEAR(p->__pyx_v_keyword);
  #if CYTHON_USE_FREELISTS
  if (((int)(__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr)))) {
    __pyx_freelist_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr[__pyx_freecount_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr++] = ((struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *)o);
  } else
  #endif
  {
    #if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY
    (*Py_TYPE(o)->tp_free)(o);
    #else
    {
      freefunc tp_free = (freefunc)PyType_GetSlot(Py_TYPE(o), Py_tp_free);
      if (tp_free) tp_free(o);
    }
    #endif
  }
}

static int __pyx_tp_traverse_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr(PyObject *o, visitproc v, void *a) {
  int e;
  struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr *)o;
  if (p->__pyx_outer_scope) {
    e = (*v)(((PyObject *)p->__pyx_outer_scope), a); if (e) return e;
  }
  if (p->__pyx_genexpr_arg_0) {
    e = (*v)(p->__pyx_genexpr_arg_0, a); if (e) return e;
  }
  if (p->__pyx_v_keyword) {
    e = (*v)(p->__pyx_v_keyword, a); if (e) return e;
  }
  return 0;
}
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr_slots[] = {
  {Py_tp_dealloc, (void *)__pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr},
  {Py_tp_traverse, (void *)__pyx_tp_traverse_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr},
  {Py_tp_new, (void *)__pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr},
  {0, 0},
};
static PyType_Spec __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr_spec = {
  "sQQideR.SQLBuilder.__pyx_scope_struct_1_genexpr",
  sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr),
  0,
  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE,
  __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr_slots,
};
#else

static PyTypeObject __pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr = {
  PyVarObject_HEAD_INIT(0, 0)
  "sQQideR.SQLBuilder.""__pyx_scope_struct_1_genexpr", /*tp_name*/
  sizeof(struct __pyx_obj_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr), /*tp_basicsize*/
  0, /*tp_itemsize*/
  __pyx_tp_dealloc_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr, /*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_HAVE_GC|Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
  0, /*tp_doc*/
  __pyx_tp_traverse_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr, /*tp_traverse*/
  0, /*tp_clear*/
  0, /*tp_richcompare*/
  0, /*tp_weaklistoffset*/
  0, /*tp_iter*/
  0, /*tp_iternext*/
  0, /*tp_methods*/
  0, /*tp_members*/
  0, /*tp_getset*/
  0, /*tp_base*/
  0, /*tp_dict*/
  0, /*tp_descr_get*/
  0, /*tp_descr_set*/
  #if !CYTHON_USE_TYPE_SPECS
  0, /*tp_dictoffset*/
  #endif
  0, /*tp_init*/
  0, /*tp_alloc*/
  __pyx_tp_new_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr, /*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
  #if CYTHON_USE_TP_FINALIZE
  0, /*tp_finalize*/
  #else
  NULL, /*tp_finalize*/
  #endif
  #endif
  #if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800)
  0, /*tp_vectorcall*/
  #endif
  #if __PYX_NEED_TP_PRINT_SLOT == 1
  0, /*tp_print*/
  #endif
  #if PY_VERSION_HEX >= 0x030C0000
  0, /*tp_watched*/
  #endif
  #if PY_VERSION_HEX >= 0x030d00A4
  0, /*tp_versions_used*/
  #endif
  #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
  0, /*tp_pypy_flags*/
  #endif
};
#endif

static PyMethodDef __pyx_methods[] = {
  {0, 0, 0, 0}
};
#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
/* #### Code section: pystring_table ### */

static int __Pyx_CreateStringTabAndInitStrings(void) {
  __Pyx_StringTabEntry __pyx_string_tab[] = {
    {&__pyx_kp_u_AI_generated_query_appears_more, __pyx_k_AI_generated_query_appears_more, sizeof(__pyx_k_AI_generated_query_appears_more), 0, 1, 0, 0},
    {&__pyx_kp_u_AI_service_not_available_for_SQL, __pyx_k_AI_service_not_available_for_SQL, sizeof(__pyx_k_AI_service_not_available_for_SQL), 0, 1, 0, 0},
    {&__pyx_kp_u_AI_service_or_database_connectio, __pyx_k_AI_service_or_database_connectio, sizeof(__pyx_k_AI_service_or_database_connectio), 0, 1, 0, 0},
    {&__pyx_kp_u_ALTER_operations_are_not_allowed, __pyx_k_ALTER_operations_are_not_allowed, sizeof(__pyx_k_ALTER_operations_are_not_allowed), 0, 1, 0, 0},
    {&__pyx_kp_u_AS_avg, __pyx_k_AS_avg, sizeof(__pyx_k_AS_avg), 0, 1, 0, 0},
    {&__pyx_kp_u_AS_max, __pyx_k_AS_max, sizeof(__pyx_k_AS_max), 0, 1, 0, 0},
    {&__pyx_kp_u_AS_min, __pyx_k_AS_min, sizeof(__pyx_k_AS_min), 0, 1, 0, 0},
    {&__pyx_kp_u_ATTACH_DATABASE_operations_are_n, __pyx_k_ATTACH_DATABASE_operations_are_n, sizeof(__pyx_k_ATTACH_DATABASE_operations_are_n), 0, 1, 0, 0},
    {&__pyx_kp_u_AVG, __pyx_k_AVG, sizeof(__pyx_k_AVG), 0, 1, 0, 0},
    {&__pyx_n_s_Any, __pyx_k_Any, sizeof(__pyx_k_Any), 0, 0, 1, 1},
    {&__pyx_kp_u_Asking_AI_to_fix_SQL, __pyx_k_Asking_AI_to_fix_SQL, sizeof(__pyx_k_Asking_AI_to_fix_SQL), 0, 1, 0, 0},
    {&__pyx_kp_u_Attempt, __pyx_k_Attempt, sizeof(__pyx_k_Attempt), 0, 1, 0, 0},
    {&__pyx_kp_u_Blocked_dangerous_SQL_operation, __pyx_k_Blocked_dangerous_SQL_operation, sizeof(__pyx_k_Blocked_dangerous_SQL_operation), 0, 1, 0, 0},
    {&__pyx_kp_u_COUNT_as_count_FROM, __pyx_k_COUNT_as_count_FROM, sizeof(__pyx_k_COUNT_as_count_FROM), 0, 1, 0, 0},
    {&__pyx_kp_u_CREATE_operations_are_not_allowe, __pyx_k_CREATE_operations_are_not_allowe, sizeof(__pyx_k_CREATE_operations_are_not_allowe), 0, 1, 0, 0},
    {&__pyx_kp_s_Class_for_building_and_testing, __pyx_k_Class_for_building_and_testing, sizeof(__pyx_k_Class_for_building_and_testing), 0, 0, 1, 0},
    {&__pyx_kp_u_Columns, __pyx_k_Columns, sizeof(__pyx_k_Columns), 0, 1, 0, 0},
    {&__pyx_kp_u_Connected_to_database, __pyx_k_Connected_to_database, sizeof(__pyx_k_Connected_to_database), 0, 1, 0, 0},
    {&__pyx_kp_u_Count_records_in, __pyx_k_Count_records_in, sizeof(__pyx_k_Count_records_in), 0, 1, 0, 0},
    {&__pyx_kp_u_DATABASE_CONTEXT, __pyx_k_DATABASE_CONTEXT, sizeof(__pyx_k_DATABASE_CONTEXT), 0, 1, 0, 0},
    {&__pyx_kp_u_DATABASE_SCHEMA_INFORMATION, __pyx_k_DATABASE_SCHEMA_INFORMATION, sizeof(__pyx_k_DATABASE_SCHEMA_INFORMATION), 0, 1, 0, 0},
    {&__pyx_kp_u_DELETE_operations_are_not_allowe, __pyx_k_DELETE_operations_are_not_allowe, sizeof(__pyx_k_DELETE_operations_are_not_allowe), 0, 1, 0, 0},
    {&__pyx_kp_u_DETACH_DATABASE_operations_are_n, __pyx_k_DETACH_DATABASE_operations_are_n, sizeof(__pyx_k_DETACH_DATABASE_operations_are_n), 0, 1, 0, 0},
    {&__pyx_n_s_DOTALL, __pyx_k_DOTALL, sizeof(__pyx_k_DOTALL), 0, 0, 1, 1},
    {&__pyx_kp_u_DROP_operations_are_not_allowed, __pyx_k_DROP_operations_are_not_allowed, sizeof(__pyx_k_DROP_operations_are_not_allowed), 0, 1, 0, 0},
    {&__pyx_kp_u_Database_connection_closed, __pyx_k_Database_connection_closed, sizeof(__pyx_k_Database_connection_closed), 0, 1, 0, 0},
    {&__pyx_kp_u_Database_file_not_found, __pyx_k_Database_file_not_found, sizeof(__pyx_k_Database_file_not_found), 0, 1, 0, 0},
    {&__pyx_n_s_Dict, __pyx_k_Dict, sizeof(__pyx_k_Dict), 0, 0, 1, 1},
    {&__pyx_kp_u_ERROR_MESSAGE, __pyx_k_ERROR_MESSAGE, sizeof(__pyx_k_ERROR_MESSAGE), 0, 1, 0, 0},
    {&__pyx_kp_u_EXPLANATION, __pyx_k_EXPLANATION, sizeof(__pyx_k_EXPLANATION), 0, 1, 0, 0},
    {&__pyx_kp_u_Equal_relevance_using_historical, __pyx_k_Equal_relevance_using_historical, sizeof(__pyx_k_Equal_relevance_using_historical), 0, 1, 0, 0},
    {&__pyx_kp_u_Error, __pyx_k_Error, sizeof(__pyx_k_Error), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_connecting_to_database, __pyx_k_Error_connecting_to_database, sizeof(__pyx_k_Error_connecting_to_database), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_during_AI_retry, __pyx_k_Error_during_AI_retry, sizeof(__pyx_k_Error_during_AI_retry), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_during_retry_attempt, __pyx_k_Error_during_retry_attempt, sizeof(__pyx_k_Error_during_retry_attempt), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_executing_count_exploratio, __pyx_k_Error_executing_count_exploratio, sizeof(__pyx_k_Error_executing_count_exploratio), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_executing_query, __pyx_k_Error_executing_query, sizeof(__pyx_k_Error_executing_query), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_executing_relationship_exp, __pyx_k_Error_executing_relationship_exp, sizeof(__pyx_k_Error_executing_relationship_exp), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_executing_time_exploration, __pyx_k_Error_executing_time_exploration, sizeof(__pyx_k_Error_executing_time_exploration), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_exploring_database_schema, __pyx_k_Error_exploring_database_schema, sizeof(__pyx_k_Error_exploring_database_schema), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_exploring_table, __pyx_k_Error_exploring_table, sizeof(__pyx_k_Error_exploring_table), 0, 1, 0, 0},
    {&__pyx_kp_u_Error_generating_SQL, __pyx_k_Error_generating_SQL, sizeof(__pyx_k_Error_generating_SQL), 0, 1, 0, 0},
    {&__pyx_kp_u_FROM, __pyx_k_FROM, sizeof(__pyx_k_FROM), 0, 1, 0, 0},
    {&__pyx_kp_u_FROM_s_a_zA_Z0_9, __pyx_k_FROM_s_a_zA_Z0_9, sizeof(__pyx_k_FROM_s_a_zA_Z0_9), 0, 1, 0, 0},
    {&__pyx_kp_u_Failed_to_check_existing_logs, __pyx_k_Failed_to_check_existing_logs, sizeof(__pyx_k_Failed_to_check_existing_logs), 0, 1, 0, 0},
    {&__pyx_kp_u_Failed_to_fix_SQL_after, __pyx_k_Failed_to_fix_SQL_after, sizeof(__pyx_k_Failed_to_fix_SQL_after), 0, 1, 0, 0},
    {&__pyx_kp_u_Failed_to_generate_SQL, __pyx_k_Failed_to_generate_SQL, sizeof(__pyx_k_Failed_to_generate_SQL), 0, 1, 0, 0},
    {&__pyx_kp_u_Failed_to_log_corrected_SQL, __pyx_k_Failed_to_log_corrected_SQL, sizeof(__pyx_k_Failed_to_log_corrected_SQL), 0, 1, 0, 0},
    {&__pyx_kp_u_Found_previous_working_SQL_for_t, __pyx_k_Found_previous_working_SQL_for_t, sizeof(__pyx_k_Found_previous_working_SQL_for_t), 0, 1, 0, 0},
    {&__pyx_kp_u_GROUP_BY, __pyx_k_GROUP_BY, sizeof(__pyx_k_GROUP_BY), 0, 1, 0, 0},
    {&__pyx_kp_u_Generated_fixed_SQL, __pyx_k_Generated_fixed_SQL, sizeof(__pyx_k_Generated_fixed_SQL), 0, 1, 0, 0},
    {&__pyx_kp_u_Historical_query_appears_more_re, __pyx_k_Historical_query_appears_more_re, sizeof(__pyx_k_Historical_query_appears_more_re), 0, 1, 0, 0},
    {&__pyx_n_s_IGNORECASE, __pyx_k_IGNORECASE, sizeof(__pyx_k_IGNORECASE), 0, 0, 1, 1},
    {&__pyx_kp_u_INSERT_operations_are_not_allowe, __pyx_k_INSERT_operations_are_not_allowe, sizeof(__pyx_k_INSERT_operations_are_not_allowe), 0, 1, 0, 0},
    {&__pyx_kp_u_INSTRUCTIONS_1_Generate_a_valid, __pyx_k_INSTRUCTIONS_1_Generate_a_valid, sizeof(__pyx_k_INSTRUCTIONS_1_Generate_a_valid), 0, 1, 0, 0},
    {&__pyx_kp_u_JOIN, __pyx_k_JOIN, sizeof(__pyx_k_JOIN), 0, 1, 0, 0},
    {&__pyx_kp_u_JOIN_s_a_zA_Z0_9, __pyx_k_JOIN_s_a_zA_Z0_9, sizeof(__pyx_k_JOIN_s_a_zA_Z0_9), 0, 1, 0, 0},
    {&__pyx_kp_u_LIMIT_3, __pyx_k_LIMIT_3, sizeof(__pyx_k_LIMIT_3), 0, 1, 0, 0},
    {&__pyx_n_s_List, __pyx_k_List, sizeof(__pyx_k_List), 0, 0, 1, 1},
    {&__pyx_kp_s_List_Dict, __pyx_k_List_Dict, sizeof(__pyx_k_List_Dict), 0, 0, 1, 0},
    {&__pyx_kp_s_List_str, __pyx_k_List_str, sizeof(__pyx_k_List_str), 0, 0, 1, 0},
    {&__pyx_kp_u_MAX, __pyx_k_MAX, sizeof(__pyx_k_MAX), 0, 1, 0, 0},
    {&__pyx_kp_u_MIN, __pyx_k_MIN, sizeof(__pyx_k_MIN), 0, 1, 0, 0},
    {&__pyx_kp_u_Neither_query_executed_successfu, __pyx_k_Neither_query_executed_successfu, sizeof(__pyx_k_Neither_query_executed_successfu), 0, 1, 0, 0},
    {&__pyx_kp_u_No_SQL, __pyx_k_No_SQL, sizeof(__pyx_k_No_SQL), 0, 1, 0, 0},
    {&__pyx_kp_u_No_SQL_query_provided, __pyx_k_No_SQL_query_provided, sizeof(__pyx_k_No_SQL_query_provided), 0, 1, 0, 0},
    {&__pyx_kp_u_No_database_connection_available, __pyx_k_No_database_connection_available, sizeof(__pyx_k_No_database_connection_available), 0, 1, 0, 0},
    {&__pyx_kp_u_No_description, __pyx_k_No_description, sizeof(__pyx_k_No_description), 0, 1, 0, 0},
    {&__pyx_kp_u_No_original_SQL_available, __pyx_k_No_original_SQL_available, sizeof(__pyx_k_No_original_SQL_available), 0, 1, 0, 0},
    {&__pyx_n_s_None, __pyx_k_None, sizeof(__pyx_k_None), 0, 0, 1, 1},
    {&__pyx_kp_u_None, __pyx_k_None, sizeof(__pyx_k_None), 0, 1, 0, 0},
    {&__pyx_kp_u_ON, __pyx_k_ON, sizeof(__pyx_k_ON), 0, 1, 0, 0},
    {&__pyx_kp_u_ORDER_BY_COUNT_DESC_LIMIT_5, __pyx_k_ORDER_BY_COUNT_DESC_LIMIT_5, sizeof(__pyx_k_ORDER_BY_COUNT_DESC_LIMIT_5), 0, 1, 0, 0},
    {&__pyx_kp_u_ORIGINAL_SQL_QUERY_THAT_FAILED, __pyx_k_ORIGINAL_SQL_QUERY_THAT_FAILED, sizeof(__pyx_k_ORIGINAL_SQL_QUERY_THAT_FAILED), 0, 1, 0, 0},
    {&__pyx_kp_u_Only_AI_generated_query_executed, __pyx_k_Only_AI_generated_query_executed, sizeof(__pyx_k_Only_AI_generated_query_executed), 0, 1, 0, 0},
    {&__pyx_kp_u_Only_historical_query_executed_s, __pyx_k_Only_historical_query_executed_s, sizeof(__pyx_k_Only_historical_query_executed_s), 0, 1, 0, 0},
    {&__pyx_n_s_Optional, __pyx_k_Optional, sizeof(__pyx_k_Optional), 0, 0, 1, 1},
    {&__pyx_kp_s_Optional_Dict, __pyx_k_Optional_Dict, sizeof(__pyx_k_Optional_Dict), 0, 0, 1, 0},
    {&__pyx_kp_s_Optional_str, __pyx_k_Optional_str, sizeof(__pyx_k_Optional_str), 0, 0, 1, 0},
    {&__pyx_kp_u_Original_error, __pyx_k_Original_error, sizeof(__pyx_k_Original_error), 0, 1, 0, 0},
    {&__pyx_kp_u_PRAGMA_operations_are_not_allowe, __pyx_k_PRAGMA_operations_are_not_allowe, sizeof(__pyx_k_PRAGMA_operations_are_not_allowe), 0, 1, 0, 0},
    {&__pyx_kp_u_PRAGMA_table_info, __pyx_k_PRAGMA_table_info, sizeof(__pyx_k_PRAGMA_table_info), 0, 1, 0, 0},
    {&__pyx_kp_u_PREVIOUSLY_RUN_QUERY_FOR_SIMILA, __pyx_k_PREVIOUSLY_RUN_QUERY_FOR_SIMILA, sizeof(__pyx_k_PREVIOUSLY_RUN_QUERY_FOR_SIMILA), 0, 1, 0, 0},
    {&__pyx_kp_u_PREVIOUS_CORRECTION_ATTEMPTS, __pyx_k_PREVIOUS_CORRECTION_ATTEMPTS, sizeof(__pyx_k_PREVIOUS_CORRECTION_ATTEMPTS), 0, 1, 0, 0},
    {&__pyx_kp_u_Previous_SQL_attempt_failed_wit, __pyx_k_Previous_SQL_attempt_failed_wit, sizeof(__pyx_k_Previous_SQL_attempt_failed_wit), 0, 1, 0, 0},
    {&__pyx_kp_u_Query, __pyx_k_Query, sizeof(__pyx_k_Query), 0, 1, 0, 0},
    {&__pyx_kp_u_Query_comparison_complete_Recomm, __pyx_k_Query_comparison_complete_Recomm, sizeof(__pyx_k_Query_comparison_complete_Recomm), 0, 1, 0, 0},
    {&__pyx_kp_u_Query_executed_successfully, __pyx_k_Query_executed_successfully, sizeof(__pyx_k_Query_executed_successfully), 0, 1, 0, 0},
    {&__pyx_kp_u_Query_returned, __pyx_k_Query_returned, sizeof(__pyx_k_Query_returned), 0, 1, 0, 0},
    {&__pyx_kp_u_Query_returned_no_results, __pyx_k_Query_returned_no_results, sizeof(__pyx_k_Query_returned_no_results), 0, 1, 0, 0},
    {&__pyx_kp_u_Question, __pyx_k_Question, sizeof(__pyx_k_Question), 0, 1, 0, 0},
    {&__pyx_kp_u_Reason, __pyx_k_Reason, sizeof(__pyx_k_Reason), 0, 1, 0, 0},
    {&__pyx_kp_u_Relationship_count_between, __pyx_k_Relationship_count_between, sizeof(__pyx_k_Relationship_count_between), 0, 1, 0, 0},
    {&__pyx_kp_u_Relevant_Columns, __pyx_k_Relevant_Columns, sizeof(__pyx_k_Relevant_Columns), 0, 1, 0, 0},
    {&__pyx_kp_u_Relevant_Tables, __pyx_k_Relevant_Tables, sizeof(__pyx_k_Relevant_Tables), 0, 1, 0, 0},
    {&__pyx_kp_u_Relevant_Tables_in_Context, __pyx_k_Relevant_Tables_in_Context, sizeof(__pyx_k_Relevant_Tables_in_Context), 0, 1, 0, 0},
    {&__pyx_kp_u_Result, __pyx_k_Result, sizeof(__pyx_k_Result), 0, 1, 0, 0},
    {&__pyx_kp_u_Results, __pyx_k_Results, sizeof(__pyx_k_Results), 0, 1, 0, 0},
    {&__pyx_kp_u_Retry_attempt, __pyx_k_Retry_attempt, sizeof(__pyx_k_Retry_attempt), 0, 1, 0, 0},
    {&__pyx_kp_u_SELECT, __pyx_k_SELECT, sizeof(__pyx_k_SELECT), 0, 1, 0, 0},
    {&__pyx_kp_u_SELECT_COUNT_AS_record_count_FRO, __pyx_k_SELECT_COUNT_AS_record_count_FRO, sizeof(__pyx_k_SELECT_COUNT_AS_record_count_FRO), 0, 1, 0, 0},
    {&__pyx_kp_u_SELECT_COUNT_DISTINCT, __pyx_k_SELECT_COUNT_DISTINCT, sizeof(__pyx_k_SELECT_COUNT_DISTINCT), 0, 1, 0, 0},
    {&__pyx_kp_u_SELECT_FROM, __pyx_k_SELECT_FROM, sizeof(__pyx_k_SELECT_FROM), 0, 1, 0, 0},
    {&__pyx_kp_u_SELECT_name_FROM_sqlite_master_W, __pyx_k_SELECT_name_FROM_sqlite_master_W, sizeof(__pyx_k_SELECT_name_FROM_sqlite_master_W), 0, 1, 0, 0},
    {&__pyx_kp_u_SQL, __pyx_k_SQL, sizeof(__pyx_k_SQL), 0, 1, 0, 0},
    {&__pyx_n_s_SQLBuilder, __pyx_k_SQLBuilder, sizeof(__pyx_k_SQLBuilder), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder___init, __pyx_k_SQLBuilder___init, sizeof(__pyx_k_SQLBuilder___init), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__clean_text, __pyx_k_SQLBuilder__clean_text, sizeof(__pyx_k_SQLBuilder__clean_text), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__create_sql_correctio, __pyx_k_SQLBuilder__create_sql_correctio, sizeof(__pyx_k_SQLBuilder__create_sql_correctio), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__create_sql_generatio, __pyx_k_SQLBuilder__create_sql_generatio, sizeof(__pyx_k_SQLBuilder__create_sql_generatio), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__evaluate_query_relev, __pyx_k_SQLBuilder__evaluate_query_relev, sizeof(__pyx_k_SQLBuilder__evaluate_query_relev), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__explore_database_sch, __pyx_k_SQLBuilder__explore_database_sch, sizeof(__pyx_k_SQLBuilder__explore_database_sch), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__explore_table_schema, __pyx_k_SQLBuilder__explore_table_schema, sizeof(__pyx_k_SQLBuilder__explore_table_schema), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__extract_explanation, __pyx_k_SQLBuilder__extract_explanation, sizeof(__pyx_k_SQLBuilder__extract_explanation), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__extract_sql_from_res, __pyx_k_SQLBuilder__extract_sql_from_res, sizeof(__pyx_k_SQLBuilder__extract_sql_from_res), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__extract_table_names, __pyx_k_SQLBuilder__extract_table_names, sizeof(__pyx_k_SQLBuilder__extract_table_names), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__generate_result_summ, __pyx_k_SQLBuilder__generate_result_summ, sizeof(__pyx_k_SQLBuilder__generate_result_summ), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder__validate_safe_sql, __pyx_k_SQLBuilder__validate_safe_sql, sizeof(__pyx_k_SQLBuilder__validate_safe_sql), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_close_connection, __pyx_k_SQLBuilder_close_connection, sizeof(__pyx_k_SQLBuilder_close_connection), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_compare_queries, __pyx_k_SQLBuilder_compare_queries, sizeof(__pyx_k_SQLBuilder_compare_queries), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_connect_database, __pyx_k_SQLBuilder_connect_database, sizeof(__pyx_k_SQLBuilder_connect_database), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_generate_additional_e, __pyx_k_SQLBuilder_generate_additional_e, sizeof(__pyx_k_SQLBuilder_generate_additional_e), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_generate_additional_e_2, __pyx_k_SQLBuilder_generate_additional_e_2, sizeof(__pyx_k_SQLBuilder_generate_additional_e_2), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_generate_sql, __pyx_k_SQLBuilder_generate_sql, sizeof(__pyx_k_SQLBuilder_generate_sql), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_get_best_sql_and_resu, __pyx_k_SQLBuilder_get_best_sql_and_resu, sizeof(__pyx_k_SQLBuilder_get_best_sql_and_resu), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_test_query, __pyx_k_SQLBuilder_test_query, sizeof(__pyx_k_SQLBuilder_test_query), 0, 0, 1, 1},
    {&__pyx_n_s_SQLBuilder_try_fix_failed_query, __pyx_k_SQLBuilder_try_fix_failed_query, sizeof(__pyx_k_SQLBuilder_try_fix_failed_query), 0, 0, 1, 1},
    {&__pyx_kp_u_SQL_Query_Builder_only_supports, __pyx_k_SQL_Query_Builder_only_supports, sizeof(__pyx_k_SQL_Query_Builder_only_supports), 0, 1, 0, 0},
    {&__pyx_kp_u_SQL_fixed_on_attempt, __pyx_k_SQL_fixed_on_attempt, sizeof(__pyx_k_SQL_fixed_on_attempt), 0, 1, 0, 0},
    {&__pyx_kp_u_Sample_data, __pyx_k_Sample_data, sizeof(__pyx_k_Sample_data), 0, 1, 0, 0},
    {&__pyx_kp_u_Sample_of_first_3_rows, __pyx_k_Sample_of_first_3_rows, sizeof(__pyx_k_Sample_of_first_3_rows), 0, 1, 0, 0},
    {&__pyx_kp_u_Security_restriction, __pyx_k_Security_restriction, sizeof(__pyx_k_Security_restriction), 0, 1, 0, 0},
    {&__pyx_kp_u_Security_restriction_Only_SELECT, __pyx_k_Security_restriction_Only_SELECT, sizeof(__pyx_k_Security_restriction_Only_SELECT), 0, 1, 0, 0},
    {&__pyx_kp_u_Shows_the_distribution_of_values, __pyx_k_Shows_the_distribution_of_values, sizeof(__pyx_k_Shows_the_distribution_of_values), 0, 1, 0, 0},
    {&__pyx_kp_u_Shows_the_number_of_connections, __pyx_k_Shows_the_number_of_connections, sizeof(__pyx_k_Shows_the_number_of_connections), 0, 1, 0, 0},
    {&__pyx_kp_u_Shows_the_total_number_of_record, __pyx_k_Shows_the_total_number_of_record, sizeof(__pyx_k_Shows_the_total_number_of_record), 0, 1, 0, 0},
    {&__pyx_kp_u_Statistical_summary, __pyx_k_Statistical_summary, sizeof(__pyx_k_Statistical_summary), 0, 1, 0, 0},
    {&__pyx_kp_u_Statistical_summary_for, __pyx_k_Statistical_summary_for, sizeof(__pyx_k_Statistical_summary_for), 0, 1, 0, 0},
    {&__pyx_kp_u_Statistical_summary_of_numeric_v, __pyx_k_Statistical_summary_of_numeric_v, sizeof(__pyx_k_Statistical_summary_of_numeric_v), 0, 1, 0, 0},
    {&__pyx_kp_u_Stats_exploration_failed_and_cou, __pyx_k_Stats_exploration_failed_and_cou, sizeof(__pyx_k_Stats_exploration_failed_and_cou), 0, 1, 0, 0},
    {&__pyx_kp_u_TASK_1_Analyze_the_error_messag, __pyx_k_TASK_1_Analyze_the_error_messag, sizeof(__pyx_k_TASK_1_Analyze_the_error_messag), 0, 1, 0, 0},
    {&__pyx_kp_u_TRUNCATE_operations_are_not_allo, __pyx_k_TRUNCATE_operations_are_not_allo, sizeof(__pyx_k_TRUNCATE_operations_are_not_allo), 0, 1, 0, 0},
    {&__pyx_kp_u_Table, __pyx_k_Table, sizeof(__pyx_k_Table), 0, 1, 0, 0},
    {&__pyx_kp_u_Table_Relationships, __pyx_k_Table_Relationships, sizeof(__pyx_k_Table_Relationships), 0, 1, 0, 0},
    {&__pyx_kp_u_Table_Relationships_in_Context, __pyx_k_Table_Relationships_in_Context, sizeof(__pyx_k_Table_Relationships_in_Context), 0, 1, 0, 0},
    {&__pyx_kp_u_This_SQL_was_reused_from_a_previ, __pyx_k_This_SQL_was_reused_from_a_previ, sizeof(__pyx_k_This_SQL_was_reused_from_a_previ), 0, 1, 0, 0},
    {&__pyx_kp_u_This_working_SQL_has_been_verif, __pyx_k_This_working_SQL_has_been_verif, sizeof(__pyx_k_This_working_SQL_has_been_verif), 0, 1, 0, 0},
    {&__pyx_kp_u_Time_distribution_for, __pyx_k_Time_distribution_for, sizeof(__pyx_k_Time_distribution_for), 0, 1, 0, 0},
    {&__pyx_n_s_Timestamp, __pyx_k_Timestamp, sizeof(__pyx_k_Timestamp), 0, 0, 1, 1},
    {&__pyx_n_s_Tuple, __pyx_k_Tuple, sizeof(__pyx_k_Tuple), 0, 0, 1, 1},
    {&__pyx_kp_u_UPDATE_operations_are_not_allowe, __pyx_k_UPDATE_operations_are_not_allowe, sizeof(__pyx_k_UPDATE_operations_are_not_allowe), 0, 1, 0, 0},
    {&__pyx_n_s_Union, __pyx_k_Union, sizeof(__pyx_k_Union), 0, 0, 1, 1},
    {&__pyx_n_u_Unknown, __pyx_k_Unknown, sizeof(__pyx_k_Unknown), 0, 1, 0, 1},
    {&__pyx_kp_u_Unknown_error, __pyx_k_Unknown_error, sizeof(__pyx_k_Unknown_error), 0, 1, 0, 0},
    {&__pyx_kp_u_VACUUM_operations_are_not_allowe, __pyx_k_VACUUM_operations_are_not_allowe, sizeof(__pyx_k_VACUUM_operations_are_not_allowe), 0, 1, 0, 0},
    {&__pyx_kp_u_You_are_an_expert_SQL_developer, __pyx_k_You_are_an_expert_SQL_developer, sizeof(__pyx_k_You_are_an_expert_SQL_developer), 0, 1, 0, 0},
    {&__pyx_kp_u_You_are_an_expert_SQL_developer_2, __pyx_k_You_are_an_expert_SQL_developer_2, sizeof(__pyx_k_You_are_an_expert_SQL_developer_2), 0, 1, 0, 0},
    {&__pyx_kp_u_You_should_strongly_consider_usi, __pyx_k_You_should_strongly_consider_usi, sizeof(__pyx_k_You_should_strongly_consider_usi), 0, 1, 0, 0},
    {&__pyx_kp_u__13, __pyx_k__13, sizeof(__pyx_k__13), 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__16, __pyx_k__16, sizeof(__pyx_k__16), 0, 1, 0, 0},
    {&__pyx_kp_u__17, __pyx_k__17, sizeof(__pyx_k__17), 0, 1, 0, 0},
    {&__pyx_kp_u__23, __pyx_k__23, sizeof(__pyx_k__23), 0, 1, 0, 0},
    {&__pyx_kp_u__26, __pyx_k__26, sizeof(__pyx_k__26), 0, 1, 0, 0},
    {&__pyx_kp_u__29, __pyx_k__29, sizeof(__pyx_k__29), 0, 1, 0, 0},
    {&__pyx_kp_u__30, __pyx_k__30, sizeof(__pyx_k__30), 0, 1, 0, 0},
    {&__pyx_kp_u__31, __pyx_k__31, sizeof(__pyx_k__31), 0, 1, 0, 0},
    {&__pyx_kp_u__32, __pyx_k__32, sizeof(__pyx_k__32), 0, 1, 0, 0},
    {&__pyx_kp_u__34, __pyx_k__34, sizeof(__pyx_k__34), 0, 1, 0, 0},
    {&__pyx_kp_u__35, __pyx_k__35, sizeof(__pyx_k__35), 0, 1, 0, 0},
    {&__pyx_n_s__69, __pyx_k__69, sizeof(__pyx_k__69), 0, 0, 1, 1},
    {&__pyx_kp_u__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 1, 0, 0},
    {&__pyx_n_s__9, __pyx_k__9, sizeof(__pyx_k__9), 0, 0, 1, 1},
    {&__pyx_n_s__90, __pyx_k__90, sizeof(__pyx_k__90), 0, 0, 1, 1},
    {&__pyx_n_s_additional_explorations, __pyx_k_additional_explorations, sizeof(__pyx_k_additional_explorations), 0, 0, 1, 1},
    {&__pyx_n_u_additional_explorations, __pyx_k_additional_explorations, sizeof(__pyx_k_additional_explorations), 0, 1, 0, 1},
    {&__pyx_n_s_agg_parts, __pyx_k_agg_parts, sizeof(__pyx_k_agg_parts), 0, 0, 1, 1},
    {&__pyx_n_u_ai, __pyx_k_ai, sizeof(__pyx_k_ai), 0, 1, 0, 1},
    {&__pyx_n_s_ai_base, __pyx_k_ai_base, sizeof(__pyx_k_ai_base), 0, 0, 1, 1},
    {&__pyx_n_u_ai_generated, __pyx_k_ai_generated, sizeof(__pyx_k_ai_generated), 0, 1, 0, 1},
    {&__pyx_n_s_ai_query, __pyx_k_ai_query, sizeof(__pyx_k_ai_query), 0, 0, 1, 1},
    {&__pyx_n_u_ai_query, __pyx_k_ai_query, sizeof(__pyx_k_ai_query), 0, 1, 0, 1},
    {&__pyx_n_u_ai_query_retry_info, __pyx_k_ai_query_retry_info, sizeof(__pyx_k_ai_query_retry_info), 0, 1, 0, 1},
    {&__pyx_n_u_ai_relevance_score, __pyx_k_ai_relevance_score, sizeof(__pyx_k_ai_relevance_score), 0, 1, 0, 1},
    {&__pyx_n_u_ai_retry_attempt, __pyx_k_ai_retry_attempt, sizeof(__pyx_k_ai_retry_attempt), 0, 1, 0, 1},
    {&__pyx_n_s_ai_score, __pyx_k_ai_score, sizeof(__pyx_k_ai_score), 0, 0, 1, 1},
    {&__pyx_n_u_ai_success, __pyx_k_ai_success, sizeof(__pyx_k_ai_success), 0, 1, 0, 1},
    {&__pyx_n_u_alter, __pyx_k_alter, sizeof(__pyx_k_alter), 0, 1, 0, 1},
    {&__pyx_kp_u_and, __pyx_k_and, sizeof(__pyx_k_and), 0, 1, 0, 0},
    {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1},
    {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1},
    {&__pyx_kp_u_as_distinct_connections_FROM, __pyx_k_as_distinct_connections_FROM, sizeof(__pyx_k_as_distinct_connections_FROM), 0, 1, 0, 0},
    {&__pyx_n_s_asyncio_coroutines, __pyx_k_asyncio_coroutines, sizeof(__pyx_k_asyncio_coroutines), 0, 0, 1, 1},
    {&__pyx_kp_u_attach, __pyx_k_attach, sizeof(__pyx_k_attach), 0, 1, 0, 0},
    {&__pyx_n_s_attempt, __pyx_k_attempt, sizeof(__pyx_k_attempt), 0, 0, 1, 1},
    {&__pyx_n_s_attempts, __pyx_k_attempts, sizeof(__pyx_k_attempts), 0, 0, 1, 1},
    {&__pyx_n_u_attempts, __pyx_k_attempts, sizeof(__pyx_k_attempts), 0, 1, 0, 1},
    {&__pyx_kp_u_attempts_Original_error, __pyx_k_attempts_Original_error, sizeof(__pyx_k_attempts_Original_error), 0, 1, 0, 0},
    {&__pyx_kp_u_b, __pyx_k_b, sizeof(__pyx_k_b), 0, 1, 0, 0},
    {&__pyx_kp_u_bSELECT_b, __pyx_k_bSELECT_b, sizeof(__pyx_k_bSELECT_b), 0, 1, 0, 0},
    {&__pyx_kp_u_b_w_4_b, __pyx_k_b_w_4_b, sizeof(__pyx_k_b_w_4_b), 0, 1, 0, 0},
    {&__pyx_n_s_best_attempt, __pyx_k_best_attempt, sizeof(__pyx_k_best_attempt), 0, 0, 1, 1},
    {&__pyx_n_u_best_attempt, __pyx_k_best_attempt, sizeof(__pyx_k_best_attempt), 0, 1, 0, 1},
    {&__pyx_n_u_best_query, __pyx_k_best_query, sizeof(__pyx_k_best_query), 0, 1, 0, 1},
    {&__pyx_n_u_between, __pyx_k_between, sizeof(__pyx_k_between), 0, 1, 0, 1},
    {&__pyx_n_s_block, __pyx_k_block, sizeof(__pyx_k_block), 0, 0, 1, 1},
    {&__pyx_n_s_bool, __pyx_k_bool, sizeof(__pyx_k_bool), 0, 0, 1, 1},
    {&__pyx_n_s_check_same_thread, __pyx_k_check_same_thread, sizeof(__pyx_k_check_same_thread), 0, 0, 1, 1},
    {&__pyx_n_s_clean_text, __pyx_k_clean_text, sizeof(__pyx_k_clean_text), 0, 0, 1, 1},
    {&__pyx_n_s_cleaned_explanation, __pyx_k_cleaned_explanation, sizeof(__pyx_k_cleaned_explanation), 0, 0, 1, 1},
    {&__pyx_n_s_cleaned_response, __pyx_k_cleaned_response, sizeof(__pyx_k_cleaned_response), 0, 0, 1, 1},
    {&__pyx_n_s_cleaned_sql, __pyx_k_cleaned_sql, sizeof(__pyx_k_cleaned_sql), 0, 0, 1, 1},
    {&__pyx_n_s_clear_history, __pyx_k_clear_history, sizeof(__pyx_k_clear_history), 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_close_connection, __pyx_k_close_connection, sizeof(__pyx_k_close_connection), 0, 0, 1, 1},
    {&__pyx_n_s_code_block_pattern, __pyx_k_code_block_pattern, sizeof(__pyx_k_code_block_pattern), 0, 0, 1, 1},
    {&__pyx_n_s_code_blocks, __pyx_k_code_blocks, sizeof(__pyx_k_code_blocks), 0, 0, 1, 1},
    {&__pyx_n_s_col, __pyx_k_col, sizeof(__pyx_k_col), 0, 0, 1, 1},
    {&__pyx_n_s_col_name, __pyx_k_col_name, sizeof(__pyx_k_col_name), 0, 0, 1, 1},
    {&__pyx_kp_u_column, __pyx_k_column, sizeof(__pyx_k_column), 0, 1, 0, 0},
    {&__pyx_n_s_column_2, __pyx_k_column_2, sizeof(__pyx_k_column_2), 0, 0, 1, 1},
    {&__pyx_n_u_column_count, __pyx_k_column_count, sizeof(__pyx_k_column_count), 0, 1, 0, 1},
    {&__pyx_n_s_column_keywords, __pyx_k_column_keywords, sizeof(__pyx_k_column_keywords), 0, 0, 1, 1},
    {&__pyx_n_s_column_obj, __pyx_k_column_obj, sizeof(__pyx_k_column_obj), 0, 0, 1, 1},
    {&__pyx_kp_u_column_s, __pyx_k_column_s, sizeof(__pyx_k_column_s), 0, 1, 0, 0},
    {&__pyx_n_s_columns, __pyx_k_columns, sizeof(__pyx_k_columns), 0, 0, 1, 1},
    {&__pyx_n_u_columns, __pyx_k_columns, sizeof(__pyx_k_columns), 0, 1, 0, 1},
    {&__pyx_n_s_columns_df, __pyx_k_columns_df, sizeof(__pyx_k_columns_df), 0, 0, 1, 1},
    {&__pyx_n_s_compare_queries, __pyx_k_compare_queries, sizeof(__pyx_k_compare_queries), 0, 0, 1, 1},
    {&__pyx_n_s_comparison, __pyx_k_comparison, sizeof(__pyx_k_comparison), 0, 0, 1, 1},
    {&__pyx_n_u_comparison, __pyx_k_comparison, sizeof(__pyx_k_comparison), 0, 1, 0, 1},
    {&__pyx_n_s_conditions, __pyx_k_conditions, sizeof(__pyx_k_conditions), 0, 0, 1, 1},
    {&__pyx_n_s_conn, __pyx_k_conn, sizeof(__pyx_k_conn), 0, 0, 1, 1},
    {&__pyx_n_s_connect, __pyx_k_connect, sizeof(__pyx_k_connect), 0, 0, 1, 1},
    {&__pyx_n_u_connect, __pyx_k_connect, sizeof(__pyx_k_connect), 0, 1, 0, 1},
    {&__pyx_n_s_connect_database, __pyx_k_connect_database, sizeof(__pyx_k_connect_database), 0, 0, 1, 1},
    {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1},
    {&__pyx_n_s_count_query, __pyx_k_count_query, sizeof(__pyx_k_count_query), 0, 0, 1, 1},
    {&__pyx_kp_u_create, __pyx_k_create, sizeof(__pyx_k_create), 0, 1, 0, 0},
    {&__pyx_n_s_create_sql_correction_prompt, __pyx_k_create_sql_correction_prompt, sizeof(__pyx_k_create_sql_correction_prompt), 0, 0, 1, 1},
    {&__pyx_n_s_create_sql_generation_prompt, __pyx_k_create_sql_generation_prompt, sizeof(__pyx_k_create_sql_generation_prompt), 0, 0, 1, 1},
    {&__pyx_n_s_dangerous_operations, __pyx_k_dangerous_operations, sizeof(__pyx_k_dangerous_operations), 0, 0, 1, 1},
    {&__pyx_n_u_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 1, 0, 1},
    {&__pyx_kp_u_data_failed_sql_json, __pyx_k_data_failed_sql_json, sizeof(__pyx_k_data_failed_sql_json), 0, 1, 0, 0},
    {&__pyx_n_s_data_type, __pyx_k_data_type, sizeof(__pyx_k_data_type), 0, 0, 1, 1},
    {&__pyx_n_u_data_type, __pyx_k_data_type, sizeof(__pyx_k_data_type), 0, 1, 0, 1},
    {&__pyx_n_u_database_objects, __pyx_k_database_objects, sizeof(__pyx_k_database_objects), 0, 1, 0, 1},
    {&__pyx_n_s_database_path, __pyx_k_database_path, sizeof(__pyx_k_database_path), 0, 0, 1, 1},
    {&__pyx_n_u_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 1, 0, 1},
    {&__pyx_n_s_date_col, __pyx_k_date_col, sizeof(__pyx_k_date_col), 0, 0, 1, 1},
    {&__pyx_n_s_date_columns, __pyx_k_date_columns, sizeof(__pyx_k_date_columns), 0, 0, 1, 1},
    {&__pyx_n_u_day, __pyx_k_day, sizeof(__pyx_k_day), 0, 1, 0, 1},
    {&__pyx_n_s_db_context, __pyx_k_db_context, sizeof(__pyx_k_db_context), 0, 0, 1, 1},
    {&__pyx_n_u_delete, __pyx_k_delete, sizeof(__pyx_k_delete), 0, 1, 0, 1},
    {&__pyx_n_u_description, __pyx_k_description, sizeof(__pyx_k_description), 0, 1, 0, 1},
    {&__pyx_kp_u_detach, __pyx_k_detach, sizeof(__pyx_k_detach), 0, 1, 0, 0},
    {&__pyx_n_s_detailed_explanation, __pyx_k_detailed_explanation, sizeof(__pyx_k_detailed_explanation), 0, 0, 1, 1},
    {&__pyx_n_s_df, __pyx_k_df, sizeof(__pyx_k_df), 0, 0, 1, 1},
    {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1},
    {&__pyx_n_s_direct_matches, __pyx_k_direct_matches, sizeof(__pyx_k_direct_matches), 0, 0, 1, 1},
    {&__pyx_n_s_direct_sql_pattern, __pyx_k_direct_sql_pattern, sizeof(__pyx_k_direct_sql_pattern), 0, 0, 1, 1},
    {&__pyx_kp_u_disable, __pyx_k_disable, sizeof(__pyx_k_disable), 0, 1, 0, 0},
    {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1},
    {&__pyx_n_u_drop, __pyx_k_drop, sizeof(__pyx_k_drop), 0, 1, 0, 1},
    {&__pyx_n_s_dump, __pyx_k_dump, sizeof(__pyx_k_dump), 0, 0, 1, 1},
    {&__pyx_n_s_dumps, __pyx_k_dumps, sizeof(__pyx_k_dumps), 0, 0, 1, 1},
    {&__pyx_n_s_e, __pyx_k_e, sizeof(__pyx_k_e), 0, 0, 1, 1},
    {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
    {&__pyx_kp_u_enable, __pyx_k_enable, sizeof(__pyx_k_enable), 0, 1, 0, 0},
    {&__pyx_n_s_encoding, __pyx_k_encoding, sizeof(__pyx_k_encoding), 0, 0, 1, 1},
    {&__pyx_n_s_enter, __pyx_k_enter, sizeof(__pyx_k_enter), 0, 0, 1, 1},
    {&__pyx_n_s_entry, __pyx_k_entry, sizeof(__pyx_k_entry), 0, 0, 1, 1},
    {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
    {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
    {&__pyx_n_u_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 1, 0, 1},
    {&__pyx_n_s_error_msg, __pyx_k_error_msg, sizeof(__pyx_k_error_msg), 0, 0, 1, 1},
    {&__pyx_n_s_escape, __pyx_k_escape, sizeof(__pyx_k_escape), 0, 0, 1, 1},
    {&__pyx_n_s_evaluate_query_relevance, __pyx_k_evaluate_query_relevance, sizeof(__pyx_k_evaluate_query_relevance), 0, 0, 1, 1},
    {&__pyx_n_u_execution_error, __pyx_k_execution_error, sizeof(__pyx_k_execution_error), 0, 1, 0, 1},
    {&__pyx_n_s_exist_ok, __pyx_k_exist_ok, sizeof(__pyx_k_exist_ok), 0, 0, 1, 1},
    {&__pyx_n_s_existing_logs, __pyx_k_existing_logs, sizeof(__pyx_k_existing_logs), 0, 0, 1, 1},
    {&__pyx_n_u_existing_sql, __pyx_k_existing_sql, sizeof(__pyx_k_existing_sql), 0, 1, 0, 1},
    {&__pyx_n_s_exists, __pyx_k_exists, sizeof(__pyx_k_exists), 0, 0, 1, 1},
    {&__pyx_n_s_exit, __pyx_k_exit, sizeof(__pyx_k_exit), 0, 0, 1, 1},
    {&__pyx_n_s_explanation, __pyx_k_explanation, sizeof(__pyx_k_explanation), 0, 0, 1, 1},
    {&__pyx_n_u_explanation, __pyx_k_explanation, sizeof(__pyx_k_explanation), 0, 1, 0, 1},
    {&__pyx_n_s_explanation_match, __pyx_k_explanation_match, sizeof(__pyx_k_explanation_match), 0, 0, 1, 1},
    {&__pyx_n_s_explanation_pattern, __pyx_k_explanation_pattern, sizeof(__pyx_k_explanation_pattern), 0, 0, 1, 1},
    {&__pyx_n_u_exploration_stats, __pyx_k_exploration_stats, sizeof(__pyx_k_exploration_stats), 0, 1, 0, 1},
    {&__pyx_n_s_explorations, __pyx_k_explorations, sizeof(__pyx_k_explorations), 0, 0, 1, 1},
    {&__pyx_n_s_explore_database_schema, __pyx_k_explore_database_schema, sizeof(__pyx_k_explore_database_schema), 0, 0, 1, 1},
    {&__pyx_n_s_explore_table_schema, __pyx_k_explore_table_schema, sizeof(__pyx_k_explore_table_schema), 0, 0, 1, 1},
    {&__pyx_n_s_extract_explanation, __pyx_k_extract_explanation, sizeof(__pyx_k_extract_explanation), 0, 0, 1, 1},
    {&__pyx_n_s_extract_sql_from_response, __pyx_k_extract_sql_from_response, sizeof(__pyx_k_extract_sql_from_response), 0, 0, 1, 1},
    {&__pyx_n_s_extract_table_names, __pyx_k_extract_table_names, sizeof(__pyx_k_extract_table_names), 0, 0, 1, 1},
    {&__pyx_n_s_f, __pyx_k_f, sizeof(__pyx_k_f), 0, 0, 1, 1},
    {&__pyx_n_s_failed_query, __pyx_k_failed_query, sizeof(__pyx_k_failed_query), 0, 0, 1, 1},
    {&__pyx_n_u_failed_sql, __pyx_k_failed_sql, sizeof(__pyx_k_failed_sql), 0, 1, 0, 1},
    {&__pyx_kp_u_failed_sql_json, __pyx_k_failed_sql_json, sizeof(__pyx_k_failed_sql_json), 0, 1, 0, 0},
    {&__pyx_n_s_file_path, __pyx_k_file_path, sizeof(__pyx_k_file_path), 0, 0, 1, 1},
    {&__pyx_n_s_findall, __pyx_k_findall, sizeof(__pyx_k_findall), 0, 0, 1, 1},
    {&__pyx_n_s_finditer, __pyx_k_finditer, sizeof(__pyx_k_finditer), 0, 0, 1, 1},
    {&__pyx_n_s_first_result, __pyx_k_first_result, sizeof(__pyx_k_first_result), 0, 0, 1, 1},
    {&__pyx_n_s_fixed_query, __pyx_k_fixed_query, sizeof(__pyx_k_fixed_query), 0, 0, 1, 1},
    {&__pyx_n_s_fixed_sql, __pyx_k_fixed_sql, sizeof(__pyx_k_fixed_sql), 0, 0, 1, 1},
    {&__pyx_n_s_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 0, 1, 1},
    {&__pyx_n_s_from_matches, __pyx_k_from_matches, sizeof(__pyx_k_from_matches), 0, 0, 1, 1},
    {&__pyx_n_s_from_pattern, __pyx_k_from_pattern, sizeof(__pyx_k_from_pattern), 0, 0, 1, 1},
    {&__pyx_kp_u_gc, __pyx_k_gc, sizeof(__pyx_k_gc), 0, 1, 0, 0},
    {&__pyx_n_s_generate_additional_explorations, __pyx_k_generate_additional_explorations, sizeof(__pyx_k_generate_additional_explorations), 0, 0, 1, 1},
    {&__pyx_n_s_generate_result_summary, __pyx_k_generate_result_summary, sizeof(__pyx_k_generate_result_summary), 0, 0, 1, 1},
    {&__pyx_n_s_generate_sql, __pyx_k_generate_sql, sizeof(__pyx_k_generate_sql), 0, 0, 1, 1},
    {&__pyx_n_s_genexpr, __pyx_k_genexpr, sizeof(__pyx_k_genexpr), 0, 0, 1, 1},
    {&__pyx_n_s_get, __pyx_k_get, sizeof(__pyx_k_get), 0, 0, 1, 1},
    {&__pyx_n_s_get_best_sql_and_results, __pyx_k_get_best_sql_and_results, sizeof(__pyx_k_get_best_sql_and_results), 0, 0, 1, 1},
    {&__pyx_n_s_get_response_sync, __pyx_k_get_response_sync, sizeof(__pyx_k_get_response_sync), 0, 0, 1, 1},
    {&__pyx_n_s_group, __pyx_k_group, sizeof(__pyx_k_group), 0, 0, 1, 1},
    {&__pyx_n_u_has_historical_match, __pyx_k_has_historical_match, sizeof(__pyx_k_has_historical_match), 0, 1, 0, 1},
    {&__pyx_n_s_head, __pyx_k_head, sizeof(__pyx_k_head), 0, 0, 1, 1},
    {&__pyx_n_s_hist_score, __pyx_k_hist_score, sizeof(__pyx_k_hist_score), 0, 0, 1, 1},
    {&__pyx_n_u_historical, __pyx_k_historical, sizeof(__pyx_k_historical), 0, 1, 0, 1},
    {&__pyx_n_s_historical_query, __pyx_k_historical_query, sizeof(__pyx_k_historical_query), 0, 0, 1, 1},
    {&__pyx_n_u_historical_query, __pyx_k_historical_query, sizeof(__pyx_k_historical_query), 0, 1, 0, 1},
    {&__pyx_n_u_historical_relevance_score, __pyx_k_historical_relevance_score, sizeof(__pyx_k_historical_relevance_score), 0, 1, 0, 1},
    {&__pyx_n_u_historical_success, __pyx_k_historical_success, sizeof(__pyx_k_historical_success), 0, 1, 0, 1},
    {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
    {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
    {&__pyx_n_s_indent, __pyx_k_indent, sizeof(__pyx_k_indent), 0, 0, 1, 1},
    {&__pyx_n_s_info, __pyx_k_info, sizeof(__pyx_k_info), 0, 0, 1, 1},
    {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1},
    {&__pyx_n_s_init_subclass, __pyx_k_init_subclass, sizeof(__pyx_k_init_subclass), 0, 0, 1, 1},
    {&__pyx_n_s_initializing, __pyx_k_initializing, sizeof(__pyx_k_initializing), 0, 0, 1, 1},
    {&__pyx_n_u_insert, __pyx_k_insert, sizeof(__pyx_k_insert), 0, 1, 0, 1},
    {&__pyx_n_s_intersection, __pyx_k_intersection, sizeof(__pyx_k_intersection), 0, 0, 1, 1},
    {&__pyx_n_s_is_coroutine, __pyx_k_is_coroutine, sizeof(__pyx_k_is_coroutine), 0, 0, 1, 1},
    {&__pyx_kp_u_isenabled, __pyx_k_isenabled, sizeof(__pyx_k_isenabled), 0, 1, 0, 0},
    {&__pyx_n_s_isoformat, __pyx_k_isoformat, sizeof(__pyx_k_isoformat), 0, 0, 1, 1},
    {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1},
    {&__pyx_n_s_iterrows, __pyx_k_iterrows, sizeof(__pyx_k_iterrows), 0, 0, 1, 1},
    {&__pyx_n_s_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 0, 1, 1},
    {&__pyx_n_u_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 1, 0, 1},
    {&__pyx_n_s_join_condition, __pyx_k_join_condition, sizeof(__pyx_k_join_condition), 0, 0, 1, 1},
    {&__pyx_n_u_join_condition, __pyx_k_join_condition, sizeof(__pyx_k_join_condition), 0, 1, 0, 1},
    {&__pyx_n_s_join_matches, __pyx_k_join_matches, sizeof(__pyx_k_join_matches), 0, 0, 1, 1},
    {&__pyx_n_s_join_pattern, __pyx_k_join_pattern, sizeof(__pyx_k_join_pattern), 0, 0, 1, 1},
    {&__pyx_n_s_json, __pyx_k_json, sizeof(__pyx_k_json), 0, 0, 1, 1},
    {&__pyx_n_s_left_side, __pyx_k_left_side, sizeof(__pyx_k_left_side), 0, 0, 1, 1},
    {&__pyx_n_u_link, __pyx_k_link, sizeof(__pyx_k_link), 0, 1, 0, 1},
    {&__pyx_n_s_load, __pyx_k_load, sizeof(__pyx_k_load), 0, 0, 1, 1},
    {&__pyx_n_s_log_e, __pyx_k_log_e, sizeof(__pyx_k_log_e), 0, 0, 1, 1},
    {&__pyx_n_s_lower, __pyx_k_lower, sizeof(__pyx_k_lower), 0, 0, 1, 1},
    {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
    {&__pyx_n_s_main_query, __pyx_k_main_query, sizeof(__pyx_k_main_query), 0, 0, 1, 1},
    {&__pyx_n_s_main_sql, __pyx_k_main_sql, sizeof(__pyx_k_main_sql), 0, 0, 1, 1},
    {&__pyx_n_s_makedirs, __pyx_k_makedirs, sizeof(__pyx_k_makedirs), 0, 0, 1, 1},
    {&__pyx_n_s_match, __pyx_k_match, sizeof(__pyx_k_match), 0, 0, 1, 1},
    {&__pyx_n_s_max_attempts, __pyx_k_max_attempts, sizeof(__pyx_k_max_attempts), 0, 0, 1, 1},
    {&__pyx_n_u_message, __pyx_k_message, sizeof(__pyx_k_message), 0, 1, 0, 1},
    {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1},
    {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1},
    {&__pyx_kp_u_more_rows, __pyx_k_more_rows, sizeof(__pyx_k_more_rows), 0, 1, 0, 0},
    {&__pyx_kp_u_n_SELECT_s_n_n_nEXPLANATION, __pyx_k_n_SELECT_s_n_n_nEXPLANATION, sizeof(__pyx_k_n_SELECT_s_n_n_nEXPLANATION), 0, 1, 0, 0},
    {&__pyx_n_u_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 1, 0, 1},
    {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
    {&__pyx_n_s_name_parts, __pyx_k_name_parts, sizeof(__pyx_k_name_parts), 0, 0, 1, 1},
    {&__pyx_n_s_normalized_sql, __pyx_k_normalized_sql, sizeof(__pyx_k_normalized_sql), 0, 0, 1, 1},
    {&__pyx_n_u_notnull, __pyx_k_notnull, sizeof(__pyx_k_notnull), 0, 1, 0, 1},
    {&__pyx_n_s_now, __pyx_k_now, sizeof(__pyx_k_now), 0, 0, 1, 1},
    {&__pyx_n_s_num_cols, __pyx_k_num_cols, sizeof(__pyx_k_num_cols), 0, 0, 1, 1},
    {&__pyx_n_s_num_rows, __pyx_k_num_rows, sizeof(__pyx_k_num_rows), 0, 0, 1, 1},
    {&__pyx_n_s_numeric_columns, __pyx_k_numeric_columns, sizeof(__pyx_k_numeric_columns), 0, 0, 1, 1},
    {&__pyx_n_s_open, __pyx_k_open, sizeof(__pyx_k_open), 0, 0, 1, 1},
    {&__pyx_n_s_operation, __pyx_k_operation, sizeof(__pyx_k_operation), 0, 0, 1, 1},
    {&__pyx_kp_u_or, __pyx_k_or, sizeof(__pyx_k_or), 0, 1, 0, 0},
    {&__pyx_n_s_orient, __pyx_k_orient, sizeof(__pyx_k_orient), 0, 0, 1, 1},
    {&__pyx_n_s_original_error, __pyx_k_original_error, sizeof(__pyx_k_original_error), 0, 0, 1, 1},
    {&__pyx_n_u_original_error, __pyx_k_original_error, sizeof(__pyx_k_original_error), 0, 1, 0, 1},
    {&__pyx_n_s_original_failed_sql, __pyx_k_original_failed_sql, sizeof(__pyx_k_original_failed_sql), 0, 0, 1, 1},
    {&__pyx_n_u_original_failed_sql, __pyx_k_original_failed_sql, sizeof(__pyx_k_original_failed_sql), 0, 1, 0, 1},
    {&__pyx_n_s_original_question, __pyx_k_original_question, sizeof(__pyx_k_original_question), 0, 0, 1, 1},
    {&__pyx_n_s_original_sql, __pyx_k_original_sql, sizeof(__pyx_k_original_sql), 0, 0, 1, 1},
    {&__pyx_n_s_os, __pyx_k_os, sizeof(__pyx_k_os), 0, 0, 1, 1},
    {&__pyx_n_s_overlap, __pyx_k_overlap, sizeof(__pyx_k_overlap), 0, 0, 1, 1},
    {&__pyx_n_s_pandas, __pyx_k_pandas, sizeof(__pyx_k_pandas), 0, 0, 1, 1},
    {&__pyx_n_s_parts, __pyx_k_parts, sizeof(__pyx_k_parts), 0, 0, 1, 1},
    {&__pyx_n_s_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 0, 1, 1},
    {&__pyx_n_s_pattern, __pyx_k_pattern, sizeof(__pyx_k_pattern), 0, 0, 1, 1},
    {&__pyx_n_s_pd, __pyx_k_pd, sizeof(__pyx_k_pd), 0, 0, 1, 1},
    {&__pyx_kp_s_pd_DataFrame, __pyx_k_pd_DataFrame, sizeof(__pyx_k_pd_DataFrame), 0, 0, 1, 0},
    {&__pyx_n_u_pk, __pyx_k_pk, sizeof(__pyx_k_pk), 0, 1, 0, 1},
    {&__pyx_kp_u_plus, __pyx_k_plus, sizeof(__pyx_k_plus), 0, 1, 0, 0},
    {&__pyx_n_u_pragma, __pyx_k_pragma, sizeof(__pyx_k_pragma), 0, 1, 0, 1},
    {&__pyx_n_s_pragma_query, __pyx_k_pragma_query, sizeof(__pyx_k_pragma_query), 0, 0, 1, 1},
    {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1},
    {&__pyx_n_s_prev, __pyx_k_prev, sizeof(__pyx_k_prev), 0, 0, 1, 1},
    {&__pyx_n_s_previous_attempts, __pyx_k_previous_attempts, sizeof(__pyx_k_previous_attempts), 0, 0, 1, 1},
    {&__pyx_n_u_previously_run_query, __pyx_k_previously_run_query, sizeof(__pyx_k_previously_run_query), 0, 1, 0, 1},
    {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1},
    {&__pyx_n_s_prompt, __pyx_k_prompt, sizeof(__pyx_k_prompt), 0, 0, 1, 1},
    {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1},
    {&__pyx_n_s_query, __pyx_k_query, sizeof(__pyx_k_query), 0, 0, 1, 1},
    {&__pyx_n_s_question, __pyx_k_question, sizeof(__pyx_k_question), 0, 0, 1, 1},
    {&__pyx_n_u_question, __pyx_k_question, sizeof(__pyx_k_question), 0, 1, 0, 1},
    {&__pyx_n_s_question_keywords, __pyx_k_question_keywords, sizeof(__pyx_k_question_keywords), 0, 0, 1, 1},
    {&__pyx_n_u_r, __pyx_k_r, sizeof(__pyx_k_r), 0, 1, 0, 1},
    {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
    {&__pyx_n_u_raw_ai_response, __pyx_k_raw_ai_response, sizeof(__pyx_k_raw_ai_response), 0, 1, 0, 1},
    {&__pyx_n_s_re, __pyx_k_re, sizeof(__pyx_k_re), 0, 0, 1, 1},
    {&__pyx_n_s_read_sql_query, __pyx_k_read_sql_query, sizeof(__pyx_k_read_sql_query), 0, 0, 1, 1},
    {&__pyx_n_u_recommendation_reason, __pyx_k_recommendation_reason, sizeof(__pyx_k_recommendation_reason), 0, 1, 0, 1},
    {&__pyx_n_u_recommended_query, __pyx_k_recommended_query, sizeof(__pyx_k_recommended_query), 0, 1, 0, 1},
    {&__pyx_n_u_records, __pyx_k_records, sizeof(__pyx_k_records), 0, 1, 0, 1},
    {&__pyx_n_s_rel, __pyx_k_rel, sizeof(__pyx_k_rel), 0, 0, 1, 1},
    {&__pyx_n_u_relation, __pyx_k_relation, sizeof(__pyx_k_relation), 0, 1, 0, 1},
    {&__pyx_n_s_relationship_keywords, __pyx_k_relationship_keywords, sizeof(__pyx_k_relationship_keywords), 0, 0, 1, 1},
    {&__pyx_n_s_relationship_query, __pyx_k_relationship_query, sizeof(__pyx_k_relationship_query), 0, 0, 1, 1},
    {&__pyx_n_s_relationships, __pyx_k_relationships, sizeof(__pyx_k_relationships), 0, 0, 1, 1},
    {&__pyx_n_u_relationships, __pyx_k_relationships, sizeof(__pyx_k_relationships), 0, 1, 0, 1},
    {&__pyx_n_s_response, __pyx_k_response, sizeof(__pyx_k_response), 0, 0, 1, 1},
    {&__pyx_n_s_result, __pyx_k_result, sizeof(__pyx_k_result), 0, 0, 1, 1},
    {&__pyx_n_u_result, __pyx_k_result, sizeof(__pyx_k_result), 0, 1, 0, 1},
    {&__pyx_n_u_results, __pyx_k_results, sizeof(__pyx_k_results), 0, 1, 0, 1},
    {&__pyx_n_u_retry_attempt, __pyx_k_retry_attempt, sizeof(__pyx_k_retry_attempt), 0, 1, 0, 1},
    {&__pyx_n_s_retry_info, __pyx_k_retry_info, sizeof(__pyx_k_retry_info), 0, 0, 1, 1},
    {&__pyx_n_s_return, __pyx_k_return, sizeof(__pyx_k_return), 0, 0, 1, 1},
    {&__pyx_n_u_reused_from_failed_json, __pyx_k_reused_from_failed_json, sizeof(__pyx_k_reused_from_failed_json), 0, 1, 0, 1},
    {&__pyx_n_s_right_side, __pyx_k_right_side, sizeof(__pyx_k_right_side), 0, 0, 1, 1},
    {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1},
    {&__pyx_n_s_row_count, __pyx_k_row_count, sizeof(__pyx_k_row_count), 0, 0, 1, 1},
    {&__pyx_n_u_row_count, __pyx_k_row_count, sizeof(__pyx_k_row_count), 0, 1, 0, 1},
    {&__pyx_kp_u_row_s_with, __pyx_k_row_s_with, sizeof(__pyx_k_row_s_with), 0, 1, 0, 0},
    {&__pyx_kp_u_rows_returned, __pyx_k_rows_returned, sizeof(__pyx_k_rows_returned), 0, 1, 0, 0},
    {&__pyx_n_s_sQQideR_SQLBuilder, __pyx_k_sQQideR_SQLBuilder, sizeof(__pyx_k_sQQideR_SQLBuilder), 0, 0, 1, 1},
    {&__pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_k_sQQideR_SQLBuilder_pyx, sizeof(__pyx_k_sQQideR_SQLBuilder_pyx), 0, 0, 1, 0},
    {&__pyx_n_s_sample, __pyx_k_sample, sizeof(__pyx_k_sample), 0, 0, 1, 1},
    {&__pyx_n_s_sample_data, __pyx_k_sample_data, sizeof(__pyx_k_sample_data), 0, 0, 1, 1},
    {&__pyx_n_u_sample_data, __pyx_k_sample_data, sizeof(__pyx_k_sample_data), 0, 1, 0, 1},
    {&__pyx_n_s_sample_df, __pyx_k_sample_df, sizeof(__pyx_k_sample_df), 0, 0, 1, 1},
    {&__pyx_n_s_sample_query, __pyx_k_sample_query, sizeof(__pyx_k_sample_query), 0, 0, 1, 1},
    {&__pyx_n_s_schema_info, __pyx_k_schema_info, sizeof(__pyx_k_schema_info), 0, 0, 1, 1},
    {&__pyx_n_s_score, __pyx_k_score, sizeof(__pyx_k_score), 0, 0, 1, 1},
    {&__pyx_n_s_search, __pyx_k_search, sizeof(__pyx_k_search), 0, 0, 1, 1},
    {&__pyx_kp_u_select, __pyx_k_select, sizeof(__pyx_k_select), 0, 1, 0, 0},
    {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1},
    {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1},
    {&__pyx_n_s_set_name, __pyx_k_set_name, sizeof(__pyx_k_set_name), 0, 0, 1, 1},
    {&__pyx_n_s_source, __pyx_k_source, sizeof(__pyx_k_source), 0, 0, 1, 1},
    {&__pyx_n_u_source, __pyx_k_source, sizeof(__pyx_k_source), 0, 1, 0, 1},
    {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1},
    {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1},
    {&__pyx_n_s_sql, __pyx_k_sql, sizeof(__pyx_k_sql), 0, 0, 1, 1},
    {&__pyx_n_u_sql, __pyx_k_sql, sizeof(__pyx_k_sql), 0, 1, 0, 1},
    {&__pyx_n_s_sql_query, __pyx_k_sql_query, sizeof(__pyx_k_sql_query), 0, 0, 1, 1},
    {&__pyx_kp_u_sql_s, __pyx_k_sql_s, sizeof(__pyx_k_sql_s), 0, 1, 0, 0},
    {&__pyx_n_s_sqlite3, __pyx_k_sqlite3, sizeof(__pyx_k_sqlite3), 0, 0, 1, 1},
    {&__pyx_n_s_stats_query_dict, __pyx_k_stats_query_dict, sizeof(__pyx_k_stats_query_dict), 0, 0, 1, 1},
    {&__pyx_n_s_str, __pyx_k_str, sizeof(__pyx_k_str), 0, 0, 1, 1},
    {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
    {&__pyx_kp_u_succeeded, __pyx_k_succeeded, sizeof(__pyx_k_succeeded), 0, 1, 0, 0},
    {&__pyx_n_u_success, __pyx_k_success, sizeof(__pyx_k_success), 0, 1, 0, 1},
    {&__pyx_n_s_summary, __pyx_k_summary, sizeof(__pyx_k_summary), 0, 0, 1, 1},
    {&__pyx_n_u_summary, __pyx_k_summary, sizeof(__pyx_k_summary), 0, 1, 0, 1},
    {&__pyx_n_s_super, __pyx_k_super, sizeof(__pyx_k_super), 0, 0, 1, 1},
    {&__pyx_kp_u_table, __pyx_k_table, sizeof(__pyx_k_table), 0, 1, 0, 0},
    {&__pyx_n_s_table_2, __pyx_k_table_2, sizeof(__pyx_k_table_2), 0, 0, 1, 1},
    {&__pyx_n_s_table_info, __pyx_k_table_info, sizeof(__pyx_k_table_info), 0, 0, 1, 1},
    {&__pyx_n_s_table_name, __pyx_k_table_name, sizeof(__pyx_k_table_name), 0, 0, 1, 1},
    {&__pyx_n_u_table_name, __pyx_k_table_name, sizeof(__pyx_k_table_name), 0, 1, 0, 1},
    {&__pyx_n_s_table_names, __pyx_k_table_names, sizeof(__pyx_k_table_names), 0, 0, 1, 1},
    {&__pyx_n_s_table_obj, __pyx_k_table_obj, sizeof(__pyx_k_table_obj), 0, 0, 1, 1},
    {&__pyx_n_s_tables, __pyx_k_tables, sizeof(__pyx_k_tables), 0, 0, 1, 1},
    {&__pyx_n_u_tables, __pyx_k_tables, sizeof(__pyx_k_tables), 0, 1, 0, 1},
    {&__pyx_n_s_tables_df, __pyx_k_tables_df, sizeof(__pyx_k_tables_df), 0, 0, 1, 1},
    {&__pyx_n_s_tables_query, __pyx_k_tables_query, sizeof(__pyx_k_tables_query), 0, 0, 1, 1},
    {&__pyx_n_s_tables_used, __pyx_k_tables_used, sizeof(__pyx_k_tables_used), 0, 0, 1, 1},
    {&__pyx_n_s_target, __pyx_k_target, sizeof(__pyx_k_target), 0, 0, 1, 1},
    {&__pyx_n_u_target, __pyx_k_target, sizeof(__pyx_k_target), 0, 1, 0, 1},
    {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
    {&__pyx_n_s_test_query, __pyx_k_test_query, sizeof(__pyx_k_test_query), 0, 0, 1, 1},
    {&__pyx_n_s_tested_query, __pyx_k_tested_query, sizeof(__pyx_k_tested_query), 0, 0, 1, 1},
    {&__pyx_n_s_text, __pyx_k_text, sizeof(__pyx_k_text), 0, 0, 1, 1},
    {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1},
    {&__pyx_n_u_time, __pyx_k_time, sizeof(__pyx_k_time), 0, 1, 0, 1},
    {&__pyx_n_s_time_query, __pyx_k_time_query, sizeof(__pyx_k_time_query), 0, 0, 1, 1},
    {&__pyx_n_u_timestamp, __pyx_k_timestamp, sizeof(__pyx_k_timestamp), 0, 1, 0, 1},
    {&__pyx_kp_u_to, __pyx_k_to, sizeof(__pyx_k_to), 0, 1, 0, 0},
    {&__pyx_n_s_to_dict, __pyx_k_to_dict, sizeof(__pyx_k_to_dict), 0, 0, 1, 1},
    {&__pyx_n_s_to_string, __pyx_k_to_string, sizeof(__pyx_k_to_string), 0, 0, 1, 1},
    {&__pyx_n_u_truncate, __pyx_k_truncate, sizeof(__pyx_k_truncate), 0, 1, 0, 1},
    {&__pyx_n_s_try_fix_failed_query, __pyx_k_try_fix_failed_query, sizeof(__pyx_k_try_fix_failed_query), 0, 0, 1, 1},
    {&__pyx_n_u_type, __pyx_k_type, sizeof(__pyx_k_type), 0, 1, 0, 1},
    {&__pyx_n_s_typing, __pyx_k_typing, sizeof(__pyx_k_typing), 0, 0, 1, 1},
    {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1},
    {&__pyx_n_u_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 1, 0, 1},
    {&__pyx_kp_u_utf_8, __pyx_k_utf_8, sizeof(__pyx_k_utf_8), 0, 1, 0, 0},
    {&__pyx_kp_u_vacuum, __pyx_k_vacuum, sizeof(__pyx_k_vacuum), 0, 1, 0, 0},
    {&__pyx_n_s_val, __pyx_k_val, sizeof(__pyx_k_val), 0, 0, 1, 1},
    {&__pyx_n_s_validate_safe_sql, __pyx_k_validate_safe_sql, sizeof(__pyx_k_validate_safe_sql), 0, 0, 1, 1},
    {&__pyx_n_s_validation_error, __pyx_k_validation_error, sizeof(__pyx_k_validation_error), 0, 0, 1, 1},
    {&__pyx_n_s_verbose, __pyx_k_verbose, sizeof(__pyx_k_verbose), 0, 0, 1, 1},
    {&__pyx_n_u_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 1, 0, 1},
    {&__pyx_n_u_where, __pyx_k_where, sizeof(__pyx_k_where), 0, 1, 0, 1},
    {&__pyx_n_s_working_sql, __pyx_k_working_sql, sizeof(__pyx_k_working_sql), 0, 0, 1, 1},
    {&__pyx_n_u_working_sql, __pyx_k_working_sql, sizeof(__pyx_k_working_sql), 0, 1, 0, 1},
    {0, 0, 0, 0, 0, 0, 0}
  };
  return __Pyx_InitStrings(__pyx_string_tab);
}
/* #### Code section: cached_builtins ### */
static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) {
  __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_n_s_print); if (!__pyx_builtin_print) __PYX_ERR(0, 41, __pyx_L1_error)
  __pyx_builtin_open = __Pyx_GetBuiltinName(__pyx_n_s_open); if (!__pyx_builtin_open) __PYX_ERR(0, 89, __pyx_L1_error)
  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 373, __pyx_L1_error)
  __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(0, 544, __pyx_L1_error)
  return 0;
  __pyx_L1_error:;
  return -1;
}
/* #### Code section: cached_constants ### */

static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);

  /* "sQQideR/SQLBuilder.pyx":71
 *             self.conn = None
 *             if self.verbose:
 *                 print("Database connection closed")             # <<<<<<<<<<<<<<
 * 
 *     def generate_sql(self, question: str, db_context: Dict) -> Dict:
 */
  __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_Database_connection_closed); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 71, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple_);
  __Pyx_GIVEREF(__pyx_tuple_);

  /* "sQQideR/SQLBuilder.pyx":89
 *         if os.path.exists("data/failed_sql.json"):
 *             try:
 *                 with open("data/failed_sql.json", "r", encoding="utf-8") as f:             # <<<<<<<<<<<<<<
 *                     existing_logs = json.load(f)
 *                 for entry in existing_logs:
 */
  __pyx_tuple__2 = PyTuple_Pack(2, __pyx_kp_u_data_failed_sql_json, __pyx_n_u_r); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 89, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__2);
  __Pyx_GIVEREF(__pyx_tuple__2);
  __pyx_tuple__3 = PyTuple_Pack(3, Py_None, Py_None, Py_None); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 89, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__3);
  __Pyx_GIVEREF(__pyx_tuple__3);

  /* "sQQideR/SQLBuilder.pyx":96
 *                         if working_sql:
 *                             if self.verbose:
 *                                 print("Found previous working SQL for this question/query, skipping AI call.")             # <<<<<<<<<<<<<<
 * 
 *                             # Create a more detailed explanation for traceability
 */
  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Found_previous_working_SQL_for_t); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 96, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__4);
  __Pyx_GIVEREF(__pyx_tuple__4);

  /* "sQQideR/SQLBuilder.pyx":99
 * 
 *                             # Create a more detailed explanation for traceability
 *                             original_error = entry.get("error", "Unknown error")             # <<<<<<<<<<<<<<
 *                             original_failed_sql = entry.get("failed_sql", "No original SQL available")
 *                             original_question = entry.get("question", question)
 */
  __pyx_tuple__5 = PyTuple_Pack(2, __pyx_n_u_error, __pyx_kp_u_Unknown_error); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 99, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__5);
  __Pyx_GIVEREF(__pyx_tuple__5);

  /* "sQQideR/SQLBuilder.pyx":100
 *                             # Create a more detailed explanation for traceability
 *                             original_error = entry.get("error", "Unknown error")
 *                             original_failed_sql = entry.get("failed_sql", "No original SQL available")             # <<<<<<<<<<<<<<
 *                             original_question = entry.get("question", question)
 * 
 */
  __pyx_tuple__6 = PyTuple_Pack(2, __pyx_n_u_failed_sql, __pyx_kp_u_No_original_SQL_available); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__6);
  __Pyx_GIVEREF(__pyx_tuple__6);

  /* "sQQideR/SQLBuilder.pyx":304
 * 
 *             # If AI query failed, try to fix it (up to 3 attempts)
 *             if not ai_query.get("success", False):             # <<<<<<<<<<<<<<
 *                 retry_info = self.try_fix_failed_query(ai_query, question, db_context)
 *                 ai_query = retry_info["best_attempt"] if retry_info["best_attempt"] else ai_query
 */
  __pyx_tuple__8 = PyTuple_Pack(2, __pyx_n_u_success, Py_False); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(0, 304, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__8);
  __Pyx_GIVEREF(__pyx_tuple__8);

  /* "sQQideR/SQLBuilder.pyx":427
 *                     try:
 *                         import os
 *                         os.makedirs("data", exist_ok=True)             # <<<<<<<<<<<<<<
 *                         file_path = os.path.join("data", "failed_sql.json")
 * 
 */
  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_n_u_data); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 427, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__10);
  __Pyx_GIVEREF(__pyx_tuple__10);

  /* "sQQideR/SQLBuilder.pyx":428
 *                         import os
 *                         os.makedirs("data", exist_ok=True)
 *                         file_path = os.path.join("data", "failed_sql.json")             # <<<<<<<<<<<<<<
 * 
 *                         if os.path.exists(file_path):
 */
  __pyx_tuple__11 = PyTuple_Pack(2, __pyx_n_u_data, __pyx_kp_u_failed_sql_json); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 428, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__11);
  __Pyx_GIVEREF(__pyx_tuple__11);

  /* "sQQideR/SQLBuilder.pyx":440
 *                             "failed_sql": original_sql,
 *                             "error": original_error,
 *                             "working_sql": best_attempt.get("sql", "")             # <<<<<<<<<<<<<<
 *                         })
 * 
 */
  __pyx_tuple__12 = PyTuple_Pack(2, __pyx_n_u_sql, __pyx_kp_u__7); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 440, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__12);
  __Pyx_GIVEREF(__pyx_tuple__12);

  /* "sQQideR/SQLBuilder.pyx":520
 *                         prompt += f"- {col['name']} ({col['type']})\n"
 *                 if "sample_data" in info and info["sample_data"]:
 *                     prompt += f"Sample data: {json.dumps(info['sample_data'][:3])}\n"             # <<<<<<<<<<<<<<
 *             elif "sql" in info and "result" in info:
 *                 prompt += f"\nQuery: {info['sql']}\n"
 */
  __pyx_slice__18 = PySlice_New(Py_None, __pyx_int_3, Py_None); if (unlikely(!__pyx_slice__18)) __PYX_ERR(0, 520, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_slice__18);
  __Pyx_GIVEREF(__pyx_slice__18);

  /* "sQQideR/SQLBuilder.pyx":532
 *                 prompt += "\nRelevant Tables in Context:\n"
 *                 for table in tables:
 *                     prompt += f"- {table['name']}: {table.get('description', 'No description')}\n"             # <<<<<<<<<<<<<<
 * 
 *             # Add relationships information
 */
  __pyx_tuple__19 = PyTuple_Pack(2, __pyx_n_u_description, __pyx_kp_u_No_description); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 532, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__19);
  __Pyx_GIVEREF(__pyx_tuple__19);

  /* "sQQideR/SQLBuilder.pyx":539
 *                 prompt += "\nTable Relationships in Context:\n"
 *                 for rel in relationships:
 *                     prompt += f"- {rel.get('source', '')} to {rel.get('target', '')}: {rel.get('join_condition', '')}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add information about previous attempts if any
 */
  __pyx_tuple__20 = PyTuple_Pack(2, __pyx_n_u_source, __pyx_kp_u__7); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(0, 539, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__20);
  __Pyx_GIVEREF(__pyx_tuple__20);
  __pyx_tuple__21 = PyTuple_Pack(2, __pyx_n_u_target, __pyx_kp_u__7); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 539, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__21);
  __Pyx_GIVEREF(__pyx_tuple__21);
  __pyx_tuple__22 = PyTuple_Pack(2, __pyx_n_u_join_condition, __pyx_kp_u__7); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 539, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__22);
  __Pyx_GIVEREF(__pyx_tuple__22);

  /* "sQQideR/SQLBuilder.pyx":546
 *             for i, attempt in enumerate(previous_attempts):
 *                 prompt += f"\nAttempt #{i+1}:\n"
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"             # <<<<<<<<<<<<<<
 *                 if not attempt.get("success", False):
 *                     prompt += f"Error: {attempt.get('execution_error', 'Unknown error')}\n"
 */
  __pyx_tuple__24 = PyTuple_Pack(2, __pyx_n_u_sql, __pyx_kp_u_No_SQL); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(0, 546, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__24);
  __Pyx_GIVEREF(__pyx_tuple__24);

  /* "sQQideR/SQLBuilder.pyx":548
 *                 prompt += f"SQL: {attempt.get('sql', 'No SQL')}\n"
 *                 if not attempt.get("success", False):
 *                     prompt += f"Error: {attempt.get('execution_error', 'Unknown error')}\n"             # <<<<<<<<<<<<<<
 * 
 *         # Add instructions for fixing the query
 */
  __pyx_tuple__25 = PyTuple_Pack(2, __pyx_n_u_execution_error, __pyx_kp_u_Unknown_error); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 548, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__25);
  __Pyx_GIVEREF(__pyx_tuple__25);

  /* "sQQideR/SQLBuilder.pyx":709
 *         # Extract table names from the main SQL query
 *         for table_obj in db_context.get("database_objects", {}).get("tables", []):
 *             table_name = table_obj.get("name", "").lower()             # <<<<<<<<<<<<<<
 *             if table_name and table_name in main_sql:
 *                 tables_used.append(table_name)
 */
  __pyx_tuple__27 = PyTuple_Pack(2, __pyx_n_u_name, __pyx_kp_u__7); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 709, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__27);
  __Pyx_GIVEREF(__pyx_tuple__27);

  /* "sQQideR/SQLBuilder.pyx":734
 *         for column_obj in db_context.get("database_objects", {}).get("columns", []):
 *             col_name = column_obj.get("name", "").lower()
 *             data_type = column_obj.get("data_type", "").lower()             # <<<<<<<<<<<<<<
 * 
 *             # Check if column is date/time related
 */
  __pyx_tuple__28 = PyTuple_Pack(2, __pyx_n_u_data_type, __pyx_kp_u__7); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(0, 734, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__28);
  __Pyx_GIVEREF(__pyx_tuple__28);

  /* "sQQideR/SQLBuilder.pyx":886
 *             prev = db_context["previously_run_query"]
 *             prompt += f"\nPREVIOUSLY RUN QUERY FOR SIMILAR QUESTION:\n"
 *             prompt += f"Question: {prev.get('question', '')}\n"             # <<<<<<<<<<<<<<
 *             prompt += f"SQL: {prev.get('sql', '')}\n\n"
 *             prompt += "You should strongly consider using this previous query as a starting point, but adapt it to the current question if needed.\n"
 */
  __pyx_tuple__33 = PyTuple_Pack(2, __pyx_n_u_question, __pyx_kp_u__7); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(0, 886, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__33);
  __Pyx_GIVEREF(__pyx_tuple__33);

  /* "sQQideR/SQLBuilder.pyx":1046
 *         # List of dangerous SQL operations to check for
 *         dangerous_operations = [
 *             ("delete", "DELETE operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("drop", "DROP operations are not allowed"),
 *             ("update", "UPDATE operations are not allowed"),
 */
  __pyx_tuple__36 = PyTuple_Pack(2, __pyx_n_u_delete, __pyx_kp_u_DELETE_operations_are_not_allowe); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(0, 1046, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__36);
  __Pyx_GIVEREF(__pyx_tuple__36);

  /* "sQQideR/SQLBuilder.pyx":1047
 *         dangerous_operations = [
 *             ("delete", "DELETE operations are not allowed"),
 *             ("drop", "DROP operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("update", "UPDATE operations are not allowed"),
 *             ("insert", "INSERT operations are not allowed"),
 */
  __pyx_tuple__37 = PyTuple_Pack(2, __pyx_n_u_drop, __pyx_kp_u_DROP_operations_are_not_allowed); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(0, 1047, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__37);
  __Pyx_GIVEREF(__pyx_tuple__37);

  /* "sQQideR/SQLBuilder.pyx":1048
 *             ("delete", "DELETE operations are not allowed"),
 *             ("drop", "DROP operations are not allowed"),
 *             ("update", "UPDATE operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("insert", "INSERT operations are not allowed"),
 *             ("alter", "ALTER operations are not allowed"),
 */
  __pyx_tuple__38 = PyTuple_Pack(2, __pyx_n_u_update, __pyx_kp_u_UPDATE_operations_are_not_allowe); if (unlikely(!__pyx_tuple__38)) __PYX_ERR(0, 1048, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__38);
  __Pyx_GIVEREF(__pyx_tuple__38);

  /* "sQQideR/SQLBuilder.pyx":1049
 *             ("drop", "DROP operations are not allowed"),
 *             ("update", "UPDATE operations are not allowed"),
 *             ("insert", "INSERT operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("alter", "ALTER operations are not allowed"),
 *             ("truncate", "TRUNCATE operations are not allowed"),
 */
  __pyx_tuple__39 = PyTuple_Pack(2, __pyx_n_u_insert, __pyx_kp_u_INSERT_operations_are_not_allowe); if (unlikely(!__pyx_tuple__39)) __PYX_ERR(0, 1049, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__39);
  __Pyx_GIVEREF(__pyx_tuple__39);

  /* "sQQideR/SQLBuilder.pyx":1050
 *             ("update", "UPDATE operations are not allowed"),
 *             ("insert", "INSERT operations are not allowed"),
 *             ("alter", "ALTER operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("truncate", "TRUNCATE operations are not allowed"),
 *             ("create ", "CREATE operations are not allowed"),
 */
  __pyx_tuple__40 = PyTuple_Pack(2, __pyx_n_u_alter, __pyx_kp_u_ALTER_operations_are_not_allowed); if (unlikely(!__pyx_tuple__40)) __PYX_ERR(0, 1050, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__40);
  __Pyx_GIVEREF(__pyx_tuple__40);

  /* "sQQideR/SQLBuilder.pyx":1051
 *             ("insert", "INSERT operations are not allowed"),
 *             ("alter", "ALTER operations are not allowed"),
 *             ("truncate", "TRUNCATE operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("create ", "CREATE operations are not allowed"),
 *             ("pragma", "PRAGMA operations are not allowed"),
 */
  __pyx_tuple__41 = PyTuple_Pack(2, __pyx_n_u_truncate, __pyx_kp_u_TRUNCATE_operations_are_not_allo); if (unlikely(!__pyx_tuple__41)) __PYX_ERR(0, 1051, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__41);
  __Pyx_GIVEREF(__pyx_tuple__41);

  /* "sQQideR/SQLBuilder.pyx":1052
 *             ("alter", "ALTER operations are not allowed"),
 *             ("truncate", "TRUNCATE operations are not allowed"),
 *             ("create ", "CREATE operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("pragma", "PRAGMA operations are not allowed"),
 *             ("; vacuum", "VACUUM operations are not allowed"),
 */
  __pyx_tuple__42 = PyTuple_Pack(2, __pyx_kp_u_create, __pyx_kp_u_CREATE_operations_are_not_allowe); if (unlikely(!__pyx_tuple__42)) __PYX_ERR(0, 1052, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__42);
  __Pyx_GIVEREF(__pyx_tuple__42);

  /* "sQQideR/SQLBuilder.pyx":1053
 *             ("truncate", "TRUNCATE operations are not allowed"),
 *             ("create ", "CREATE operations are not allowed"),
 *             ("pragma", "PRAGMA operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("; vacuum", "VACUUM operations are not allowed"),
 *             ("attach ", "ATTACH DATABASE operations are not allowed"),
 */
  __pyx_tuple__43 = PyTuple_Pack(2, __pyx_n_u_pragma, __pyx_kp_u_PRAGMA_operations_are_not_allowe); if (unlikely(!__pyx_tuple__43)) __PYX_ERR(0, 1053, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__43);
  __Pyx_GIVEREF(__pyx_tuple__43);

  /* "sQQideR/SQLBuilder.pyx":1054
 *             ("create ", "CREATE operations are not allowed"),
 *             ("pragma", "PRAGMA operations are not allowed"),
 *             ("; vacuum", "VACUUM operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("attach ", "ATTACH DATABASE operations are not allowed"),
 *             ("detach ", "DETACH DATABASE operations are not allowed")
 */
  __pyx_tuple__44 = PyTuple_Pack(2, __pyx_kp_u_vacuum, __pyx_kp_u_VACUUM_operations_are_not_allowe); if (unlikely(!__pyx_tuple__44)) __PYX_ERR(0, 1054, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__44);
  __Pyx_GIVEREF(__pyx_tuple__44);

  /* "sQQideR/SQLBuilder.pyx":1055
 *             ("pragma", "PRAGMA operations are not allowed"),
 *             ("; vacuum", "VACUUM operations are not allowed"),
 *             ("attach ", "ATTACH DATABASE operations are not allowed"),             # <<<<<<<<<<<<<<
 *             ("detach ", "DETACH DATABASE operations are not allowed")
 *         ]
 */
  __pyx_tuple__45 = PyTuple_Pack(2, __pyx_kp_u_attach, __pyx_kp_u_ATTACH_DATABASE_operations_are_n); if (unlikely(!__pyx_tuple__45)) __PYX_ERR(0, 1055, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__45);
  __Pyx_GIVEREF(__pyx_tuple__45);

  /* "sQQideR/SQLBuilder.pyx":1056
 *             ("; vacuum", "VACUUM operations are not allowed"),
 *             ("attach ", "ATTACH DATABASE operations are not allowed"),
 *             ("detach ", "DETACH DATABASE operations are not allowed")             # <<<<<<<<<<<<<<
 *         ]
 * 
 */
  __pyx_tuple__46 = PyTuple_Pack(2, __pyx_kp_u_detach, __pyx_kp_u_DETACH_DATABASE_operations_are_n); if (unlikely(!__pyx_tuple__46)) __PYX_ERR(0, 1056, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__46);
  __Pyx_GIVEREF(__pyx_tuple__46);

  /* "sQQideR/SQLBuilder.pyx":23
 *     """
 * 
 *     def __init__(self, database_path: str = None, verbose: bool = False, ai_base=None):             # <<<<<<<<<<<<<<
 *         """
 *         Initialize the SQLBuilder with optional database connection.
 */
  __pyx_tuple__47 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_database_path, __pyx_n_s_verbose, __pyx_n_s_ai_base); if (unlikely(!__pyx_tuple__47)) __PYX_ERR(0, 23, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__47);
  __Pyx_GIVEREF(__pyx_tuple__47);
  __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 4, 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_sQQideR_SQLBuilder_pyx, __pyx_n_s_init, 23, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) __PYX_ERR(0, 23, __pyx_L1_error)
  __pyx_tuple__49 = PyTuple_Pack(3, Py_None, ((PyObject *)Py_False), Py_None); if (unlikely(!__pyx_tuple__49)) __PYX_ERR(0, 23, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__49);
  __Pyx_GIVEREF(__pyx_tuple__49);

  /* "sQQideR/SQLBuilder.pyx":43
 *                 print(f"Database file not found: {database_path}")
 * 
 *     def connect_database(self, database_path: str) -> bool:             # <<<<<<<<<<<<<<
 *         """
 *         Connect to the specified SQLite database.
 */
  __pyx_tuple__50 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_database_path, __pyx_n_s_e); if (unlikely(!__pyx_tuple__50)) __PYX_ERR(0, 43, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__50);
  __Pyx_GIVEREF(__pyx_tuple__50);
  __pyx_codeobj__51 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__50, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_connect_database, 43, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__51)) __PYX_ERR(0, 43, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":65
 *             return False
 * 
 *     def close_connection(self) -> None:             # <<<<<<<<<<<<<<
 *         """Close the database connection if open."""
 *         if self.conn:
 */
  __pyx_tuple__52 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__52);
  __Pyx_GIVEREF(__pyx_tuple__52);
  __pyx_codeobj__53 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__52, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_close_connection, 65, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__53)) __PYX_ERR(0, 65, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":73
 *                 print("Database connection closed")
 * 
 *     def generate_sql(self, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Generate SQL based on the natural language question and database context.
 */
  __pyx_tuple__54 = PyTuple_Pack(19, __pyx_n_s_self, __pyx_n_s_question, __pyx_n_s_db_context, __pyx_n_s_f, __pyx_n_s_existing_logs, __pyx_n_s_entry, __pyx_n_s_working_sql, __pyx_n_s_original_error, __pyx_n_s_original_failed_sql, __pyx_n_s_original_question, __pyx_n_s_detailed_explanation, __pyx_n_s_e, __pyx_n_s_prompt, __pyx_n_s_response, __pyx_n_s_sql_query, __pyx_n_s_explanation, __pyx_n_s_cleaned_response, __pyx_n_s_cleaned_explanation, __pyx_n_s_cleaned_sql); if (unlikely(!__pyx_tuple__54)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__54);
  __Pyx_GIVEREF(__pyx_tuple__54);
  __pyx_codeobj__55 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 19, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__54, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_generate_sql, 73, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__55)) __PYX_ERR(0, 73, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":159
 *             }
 * 
 *     def test_query(self, query: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Test a SQL query against the database and add the results.
 */
  __pyx_tuple__56 = PyTuple_Pack(6, __pyx_n_s_self, __pyx_n_s_query, __pyx_n_s_sql, __pyx_n_s_validation_error, __pyx_n_s_df, __pyx_n_s_e); if (unlikely(!__pyx_tuple__56)) __PYX_ERR(0, 159, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__56);
  __Pyx_GIVEREF(__pyx_tuple__56);
  __pyx_codeobj__57 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__56, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_test_query, 159, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__57)) __PYX_ERR(0, 159, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":215
 *             return query
 * 
 *     def compare_queries(self, historical_query: Dict, ai_query: Dict, question: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Compare results from historical and AI-generated queries to see which best answers the question.
 */
  __pyx_tuple__58 = PyTuple_Pack(7, __pyx_n_s_self, __pyx_n_s_historical_query, __pyx_n_s_ai_query, __pyx_n_s_question, __pyx_n_s_comparison, __pyx_n_s_hist_score, __pyx_n_s_ai_score); if (unlikely(!__pyx_tuple__58)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__58);
  __Pyx_GIVEREF(__pyx_tuple__58);
  __pyx_codeobj__59 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__58, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_compare_queries, 215, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__59)) __PYX_ERR(0, 215, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":272
 *         return comparison
 * 
 *     def get_best_sql_and_results(self, question: str, db_context: Dict, historical_query: Optional[Dict] = None) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Get the best SQL query and results for the given question.
 */
  __pyx_tuple__60 = PyTuple_Pack(9, __pyx_n_s_self, __pyx_n_s_question, __pyx_n_s_db_context, __pyx_n_s_historical_query, __pyx_n_s_result, __pyx_n_s_ai_query, __pyx_n_s_retry_info, __pyx_n_s_comparison, __pyx_n_s_additional_explorations); if (unlikely(!__pyx_tuple__60)) __PYX_ERR(0, 272, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__60);
  __Pyx_GIVEREF(__pyx_tuple__60);
  __pyx_codeobj__61 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 9, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__60, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_get_best_sql_and_results, 272, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) __PYX_ERR(0, 272, __pyx_L1_error)
  __pyx_tuple__62 = PyTuple_Pack(1, Py_None); if (unlikely(!__pyx_tuple__62)) __PYX_ERR(0, 272, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__62);
  __Pyx_GIVEREF(__pyx_tuple__62);

  /* "sQQideR/SQLBuilder.pyx":339
 *         return result
 * 
 *     def try_fix_failed_query(self, failed_query: Dict, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Try to fix a failed SQL query using AI assistance and schema exploration.
 */
  __pyx_tuple__63 = PyTuple_Pack(26, __pyx_n_s_self, __pyx_n_s_failed_query, __pyx_n_s_question, __pyx_n_s_db_context, __pyx_n_s_max_attempts, __pyx_n_s_attempts, __pyx_n_s_best_attempt, __pyx_n_s_original_error, __pyx_n_s_original_sql, __pyx_n_s_result, __pyx_n_s_schema_info, __pyx_n_s_attempt, __pyx_n_s_prompt, __pyx_n_s_response, __pyx_n_s_fixed_sql, __pyx_n_s_explanation, __pyx_n_s_fixed_query, __pyx_n_s_os, __pyx_n_s_file_path, __pyx_n_s_f, __pyx_n_s_existing_logs, __pyx_n_s_log_e, __pyx_n_s_table_names, __pyx_n_s_table_2, __pyx_n_s_table_info, __pyx_n_s_e); if (unlikely(!__pyx_tuple__63)) __PYX_ERR(0, 339, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__63);
  __Pyx_GIVEREF(__pyx_tuple__63);
  __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 26, 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_sQQideR_SQLBuilder_pyx, __pyx_n_s_try_fix_failed_query, 339, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) __PYX_ERR(0, 339, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":481
 *         return result
 * 
 *     def _create_sql_correction_prompt(self, question: str, original_sql: str, error: str,             # <<<<<<<<<<<<<<
 *                                       schema_info: List[Dict], previous_attempts: List[Dict],
 *                                       db_context: Dict) -> str:
 */
  __pyx_tuple__65 = PyTuple_Pack(16, __pyx_n_s_self, __pyx_n_s_question, __pyx_n_s_original_sql, __pyx_n_s_error, __pyx_n_s_schema_info, __pyx_n_s_previous_attempts, __pyx_n_s_db_context, __pyx_n_s_prompt, __pyx_n_s_info, __pyx_n_s_col, __pyx_n_s_tables, __pyx_n_s_table_2, __pyx_n_s_relationships, __pyx_n_s_rel, __pyx_n_s_i, __pyx_n_s_attempt); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__65);
  __Pyx_GIVEREF(__pyx_tuple__65);
  __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(7, 0, 0, 16, 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_sQQideR_SQLBuilder_pyx, __pyx_n_s_create_sql_correction_prompt, 481, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 481, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":572
 *         return prompt
 * 
 *     def _explore_database_schema(self) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Explore the database schema to gather information for SQL correction.
 */
  __pyx_tuple__67 = PyTuple_Pack(7, __pyx_n_s_self, __pyx_n_s_schema_info, __pyx_n_s_tables_query, __pyx_n_s_tables_df, __pyx_n_s_table_name, __pyx_n_s_table_info, __pyx_n_s_e); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 572, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__67);
  __Pyx_GIVEREF(__pyx_tuple__67);
  __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 0, 7, 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_sQQideR_SQLBuilder_pyx, __pyx_n_s_explore_database_schema, 572, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 572, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":607
 *         return schema_info
 * 
 *     def _explore_table_schema(self, table_name: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Explore a specific table's schema and sample data.
 */
  __pyx_tuple__70 = PyTuple_Pack(11, __pyx_n_s_self, __pyx_n_s_table_name, __pyx_n_s_pragma_query, __pyx_n_s_columns_df, __pyx_n_s_sample_query, __pyx_n_s_sample_df, __pyx_n_s_sample_data, __pyx_n_s_columns, __pyx_n_s__69, __pyx_n_s_row, __pyx_n_s_e); if (unlikely(!__pyx_tuple__70)) __PYX_ERR(0, 607, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__70);
  __Pyx_GIVEREF(__pyx_tuple__70);
  __pyx_codeobj__71 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__70, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_explore_table_schema, 607, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__71)) __PYX_ERR(0, 607, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":654
 *             return {}
 * 
 *     def _extract_table_names(self, sql: str) -> List[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Extract table names from a SQL query.
 */
  __pyx_tuple__72 = PyTuple_Pack(8, __pyx_n_s_self, __pyx_n_s_sql, __pyx_n_s_from_pattern, __pyx_n_s_join_pattern, __pyx_n_s_table_names, __pyx_n_s_from_matches, __pyx_n_s_match, __pyx_n_s_join_matches); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 654, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__72);
  __Pyx_GIVEREF(__pyx_tuple__72);
  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_extract_table_names, 654, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 654, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":683
 *         return list(table_names)
 * 
 *     def generate_additional_explorations(self, question: str, main_query: Dict, db_context: Dict) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Generate and execute additional SQL queries to explore related aspects of the main query.
 */
  __pyx_tuple__74 = PyTuple_Pack(39, __pyx_n_s_self, __pyx_n_s_question, __pyx_n_s_main_query, __pyx_n_s_db_context, __pyx_n_s_explorations, __pyx_n_s_main_sql, __pyx_n_s_tables_used, __pyx_n_s_table_obj, __pyx_n_s_table_name, __pyx_n_s_table_2, __pyx_n_s_count_query, __pyx_n_s_df, __pyx_n_s_e, __pyx_n_s_date_columns, __pyx_n_s_column_obj, __pyx_n_s_col_name, __pyx_n_s_data_type, __pyx_n_s_date_col, __pyx_n_s_time_query, __pyx_n_s_numeric_columns, __pyx_n_s_first_result, __pyx_n_s_col, __pyx_n_s_val, __pyx_n_s_stats_query_dict, __pyx_n_s_agg_parts, __pyx_n_s_sql, __pyx_n_s_tested_query, __pyx_n_s_retry_info, __pyx_n_s_relationship_keywords, __pyx_n_s_rel, __pyx_n_s_source, __pyx_n_s_target, __pyx_n_s_join_condition, __pyx_n_s_parts, __pyx_n_s_left_side, __pyx_n_s_right_side, __pyx_n_s_relationship_query, __pyx_n_s_genexpr, __pyx_n_s_genexpr); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 683, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__74);
  __Pyx_GIVEREF(__pyx_tuple__74);
  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(4, 0, 0, 39, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_generate_additional_explorations, 683, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 683, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":837
 *         return explorations
 * 
 *     def _create_sql_generation_prompt(self, question: str, db_context: Dict) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Create a detailed prompt for SQL generation using the database context.
 */
  __pyx_tuple__76 = PyTuple_Pack(13, __pyx_n_s_self, __pyx_n_s_question, __pyx_n_s_db_context, __pyx_n_s_tables, __pyx_n_s_columns, __pyx_n_s_relationships, __pyx_n_s_prompt, __pyx_n_s_table_2, __pyx_n_s_col, __pyx_n_s_name_parts, __pyx_n_s_column_2, __pyx_n_s_rel, __pyx_n_s_prev); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 837, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__76);
  __Pyx_GIVEREF(__pyx_tuple__76);
  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_create_sql_generation_prompt, 837, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 837, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":903
 *         return prompt
 * 
 *     def _extract_sql_from_response(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the SQL query from the AI response.
 */
  __pyx_tuple__78 = PyTuple_Pack(7, __pyx_n_s_self, __pyx_n_s_response, __pyx_n_s_code_block_pattern, __pyx_n_s_code_blocks, __pyx_n_s_block, __pyx_n_s_direct_sql_pattern, __pyx_n_s_direct_matches); if (unlikely(!__pyx_tuple__78)) __PYX_ERR(0, 903, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__78);
  __Pyx_GIVEREF(__pyx_tuple__78);
  __pyx_codeobj__79 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__78, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_extract_sql_from_response, 903, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__79)) __PYX_ERR(0, 903, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":933
 *         return response.strip()
 * 
 *     def _extract_explanation(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the explanation part from the AI response.
 */
  __pyx_tuple__80 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_response, __pyx_n_s_explanation_pattern, __pyx_n_s_explanation_match); if (unlikely(!__pyx_tuple__80)) __PYX_ERR(0, 933, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__80);
  __Pyx_GIVEREF(__pyx_tuple__80);
  __pyx_codeobj__81 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__80, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_extract_explanation, 933, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__81)) __PYX_ERR(0, 933, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":951
 *         return ""
 * 
 *     def _generate_result_summary(self, df: pd.DataFrame) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Generate a human-readable summary of query results.
 */
  __pyx_tuple__82 = PyTuple_Pack(6, __pyx_n_s_self, __pyx_n_s_df, __pyx_n_s_num_rows, __pyx_n_s_num_cols, __pyx_n_s_summary, __pyx_n_s_sample); if (unlikely(!__pyx_tuple__82)) __PYX_ERR(0, 951, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__82);
  __Pyx_GIVEREF(__pyx_tuple__82);
  __pyx_codeobj__83 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__82, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_generate_result_summary, 951, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__83)) __PYX_ERR(0, 951, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":979
 *         return summary
 * 
 *     def _evaluate_query_relevance(self, query: Dict, question: str) -> float:             # <<<<<<<<<<<<<<
 *         """
 *         Evaluate how relevant a query's results are to the original question.
 */
  __pyx_tuple__84 = PyTuple_Pack(13, __pyx_n_s_self, __pyx_n_s_query, __pyx_n_s_question, __pyx_n_s_score, __pyx_n_s_row_count, __pyx_n_s_question_keywords, __pyx_n_s_columns, __pyx_n_s_column_keywords, __pyx_n_s_col, __pyx_n_s_overlap, __pyx_n_s_sql, __pyx_n_s_conditions, __pyx_n_s_col); if (unlikely(!__pyx_tuple__84)) __PYX_ERR(0, 979, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__84);
  __Pyx_GIVEREF(__pyx_tuple__84);
  __pyx_codeobj__85 = (PyObject*)__Pyx_PyCode_New(3, 0, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__84, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_evaluate_query_relevance, 979, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__85)) __PYX_ERR(0, 979, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":1031
 *         return max(0, min(10, score))
 * 
 *     def _validate_safe_sql(self, sql: str) -> Optional[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Validate that SQL doesn't contain destructive operations.
 */
  __pyx_tuple__86 = PyTuple_Pack(7, __pyx_n_s_self, __pyx_n_s_sql, __pyx_n_s_normalized_sql, __pyx_n_s_dangerous_operations, __pyx_n_s_operation, __pyx_n_s_error_msg, __pyx_n_s_pattern); if (unlikely(!__pyx_tuple__86)) __PYX_ERR(0, 1031, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__86);
  __Pyx_GIVEREF(__pyx_tuple__86);
  __pyx_codeobj__87 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__86, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_validate_safe_sql, 1031, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__87)) __PYX_ERR(0, 1031, __pyx_L1_error)

  /* "sQQideR/SQLBuilder.pyx":1074
 *         return None  # SQL is safe
 * 
 *     def _clean_text(self, text: str) -> str:             # <<<<<<<<<<<<<<
 *         # Remove newline characters and extra spaces for downstream system compatibility
 *         return " ".join(text.split())
 */
  __pyx_tuple__88 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_text); if (unlikely(!__pyx_tuple__88)) __PYX_ERR(0, 1074, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__88);
  __Pyx_GIVEREF(__pyx_tuple__88);
  __pyx_codeobj__89 = (PyObject*)__Pyx_PyCode_New(2, 0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__88, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_sQQideR_SQLBuilder_pyx, __pyx_n_s_clean_text, 1074, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__89)) __PYX_ERR(0, 1074, __pyx_L1_error)
  __Pyx_RefNannyFinishContext();
  return 0;
  __pyx_L1_error:;
  __Pyx_RefNannyFinishContext();
  return -1;
}
/* #### Code section: init_constants ### */

static CYTHON_SMALL_CODE int __Pyx_InitConstants(void) {
  __pyx_umethod_PyDict_Type_get.type = (PyObject*)&PyDict_Type;
  __pyx_umethod_PyDict_Type_get.method_name = &__pyx_n_s_get;
  __pyx_umethod_PySet_Type_intersection.type = (PyObject*)&PySet_Type;
  __pyx_umethod_PySet_Type_intersection.method_name = &__pyx_n_s_intersection;
  __pyx_umethod_PySet_Type_update.type = (PyObject*)&PySet_Type;
  __pyx_umethod_PySet_Type_update.method_name = &__pyx_n_s_update;
  __pyx_umethod_PyUnicode_Type_lower.type = (PyObject*)&PyUnicode_Type;
  __pyx_umethod_PyUnicode_Type_lower.method_name = &__pyx_n_s_lower;
  __pyx_umethod_PyUnicode_Type_strip.type = (PyObject*)&PyUnicode_Type;
  __pyx_umethod_PyUnicode_Type_strip.method_name = &__pyx_n_s_strip;
  if (__Pyx_CreateStringTabAndInitStrings() < 0) __PYX_ERR(0, 1, __pyx_L1_error);
  __pyx_float_0_0 = PyFloat_FromDouble(0.0); if (unlikely(!__pyx_float_0_0)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_float_0_5 = PyFloat_FromDouble(0.5); if (unlikely(!__pyx_float_0_5)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_float_5_0 = PyFloat_FromDouble(5.0); if (unlikely(!__pyx_float_5_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_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_int_20 = PyInt_FromLong(20); if (unlikely(!__pyx_int_20)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_int_100 = PyInt_FromLong(100); if (unlikely(!__pyx_int_100)) __PYX_ERR(0, 1, __pyx_L1_error)
  return 0;
  __pyx_L1_error:;
  return -1;
}
/* #### Code section: init_globals ### */

static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) {
  return 0;
}
/* #### Code section: init_module ### */

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_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 CYTHON_USE_TYPE_SPECS
  __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations_spec, NULL); if (unlikely(!__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations)) __PYX_ERR(0, 683, __pyx_L1_error)
  if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations_spec, __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations) < 0) __PYX_ERR(0, 683, __pyx_L1_error)
  #else
  __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations = &__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations;
  #endif
  #if !CYTHON_COMPILING_IN_LIMITED_API
  #endif
  #if !CYTHON_USE_TYPE_SPECS
  if (__Pyx_PyType_Ready(__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations) < 0) __PYX_ERR(0, 683, __pyx_L1_error)
  #endif
  #if PY_MAJOR_VERSION < 3
  __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations->tp_print = 0;
  #endif
  #if !CYTHON_COMPILING_IN_LIMITED_API
  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations->tp_dictoffset && __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations->tp_getattro == PyObject_GenericGetAttr)) {
    __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct__generate_additional_explorations->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
  }
  #endif
  #if CYTHON_USE_TYPE_SPECS
  __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr = (PyTypeObject *) __Pyx_PyType_FromModuleAndSpec(__pyx_m, &__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr_spec, NULL); if (unlikely(!__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr)) __PYX_ERR(0, 806, __pyx_L1_error)
  if (__Pyx_fix_up_extension_type_from_spec(&__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr_spec, __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 806, __pyx_L1_error)
  #else
  __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr = &__pyx_type_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr;
  #endif
  #if !CYTHON_COMPILING_IN_LIMITED_API
  #endif
  #if !CYTHON_USE_TYPE_SPECS
  if (__Pyx_PyType_Ready(__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 806, __pyx_L1_error)
  #endif
  #if PY_MAJOR_VERSION < 3
  __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr->tp_print = 0;
  #endif
  #if !CYTHON_COMPILING_IN_LIMITED_API
  if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr->tp_dictoffset && __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr->tp_getattro == PyObject_GenericGetAttr)) {
    __pyx_ptype_7sQQideR_10SQLBuilder___pyx_scope_struct_1_genexpr->tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
  }
  #endif
  __Pyx_RefNannyFinishContext();
  return 0;
  __pyx_L1_error:;
  __Pyx_RefNannyFinishContext();
  return -1;
}

static int __Pyx_modinit_type_import_code(void) {
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0);
  /*--- Type import code ---*/
  __Pyx_RefNannyFinishContext();
  return 0;
}

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;
}


#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_SQLBuilder(PyObject* module); /*proto*/
static PyModuleDef_Slot __pyx_moduledef_slots[] = {
  {Py_mod_create, (void*)__pyx_pymod_create},
  {Py_mod_exec, (void*)__pyx_pymod_exec_SQLBuilder},
  {0, NULL}
};
#endif

#ifdef __cplusplus
namespace {
  struct PyModuleDef __pyx_moduledef =
  #else
  static struct PyModuleDef __pyx_moduledef =
  #endif
  {
      PyModuleDef_HEAD_INIT,
      "SQLBuilder",
      __pyx_k_SQLBuilder_Responsible_for_cons, /* m_doc */
    #if CYTHON_PEP489_MULTI_PHASE_INIT
      0, /* m_size */
    #elif CYTHON_USE_MODULE_STATE
      sizeof(__pyx_mstate), /* 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
    #if CYTHON_USE_MODULE_STATE
      __pyx_m_traverse, /* m_traverse */
      __pyx_m_clear, /* m_clear */
      NULL /* m_free */
    #else
      NULL, /* m_traverse */
      NULL, /* m_clear */
      NULL /* m_free */
    #endif
  };
  #ifdef __cplusplus
} /* anonymous namespace */
#endif
#endif

#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 initSQLBuilder(void) CYTHON_SMALL_CODE; /*proto*/
__Pyx_PyMODINIT_FUNC initSQLBuilder(void)
#else
__Pyx_PyMODINIT_FUNC PyInit_SQLBuilder(void) CYTHON_SMALL_CODE; /*proto*/
__Pyx_PyMODINIT_FUNC PyInit_SQLBuilder(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;
}
#if CYTHON_COMPILING_IN_LIMITED_API
static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *module, const char* from_name, const char* to_name, int allow_none)
#else
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)
#endif
{
    PyObject *value = PyObject_GetAttrString(spec, from_name);
    int result = 0;
    if (likely(value)) {
        if (allow_none || value != Py_None) {
#if CYTHON_COMPILING_IN_LIMITED_API
            result = PyModule_AddObject(module, to_name, value);
#else
            result = PyDict_SetItemString(moddict, to_name, value);
#endif
        }
        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, PyModuleDef *def) {
    PyObject *module = NULL, *moddict, *modname;
    CYTHON_UNUSED_VAR(def);
    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;
#if CYTHON_COMPILING_IN_LIMITED_API
    moddict = module;
#else
    moddict = PyModule_GetDict(module);
    if (unlikely(!moddict)) goto bad;
#endif
    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_SQLBuilder(PyObject *__pyx_pyinit_module)
#endif
#endif
{
  int stringtab_initialized = 0;
  #if CYTHON_USE_MODULE_STATE
  int pystate_addmodule_run = 0;
  #endif
  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_RefNannyDeclarations
  #if CYTHON_PEP489_MULTI_PHASE_INIT
  if (__pyx_m) {
    if (__pyx_m == __pyx_pyinit_module) return 0;
    PyErr_SetString(PyExc_RuntimeError, "Module 'SQLBuilder' 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
  /*--- 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("SQLBuilder", __pyx_methods, __pyx_k_SQLBuilder_Responsible_for_cons, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
  if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error)
  #elif CYTHON_USE_MODULE_STATE
  __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
  {
    int add_module_result = PyState_AddModule(__pyx_t_1, &__pyx_moduledef);
    __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "SQLBuilder" pseudovariable */
    if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error)
    pystate_addmodule_run = 1;
  }
  #else
  __pyx_m = PyModule_Create(&__pyx_moduledef);
  if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error)
  #endif
  #endif
  CYTHON_UNUSED_VAR(__pyx_t_1);
  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error)
  Py_INCREF(__pyx_d);
  __pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error)
  __pyx_cython_runtime = __Pyx_PyImport_AddModuleRef((const char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error)
  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  #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_SQLBuilder(void)", 0);
  if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < 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(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  #endif
  #ifdef __Pyx_FusedFunction_USED
  if (__pyx_FusedFunction_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  #endif
  #ifdef __Pyx_Coroutine_USED
  if (__pyx_Coroutine_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  #endif
  #ifdef __Pyx_Generator_USED
  if (__pyx_Generator_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  #endif
  #ifdef __Pyx_AsyncGen_USED
  if (__pyx_AsyncGen_init(__pyx_m) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  #endif
  #ifdef __Pyx_StopAsyncIteration_USED
  if (__pyx_StopAsyncIteration_init(__pyx_m) < 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
  /*--- Initialize various global constants etc. ---*/
  if (__Pyx_InitConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  stringtab_initialized = 1;
  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_sQQideR__SQLBuilder) {
    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, "sQQideR.SQLBuilder")) {
      if (unlikely((PyDict_SetItemString(modules, "sQQideR.SQLBuilder", __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)
  (void)__Pyx_modinit_type_import_code();
  (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

  /* "sQQideR/SQLBuilder.pyx":11
 * """
 * 
 * import json             # <<<<<<<<<<<<<<
 * import os
 * import re
 */
  __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_json, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_json, __pyx_t_2) < 0) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":12
 * 
 * import json
 * import os             # <<<<<<<<<<<<<<
 * import re
 * import sqlite3
 */
  __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_os, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 12, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_2) < 0) __PYX_ERR(0, 12, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":13
 * import json
 * import os
 * import re             # <<<<<<<<<<<<<<
 * import sqlite3
 * import pandas as pd
 */
  __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_re, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_re, __pyx_t_2) < 0) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":14
 * import os
 * import re
 * import sqlite3             # <<<<<<<<<<<<<<
 * import pandas as pd
 * from typing import Dict, List, Tuple, Optional, Any, Union
 */
  __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_sqlite3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_sqlite3, __pyx_t_2) < 0) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":15
 * import re
 * import sqlite3
 * import pandas as pd             # <<<<<<<<<<<<<<
 * from typing import Dict, List, Tuple, Optional, Any, Union
 * 
 */
  __pyx_t_2 = __Pyx_ImportDottedModule(__pyx_n_s_pandas, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pd, __pyx_t_2) < 0) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":16
 * import sqlite3
 * import pandas as pd
 * from typing import Dict, List, Tuple, Optional, Any, Union             # <<<<<<<<<<<<<<
 * 
 * class SQLBuilder:
 */
  __pyx_t_2 = PyList_New(6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_INCREF(__pyx_n_s_Dict);
  __Pyx_GIVEREF(__pyx_n_s_Dict);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_Dict)) __PYX_ERR(0, 16, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_s_List);
  __Pyx_GIVEREF(__pyx_n_s_List);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_List)) __PYX_ERR(0, 16, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_s_Tuple);
  __Pyx_GIVEREF(__pyx_n_s_Tuple);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_Tuple)) __PYX_ERR(0, 16, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_s_Optional);
  __Pyx_GIVEREF(__pyx_n_s_Optional);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_s_Optional)) __PYX_ERR(0, 16, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_s_Any);
  __Pyx_GIVEREF(__pyx_n_s_Any);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_s_Any)) __PYX_ERR(0, 16, __pyx_L1_error);
  __Pyx_INCREF(__pyx_n_s_Union);
  __Pyx_GIVEREF(__pyx_n_s_Union);
  if (__Pyx_PyList_SET_ITEM(__pyx_t_2, 5, __pyx_n_s_Union)) __PYX_ERR(0, 16, __pyx_L1_error);
  __pyx_t_3 = __Pyx_Import(__pyx_n_s_typing, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_Dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Dict, __pyx_t_2) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_List, __pyx_t_2) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Tuple, __pyx_t_2) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_Optional); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Optional, __pyx_t_2) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_Any); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Any, __pyx_t_2) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Union, __pyx_t_2) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;

  /* "sQQideR/SQLBuilder.pyx":18
 * from typing import Dict, List, Tuple, Optional, Any, Union
 * 
 * class SQLBuilder:             # <<<<<<<<<<<<<<
 *     """
 *     Class for building and testing SQL queries using AI and historical data.
 */
  __pyx_t_3 = __Pyx_Py3MetaclassPrepare((PyObject *) NULL, __pyx_empty_tuple, __pyx_n_s_SQLBuilder, __pyx_n_s_SQLBuilder, (PyObject *) NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_kp_s_Class_for_building_and_testing); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);

  /* "sQQideR/SQLBuilder.pyx":23
 *     """
 * 
 *     def __init__(self, database_path: str = None, verbose: bool = False, ai_base=None):             # <<<<<<<<<<<<<<
 *         """
 *         Initialize the SQLBuilder with optional database connection.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 23, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_database_path, __pyx_n_s_str) < 0) __PYX_ERR(0, 23, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_verbose, __pyx_n_s_bool) < 0) __PYX_ERR(0, 23, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_1__init__, 0, __pyx_n_s_SQLBuilder___init, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 23, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__49);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_2);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_init, __pyx_t_4) < 0) __PYX_ERR(0, 23, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":43
 *                 print(f"Database file not found: {database_path}")
 * 
 *     def connect_database(self, database_path: str) -> bool:             # <<<<<<<<<<<<<<
 *         """
 *         Connect to the specified SQLite database.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 43, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_database_path, __pyx_n_s_str) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_bool) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_3connect_database, 0, __pyx_n_s_SQLBuilder_connect_database, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__51)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_connect_database, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":65
 *             return False
 * 
 *     def close_connection(self) -> None:             # <<<<<<<<<<<<<<
 *         """Close the database connection if open."""
 *         if self.conn:
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_s_None) < 0) __PYX_ERR(0, 65, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_5close_connection, 0, __pyx_n_s_SQLBuilder_close_connection, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__53)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 65, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_close_connection, __pyx_t_4) < 0) __PYX_ERR(0, 65, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":73
 *                 print("Database connection closed")
 * 
 *     def generate_sql(self, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Generate SQL based on the natural language question and database context.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(3); 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_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 73, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_db_context, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 73, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 73, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_7generate_sql, 0, __pyx_n_s_SQLBuilder_generate_sql, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__55)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_generate_sql, __pyx_t_2) < 0) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":159
 *             }
 * 
 *     def test_query(self, query: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Test a SQL query against the database and add the results.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 159, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_query, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 159, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 159, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_9test_query, 0, __pyx_n_s_SQLBuilder_test_query, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__57)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 159, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_test_query, __pyx_t_4) < 0) __PYX_ERR(0, 159, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":215
 *             return query
 * 
 *     def compare_queries(self, historical_query: Dict, ai_query: Dict, question: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Compare results from historical and AI-generated queries to see which best answers the question.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_historical_query, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_ai_query, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_11compare_queries, 0, __pyx_n_s_SQLBuilder_compare_queries, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__59)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_compare_queries, __pyx_t_2) < 0) __PYX_ERR(0, 215, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":272
 *         return comparison
 * 
 *     def get_best_sql_and_results(self, question: str, db_context: Dict, historical_query: Optional[Dict] = None) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Get the best SQL query and results for the given question.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 272, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 272, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_db_context, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 272, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_historical_query, __pyx_kp_s_Optional_Dict) < 0) __PYX_ERR(0, 272, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 272, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_13get_best_sql_and_results, 0, __pyx_n_s_SQLBuilder_get_best_sql_and_resu, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__61)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 272, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_tuple__62);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_2);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_get_best_sql_and_results, __pyx_t_4) < 0) __PYX_ERR(0, 272, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":339
 *         return result
 * 
 *     def try_fix_failed_query(self, failed_query: Dict, question: str, db_context: Dict) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Try to fix a failed SQL query using AI assistance and schema exploration.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 339, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_failed_query, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_db_context, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_15try_fix_failed_query, 0, __pyx_n_s_SQLBuilder_try_fix_failed_query, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__64)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 339, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_try_fix_failed_query, __pyx_t_2) < 0) __PYX_ERR(0, 339, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":481
 *         return result
 * 
 *     def _create_sql_correction_prompt(self, question: str, original_sql: str, error: str,             # <<<<<<<<<<<<<<
 *                                       schema_info: List[Dict], previous_attempts: List[Dict],
 *                                       db_context: Dict) -> str:
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(7); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_original_sql, __pyx_n_s_str) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_error, __pyx_n_s_str) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_schema_info, __pyx_kp_s_List_Dict) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_previous_attempts, __pyx_kp_s_List_Dict) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_db_context, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_s_str) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_17_create_sql_correction_prompt, 0, __pyx_n_s_SQLBuilder__create_sql_correctio, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__66)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 481, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_create_sql_correction_prompt, __pyx_t_4) < 0) __PYX_ERR(0, 481, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":572
 *         return prompt
 * 
 *     def _explore_database_schema(self) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Explore the database schema to gather information for SQL correction.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 572, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_kp_s_List_Dict) < 0) __PYX_ERR(0, 572, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_19_explore_database_schema, 0, __pyx_n_s_SQLBuilder__explore_database_sch, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 572, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_explore_database_schema, __pyx_t_2) < 0) __PYX_ERR(0, 572, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":607
 *         return schema_info
 * 
 *     def _explore_table_schema(self, table_name: str) -> Dict:             # <<<<<<<<<<<<<<
 *         """
 *         Explore a specific table's schema and sample data.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 607, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_table_name, __pyx_n_s_str) < 0) __PYX_ERR(0, 607, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 607, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_21_explore_table_schema, 0, __pyx_n_s_SQLBuilder__explore_table_schema, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__71)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 607, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_explore_table_schema, __pyx_t_4) < 0) __PYX_ERR(0, 607, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":654
 *             return {}
 * 
 *     def _extract_table_names(self, sql: str) -> List[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Extract table names from a SQL query.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 654, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_sql, __pyx_n_s_str) < 0) __PYX_ERR(0, 654, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_kp_s_List_str) < 0) __PYX_ERR(0, 654, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_23_extract_table_names, 0, __pyx_n_s_SQLBuilder__extract_table_names, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 654, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_extract_table_names, __pyx_t_2) < 0) __PYX_ERR(0, 654, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":683
 *         return list(table_names)
 * 
 *     def generate_additional_explorations(self, question: str, main_query: Dict, db_context: Dict) -> List[Dict]:             # <<<<<<<<<<<<<<
 *         """
 *         Generate and execute additional SQL queries to explore related aspects of the main query.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 683, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 683, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_main_query, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 683, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_db_context, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 683, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_kp_s_List_Dict) < 0) __PYX_ERR(0, 683, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_25generate_additional_explorations, 0, __pyx_n_s_SQLBuilder_generate_additional_e_2, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 683, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_generate_additional_explorations, __pyx_t_4) < 0) __PYX_ERR(0, 683, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":837
 *         return explorations
 * 
 *     def _create_sql_generation_prompt(self, question: str, db_context: Dict) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Create a detailed prompt for SQL generation using the database context.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 837, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 837, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_db_context, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 837, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_str) < 0) __PYX_ERR(0, 837, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_27_create_sql_generation_prompt, 0, __pyx_n_s_SQLBuilder__create_sql_generatio, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__77)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 837, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_create_sql_generation_prompt, __pyx_t_2) < 0) __PYX_ERR(0, 837, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":903
 *         return prompt
 * 
 *     def _extract_sql_from_response(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the SQL query from the AI response.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 903, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_response, __pyx_n_s_str) < 0) __PYX_ERR(0, 903, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_s_str) < 0) __PYX_ERR(0, 903, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_29_extract_sql_from_response, 0, __pyx_n_s_SQLBuilder__extract_sql_from_res, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__79)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 903, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_extract_sql_from_response, __pyx_t_4) < 0) __PYX_ERR(0, 903, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":933
 *         return response.strip()
 * 
 *     def _extract_explanation(self, response: str) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Extract the explanation part from the AI response.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 933, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_response, __pyx_n_s_str) < 0) __PYX_ERR(0, 933, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_str) < 0) __PYX_ERR(0, 933, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_31_extract_explanation, 0, __pyx_n_s_SQLBuilder__extract_explanation, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__81)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 933, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_extract_explanation, __pyx_t_2) < 0) __PYX_ERR(0, 933, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":951
 *         return ""
 * 
 *     def _generate_result_summary(self, df: pd.DataFrame) -> str:             # <<<<<<<<<<<<<<
 *         """
 *         Generate a human-readable summary of query results.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 951, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_df, __pyx_kp_s_pd_DataFrame) < 0) __PYX_ERR(0, 951, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_s_str) < 0) __PYX_ERR(0, 951, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_33_generate_result_summary, 0, __pyx_n_s_SQLBuilder__generate_result_summ, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__83)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 951, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_generate_result_summary, __pyx_t_4) < 0) __PYX_ERR(0, 951, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":979
 *         return summary
 * 
 *     def _evaluate_query_relevance(self, query: Dict, question: str) -> float:             # <<<<<<<<<<<<<<
 *         """
 *         Evaluate how relevant a query's results are to the original question.
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 979, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_query, __pyx_n_s_Dict) < 0) __PYX_ERR(0, 979, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_question, __pyx_n_s_str) < 0) __PYX_ERR(0, 979, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_float) < 0) __PYX_ERR(0, 979, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_35_evaluate_query_relevance, 0, __pyx_n_s_SQLBuilder__evaluate_query_relev, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__85)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 979, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_evaluate_query_relevance, __pyx_t_2) < 0) __PYX_ERR(0, 979, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":1031
 *         return max(0, min(10, score))
 * 
 *     def _validate_safe_sql(self, sql: str) -> Optional[str]:             # <<<<<<<<<<<<<<
 *         """
 *         Validate that SQL doesn't contain destructive operations.
 */
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1031, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_sql, __pyx_n_s_str) < 0) __PYX_ERR(0, 1031, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_kp_s_Optional_str) < 0) __PYX_ERR(0, 1031, __pyx_L1_error)
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_37_validate_safe_sql, 0, __pyx_n_s_SQLBuilder__validate_safe_sql, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__87)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1031, __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 (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_validate_safe_sql, __pyx_t_4) < 0) __PYX_ERR(0, 1031, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

  /* "sQQideR/SQLBuilder.pyx":1074
 *         return None  # SQL is safe
 * 
 *     def _clean_text(self, text: str) -> str:             # <<<<<<<<<<<<<<
 *         # Remove newline characters and extra spaces for downstream system compatibility
 *         return " ".join(text.split())
 */
  __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1074, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_text, __pyx_n_s_str) < 0) __PYX_ERR(0, 1074, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_n_s_str) < 0) __PYX_ERR(0, 1074, __pyx_L1_error)
  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_7sQQideR_10SQLBuilder_10SQLBuilder_39_clean_text, 0, __pyx_n_s_SQLBuilder__clean_text, NULL, __pyx_n_s_sQQideR_SQLBuilder, __pyx_d, ((PyObject *)__pyx_codeobj__89)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1074, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_clean_text, __pyx_t_2) < 0) __PYX_ERR(0, 1074, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;

  /* "sQQideR/SQLBuilder.pyx":18
 * from typing import Dict, List, Tuple, Optional, Any, Union
 * 
 * class SQLBuilder:             # <<<<<<<<<<<<<<
 *     """
 *     Class for building and testing SQL queries using AI and historical data.
 */
  __pyx_t_2 = __Pyx_Py3ClassCreate(((PyObject*)&PyType_Type), __pyx_n_s_SQLBuilder, __pyx_empty_tuple, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_SQLBuilder, __pyx_t_2) < 0) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;

  /* "sQQideR/SQLBuilder.pyx":1
 * """             # <<<<<<<<<<<<<<
 * SQLBuilder - Responsible for constructing SQL queries based on the DatabaseContext
 * 
 */
  __pyx_t_3 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_3) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;

  /*--- Wrapped vars code ---*/

  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  if (__pyx_m) {
    if (__pyx_d && stringtab_initialized) {
      __Pyx_AddTraceback("init sQQideR.SQLBuilder", __pyx_clineno, __pyx_lineno, __pyx_filename);
    }
    #if !CYTHON_USE_MODULE_STATE
    Py_CLEAR(__pyx_m);
    #else
    Py_DECREF(__pyx_m);
    if (pystate_addmodule_run) {
      PyObject *tp, *value, *tb;
      PyErr_Fetch(&tp, &value, &tb);
      PyState_RemoveModule(&__pyx_moduledef);
      PyErr_Restore(tp, value, tb);
    }
    #endif
  } else if (!PyErr_Occurred()) {
    PyErr_SetString(PyExc_ImportError, "init sQQideR.SQLBuilder");
  }
  __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
}
/* #### Code section: cleanup_globals ### */
/* #### Code section: cleanup_module ### */
/* #### Code section: main_method ### */
/* #### Code section: utility_code_pragmas ### */
#ifdef _MSC_VER
#pragma warning( push )
/* Warning 4127: conditional expression is constant
 * Cython uses constant conditional expressions to allow in inline functions to be optimized at
 * compile-time, so this warning is not useful
 */
#pragma warning( disable : 4127 )
#endif



/* #### Code section: utility_code_def ### */

/* --- 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

/* 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; i<n; i++) {
        if (exc_type == PyTuple_GET_ITEM(tuple, i)) return 1;
    }
#endif
    for (i=0; i<n; i++) {
        if (__Pyx_PyErr_GivenExceptionMatches(exc_type, PyTuple_GET_ITEM(tuple, i))) return 1;
    }
    return 0;
}
static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err) {
    int result;
    PyObject *exc_type;
#if PY_VERSION_HEX >= 0x030C00A6
    PyObject *current_exception = tstate->current_exception;
    if (unlikely(!current_exception)) return 0;
    exc_type = (PyObject*) Py_TYPE(current_exception);
    if (exc_type == err) return 1;
#else
    exc_type = tstate->curexc_type;
    if (exc_type == err) return 1;
    if (unlikely(!exc_type)) return 0;
#endif
    #if CYTHON_AVOID_BORROWED_REFS
    Py_INCREF(exc_type);
    #endif
    if (unlikely(PyTuple_Check(err))) {
        result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err);
    } else {
        result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err);
    }
    #if CYTHON_AVOID_BORROWED_REFS
    Py_DECREF(exc_type);
    #endif
    return result;
}
#endif

/* PyErrFetchRestore */
#if CYTHON_FAST_THREAD_STATE
static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) {
#if PY_VERSION_HEX >= 0x030C00A6
    PyObject *tmp_value;
    assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value)));
    if (value) {
        #if CYTHON_COMPILING_IN_CPYTHON
        if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb))
        #endif
            PyException_SetTraceback(value, tb);
    }
    tmp_value = tstate->current_exception;
    tstate->current_exception = value;
    Py_XDECREF(tmp_value);
    Py_XDECREF(type);
    Py_XDECREF(tb);
#else
    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);
#endif
}
static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
#if PY_VERSION_HEX >= 0x030C00A6
    PyObject* exc_value;
    exc_value = tstate->current_exception;
    tstate->current_exception = 0;
    *value = exc_value;
    *type = NULL;
    *tb = NULL;
    if (exc_value) {
        *type = (PyObject*) Py_TYPE(exc_value);
        Py_INCREF(*type);
        #if CYTHON_COMPILING_IN_CPYTHON
        *tb = ((PyBaseExceptionObject*) exc_value)->traceback;
        Py_XINCREF(*tb);
        #else
        *tb = PyException_GetTraceback(exc_value);
        #endif
    }
#else
    *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
}
#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

/* PyObjectGetAttrStrNoError */
#if __PYX_LIMITED_VERSION_HEX < 0x030d00A1
static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) {
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError)))
        __Pyx_PyErr_Clear();
}
#endif
static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) {
    PyObject *result;
#if __PYX_LIMITED_VERSION_HEX >= 0x030d00A1
    (void) PyObject_GetOptionalAttr(obj, attr_name, &result);
    return result;
#else
#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;
#endif
}

/* GetBuiltinName */
static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
    PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_b, name);
    if (unlikely(!result) && !PyErr_Occurred()) {
        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;
}

/* TupleAndListFromArray */
#if CYTHON_COMPILING_IN_CPYTHON
static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) {
    PyObject *v;
    Py_ssize_t i;
    for (i = 0; i < length; i++) {
        v = dest[i] = src[i];
        Py_INCREF(v);
    }
}
static CYTHON_INLINE PyObject *
__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
{
    PyObject *res;
    if (n <= 0) {
        Py_INCREF(__pyx_empty_tuple);
        return __pyx_empty_tuple;
    }
    res = PyTuple_New(n);
    if (unlikely(res == NULL)) return NULL;
    __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n);
    return res;
}
static CYTHON_INLINE PyObject *
__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n)
{
    PyObject *res;
    if (n <= 0) {
        return PyList_New(0);
    }
    res = PyList_New(n);
    if (unlikely(res == NULL)) return NULL;
    __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n);
    return res;
}
#endif

/* BytesEquals */
static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API
    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 || CYTHON_COMPILING_IN_LIMITED_API
    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
}

/* fastcall */
#if CYTHON_METH_FASTCALL
static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s)
{
    Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames);
    for (i = 0; i < n; i++)
    {
        if (s == PyTuple_GET_ITEM(kwnames, i)) return kwvalues[i];
    }
    for (i = 0; i < n; i++)
    {
        int eq = __Pyx_PyUnicode_Equals(s, PyTuple_GET_ITEM(kwnames, i), Py_EQ);
        if (unlikely(eq != 0)) {
            if (unlikely(eq < 0)) return NULL;
            return kwvalues[i];
        }
    }
    return NULL;
}
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000
CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) {
    Py_ssize_t i, nkwargs = PyTuple_GET_SIZE(kwnames);
    PyObject *dict;
    dict = PyDict_New();
    if (unlikely(!dict))
        return NULL;
    for (i=0; i<nkwargs; i++) {
        PyObject *key = PyTuple_GET_ITEM(kwnames, i);
        if (unlikely(PyDict_SetItem(dict, key, kwvalues[i]) < 0))
            goto bad;
    }
    return dict;
bad:
    Py_DECREF(dict);
    return NULL;
}
#endif
#endif

/* 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 *const *kwvalues,
    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;
    int kwds_is_tuple = CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds));
    while (1) {
        Py_XDECREF(key); key = NULL;
        Py_XDECREF(value); value = NULL;
        if (kwds_is_tuple) {
            Py_ssize_t size;
#if CYTHON_ASSUME_SAFE_MACROS
            size = PyTuple_GET_SIZE(kwds);
#else
            size = PyTuple_Size(kwds);
            if (size < 0) goto bad;
#endif
            if (pos >= size) break;
#if CYTHON_AVOID_BORROWED_REFS
            key = __Pyx_PySequence_ITEM(kwds, pos);
            if (!key) goto bad;
#elif CYTHON_ASSUME_SAFE_MACROS
            key = PyTuple_GET_ITEM(kwds, pos);
#else
            key = PyTuple_GetItem(kwds, pos);
            if (!key) goto bad;
#endif
            value = kwvalues[pos];
            pos++;
        }
        else
        {
            if (!PyDict_Next(kwds, &pos, &key, &value)) break;
#if CYTHON_AVOID_BORROWED_REFS
            Py_INCREF(key);
#endif
        }
        name = first_kw_arg;
        while (*name && (**name != key)) name++;
        if (*name) {
            values[name-argnames] = value;
#if CYTHON_AVOID_BORROWED_REFS
            Py_INCREF(value);
            Py_DECREF(key);
#endif
            key = NULL;
            value = NULL;
            continue;
        }
#if !CYTHON_AVOID_BORROWED_REFS
        Py_INCREF(key);
#endif
        Py_INCREF(value);
        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;
#if CYTHON_AVOID_BORROWED_REFS
                    value = NULL;
#endif
                    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 = (
                #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;
#if CYTHON_AVOID_BORROWED_REFS
                    value = NULL;
#endif
                    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;
        }
    }
    Py_XDECREF(key);
    Py_XDECREF(value);
    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:
    #if PY_MAJOR_VERSION < 3
    PyErr_Format(PyExc_TypeError,
        "%.200s() got an unexpected keyword argument '%.200s'",
        function_name, PyString_AsString(key));
    #else
    PyErr_Format(PyExc_TypeError,
        "%s() got an unexpected keyword argument '%U'",
        function_name, key);
    #endif
bad:
    Py_XDECREF(key);
    Py_XDECREF(value);
    return -1;
}

/* 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);
}

/* ArgTypeTest */
static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact)
{
    __Pyx_TypeName type_name;
    __Pyx_TypeName obj_type_name;
    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;
    }
    type_name = __Pyx_PyType_GetName(type);
    obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj));
    PyErr_Format(PyExc_TypeError,
        "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME
        ", got " __Pyx_FMT_TYPENAME ")", name, type_name, obj_type_name);
    __Pyx_DECREF_TypeName(type_name);
    __Pyx_DECREF_TypeName(obj_type_name);
    return 0;
}

/* 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

/* PyDictVersioning */
#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS
static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) {
    PyObject *dict = Py_TYPE(obj)->tp_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 && PY_VERSION_HEX < 0x030d0000
    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;
    }
#elif CYTHON_COMPILING_IN_LIMITED_API
    if (unlikely(!__pyx_m)) {
        return NULL;
    }
    result = PyObject_GetAttr(__pyx_m, name);
    if (likely(result)) {
        return result;
    }
#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);
}

/* PyFunctionFastCall */
#if CYTHON_FAST_PYCALL && !CYTHON_VECTORCALL
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;
}
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_MAJOR_VERSION < 3
    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) {
        return NULL;
    }
    #else
    if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) {
        return NULL;
    }
    #endif
    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

/* 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 PY_MAJOR_VERSION < 3
    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
        return NULL;
    #else
    if (unlikely(Py_EnterRecursiveCall(" while calling a Python object")))
        return NULL;
    #endif
    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 = __Pyx_CyOrPyCFunction_GET_FUNCTION(func);
    self = __Pyx_CyOrPyCFunction_GET_SELF(func);
    #if PY_MAJOR_VERSION < 3
    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
        return NULL;
    #else
    if (unlikely(Py_EnterRecursiveCall(" while calling a Python object")))
        return NULL;
    #endif
    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

/* PyObjectFastCall */
#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API
static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) {
    PyObject *argstuple;
    PyObject *result = 0;
    size_t i;
    argstuple = PyTuple_New((Py_ssize_t)nargs);
    if (unlikely(!argstuple)) return NULL;
    for (i = 0; i < nargs; i++) {
        Py_INCREF(args[i]);
        if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) < 0) goto bad;
    }
    result = __Pyx_PyObject_Call(func, argstuple, kwargs);
  bad:
    Py_DECREF(argstuple);
    return result;
}
#endif
static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject **args, size_t _nargs, PyObject *kwargs) {
    Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs);
#if CYTHON_COMPILING_IN_CPYTHON
    if (nargs == 0 && kwargs == NULL) {
        if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS))
            return __Pyx_PyObject_CallMethO(func, NULL);
    }
    else if (nargs == 1 && kwargs == NULL) {
        if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O))
            return __Pyx_PyObject_CallMethO(func, args[0]);
    }
#endif
    #if PY_VERSION_HEX < 0x030800B1
    #if CYTHON_FAST_PYCCALL
    if (PyCFunction_Check(func)) {
        if (kwargs) {
            return _PyCFunction_FastCallDict(func, args, nargs, kwargs);
        } else {
            return _PyCFunction_FastCallKeywords(func, args, nargs, NULL);
        }
    }
    #if PY_VERSION_HEX >= 0x030700A1
    if (!kwargs && __Pyx_IS_TYPE(func, &PyMethodDescr_Type)) {
        return _PyMethodDescr_FastCallKeywords(func, args, nargs, NULL);
    }
    #endif
    #endif
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(func)) {
        return __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs);
    }
    #endif
    #endif
    if (kwargs == NULL) {
        #if CYTHON_VECTORCALL
        #if PY_VERSION_HEX < 0x03090000
        vectorcallfunc f = _PyVectorcall_Function(func);
        #else
        vectorcallfunc f = PyVectorcall_Function(func);
        #endif
        if (f) {
            return f(func, args, (size_t)nargs, NULL);
        }
        #elif defined(__Pyx_CyFunction_USED) && CYTHON_BACKPORT_VECTORCALL
        if (__Pyx_CyFunction_CheckExact(func)) {
            __pyx_vectorcallfunc f = __Pyx_CyFunction_func_vectorcall(func);
            if (f) return f(func, args, (size_t)nargs, NULL);
        }
        #endif
    }
    if (nargs == 0) {
        return __Pyx_PyObject_Call(func, __pyx_empty_tuple, kwargs);
    }
    #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API
    return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs);
    #else
    return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs);
    #endif
}

/* 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);
}

/* PyObjectCallOneArg */
static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
    PyObject *args[2] = {NULL, arg};
    return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
}

/* GetTopmostException */
#if CYTHON_USE_EXC_INFO_STACK && CYTHON_FAST_THREAD_STATE
static _PyErr_StackItem *
__Pyx_PyErr_GetTopmostException(PyThreadState *tstate)
{
    _PyErr_StackItem *exc_info = tstate->exc_info;
    while ((exc_info->exc_value == NULL || exc_info->exc_value == 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 && PY_VERSION_HEX >= 0x030B00a4
    _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
    PyObject *exc_value = exc_info->exc_value;
    if (exc_value == NULL || exc_value == Py_None) {
        *value = NULL;
        *type = NULL;
        *tb = NULL;
    } else {
        *value = exc_value;
        Py_INCREF(*value);
        *type = (PyObject*) Py_TYPE(exc_value);
        Py_INCREF(*type);
        *tb = PyException_GetTraceback(exc_value);
    }
  #elif 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;
    Py_XINCREF(*type);
    Py_XINCREF(*value);
    Py_XINCREF(*tb);
  #else
    *type = tstate->exc_type;
    *value = tstate->exc_value;
    *tb = tstate->exc_traceback;
    Py_XINCREF(*type);
    Py_XINCREF(*value);
    Py_XINCREF(*tb);
  #endif
}
static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) {
  #if CYTHON_USE_EXC_INFO_STACK && PY_VERSION_HEX >= 0x030B00a4
    _PyErr_StackItem *exc_info = tstate->exc_info;
    PyObject *tmp_value = exc_info->exc_value;
    exc_info->exc_value = value;
    Py_XDECREF(tmp_value);
    Py_XDECREF(type);
    Py_XDECREF(tb);
  #else
    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
}
#endif

/* 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 = NULL, *local_value, *local_tb = NULL;
#if CYTHON_FAST_THREAD_STATE
    PyObject *tmp_type, *tmp_value, *tmp_tb;
  #if PY_VERSION_HEX >= 0x030C00A6
    local_value = tstate->current_exception;
    tstate->current_exception = 0;
    if (likely(local_value)) {
        local_type = (PyObject*) Py_TYPE(local_value);
        Py_INCREF(local_type);
        local_tb = PyException_GetTraceback(local_value);
    }
  #else
    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;
  #endif
#else
    PyErr_Fetch(&local_type, &local_value, &local_tb);
#endif
    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
#if CYTHON_FAST_THREAD_STATE && PY_VERSION_HEX >= 0x030C00A6
    if (unlikely(tstate->current_exception))
#elif 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;
      #if PY_VERSION_HEX >= 0x030B00a4
        tmp_value = exc_info->exc_value;
        exc_info->exc_value = local_value;
        tmp_type = NULL;
        tmp_tb = NULL;
        Py_XDECREF(local_type);
        Py_XDECREF(local_tb);
      #else
        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;
      #endif
    }
    #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 && PY_VERSION_HEX >= 0x030B00a4
    _PyErr_StackItem *exc_info = tstate->exc_info;
    tmp_value = exc_info->exc_value;
    exc_info->exc_value = *value;
    if (tmp_value == NULL || tmp_value == Py_None) {
        Py_XDECREF(tmp_value);
        tmp_value = NULL;
        tmp_type = NULL;
        tmp_tb = NULL;
    } else {
        tmp_type = (PyObject*) Py_TYPE(tmp_value);
        Py_INCREF(tmp_type);
        #if CYTHON_COMPILING_IN_CPYTHON
        tmp_tb = ((PyBaseExceptionObject*) tmp_value)->traceback;
        Py_XINCREF(tmp_tb);
        #else
        tmp_tb = PyException_GetTraceback(tmp_value);
        #endif
    }
  #elif 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

/* PyObjectLookupSpecial */
#if CYTHON_USE_PYTYPE_LOOKUP && CYTHON_USE_TYPE_SLOTS
static CYTHON_INLINE PyObject* __Pyx__PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name, int with_error) {
    PyObject *res;
    PyTypeObject *tp = Py_TYPE(obj);
#if PY_MAJOR_VERSION < 3
    if (unlikely(PyInstance_Check(obj)))
        return with_error ? __Pyx_PyObject_GetAttrStr(obj, attr_name) : __Pyx_PyObject_GetAttrStrNoError(obj, attr_name);
#endif
    res = _PyType_Lookup(tp, attr_name);
    if (likely(res)) {
        descrgetfunc f = Py_TYPE(res)->tp_descr_get;
        if (!f) {
            Py_INCREF(res);
        } else {
            res = f(res, obj, (PyObject *)tp);
        }
    } else if (with_error) {
        PyErr_SetObject(PyExc_AttributeError, attr_name);
    }
    return res;
}
#endif

/* RaiseUnboundLocalError */
static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
    PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
}

/* UnpackUnboundCMethod */
static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *args, PyObject *kwargs) {
    PyObject *result;
    PyObject *selfless_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args));
    if (unlikely(!selfless_args)) return NULL;
    result = PyObject_Call(method, selfless_args, kwargs);
    Py_DECREF(selfless_args);
    return result;
}
static PyMethodDef __Pyx_UnboundCMethod_Def = {
     "CythonUnboundCMethod",
     __PYX_REINTERPRET_FUNCION(PyCFunction, __Pyx_SelflessCall),
     METH_VARARGS | METH_KEYWORDS,
     NULL
};
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)))
    #else
    if (likely(!__Pyx_CyOrPyCFunction_Check(method)))
    #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);
    } else
#endif
#if CYTHON_COMPILING_IN_PYPY
#else
    if (PyCFunction_Check(method))
#endif
    {
        PyObject *self;
        int self_found;
#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY
        self = PyObject_GetAttrString(method, "__self__");
        if (!self) {
            PyErr_Clear();
        }
#else
        self = PyCFunction_GET_SELF(method);
#endif
        self_found = (self && self != Py_None);
#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY
        Py_XDECREF(self);
#endif
        if (self_found) {
            PyObject *unbound_method = PyCFunction_New(&__Pyx_UnboundCMethod_Def, method);
            if (unlikely(!unbound_method)) return -1;
            Py_DECREF(method);
            target->method = unbound_method;
        }
    }
    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);
            #endif
        } 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;
}

/* CallUnboundCMethod2 */
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030600B1
static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2) {
    if (likely(cfunc->func)) {
        PyObject *args[2] = {arg1, arg2};
        if (cfunc->flag == METH_FASTCALL) {
            #if PY_VERSION_HEX >= 0x030700A0
            return (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)cfunc->func)(self, args, 2);
            #else
            return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, 2, NULL);
            #endif
        }
        #if PY_VERSION_HEX >= 0x030700A0
        if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS))
            return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, 2, NULL);
        #endif
    }
    return __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2);
}
#endif
static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2){
    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(2);
        if (unlikely(!args)) goto bad;
        Py_INCREF(arg1);
        PyTuple_SET_ITEM(args, 0, arg1);
        Py_INCREF(arg2);
        PyTuple_SET_ITEM(args, 1, arg2);
        if (cfunc->flag & METH_KEYWORDS)
            result = (*(PyCFunctionWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, NULL);
        else
            result = (*cfunc->func)(self, args);
    } else {
        args = PyTuple_New(3);
        if (unlikely(!args)) goto bad;
        Py_INCREF(self);
        PyTuple_SET_ITEM(args, 0, self);
        Py_INCREF(arg1);
        PyTuple_SET_ITEM(args, 1, arg1);
        Py_INCREF(arg2);
        PyTuple_SET_ITEM(args, 2, arg2);
        result = __Pyx_PyObject_Call(cfunc->method, args, NULL);
    }
#else
    args = PyTuple_Pack(3, self, arg1, arg2);
    if (unlikely(!args)) goto bad;
    result = __Pyx_PyObject_Call(cfunc->method, args, NULL);
#endif
bad:
    Py_XDECREF(args);
    return result;
}

/* dict_getitem_default */
static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value) {
    PyObject* value;
#if PY_MAJOR_VERSION >= 3 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000)
    value = PyDict_GetItemWithError(d, key);
    if (unlikely(!value)) {
        if (unlikely(PyErr_Occurred()))
            return NULL;
        value = default_value;
    }
    Py_INCREF(value);
    if ((1));
#else
    if (PyString_CheckExact(key) || PyUnicode_CheckExact(key) || PyInt_CheckExact(key)) {
        value = PyDict_GetItem(d, key);
        if (unlikely(!value)) {
            value = default_value;
        }
        Py_INCREF(value);
    }
#endif
    else {
        if (default_value == Py_None)
            value = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PyDict_Type_get, d, key);
        else
            value = __Pyx_CallUnboundCMethod2(&__pyx_umethod_PyDict_Type_get, d, key, default_value);
    }
    return value;
}

/* JoinPyUnicode */
static PyObject* __Pyx_PyUnicode_Join(PyObject* value_tuple, Py_ssize_t value_count, Py_ssize_t result_ulength,
                                      Py_UCS4 max_char) {
#if CYTHON_USE_UNICODE_INTERNALS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    PyObject *result_uval;
    int result_ukind, kind_shift;
    Py_ssize_t i, char_pos;
    void *result_udata;
    CYTHON_MAYBE_UNUSED_VAR(max_char);
#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;
    kind_shift = (result_ukind == PyUnicode_4BYTE_KIND) ? 2 : result_ukind - 1;
    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);
    kind_shift = (result_ukind == 4) ? 2 : result_ukind - 1;
    result_udata = PyUnicode_AS_UNICODE(result_uval);
#endif
    assert(kind_shift == 2 || kind_shift == 1 || kind_shift == 0);
    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((PY_SSIZE_T_MAX >> kind_shift) - ulength < char_pos))
            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 << kind_shift), udata, (size_t) (ulength << kind_shift));
        } else {
            #if PY_VERSION_HEX >= 0x030d0000
            if (unlikely(PyUnicode_CopyCharacters(result_uval, char_pos, uval, 0, ulength) < 0)) goto bad;
            #elif 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
    CYTHON_UNUSED_VAR(max_char);
    CYTHON_UNUSED_VAR(result_ulength);
    CYTHON_UNUSED_VAR(value_count);
    return PyUnicode_Join(__pyx_empty_unicode, value_tuple);
#endif
}

/* 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_FromSsize_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_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));
    assert(!last_one_off || *dpos == '0');
    dpos += last_one_off;
    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);
}

/* DictGetItem */
#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
    PyObject *value;
    value = PyDict_GetItemWithError(d, key);
    if (unlikely(!value)) {
        if (!PyErr_Occurred()) {
            if (unlikely(PyTuple_Check(key))) {
                PyObject* args = PyTuple_Pack(1, key);
                if (likely(args)) {
                    PyErr_SetObject(PyExc_KeyError, args);
                    Py_DECREF(args);
                }
            } else {
                PyErr_SetObject(PyExc_KeyError, key);
            }
        }
        return NULL;
    }
    Py_INCREF(value);
    return value;
}
#endif

/* RaiseUnexpectedTypeError */
static int
__Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj)
{
    __Pyx_TypeName obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj));
    PyErr_Format(PyExc_TypeError, "Expected %s, got " __Pyx_FMT_TYPENAME,
                 expected, obj_type_name);
    __Pyx_DECREF_TypeName(obj_type_name);
    return 0;
}

/* PyIntBinop */
#if !CYTHON_COMPILING_IN_PYPY
static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) {
    CYTHON_MAYBE_UNUSED_VAR(intval);
    CYTHON_MAYBE_UNUSED_VAR(inplace);
    CYTHON_UNUSED_VAR(zerodivision_check);
    #if PY_MAJOR_VERSION < 3
    if (likely(PyInt_CheckExact(op1))) {
        const long b = intval;
        long x;
        long a = PyInt_AS_LONG(op1);
        
            x = (long)((unsigned long)a + (unsigned long)b);
            if (likely((x^a) >= 0 || (x^b) >= 0))
                return PyInt_FromLong(x);
            return PyLong_Type.tp_as_number->nb_add(op1, op2);
    }
    #endif
    #if CYTHON_USE_PYLONG_INTERNALS
    if (likely(PyLong_CheckExact(op1))) {
        const long b = intval;
        long a, x;
#ifdef HAVE_LONG_LONG
        const PY_LONG_LONG llb = intval;
        PY_LONG_LONG lla, llx;
#endif
        if (unlikely(__Pyx_PyLong_IsZero(op1))) {
            return __Pyx_NewRef(op2);
        }
        if (likely(__Pyx_PyLong_IsCompact(op1))) {
            a = __Pyx_PyLong_CompactValue(op1);
        } else {
            const digit* digits = __Pyx_PyLong_Digits(op1);
            const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1);
            switch (size) {
                case -2:
                    if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
                        a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) {
                        lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case 2:
                    if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
                        a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) {
                        lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case -3:
                    if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
                        a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) {
                        lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case 3:
                    if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
                        a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) {
                        lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case -4:
                    if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
                        a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) {
                        lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case 4:
                    if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
                        a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) {
                        lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                default: return PyLong_Type.tp_as_number->nb_add(op1, op2);
            }
        }
                x = a + b;
            return PyLong_FromLong(x);
#ifdef HAVE_LONG_LONG
        long_long:
                llx = lla + llb;
            return PyLong_FromLongLong(llx);
#endif
        
        
    }
    #endif
    if (PyFloat_CheckExact(op1)) {
        const long b = intval;
#if CYTHON_COMPILING_IN_LIMITED_API
        double a = __pyx_PyFloat_AsDouble(op1);
#else
        double a = PyFloat_AS_DOUBLE(op1);
#endif
            double result;
            
            PyFPE_START_PROTECT("add", return NULL)
            result = ((double)a) + (double)b;
            PyFPE_END_PROTECT(result)
            return PyFloat_FromDouble(result);
    }
    return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2);
}
#endif

/* Import */
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
    PyObject *module = 0;
    PyObject *empty_dict = 0;
    PyObject *empty_list = 0;
    #if PY_MAJOR_VERSION < 3
    PyObject *py_import;
    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
    if (unlikely(!py_import))
        goto bad;
    if (!from_list) {
        empty_list = PyList_New(0);
        if (unlikely(!empty_list))
            goto bad;
        from_list = empty_list;
    }
    #endif
    empty_dict = PyDict_New();
    if (unlikely(!empty_dict))
        goto bad;
    {
        #if PY_MAJOR_VERSION >= 3
        if (level == -1) {
            if (strchr(__Pyx_MODULE_NAME, '.') != NULL) {
                module = PyImport_ImportModuleLevelObject(
                    name, __pyx_d, empty_dict, from_list, 1);
                if (unlikely(!module)) {
                    if (unlikely(!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 (unlikely(!py_level))
                goto bad;
            module = PyObject_CallFunctionObjArgs(py_import,
                name, __pyx_d, empty_dict, from_list, py_level, (PyObject *)NULL);
            Py_DECREF(py_level);
            #else
            module = PyImport_ImportModuleLevelObject(
                name, __pyx_d, empty_dict, from_list, level);
            #endif
        }
    }
bad:
    Py_XDECREF(empty_dict);
    Py_XDECREF(empty_list);
    #if PY_MAJOR_VERSION < 3
    Py_XDECREF(py_import);
    #endif
    return module;
}

/* ImportDottedModule */
#if PY_MAJOR_VERSION >= 3
static PyObject *__Pyx__ImportDottedModule_Error(PyObject *name, PyObject *parts_tuple, Py_ssize_t count) {
    PyObject *partial_name = NULL, *slice = NULL, *sep = NULL;
    if (unlikely(PyErr_Occurred())) {
        PyErr_Clear();
    }
    if (likely(PyTuple_GET_SIZE(parts_tuple) == count)) {
        partial_name = name;
    } else {
        slice = PySequence_GetSlice(parts_tuple, 0, count);
        if (unlikely(!slice))
            goto bad;
        sep = PyUnicode_FromStringAndSize(".", 1);
        if (unlikely(!sep))
            goto bad;
        partial_name = PyUnicode_Join(sep, slice);
    }
    PyErr_Format(
#if PY_MAJOR_VERSION < 3
        PyExc_ImportError,
        "No module named '%s'", PyString_AS_STRING(partial_name));
#else
#if PY_VERSION_HEX >= 0x030600B1
        PyExc_ModuleNotFoundError,
#else
        PyExc_ImportError,
#endif
        "No module named '%U'", partial_name);
#endif
bad:
    Py_XDECREF(sep);
    Py_XDECREF(slice);
    Py_XDECREF(partial_name);
    return NULL;
}
#endif
#if PY_MAJOR_VERSION >= 3
static PyObject *__Pyx__ImportDottedModule_Lookup(PyObject *name) {
    PyObject *imported_module;
#if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM  < 0x07030400)
    PyObject *modules = PyImport_GetModuleDict();
    if (unlikely(!modules))
        return NULL;
    imported_module = __Pyx_PyDict_GetItemStr(modules, name);
    Py_XINCREF(imported_module);
#else
    imported_module = PyImport_GetModule(name);
#endif
    return imported_module;
}
#endif
#if PY_MAJOR_VERSION >= 3
static PyObject *__Pyx_ImportDottedModule_WalkParts(PyObject *module, PyObject *name, PyObject *parts_tuple) {
    Py_ssize_t i, nparts;
    nparts = PyTuple_GET_SIZE(parts_tuple);
    for (i=1; i < nparts && module; i++) {
        PyObject *part, *submodule;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        part = PyTuple_GET_ITEM(parts_tuple, i);
#else
        part = PySequence_ITEM(parts_tuple, i);
#endif
        submodule = __Pyx_PyObject_GetAttrStrNoError(module, part);
#if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS)
        Py_DECREF(part);
#endif
        Py_DECREF(module);
        module = submodule;
    }
    if (unlikely(!module)) {
        return __Pyx__ImportDottedModule_Error(name, parts_tuple, i);
    }
    return module;
}
#endif
static PyObject *__Pyx__ImportDottedModule(PyObject *name, PyObject *parts_tuple) {
#if PY_MAJOR_VERSION < 3
    PyObject *module, *from_list, *star = __pyx_n_s__9;
    CYTHON_UNUSED_VAR(parts_tuple);
    from_list = PyList_New(1);
    if (unlikely(!from_list))
        return NULL;
    Py_INCREF(star);
    PyList_SET_ITEM(from_list, 0, star);
    module = __Pyx_Import(name, from_list, 0);
    Py_DECREF(from_list);
    return module;
#else
    PyObject *imported_module;
    PyObject *module = __Pyx_Import(name, NULL, 0);
    if (!parts_tuple || unlikely(!module))
        return module;
    imported_module = __Pyx__ImportDottedModule_Lookup(name);
    if (likely(imported_module)) {
        Py_DECREF(module);
        return imported_module;
    }
    PyErr_Clear();
    return __Pyx_ImportDottedModule_WalkParts(module, name, parts_tuple);
#endif
}
static PyObject *__Pyx_ImportDottedModule(PyObject *name, PyObject *parts_tuple) {
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030400B1
    PyObject *module = __Pyx__ImportDottedModule_Lookup(name);
    if (likely(module)) {
        PyObject *spec = __Pyx_PyObject_GetAttrStrNoError(module, __pyx_n_s_spec);
        if (likely(spec)) {
            PyObject *unsafe = __Pyx_PyObject_GetAttrStrNoError(spec, __pyx_n_s_initializing);
            if (likely(!unsafe || !__Pyx_PyObject_IsTrue(unsafe))) {
                Py_DECREF(spec);
                spec = NULL;
            }
            Py_XDECREF(unsafe);
        }
        if (likely(!spec)) {
            PyErr_Clear();
            return module;
        }
        Py_DECREF(spec);
        Py_DECREF(module);
    } else if (PyErr_Occurred()) {
        PyErr_Clear();
    }
#endif
    return __Pyx__ImportDottedModule(name, parts_tuple);
}

/* PyObjectCall2Args */
static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) {
    PyObject *args[3] = {NULL, arg1, arg2};
    return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
}

/* 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
    __Pyx_TypeName type_name;
    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 defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR
        if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR))
#elif PY_MAJOR_VERSION >= 3
        #ifdef __Pyx_CyFunction_USED
        if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr)))
        #else
        if (likely(PyFunction_Check(descr) || __Pyx_IS_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 (likely(descr != NULL)) {
        *method = descr;
        return 0;
    }
    type_name = __Pyx_PyType_GetName(tp);
    PyErr_Format(PyExc_AttributeError,
#if PY_MAJOR_VERSION >= 3
                 "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'",
                 type_name, name);
#else
                 "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'",
                 type_name, PyString_AS_STRING(name));
#endif
    __Pyx_DECREF_TypeName(type_name);
    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;
}

/* PyObjectCallMethod1 */
#if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2)
static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
    PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
    Py_DECREF(method);
    return result;
}
#endif
static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
#if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C00A2
    PyObject *args[2] = {obj, arg};
    (void) __Pyx_PyObject_GetMethod;
    (void) __Pyx_PyObject_CallOneArg;
    (void) __Pyx_PyObject_Call2Args;
    return PyObject_VectorcallMethod(method_name, args, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
#else
    PyObject *method = NULL, *result;
    int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
    if (likely(is_method)) {
        result = __Pyx_PyObject_Call2Args(method, obj, arg);
        Py_DECREF(method);
        return result;
    }
    if (unlikely(!method)) return NULL;
    return __Pyx__PyObject_CallMethod1(method, arg);
#endif
}

/* append */
static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
    if (likely(PyList_CheckExact(L))) {
        if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
    } else {
        PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x);
        if (unlikely(!retval))
            return -1;
        Py_DECREF(retval);
    }
    return 0;
}

/* PyIntBinop */
#if !CYTHON_COMPILING_IN_PYPY
static PyObject* __Pyx_PyInt_SubtractObjC(PyObject *op1, PyObject *op2, long intval, int inplace, int zerodivision_check) {
    CYTHON_MAYBE_UNUSED_VAR(intval);
    CYTHON_MAYBE_UNUSED_VAR(inplace);
    CYTHON_UNUSED_VAR(zerodivision_check);
    #if PY_MAJOR_VERSION < 3
    if (likely(PyInt_CheckExact(op1))) {
        const long b = intval;
        long x;
        long a = PyInt_AS_LONG(op1);
        
            x = (long)((unsigned long)a - (unsigned long)b);
            if (likely((x^a) >= 0 || (x^~b) >= 0))
                return PyInt_FromLong(x);
            return PyLong_Type.tp_as_number->nb_subtract(op1, op2);
    }
    #endif
    #if CYTHON_USE_PYLONG_INTERNALS
    if (likely(PyLong_CheckExact(op1))) {
        const long b = intval;
        long a, x;
#ifdef HAVE_LONG_LONG
        const PY_LONG_LONG llb = intval;
        PY_LONG_LONG lla, llx;
#endif
        if (unlikely(__Pyx_PyLong_IsZero(op1))) {
            return PyLong_FromLong(-intval);
        }
        if (likely(__Pyx_PyLong_IsCompact(op1))) {
            a = __Pyx_PyLong_CompactValue(op1);
        } else {
            const digit* digits = __Pyx_PyLong_Digits(op1);
            const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(op1);
            switch (size) {
                case -2:
                    if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
                        a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) {
                        lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case 2:
                    if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
                        a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) {
                        lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case -3:
                    if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
                        a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) {
                        lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case 3:
                    if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
                        a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) {
                        lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case -4:
                    if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
                        a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) {
                        lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                case 4:
                    if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
                        a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
                        break;
                    #ifdef HAVE_LONG_LONG
                    } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) {
                        lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0]));
                        goto long_long;
                    #endif
                    }
                    CYTHON_FALLTHROUGH;
                default: return PyLong_Type.tp_as_number->nb_subtract(op1, op2);
            }
        }
                x = a - b;
            return PyLong_FromLong(x);
#ifdef HAVE_LONG_LONG
        long_long:
                llx = lla - llb;
            return PyLong_FromLongLong(llx);
#endif
        
        
    }
    #endif
    if (PyFloat_CheckExact(op1)) {
        const long b = intval;
#if CYTHON_COMPILING_IN_LIMITED_API
        double a = __pyx_PyFloat_AsDouble(op1);
#else
        double a = PyFloat_AS_DOUBLE(op1);
#endif
            double result;
            
            PyFPE_START_PROTECT("subtract", return NULL)
            result = ((double)a) - (double)b;
            PyFPE_END_PROTECT(result)
            return PyFloat_FromDouble(result);
    }
    return (inplace ? PyNumber_InPlaceSubtract : PyNumber_Subtract)(op1, op2);
}
#endif

/* UnicodeConcatInPlace */
# if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
static int
__Pyx_unicode_modifiable(PyObject *unicode)
{
    if (Py_REFCNT(unicode) != 1)
        return 0;
    if (!PyUnicode_CheckExact(unicode))
        return 0;
    if (PyUnicode_CHECK_INTERNED(unicode))
        return 0;
    return 1;
}
static CYTHON_INLINE PyObject *__Pyx_PyUnicode_ConcatInPlaceImpl(PyObject **p_left, PyObject *right
        #if CYTHON_REFNANNY
        , void* __pyx_refnanny
        #endif
    ) {
    PyObject *left = *p_left;
    Py_ssize_t left_len, right_len, new_len;
    if (unlikely(__Pyx_PyUnicode_READY(left) == -1))
        return NULL;
    if (unlikely(__Pyx_PyUnicode_READY(right) == -1))
        return NULL;
    left_len = PyUnicode_GET_LENGTH(left);
    if (left_len == 0) {
        Py_INCREF(right);
        return right;
    }
    right_len = PyUnicode_GET_LENGTH(right);
    if (right_len == 0) {
        Py_INCREF(left);
        return left;
    }
    if (unlikely(left_len > PY_SSIZE_T_MAX - right_len)) {
        PyErr_SetString(PyExc_OverflowError,
                        "strings are too large to concat");
        return NULL;
    }
    new_len = left_len + right_len;
    if (__Pyx_unicode_modifiable(left)
            && PyUnicode_CheckExact(right)
            && PyUnicode_KIND(right) <= PyUnicode_KIND(left)
            && !(PyUnicode_IS_ASCII(left) && !PyUnicode_IS_ASCII(right))) {
        int ret;
        __Pyx_GIVEREF(*p_left);
        ret = PyUnicode_Resize(p_left, new_len);
        __Pyx_GOTREF(*p_left);
        if (unlikely(ret != 0))
            return NULL;
        #if PY_VERSION_HEX >= 0x030d0000
        if (unlikely(PyUnicode_CopyCharacters(*p_left, left_len, right, 0, right_len) < 0)) return NULL;
        #else
        _PyUnicode_FastCopyCharacters(*p_left, left_len, right, 0, right_len);
        #endif
        __Pyx_INCREF(*p_left);
        __Pyx_GIVEREF(*p_left);
        return *p_left;
    } else {
        return __Pyx_PyUnicode_Concat(left, right);
    }
  }
#endif

/* SliceObject */
static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj,
        Py_ssize_t cstart, Py_ssize_t cstop,
        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
        int has_cstart, int has_cstop, int wraparound) {
    __Pyx_TypeName obj_type_name;
#if CYTHON_USE_TYPE_SLOTS
    PyMappingMethods* mp;
#if PY_MAJOR_VERSION < 3
    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
    if (likely(ms && ms->sq_slice)) {
        if (!has_cstart) {
            if (_py_start && (*_py_start != Py_None)) {
                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
            } else
                cstart = 0;
        }
        if (!has_cstop) {
            if (_py_stop && (*_py_stop != Py_None)) {
                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
            } else
                cstop = PY_SSIZE_T_MAX;
        }
        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
            Py_ssize_t l = ms->sq_length(obj);
            if (likely(l >= 0)) {
                if (cstop < 0) {
                    cstop += l;
                    if (cstop < 0) cstop = 0;
                }
                if (cstart < 0) {
                    cstart += l;
                    if (cstart < 0) cstart = 0;
                }
            } else {
                if (!PyErr_ExceptionMatches(PyExc_OverflowError))
                    goto bad;
                PyErr_Clear();
            }
        }
        return ms->sq_slice(obj, cstart, cstop);
    }
#else
    CYTHON_UNUSED_VAR(wraparound);
#endif
    mp = Py_TYPE(obj)->tp_as_mapping;
    if (likely(mp && mp->mp_subscript))
#else
    CYTHON_UNUSED_VAR(wraparound);
#endif
    {
        PyObject* result;
        PyObject *py_slice, *py_start, *py_stop;
        if (_py_slice) {
            py_slice = *_py_slice;
        } else {
            PyObject* owned_start = NULL;
            PyObject* owned_stop = NULL;
            if (_py_start) {
                py_start = *_py_start;
            } else {
                if (has_cstart) {
                    owned_start = py_start = PyInt_FromSsize_t(cstart);
                    if (unlikely(!py_start)) goto bad;
                } else
                    py_start = Py_None;
            }
            if (_py_stop) {
                py_stop = *_py_stop;
            } else {
                if (has_cstop) {
                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
                    if (unlikely(!py_stop)) {
                        Py_XDECREF(owned_start);
                        goto bad;
                    }
                } else
                    py_stop = Py_None;
            }
            py_slice = PySlice_New(py_start, py_stop, Py_None);
            Py_XDECREF(owned_start);
            Py_XDECREF(owned_stop);
            if (unlikely(!py_slice)) goto bad;
        }
#if CYTHON_USE_TYPE_SLOTS
        result = mp->mp_subscript(obj, py_slice);
#else
        result = PyObject_GetItem(obj, py_slice);
#endif
        if (!_py_slice) {
            Py_DECREF(py_slice);
        }
        return result;
    }
    obj_type_name = __Pyx_PyType_GetName(Py_TYPE(obj));
    PyErr_Format(PyExc_TypeError,
        "'" __Pyx_FMT_TYPENAME "' object is unsliceable", obj_type_name);
    __Pyx_DECREF_TypeName(obj_type_name);
bad:
    return NULL;
}

/* 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);
}

/* 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");
}

/* IterFinish */
static CYTHON_INLINE int __Pyx_IterFinish(void) {
    PyObject* exc_type;
    __Pyx_PyThreadState_declare
    __Pyx_PyThreadState_assign
    exc_type = __Pyx_PyErr_CurrentExceptionType();
    if (unlikely(exc_type)) {
        if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)))
            return -1;
        __Pyx_PyErr_Clear();
        return 0;
    }
    return 0;
}

/* UnpackItemEndCheck */
static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
    if (unlikely(retval)) {
        Py_DECREF(retval);
        __Pyx_RaiseTooManyValuesError(expected);
        return -1;
    }
    return __Pyx_IterFinish();
}

/* RaiseClosureNameError */
static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
    PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
}

/* CallUnboundCMethod0 */
static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) {
    PyObject *args, *result = NULL;
    if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL;
#if CYTHON_ASSUME_SAFE_MACROS
    args = PyTuple_New(1);
    if (unlikely(!args)) goto bad;
    Py_INCREF(self);
    PyTuple_SET_ITEM(args, 0, self);
#else
    args = PyTuple_Pack(1, self);
    if (unlikely(!args)) goto bad;
#endif
    result = __Pyx_PyObject_Call(cfunc->method, args, NULL);
    Py_DECREF(args);
bad:
    return result;
}

/* pep479 */
static void __Pyx_Generator_Replace_StopIteration(int in_async_gen) {
    PyObject *exc, *val, *tb, *cur_exc;
    __Pyx_PyThreadState_declare
    #ifdef __Pyx_StopAsyncIteration_USED
    int is_async_stopiteration = 0;
    #endif
    CYTHON_MAYBE_UNUSED_VAR(in_async_gen);
    cur_exc = PyErr_Occurred();
    if (likely(!__Pyx_PyErr_GivenExceptionMatches(cur_exc, PyExc_StopIteration))) {
        #ifdef __Pyx_StopAsyncIteration_USED
        if (in_async_gen && unlikely(__Pyx_PyErr_GivenExceptionMatches(cur_exc, __Pyx_PyExc_StopAsyncIteration))) {
            is_async_stopiteration = 1;
        } else
        #endif
            return;
    }
    __Pyx_PyThreadState_assign
    __Pyx_GetException(&exc, &val, &tb);
    Py_XDECREF(exc);
    Py_XDECREF(val);
    Py_XDECREF(tb);
    PyErr_SetString(PyExc_RuntimeError,
        #ifdef __Pyx_StopAsyncIteration_USED
        is_async_stopiteration ? "async generator raised StopAsyncIteration" :
        in_async_gen ? "async generator raised StopIteration" :
        #endif
        "generator raised StopIteration");
}

/* GetItemInt */
static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
    PyObject *r;
    if (unlikely(!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 {
        PyMappingMethods *mm = Py_TYPE(o)->tp_as_mapping;
        PySequenceMethods *sm = Py_TYPE(o)->tp_as_sequence;
        if (mm && mm->mp_subscript) {
            PyObject *r, *key = PyInt_FromSsize_t(i);
            if (unlikely(!key)) return NULL;
            r = mm->mp_subscript(o, key);
            Py_DECREF(key);
            return r;
        }
        if (likely(sm && sm->sq_item)) {
            if (wraparound && unlikely(i < 0) && likely(sm->sq_length)) {
                Py_ssize_t l = sm->sq_length(o);
                if (likely(l >= 0)) {
                    i += l;
                } else {
                    if (!PyErr_ExceptionMatches(PyExc_OverflowError))
                        return NULL;
                    PyErr_Clear();
                }
            }
            return sm->sq_item(o, i);
        }
    }
#else
    if (is_list || !PyMapping_Check(o)) {
        return PySequence_GetItem(o, i);
    }
#endif
    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
}

/* PyObjectCallNoArg */
static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
    PyObject *arg[2] = {NULL, NULL};
    return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
}

/* 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;
}

/* 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 = __Pyx_PyObject_GetIterNextFunc(iter);
    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 */
#if CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
#include <string.h>
#endif
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;
}

/* PyIntCompare */
static CYTHON_INLINE int __Pyx_PyInt_BoolEqObjC(PyObject *op1, PyObject *op2, long intval, long inplace) {
    CYTHON_MAYBE_UNUSED_VAR(intval);
    CYTHON_UNUSED_VAR(inplace);
    if (op1 == op2) {
        return 1;
    }
    #if PY_MAJOR_VERSION < 3
    if (likely(PyInt_CheckExact(op1))) {
        const long b = intval;
        long a = PyInt_AS_LONG(op1);
        return (a == b);
    }
    #endif
    #if CYTHON_USE_PYLONG_INTERNALS
    if (likely(PyLong_CheckExact(op1))) {
        int unequal;
        unsigned long uintval;
        Py_ssize_t size = __Pyx_PyLong_DigitCount(op1);
        const digit* digits = __Pyx_PyLong_Digits(op1);
        if (intval == 0) {
            return (__Pyx_PyLong_IsZero(op1) == 1);
        } else if (intval < 0) {
            if (__Pyx_PyLong_IsNonNeg(op1))
                return 0;
            intval = -intval;
        } else {
            if (__Pyx_PyLong_IsNeg(op1))
                return 0;
        }
        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));
        return (unequal == 0);
    }
    #endif
    if (PyFloat_CheckExact(op1)) {
        const long b = intval;
#if CYTHON_COMPILING_IN_LIMITED_API
        double a = __pyx_PyFloat_AsDouble(op1);
#else
        double a = PyFloat_AS_DOUBLE(op1);
#endif
        return ((double)a == (double)b);
    }
    return __Pyx_PyObject_IsTrueAndDecref(
        PyObject_RichCompare(op1, op2, Py_EQ));
}

/* unicode_tailmatch */
static int __Pyx_PyUnicode_TailmatchTuple(PyObject* s, PyObject* substrings,
                                          Py_ssize_t start, Py_ssize_t end, int direction) {
    Py_ssize_t i, count = PyTuple_GET_SIZE(substrings);
    for (i = 0; i < count; i++) {
        Py_ssize_t result;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        result = PyUnicode_Tailmatch(s, PyTuple_GET_ITEM(substrings, i),
                                     start, end, direction);
#else
        PyObject* sub = PySequence_ITEM(substrings, i);
        if (unlikely(!sub)) return -1;
        result = PyUnicode_Tailmatch(s, sub, start, end, direction);
        Py_DECREF(sub);
#endif
        if (result) {
            return (int) result;
        }
    }
    return 0;
}
static int __Pyx_PyUnicode_Tailmatch(PyObject* s, PyObject* substr,
                                     Py_ssize_t start, Py_ssize_t end, int direction) {
    if (unlikely(PyTuple_Check(substr))) {
        return __Pyx_PyUnicode_TailmatchTuple(s, substr, start, end, direction);
    }
    return (int) PyUnicode_Tailmatch(s, substr, start, end, direction);
}

/* FixUpExtensionType */
#if CYTHON_USE_TYPE_SPECS
static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) {
#if PY_VERSION_HEX > 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API
    CYTHON_UNUSED_VAR(spec);
    CYTHON_UNUSED_VAR(type);
#else
    const PyType_Slot *slot = spec->slots;
    while (slot && slot->slot && slot->slot != Py_tp_members)
        slot++;
    if (slot && slot->slot == Py_tp_members) {
        int changed = 0;
#if !(PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON)
        const
#endif
            PyMemberDef *memb = (PyMemberDef*) slot->pfunc;
        while (memb && memb->name) {
            if (memb->name[0] == '_' && memb->name[1] == '_') {
#if PY_VERSION_HEX < 0x030900b1
                if (strcmp(memb->name, "__weaklistoffset__") == 0) {
                    assert(memb->type == T_PYSSIZET);
                    assert(memb->flags == READONLY);
                    type->tp_weaklistoffset = memb->offset;
                    changed = 1;
                }
                else if (strcmp(memb->name, "__dictoffset__") == 0) {
                    assert(memb->type == T_PYSSIZET);
                    assert(memb->flags == READONLY);
                    type->tp_dictoffset = memb->offset;
                    changed = 1;
                }
#if CYTHON_METH_FASTCALL
                else if (strcmp(memb->name, "__vectorcalloffset__") == 0) {
                    assert(memb->type == T_PYSSIZET);
                    assert(memb->flags == READONLY);
#if PY_VERSION_HEX >= 0x030800b4
                    type->tp_vectorcall_offset = memb->offset;
#else
                    type->tp_print = (printfunc) memb->offset;
#endif
                    changed = 1;
                }
#endif
#else
                if ((0));
#endif
#if PY_VERSION_HEX <= 0x030900b1 && CYTHON_COMPILING_IN_CPYTHON
                else if (strcmp(memb->name, "__module__") == 0) {
                    PyObject *descr;
                    assert(memb->type == T_OBJECT);
                    assert(memb->flags == 0 || memb->flags == READONLY);
                    descr = PyDescr_NewMember(type, memb);
                    if (unlikely(!descr))
                        return -1;
                    if (unlikely(PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr) < 0)) {
                        Py_DECREF(descr);
                        return -1;
                    }
                    Py_DECREF(descr);
                    changed = 1;
                }
#endif
            }
            memb++;
        }
        if (changed)
            PyType_Modified(type);
    }
#endif
    return 0;
}
#endif

/* ValidateBasesTuple */
#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_USE_TYPE_SPECS
static int __Pyx_validate_bases_tuple(const char *type_name, Py_ssize_t dictoffset, PyObject *bases) {
    Py_ssize_t i, n;
#if CYTHON_ASSUME_SAFE_MACROS
    n = PyTuple_GET_SIZE(bases);
#else
    n = PyTuple_Size(bases);
    if (n < 0) return -1;
#endif
    for (i = 1; i < n; i++)
    {
#if CYTHON_AVOID_BORROWED_REFS
        PyObject *b0 = PySequence_GetItem(bases, i);
        if (!b0) return -1;
#elif CYTHON_ASSUME_SAFE_MACROS
        PyObject *b0 = PyTuple_GET_ITEM(bases, i);
#else
        PyObject *b0 = PyTuple_GetItem(bases, i);
        if (!b0) return -1;
#endif
        PyTypeObject *b;
#if PY_MAJOR_VERSION < 3
        if (PyClass_Check(b0))
        {
            PyErr_Format(PyExc_TypeError, "base class '%.200s' is an old-style class",
                         PyString_AS_STRING(((PyClassObject*)b0)->cl_name));
#if CYTHON_AVOID_BORROWED_REFS
            Py_DECREF(b0);
#endif
            return -1;
        }
#endif
        b = (PyTypeObject*) b0;
        if (!__Pyx_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE))
        {
            __Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
            PyErr_Format(PyExc_TypeError,
                "base class '" __Pyx_FMT_TYPENAME "' is not a heap type", b_name);
            __Pyx_DECREF_TypeName(b_name);
#if CYTHON_AVOID_BORROWED_REFS
            Py_DECREF(b0);
#endif
            return -1;
        }
        if (dictoffset == 0)
        {
            Py_ssize_t b_dictoffset = 0;
#if CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY
            b_dictoffset = b->tp_dictoffset;
#else
            PyObject *py_b_dictoffset = PyObject_GetAttrString((PyObject*)b, "__dictoffset__");
            if (!py_b_dictoffset) goto dictoffset_return;
            b_dictoffset = PyLong_AsSsize_t(py_b_dictoffset);
            Py_DECREF(py_b_dictoffset);
            if (b_dictoffset == -1 && PyErr_Occurred()) goto dictoffset_return;
#endif
            if (b_dictoffset) {
                {
                    __Pyx_TypeName b_name = __Pyx_PyType_GetName(b);
                    PyErr_Format(PyExc_TypeError,
                        "extension type '%.200s' has no __dict__ slot, "
                        "but base type '" __Pyx_FMT_TYPENAME "' has: "
                        "either add 'cdef dict __dict__' to the extension type "
                        "or add '__slots__ = [...]' to the base type",
                        type_name, b_name);
                    __Pyx_DECREF_TypeName(b_name);
                }
#if !(CYTHON_USE_TYPE_SLOTS || CYTHON_COMPILING_IN_PYPY)
              dictoffset_return:
#endif
#if CYTHON_AVOID_BORROWED_REFS
                Py_DECREF(b0);
#endif
                return -1;
            }
        }
#if CYTHON_AVOID_BORROWED_REFS
        Py_DECREF(b0);
#endif
    }
    return 0;
}
#endif

/* PyType_Ready */
static int __Pyx_PyType_Ready(PyTypeObject *t) {
#if CYTHON_USE_TYPE_SPECS || !(CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_LIMITED_API) || defined(PYSTON_MAJOR_VERSION)
    (void)__Pyx_PyObject_CallMethod0;
#if CYTHON_USE_TYPE_SPECS
    (void)__Pyx_validate_bases_tuple;
#endif
    return PyType_Ready(t);
#else
    int r;
    PyObject *bases = __Pyx_PyType_GetSlot(t, tp_bases, PyObject*);
    if (bases && unlikely(__Pyx_validate_bases_tuple(t->tp_name, t->tp_dictoffset, bases) == -1))
        return -1;
#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION)
    {
        int gc_was_enabled;
    #if PY_VERSION_HEX >= 0x030A00b1
        gc_was_enabled = PyGC_Disable();
        (void)__Pyx_PyObject_CallMethod0;
    #else
        PyObject *ret, *py_status;
        PyObject *gc = NULL;
        #if PY_VERSION_HEX >= 0x030700a1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM+0 >= 0x07030400)
        gc = PyImport_GetModule(__pyx_kp_u_gc);
        #endif
        if (unlikely(!gc)) gc = PyImport_Import(__pyx_kp_u_gc);
        if (unlikely(!gc)) return -1;
        py_status = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_isenabled);
        if (unlikely(!py_status)) {
            Py_DECREF(gc);
            return -1;
        }
        gc_was_enabled = __Pyx_PyObject_IsTrue(py_status);
        Py_DECREF(py_status);
        if (gc_was_enabled > 0) {
            ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_disable);
            if (unlikely(!ret)) {
                Py_DECREF(gc);
                return -1;
            }
            Py_DECREF(ret);
        } else if (unlikely(gc_was_enabled == -1)) {
            Py_DECREF(gc);
            return -1;
        }
    #endif
        t->tp_flags |= Py_TPFLAGS_HEAPTYPE;
#if PY_VERSION_HEX >= 0x030A0000
        t->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
#endif
#else
        (void)__Pyx_PyObject_CallMethod0;
#endif
    r = PyType_Ready(t);
#if PY_VERSION_HEX >= 0x03050000 && !defined(PYSTON_MAJOR_VERSION)
        t->tp_flags &= ~Py_TPFLAGS_HEAPTYPE;
    #if PY_VERSION_HEX >= 0x030A00b1
        if (gc_was_enabled)
            PyGC_Enable();
    #else
        if (gc_was_enabled) {
            PyObject *tp, *v, *tb;
            PyErr_Fetch(&tp, &v, &tb);
            ret = __Pyx_PyObject_CallMethod0(gc, __pyx_kp_u_enable);
            if (likely(ret || r == -1)) {
                Py_XDECREF(ret);
                PyErr_Restore(tp, v, tb);
            } else {
                Py_XDECREF(tp);
                Py_XDECREF(v);
                Py_XDECREF(tb);
                r = -1;
            }
        }
        Py_DECREF(gc);
    #endif
    }
#endif
    return r;
#endif
}

/* PyObject_GenericGetAttrNoDict */
#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000
static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) {
    __Pyx_TypeName type_name = __Pyx_PyType_GetName(tp);
    PyErr_Format(PyExc_AttributeError,
#if PY_MAJOR_VERSION >= 3
                 "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'",
                 type_name, attr_name);
#else
                 "'" __Pyx_FMT_TYPENAME "' object has no attribute '%.400s'",
                 type_name, PyString_AS_STRING(attr_name));
#endif
    __Pyx_DECREF_TypeName(type_name);
    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

/* ImportFrom */
static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
    PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
    if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
        const char* module_name_str = 0;
        PyObject* module_name = 0;
        PyObject* module_dot = 0;
        PyObject* full_name = 0;
        PyErr_Clear();
        module_name_str = PyModule_GetName(module);
        if (unlikely(!module_name_str)) { goto modbad; }
        module_name = PyUnicode_FromString(module_name_str);
        if (unlikely(!module_name)) { goto modbad; }
        module_dot = PyUnicode_Concat(module_name, __pyx_kp_u__29);
        if (unlikely(!module_dot)) { goto modbad; }
        full_name = PyUnicode_Concat(module_dot, name);
        if (unlikely(!full_name)) { goto modbad; }
        #if PY_VERSION_HEX < 0x030700A1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM  < 0x07030400)
        {
            PyObject *modules = PyImport_GetModuleDict();
            if (unlikely(!modules))
                goto modbad;
            value = PyObject_GetItem(modules, full_name);
        }
        #else
        value = PyImport_GetModule(full_name);
        #endif
      modbad:
        Py_XDECREF(full_name);
        Py_XDECREF(module_dot);
        Py_XDECREF(module_name);
    }
    if (unlikely(!value)) {
        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;
}

/* FetchSharedCythonModule */
static PyObject *__Pyx_FetchSharedCythonABIModule(void) {
    return __Pyx_PyImport_AddModuleRef((char*) __PYX_ABI_MODULE_NAME);
}

/* FetchCommonType */
static int __Pyx_VerifyCachedType(PyObject *cached_type,
                               const char *name,
                               Py_ssize_t basicsize,
                               Py_ssize_t expected_basicsize) {
    if (!PyType_Check(cached_type)) {
        PyErr_Format(PyExc_TypeError,
            "Shared Cython type %.200s is not a type object", name);
        return -1;
    }
    if (basicsize != expected_basicsize) {
        PyErr_Format(PyExc_TypeError,
            "Shared Cython type %.200s has the wrong size, try recompiling",
            name);
        return -1;
    }
    return 0;
}
#if !CYTHON_USE_TYPE_SPECS
static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
    PyObject* abi_module;
    const char* object_name;
    PyTypeObject *cached_type = NULL;
    abi_module = __Pyx_FetchSharedCythonABIModule();
    if (!abi_module) return NULL;
    object_name = strrchr(type->tp_name, '.');
    object_name = object_name ? object_name+1 : type->tp_name;
    cached_type = (PyTypeObject*) PyObject_GetAttrString(abi_module, object_name);
    if (cached_type) {
        if (__Pyx_VerifyCachedType(
              (PyObject *)cached_type,
              object_name,
              cached_type->tp_basicsize,
              type->tp_basicsize) < 0) {
            goto bad;
        }
        goto done;
    }
    if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
    PyErr_Clear();
    if (PyType_Ready(type) < 0) goto bad;
    if (PyObject_SetAttrString(abi_module, object_name, (PyObject *)type) < 0)
        goto bad;
    Py_INCREF(type);
    cached_type = type;
done:
    Py_DECREF(abi_module);
    return cached_type;
bad:
    Py_XDECREF(cached_type);
    cached_type = NULL;
    goto done;
}
#else
static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) {
    PyObject *abi_module, *cached_type = NULL;
    const char* object_name = strrchr(spec->name, '.');
    object_name = object_name ? object_name+1 : spec->name;
    abi_module = __Pyx_FetchSharedCythonABIModule();
    if (!abi_module) return NULL;
    cached_type = PyObject_GetAttrString(abi_module, object_name);
    if (cached_type) {
        Py_ssize_t basicsize;
#if CYTHON_COMPILING_IN_LIMITED_API
        PyObject *py_basicsize;
        py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__");
        if (unlikely(!py_basicsize)) goto bad;
        basicsize = PyLong_AsSsize_t(py_basicsize);
        Py_DECREF(py_basicsize);
        py_basicsize = 0;
        if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
#else
        basicsize = likely(PyType_Check(cached_type)) ? ((PyTypeObject*) cached_type)->tp_basicsize : -1;
#endif
        if (__Pyx_VerifyCachedType(
              cached_type,
              object_name,
              basicsize,
              spec->basicsize) < 0) {
            goto bad;
        }
        goto done;
    }
    if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
    PyErr_Clear();
    CYTHON_UNUSED_VAR(module);
    cached_type = __Pyx_PyType_FromModuleAndSpec(abi_module, spec, bases);
    if (unlikely(!cached_type)) goto bad;
    if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad;
    if (PyObject_SetAttrString(abi_module, object_name, cached_type) < 0) goto bad;
done:
    Py_DECREF(abi_module);
    assert(cached_type == NULL || PyType_Check(cached_type));
    return (PyTypeObject *) cached_type;
bad:
    Py_XDECREF(cached_type);
    cached_type = NULL;
    goto done;
}
#endif

/* PyVectorcallFastCallDict */
#if CYTHON_METH_FASTCALL
static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw)
{
    PyObject *res = NULL;
    PyObject *kwnames;
    PyObject **newargs;
    PyObject **kwvalues;
    Py_ssize_t i, pos;
    size_t j;
    PyObject *key, *value;
    unsigned long keys_are_strings;
    Py_ssize_t nkw = PyDict_GET_SIZE(kw);
    newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0]));
    if (unlikely(newargs == NULL)) {
        PyErr_NoMemory();
        return NULL;
    }
    for (j = 0; j < nargs; j++) newargs[j] = args[j];
    kwnames = PyTuple_New(nkw);
    if (unlikely(kwnames == NULL)) {
        PyMem_Free(newargs);
        return NULL;
    }
    kwvalues = newargs + nargs;
    pos = i = 0;
    keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS;
    while (PyDict_Next(kw, &pos, &key, &value)) {
        keys_are_strings &= Py_TYPE(key)->tp_flags;
        Py_INCREF(key);
        Py_INCREF(value);
        PyTuple_SET_ITEM(kwnames, i, key);
        kwvalues[i] = value;
        i++;
    }
    if (unlikely(!keys_are_strings)) {
        PyErr_SetString(PyExc_TypeError, "keywords must be strings");
        goto cleanup;
    }
    res = vc(func, newargs, nargs, kwnames);
cleanup:
    Py_DECREF(kwnames);
    for (i = 0; i < nkw; i++)
        Py_DECREF(kwvalues[i]);
    PyMem_Free(newargs);
    return res;
}
static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw)
{
    if (likely(kw == NULL) || PyDict_GET_SIZE(kw) == 0) {
        return vc(func, args, nargs, NULL);
    }
    return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw);
}
#endif

/* CythonFunctionShared */
#if CYTHON_COMPILING_IN_LIMITED_API
static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) {
    if (__Pyx_CyFunction_Check(func)) {
        return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc;
    } else if (PyCFunction_Check(func)) {
        return PyCFunction_GetFunction(func) == (PyCFunction) cfunc;
    }
    return 0;
}
#else
static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void *cfunc) {
    return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc;
}
#endif
static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) {
#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API
    __Pyx_Py_XDECREF_SET(
        __Pyx_CyFunction_GetClassObj(f),
            ((classobj) ? __Pyx_NewRef(classobj) : NULL));
#else
    __Pyx_Py_XDECREF_SET(
        ((PyCMethodObject *) (f))->mm_class,
        (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL));
#endif
}
static PyObject *
__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure)
{
    CYTHON_UNUSED_VAR(closure);
    if (unlikely(op->func_doc == NULL)) {
#if CYTHON_COMPILING_IN_LIMITED_API
        op->func_doc = PyObject_GetAttrString(op->func, "__doc__");
        if (unlikely(!op->func_doc)) return NULL;
#else
        if (((PyCFunctionObject*)op)->m_ml->ml_doc) {
#if PY_MAJOR_VERSION >= 3
            op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc);
#else
            op->func_doc = PyString_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc);
#endif
            if (unlikely(op->func_doc == NULL))
                return NULL;
        } else {
            Py_INCREF(Py_None);
            return Py_None;
        }
#endif
    }
    Py_INCREF(op->func_doc);
    return op->func_doc;
}
static int
__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context)
{
    CYTHON_UNUSED_VAR(context);
    if (value == NULL) {
        value = Py_None;
    }
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(op->func_doc, value);
    return 0;
}
static PyObject *
__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context)
{
    CYTHON_UNUSED_VAR(context);
    if (unlikely(op->func_name == NULL)) {
#if CYTHON_COMPILING_IN_LIMITED_API
        op->func_name = PyObject_GetAttrString(op->func, "__name__");
#elif PY_MAJOR_VERSION >= 3
        op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name);
#else
        op->func_name = PyString_InternFromString(((PyCFunctionObject*)op)->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, void *context)
{
    CYTHON_UNUSED_VAR(context);
#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;
    }
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(op->func_name, value);
    return 0;
}
static PyObject *
__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context)
{
    CYTHON_UNUSED_VAR(context);
    Py_INCREF(op->func_qualname);
    return op->func_qualname;
}
static int
__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context)
{
    CYTHON_UNUSED_VAR(context);
#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;
    }
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(op->func_qualname, value);
    return 0;
}
static PyObject *
__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context)
{
    CYTHON_UNUSED_VAR(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, void *context)
{
    CYTHON_UNUSED_VAR(context);
    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;
    }
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(op->func_dict, value);
    return 0;
}
static PyObject *
__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context)
{
    CYTHON_UNUSED_VAR(context);
    Py_INCREF(op->func_globals);
    return op->func_globals;
}
static PyObject *
__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context)
{
    CYTHON_UNUSED_VAR(op);
    CYTHON_UNUSED_VAR(context);
    Py_INCREF(Py_None);
    return Py_None;
}
static PyObject *
__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context)
{
    PyObject* result = (op->func_code) ? op->func_code : Py_None;
    CYTHON_UNUSED_VAR(context);
    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 = __Pyx_PySequence_ITEM(res, 0);
    if (unlikely(!op->defaults_tuple)) result = -1;
    else {
        op->defaults_kwdict = __Pyx_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, void *context) {
    CYTHON_UNUSED_VAR(context);
    if (!value) {
        value = Py_None;
    } else if (unlikely(value != Py_None && !PyTuple_Check(value))) {
        PyErr_SetString(PyExc_TypeError,
                        "__defaults__ must be set to a tuple object");
        return -1;
    }
    PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not "
                 "currently affect the values used in function calls", 1);
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(op->defaults_tuple, value);
    return 0;
}
static PyObject *
__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) {
    PyObject* result = op->defaults_tuple;
    CYTHON_UNUSED_VAR(context);
    if (unlikely(!result)) {
        if (op->defaults_getter) {
            if (unlikely(__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, void *context) {
    CYTHON_UNUSED_VAR(context);
    if (!value) {
        value = Py_None;
    } else if (unlikely(value != Py_None && !PyDict_Check(value))) {
        PyErr_SetString(PyExc_TypeError,
                        "__kwdefaults__ must be set to a dict object");
        return -1;
    }
    PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not "
                 "currently affect the values used in function calls", 1);
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value);
    return 0;
}
static PyObject *
__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) {
    PyObject* result = op->defaults_kwdict;
    CYTHON_UNUSED_VAR(context);
    if (unlikely(!result)) {
        if (op->defaults_getter) {
            if (unlikely(__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, void *context) {
    CYTHON_UNUSED_VAR(context);
    if (!value || value == Py_None) {
        value = NULL;
    } else if (unlikely(!PyDict_Check(value))) {
        PyErr_SetString(PyExc_TypeError,
                        "__annotations__ must be set to a dict object");
        return -1;
    }
    Py_XINCREF(value);
    __Pyx_Py_XDECREF_SET(op->func_annotations, value);
    return 0;
}
static PyObject *
__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) {
    PyObject* result = op->func_annotations;
    CYTHON_UNUSED_VAR(context);
    if (unlikely(!result)) {
        result = PyDict_New();
        if (unlikely(!result)) return NULL;
        op->func_annotations = result;
    }
    Py_INCREF(result);
    return result;
}
static PyObject *
__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) {
    int is_coroutine;
    CYTHON_UNUSED_VAR(context);
    if (op->func_is_coroutine) {
        return __Pyx_NewRef(op->func_is_coroutine);
    }
    is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE;
#if PY_VERSION_HEX >= 0x03050000
    if (is_coroutine) {
        PyObject *module, *fromlist, *marker = __pyx_n_s_is_coroutine;
        fromlist = PyList_New(1);
        if (unlikely(!fromlist)) return NULL;
        Py_INCREF(marker);
#if CYTHON_ASSUME_SAFE_MACROS
        PyList_SET_ITEM(fromlist, 0, marker);
#else
        if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) {
            Py_DECREF(marker);
            Py_DECREF(fromlist);
            return NULL;
        }
#endif
        module = PyImport_ImportModuleLevelObject(__pyx_n_s_asyncio_coroutines, NULL, NULL, fromlist, 0);
        Py_DECREF(fromlist);
        if (unlikely(!module)) goto ignore;
        op->func_is_coroutine = __Pyx_PyObject_GetAttrStr(module, marker);
        Py_DECREF(module);
        if (likely(op->func_is_coroutine)) {
            return __Pyx_NewRef(op->func_is_coroutine);
        }
ignore:
        PyErr_Clear();
    }
#endif
    op->func_is_coroutine = __Pyx_PyBool_FromLong(is_coroutine);
    return __Pyx_NewRef(op->func_is_coroutine);
}
#if CYTHON_COMPILING_IN_LIMITED_API
static PyObject *
__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) {
    CYTHON_UNUSED_VAR(context);
    return PyObject_GetAttrString(op->func, "__module__");
}
static int
__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) {
    CYTHON_UNUSED_VAR(context);
    return PyObject_SetAttrString(op->func, "__module__", value);
}
#endif
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 *) "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},
    {(char *) "_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0},
#if CYTHON_COMPILING_IN_LIMITED_API
    {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0},
#endif
    {0, 0, 0, 0, 0}
};
static PyMemberDef __pyx_CyFunction_members[] = {
#if !CYTHON_COMPILING_IN_LIMITED_API
    {(char *) "__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0},
#endif
#if CYTHON_USE_TYPE_SPECS
    {(char *) "__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0},
#if CYTHON_METH_FASTCALL
#if CYTHON_BACKPORT_VECTORCALL
    {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0},
#else
#if !CYTHON_COMPILING_IN_LIMITED_API
    {(char *) "__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0},
#endif
#endif
#endif
#if PY_VERSION_HEX < 0x030500A0 || CYTHON_COMPILING_IN_LIMITED_API
    {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0},
#else
    {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0},
#endif
#endif
    {0, 0, 0,  0, 0}
};
static PyObject *
__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args)
{
    CYTHON_UNUSED_VAR(args);
#if PY_MAJOR_VERSION >= 3
    Py_INCREF(m->func_qualname);
    return m->func_qualname;
#else
    return PyString_FromString(((PyCFunctionObject*)m)->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 || CYTHON_COMPILING_IN_LIMITED_API
#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
#else
#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->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 !CYTHON_COMPILING_IN_LIMITED_API
    PyCFunctionObject *cf = (PyCFunctionObject*) op;
#endif
    if (unlikely(op == NULL))
        return NULL;
#if CYTHON_COMPILING_IN_LIMITED_API
    op->func = PyCFunction_NewEx(ml, (PyObject*)op, module);
    if (unlikely(!op->func)) return NULL;
#endif
    op->flags = flags;
    __Pyx_CyFunction_weakreflist(op) = NULL;
#if !CYTHON_COMPILING_IN_LIMITED_API
    cf->m_ml = ml;
    cf->m_self = (PyObject *) op;
#endif
    Py_XINCREF(closure);
    op->func_closure = closure;
#if !CYTHON_COMPILING_IN_LIMITED_API
    Py_XINCREF(module);
    cf->m_module = module;
#endif
    op->func_dict = NULL;
    op->func_name = NULL;
    Py_INCREF(qualname);
    op->func_qualname = qualname;
    op->func_doc = NULL;
#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API
    op->func_classobj = NULL;
#else
    ((PyCMethodObject*)op)->mm_class = NULL;
#endif
    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;
    op->func_is_coroutine = NULL;
#if CYTHON_METH_FASTCALL
    switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) {
    case METH_NOARGS:
        __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS;
        break;
    case METH_O:
        __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O;
        break;
    case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
        __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD;
        break;
    case METH_FASTCALL | METH_KEYWORDS:
        __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS;
        break;
    case METH_VARARGS | METH_KEYWORDS:
        __Pyx_CyFunction_func_vectorcall(op) = NULL;
        break;
    default:
        PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction");
        Py_DECREF(op);
        return NULL;
    }
#endif
    return (PyObject *) op;
}
static int
__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
{
    Py_CLEAR(m->func_closure);
#if CYTHON_COMPILING_IN_LIMITED_API
    Py_CLEAR(m->func);
#else
    Py_CLEAR(((PyCFunctionObject*)m)->m_module);
#endif
    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);
#if !CYTHON_COMPILING_IN_LIMITED_API
#if PY_VERSION_HEX < 0x030900B1
    Py_CLEAR(__Pyx_CyFunction_GetClassObj(m));
#else
    {
        PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class;
        ((PyCMethodObject *) (m))->mm_class = NULL;
        Py_XDECREF(cls);
    }
#endif
#endif
    Py_CLEAR(m->defaults_tuple);
    Py_CLEAR(m->defaults_kwdict);
    Py_CLEAR(m->func_annotations);
    Py_CLEAR(m->func_is_coroutine);
    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);
    __Pyx_PyHeapTypeObject_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);
#if CYTHON_COMPILING_IN_LIMITED_API
    Py_VISIT(m->func);
#else
    Py_VISIT(((PyCFunctionObject*)m)->m_module);
#endif
    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);
#if !CYTHON_COMPILING_IN_LIMITED_API
    Py_VISIT(__Pyx_CyFunction_GetClassObj(m));
#endif
    Py_VISIT(m->defaults_tuple);
    Py_VISIT(m->defaults_kwdict);
    Py_VISIT(m->func_is_coroutine);
    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_repr(__pyx_CyFunctionObject *op)
{
#if PY_MAJOR_VERSION >= 3
    return PyUnicode_FromFormat("<cyfunction %U at %p>",
                                op->func_qualname, (void *)op);
#else
    return PyString_FromFormat("<cyfunction %s at %p>",
                               PyString_AsString(op->func_qualname), (void *)op);
#endif
}
static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) {
#if CYTHON_COMPILING_IN_LIMITED_API
    PyObject *f = ((__pyx_CyFunctionObject*)func)->func;
    PyObject *py_name = NULL;
    PyCFunction meth;
    int flags;
    meth = PyCFunction_GetFunction(f);
    if (unlikely(!meth)) return NULL;
    flags = PyCFunction_GetFlags(f);
    if (unlikely(flags < 0)) return NULL;
#else
    PyCFunctionObject* f = (PyCFunctionObject*)func;
    PyCFunction meth = f->m_ml->ml_meth;
    int flags = f->m_ml->ml_flags;
#endif
    Py_ssize_t size;
    switch (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)) {
#if CYTHON_ASSUME_SAFE_MACROS
            size = PyTuple_GET_SIZE(arg);
#else
            size = PyTuple_Size(arg);
            if (unlikely(size < 0)) return NULL;
#endif
            if (likely(size == 0))
                return (*meth)(self, NULL);
#if CYTHON_COMPILING_IN_LIMITED_API
            py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL);
            if (!py_name) return NULL;
            PyErr_Format(PyExc_TypeError,
                "%.200S() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)",
                py_name, size);
            Py_DECREF(py_name);
#else
            PyErr_Format(PyExc_TypeError,
                "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)",
                f->m_ml->ml_name, size);
#endif
            return NULL;
        }
        break;
    case METH_O:
        if (likely(kw == NULL || PyDict_Size(kw) == 0)) {
#if CYTHON_ASSUME_SAFE_MACROS
            size = PyTuple_GET_SIZE(arg);
#else
            size = PyTuple_Size(arg);
            if (unlikely(size < 0)) return NULL;
#endif
            if (likely(size == 1)) {
                PyObject *result, *arg0;
                #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
                arg0 = PyTuple_GET_ITEM(arg, 0);
                #else
                arg0 = __Pyx_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;
            }
#if CYTHON_COMPILING_IN_LIMITED_API
            py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL);
            if (!py_name) return NULL;
            PyErr_Format(PyExc_TypeError,
                "%.200S() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)",
                py_name, size);
            Py_DECREF(py_name);
#else
            PyErr_Format(PyExc_TypeError,
                "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)",
                f->m_ml->ml_name, size);
#endif
            return NULL;
        }
        break;
    default:
        PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction");
        return NULL;
    }
#if CYTHON_COMPILING_IN_LIMITED_API
    py_name = __Pyx_CyFunction_get_name((__pyx_CyFunctionObject*)func, NULL);
    if (!py_name) return NULL;
    PyErr_Format(PyExc_TypeError, "%.200S() takes no keyword arguments",
                 py_name);
    Py_DECREF(py_name);
#else
    PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
                 f->m_ml->ml_name);
#endif
    return NULL;
}
static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
    PyObject *self, *result;
#if CYTHON_COMPILING_IN_LIMITED_API
    self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func);
    if (unlikely(!self) && PyErr_Occurred()) return NULL;
#else
    self = ((PyCFunctionObject*)func)->m_self;
#endif
    result = __Pyx_CyFunction_CallMethod(func, self, arg, kw);
    return result;
}
static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) {
    PyObject *result;
    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func;
#if CYTHON_METH_FASTCALL
     __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc);
    if (vc) {
#if CYTHON_ASSUME_SAFE_MACROS
        return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw);
#else
        (void) &__Pyx_PyVectorcall_FastCallDict;
        return PyVectorcall_Call(func, args, kw);
#endif
    }
#endif
    if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) {
        Py_ssize_t argc;
        PyObject *new_args;
        PyObject *self;
#if CYTHON_ASSUME_SAFE_MACROS
        argc = PyTuple_GET_SIZE(args);
#else
        argc = PyTuple_Size(args);
        if (unlikely(!argc) < 0) return NULL;
#endif
        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);
#if PY_MAJOR_VERSION > 2
            PyErr_Format(PyExc_TypeError,
                         "unbound method %.200S() needs an argument",
                         cyfunc->func_qualname);
#else
            PyErr_SetString(PyExc_TypeError,
                            "unbound method needs an argument");
#endif
            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;
}
#if CYTHON_METH_FASTCALL
static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames)
{
    int ret = 0;
    if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) {
        if (unlikely(nargs < 1)) {
            PyErr_Format(PyExc_TypeError, "%.200s() needs an argument",
                         ((PyCFunctionObject*)cyfunc)->m_ml->ml_name);
            return -1;
        }
        ret = 1;
    }
    if (unlikely(kwnames) && unlikely(PyTuple_GET_SIZE(kwnames))) {
        PyErr_Format(PyExc_TypeError,
                     "%.200s() takes no keyword arguments", ((PyCFunctionObject*)cyfunc)->m_ml->ml_name);
        return -1;
    }
    return ret;
}
static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
    PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
#if CYTHON_BACKPORT_VECTORCALL
    Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
#endif
    PyObject *self;
    switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) {
    case 1:
        self = args[0];
        args += 1;
        nargs -= 1;
        break;
    case 0:
        self = ((PyCFunctionObject*)cyfunc)->m_self;
        break;
    default:
        return NULL;
    }
    if (unlikely(nargs != 0)) {
        PyErr_Format(PyExc_TypeError,
            "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)",
            def->ml_name, nargs);
        return NULL;
    }
    return def->ml_meth(self, NULL);
}
static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
    PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
#if CYTHON_BACKPORT_VECTORCALL
    Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
#endif
    PyObject *self;
    switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) {
    case 1:
        self = args[0];
        args += 1;
        nargs -= 1;
        break;
    case 0:
        self = ((PyCFunctionObject*)cyfunc)->m_self;
        break;
    default:
        return NULL;
    }
    if (unlikely(nargs != 1)) {
        PyErr_Format(PyExc_TypeError,
            "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)",
            def->ml_name, nargs);
        return NULL;
    }
    return def->ml_meth(self, args[0]);
}
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
    PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
#if CYTHON_BACKPORT_VECTORCALL
    Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
#endif
    PyObject *self;
    switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) {
    case 1:
        self = args[0];
        args += 1;
        nargs -= 1;
        break;
    case 0:
        self = ((PyCFunctionObject*)cyfunc)->m_self;
        break;
    default:
        return NULL;
    }
    return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))def->ml_meth)(self, args, nargs, kwnames);
}
static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames)
{
    __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func;
    PyMethodDef* def = ((PyCFunctionObject*)cyfunc)->m_ml;
    PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc);
#if CYTHON_BACKPORT_VECTORCALL
    Py_ssize_t nargs = (Py_ssize_t)nargsf;
#else
    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
#endif
    PyObject *self;
    switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) {
    case 1:
        self = args[0];
        args += 1;
        nargs -= 1;
        break;
    case 0:
        self = ((PyCFunctionObject*)cyfunc)->m_self;
        break;
    default:
        return NULL;
    }
    return ((__Pyx_PyCMethod)(void(*)(void))def->ml_meth)(self, cls, args, (size_t)nargs, kwnames);
}
#endif
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_CyFunctionType_slots[] = {
    {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc},
    {Py_tp_repr, (void *)__Pyx_CyFunction_repr},
    {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod},
    {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse},
    {Py_tp_clear, (void *)__Pyx_CyFunction_clear},
    {Py_tp_methods, (void *)__pyx_CyFunction_methods},
    {Py_tp_members, (void *)__pyx_CyFunction_members},
    {Py_tp_getset, (void *)__pyx_CyFunction_getsets},
    {Py_tp_descr_get, (void *)__Pyx_PyMethod_New},
    {0, 0},
};
static PyType_Spec __pyx_CyFunctionType_spec = {
    __PYX_TYPE_MODULE_PREFIX "cython_function_or_method",
    sizeof(__pyx_CyFunctionObject),
    0,
#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR
    Py_TPFLAGS_METHOD_DESCRIPTOR |
#endif
#if (defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL)
    _Py_TPFLAGS_HAVE_VECTORCALL |
#endif
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
    __pyx_CyFunctionType_slots
};
#else
static PyTypeObject __pyx_CyFunctionType_type = {
    PyVarObject_HEAD_INIT(0, 0)
    __PYX_TYPE_MODULE_PREFIX "cython_function_or_method",
    sizeof(__pyx_CyFunctionObject),
    0,
    (destructor) __Pyx_CyFunction_dealloc,
#if !CYTHON_METH_FASTCALL
    0,
#elif CYTHON_BACKPORT_VECTORCALL
    (printfunc)offsetof(__pyx_CyFunctionObject, func_vectorcall),
#else
    offsetof(PyCFunctionObject, vectorcall),
#endif
    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,
#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR
    Py_TPFLAGS_METHOD_DESCRIPTOR |
#endif
#if defined(_Py_TPFLAGS_HAVE_VECTORCALL) && CYTHON_METH_FASTCALL
    _Py_TPFLAGS_HAVE_VECTORCALL |
#endif
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
    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_PyMethod_New,
    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 __PYX_NEED_TP_PRINT_SLOT
    0,
#endif
#if PY_VERSION_HEX >= 0x030C0000
    0,
#endif
#if PY_VERSION_HEX >= 0x030d00A4
    0,
#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
    0,
#endif
};
#endif
static int __pyx_CyFunction_init(PyObject *module) {
#if CYTHON_USE_TYPE_SPECS
    __pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_CyFunctionType_spec, NULL);
#else
    CYTHON_UNUSED_VAR(module);
    __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
#endif
    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;
}

/* CalculateMetaclass */
static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) {
    Py_ssize_t i, nbases;
#if CYTHON_ASSUME_SAFE_MACROS
    nbases = PyTuple_GET_SIZE(bases);
#else
    nbases = PyTuple_Size(bases);
    if (nbases < 0) return NULL;
#endif
    for (i=0; i < nbases; i++) {
        PyTypeObject *tmptype;
#if CYTHON_ASSUME_SAFE_MACROS
        PyObject *tmp = PyTuple_GET_ITEM(bases, i);
#else
        PyObject *tmp = PyTuple_GetItem(bases, i);
        if (!tmp) return NULL;
#endif
        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;
}

/* 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_GetAttrStrNoError(metaclass, __pyx_n_s_prepare);
        if (prep) {
            PyObject *pargs[3] = {NULL, name, bases};
            ns = __Pyx_PyObject_FastCallDict(prep, pargs+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, mkw);
            Py_DECREF(prep);
        } else {
            if (unlikely(PyErr_Occurred()))
                return NULL;
            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 PY_VERSION_HEX >= 0x03030000
    if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad;
#else
    CYTHON_MAYBE_UNUSED_VAR(qualname);
#endif
    if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad;
    return ns;
bad:
    Py_DECREF(ns);
    return NULL;
}
#if PY_VERSION_HEX < 0x030600A4 && CYTHON_PEP487_INIT_SUBCLASS
static int __Pyx_SetNamesPEP487(PyObject *type_obj) {
    PyTypeObject *type = (PyTypeObject*) type_obj;
    PyObject *names_to_set, *key, *value, *set_name, *tmp;
    Py_ssize_t i = 0;
#if CYTHON_USE_TYPE_SLOTS
    names_to_set = PyDict_Copy(type->tp_dict);
#else
    {
        PyObject *d = PyObject_GetAttr(type_obj, __pyx_n_s_dict);
        names_to_set = NULL;
        if (likely(d)) {
            PyObject *names_to_set = PyDict_New();
            int ret = likely(names_to_set) ? PyDict_Update(names_to_set, d) : -1;
            Py_DECREF(d);
            if (unlikely(ret < 0))
                Py_CLEAR(names_to_set);
        }
    }
#endif
    if (unlikely(names_to_set == NULL))
        goto bad;
    while (PyDict_Next(names_to_set, &i, &key, &value)) {
        set_name = __Pyx_PyObject_LookupSpecialNoError(value, __pyx_n_s_set_name);
        if (unlikely(set_name != NULL)) {
            tmp = __Pyx_PyObject_Call2Args(set_name, type_obj, key);
            Py_DECREF(set_name);
            if (unlikely(tmp == NULL)) {
                __Pyx_TypeName value_type_name =
                    __Pyx_PyType_GetName(Py_TYPE(value));
                __Pyx_TypeName type_name = __Pyx_PyType_GetName(type);
                PyErr_Format(PyExc_RuntimeError,
#if PY_MAJOR_VERSION >= 3
                    "Error calling __set_name__ on '" __Pyx_FMT_TYPENAME "' instance %R " "in '" __Pyx_FMT_TYPENAME "'",
                    value_type_name, key, type_name);
#else
                    "Error calling __set_name__ on '" __Pyx_FMT_TYPENAME "' instance %.100s in '" __Pyx_FMT_TYPENAME "'",
                    value_type_name,
                    PyString_Check(key) ? PyString_AS_STRING(key) : "?",
                    type_name);
#endif
                goto bad;
            } else {
                Py_DECREF(tmp);
            }
        }
        else if (unlikely(PyErr_Occurred())) {
            goto bad;
        }
    }
    Py_DECREF(names_to_set);
    return 0;
bad:
    Py_XDECREF(names_to_set);
    return -1;
}
static PyObject *__Pyx_InitSubclassPEP487(PyObject *type_obj, PyObject *mkw) {
#if CYTHON_USE_TYPE_SLOTS && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    PyTypeObject *type = (PyTypeObject*) type_obj;
    PyObject *mro = type->tp_mro;
    Py_ssize_t i, nbases;
    if (unlikely(!mro)) goto done;
    (void) &__Pyx_GetBuiltinName;
    Py_INCREF(mro);
    nbases = PyTuple_GET_SIZE(mro);
    assert(PyTuple_GET_ITEM(mro, 0) == type_obj);
    for (i = 1; i < nbases-1; i++) {
        PyObject *base, *dict, *meth;
        base = PyTuple_GET_ITEM(mro, i);
        dict = ((PyTypeObject *)base)->tp_dict;
        meth = __Pyx_PyDict_GetItemStrWithError(dict, __pyx_n_s_init_subclass);
        if (unlikely(meth)) {
            descrgetfunc f = Py_TYPE(meth)->tp_descr_get;
            PyObject *res;
            Py_INCREF(meth);
            if (likely(f)) {
                res = f(meth, NULL, type_obj);
                Py_DECREF(meth);
                if (unlikely(!res)) goto bad;
                meth = res;
            }
            res = __Pyx_PyObject_FastCallDict(meth, NULL, 0, mkw);
            Py_DECREF(meth);
            if (unlikely(!res)) goto bad;
            Py_DECREF(res);
            goto done;
        } else if (unlikely(PyErr_Occurred())) {
            goto bad;
        }
    }
done:
    Py_XDECREF(mro);
    return type_obj;
bad:
    Py_XDECREF(mro);
    Py_DECREF(type_obj);
    return NULL;
#else
    PyObject *super_type, *super, *func, *res;
#if CYTHON_COMPILING_IN_PYPY && !defined(PySuper_Type)
    super_type = __Pyx_GetBuiltinName(__pyx_n_s_super);
#else
    super_type = (PyObject*) &PySuper_Type;
    (void) &__Pyx_GetBuiltinName;
#endif
    super = likely(super_type) ? __Pyx_PyObject_Call2Args(super_type, type_obj, type_obj) : NULL;
#if CYTHON_COMPILING_IN_PYPY && !defined(PySuper_Type)
    Py_XDECREF(super_type);
#endif
    if (unlikely(!super)) {
        Py_CLEAR(type_obj);
        goto done;
    }
    func = __Pyx_PyObject_GetAttrStrNoError(super, __pyx_n_s_init_subclass);
    Py_DECREF(super);
    if (likely(!func)) {
        if (unlikely(PyErr_Occurred()))
            Py_CLEAR(type_obj);
        goto done;
    }
    res = __Pyx_PyObject_FastCallDict(func, NULL, 0, mkw);
    Py_DECREF(func);
    if (unlikely(!res))
        Py_CLEAR(type_obj);
    Py_XDECREF(res);
done:
    return type_obj;
#endif
}
#endif
static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases,
                                      PyObject *dict, PyObject *mkw,
                                      int calculate_metaclass, int allow_py2_metaclass) {
    PyObject *result;
    PyObject *owned_metaclass = NULL;
    PyObject *margs[4] = {NULL, name, bases, dict};
    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;
    }
    result = __Pyx_PyObject_FastCallDict(metaclass, margs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET,
#if PY_VERSION_HEX < 0x030600A4
        (metaclass == (PyObject*)&PyType_Type) ? NULL : mkw
#else
        mkw
#endif
    );
    Py_XDECREF(owned_metaclass);
#if PY_VERSION_HEX < 0x030600A4 && CYTHON_PEP487_INIT_SUBCLASS
    if (likely(result) && likely(PyType_Check(result))) {
        if (unlikely(__Pyx_SetNamesPEP487(result) < 0)) {
            Py_CLEAR(result);
        } else {
            result = __Pyx_InitSubclassPEP487(result, mkw);
        }
    }
#else
    (void) &__Pyx_GetBuiltinName;
#endif
    return result;
}

/* CLineInTraceback */
#ifndef CYTHON_CLINE_IN_TRACEBACK
static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) {
    PyObject *use_cline;
    PyObject *ptype, *pvalue, *ptraceback;
#if CYTHON_COMPILING_IN_CPYTHON
    PyObject **cython_runtime_dict;
#endif
    CYTHON_MAYBE_UNUSED_VAR(tstate);
    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_GetAttrStrNoError(__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 */
#if !CYTHON_COMPILING_IN_LIMITED_API
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);
}
#endif

/* AddTraceback */
#include "compile.h"
#include "frameobject.h"
#include "traceback.h"
#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION)
  #ifndef Py_BUILD_CORE
    #define Py_BUILD_CORE 1
  #endif
  #include "internal/pycore_frame.h"
#endif
#if CYTHON_COMPILING_IN_LIMITED_API
static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict,
                                                       PyObject *firstlineno, PyObject *name) {
    PyObject *replace = NULL;
    if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL;
    if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL;
    replace = PyObject_GetAttrString(code, "replace");
    if (likely(replace)) {
        PyObject *result;
        result = PyObject_Call(replace, __pyx_empty_tuple, scratch_dict);
        Py_DECREF(replace);
        return result;
    }
    PyErr_Clear();
    #if __PYX_LIMITED_VERSION_HEX < 0x030780000
    {
        PyObject *compiled = NULL, *result = NULL;
        if (unlikely(PyDict_SetItemString(scratch_dict, "code", code))) return NULL;
        if (unlikely(PyDict_SetItemString(scratch_dict, "type", (PyObject*)(&PyType_Type)))) return NULL;
        compiled = Py_CompileString(
            "out = type(code)(\n"
            "  code.co_argcount, code.co_kwonlyargcount, code.co_nlocals, code.co_stacksize,\n"
            "  code.co_flags, code.co_code, code.co_consts, code.co_names,\n"
            "  code.co_varnames, code.co_filename, co_name, co_firstlineno,\n"
            "  code.co_lnotab)\n", "<dummy>", Py_file_input);
        if (!compiled) return NULL;
        result = PyEval_EvalCode(compiled, scratch_dict, scratch_dict);
        Py_DECREF(compiled);
        if (!result) PyErr_Print();
        Py_DECREF(result);
        result = PyDict_GetItemString(scratch_dict, "out");
        if (result) Py_INCREF(result);
        return result;
    }
    #else
    return NULL;
    #endif
}
static void __Pyx_AddTraceback(const char *funcname, int c_line,
                               int py_line, const char *filename) {
    PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL;
    PyObject *replace = NULL, *getframe = NULL, *frame = NULL;
    PyObject *exc_type, *exc_value, *exc_traceback;
    int success = 0;
    if (c_line) {
        (void) __pyx_cfilenm;
        (void) __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line);
    }
    PyErr_Fetch(&exc_type, &exc_value, &exc_traceback);
    code_object = Py_CompileString("_getframe()", filename, Py_eval_input);
    if (unlikely(!code_object)) goto bad;
    py_py_line = PyLong_FromLong(py_line);
    if (unlikely(!py_py_line)) goto bad;
    py_funcname = PyUnicode_FromString(funcname);
    if (unlikely(!py_funcname)) goto bad;
    dict = PyDict_New();
    if (unlikely(!dict)) goto bad;
    {
        PyObject *old_code_object = code_object;
        code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname);
        Py_DECREF(old_code_object);
    }
    if (unlikely(!code_object)) goto bad;
    getframe = PySys_GetObject("_getframe");
    if (unlikely(!getframe)) goto bad;
    if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad;
    frame = PyEval_EvalCode(code_object, dict, dict);
    if (unlikely(!frame) || frame == Py_None) goto bad;
    success = 1;
  bad:
    PyErr_Restore(exc_type, exc_value, exc_traceback);
    Py_XDECREF(code_object);
    Py_XDECREF(py_py_line);
    Py_XDECREF(py_funcname);
    Py_XDECREF(dict);
    Py_XDECREF(replace);
    if (success) {
        PyTraceBack_Here(
            (struct _frame*)frame);
    }
    Py_XDECREF(frame);
}
#else
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,
        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);
    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);
}
#endif

/* 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
        }
    }
    {
        unsigned char *bytes = (unsigned char *)&value;
#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4
        if (is_unsigned) {
            return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1);
        } else {
            return PyLong_FromNativeBytes(bytes, sizeof(value), -1);
        }
#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000
        int one = 1; int little = (int)*(unsigned char *)&one;
        return _PyLong_FromByteArray(bytes, sizeof(long),
                                     little, !is_unsigned);
#else
        int one = 1; int little = (int)*(unsigned char *)&one;
        PyObject *from_bytes, *result = NULL;
        PyObject *py_bytes = NULL, *arg_tuple = NULL, *kwds = NULL, *order_str = NULL;
        from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes");
        if (!from_bytes) return NULL;
        py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long));
        if (!py_bytes) goto limited_bad;
        order_str = PyUnicode_FromString(little ? "little" : "big");
        if (!order_str) goto limited_bad;
        arg_tuple = PyTuple_Pack(2, py_bytes, order_str);
        if (!arg_tuple) goto limited_bad;
        if (!is_unsigned) {
            kwds = PyDict_New();
            if (!kwds) goto limited_bad;
            if (PyDict_SetItemString(kwds, "signed", __Pyx_NewRef(Py_True))) goto limited_bad;
        }
        result = PyObject_Call(from_bytes, arg_tuple, kwds);
        limited_bad:
        Py_XDECREF(kwds);
        Py_XDECREF(arg_tuple);
        Py_XDECREF(order_str);
        Py_XDECREF(py_bytes);
        Py_XDECREF(from_bytes);
        return result;
#endif
    }
}

/* FormatTypeName */
#if CYTHON_COMPILING_IN_LIMITED_API
static __Pyx_TypeName
__Pyx_PyType_GetName(PyTypeObject* tp)
{
    PyObject *name = __Pyx_PyObject_GetAttrStr((PyObject *)tp,
                                               __pyx_n_s_name_2);
    if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) {
        PyErr_Clear();
        Py_XDECREF(name);
        name = __Pyx_NewRef(__pyx_n_s__90);
    }
    return name;
}
#endif

/* 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;\
    }

/* 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;
        }
    }
#endif
    if (unlikely(!PyLong_Check(x))) {
        long val;
        PyObject *tmp = __Pyx_PyNumber_IntOrLong(x);
        if (!tmp) return (long) -1;
        val = __Pyx_PyInt_As_long(tmp);
        Py_DECREF(tmp);
        return val;
    }
    if (is_unsigned) {
#if CYTHON_USE_PYLONG_INTERNALS
        if (unlikely(__Pyx_PyLong_IsNeg(x))) {
            goto raise_neg_overflow;
        } else if (__Pyx_PyLong_IsCompact(x)) {
            __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x))
        } else {
            const digit* digits = __Pyx_PyLong_Digits(x);
            assert(__Pyx_PyLong_DigitCount(x) > 1);
            switch (__Pyx_PyLong_DigitCount(x)) {
                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 && PY_VERSION_HEX < 0x030C00A7
        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
        if (__Pyx_PyLong_IsCompact(x)) {
            __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x))
        } else {
            const digit* digits = __Pyx_PyLong_Digits(x);
            assert(__Pyx_PyLong_DigitCount(x) > 1);
            switch (__Pyx_PyLong_SignedDigitCount(x)) {
                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
        }
    }
    {
        long val;
        int ret = -1;
#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API
        Py_ssize_t bytes_copied = PyLong_AsNativeBytes(
            x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0));
        if (unlikely(bytes_copied == -1)) {
        } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) {
            goto raise_overflow;
        } else {
            ret = 0;
        }
#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray)
        int one = 1; int is_little = (int)*(unsigned char *)&one;
        unsigned char *bytes = (unsigned char *)&val;
        ret = _PyLong_AsByteArray((PyLongObject *)x,
                                    bytes, sizeof(val),
                                    is_little, !is_unsigned);
#else
        PyObject *v;
        PyObject *stepval = NULL, *mask = NULL, *shift = NULL;
        int bits, remaining_bits, is_negative = 0;
        int chunk_size = (sizeof(long) < 8) ? 30 : 62;
        if (likely(PyLong_CheckExact(x))) {
            v = __Pyx_NewRef(x);
        } else {
            v = PyNumber_Long(x);
            if (unlikely(!v)) return (long) -1;
            assert(PyLong_CheckExact(v));
        }
        {
            int result = PyObject_RichCompareBool(v, Py_False, Py_LT);
            if (unlikely(result < 0)) {
                Py_DECREF(v);
                return (long) -1;
            }
            is_negative = result == 1;
        }
        if (is_unsigned && unlikely(is_negative)) {
            Py_DECREF(v);
            goto raise_neg_overflow;
        } else if (is_negative) {
            stepval = PyNumber_Invert(v);
            Py_DECREF(v);
            if (unlikely(!stepval))
                return (long) -1;
        } else {
            stepval = v;
        }
        v = NULL;
        val = (long) 0;
        mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done;
        shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done;
        for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) {
            PyObject *tmp, *digit;
            long idigit;
            digit = PyNumber_And(stepval, mask);
            if (unlikely(!digit)) goto done;
            idigit = PyLong_AsLong(digit);
            Py_DECREF(digit);
            if (unlikely(idigit < 0)) goto done;
            val |= ((long) idigit) << bits;
            tmp = PyNumber_Rshift(stepval, shift);
            if (unlikely(!tmp)) goto done;
            Py_DECREF(stepval); stepval = tmp;
        }
        Py_DECREF(shift); shift = NULL;
        Py_DECREF(mask); mask = NULL;
        {
            long idigit = PyLong_AsLong(stepval);
            if (unlikely(idigit < 0)) goto done;
            remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1);
            if (unlikely(idigit >= (1L << remaining_bits)))
                goto raise_overflow;
            val |= ((long) idigit) << bits;
        }
        if (!is_unsigned) {
            if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1))))
                goto raise_overflow;
            if (is_negative)
                val = ~val;
        }
        ret = 0;
    done:
        Py_XDECREF(shift);
        Py_XDECREF(mask);
        Py_XDECREF(stepval);
#endif
        if (unlikely(ret))
            return (long) -1;
        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;
}

/* 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;
        }
    }
#endif
    if (unlikely(!PyLong_Check(x))) {
        int val;
        PyObject *tmp = __Pyx_PyNumber_IntOrLong(x);
        if (!tmp) return (int) -1;
        val = __Pyx_PyInt_As_int(tmp);
        Py_DECREF(tmp);
        return val;
    }
    if (is_unsigned) {
#if CYTHON_USE_PYLONG_INTERNALS
        if (unlikely(__Pyx_PyLong_IsNeg(x))) {
            goto raise_neg_overflow;
        } else if (__Pyx_PyLong_IsCompact(x)) {
            __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x))
        } else {
            const digit* digits = __Pyx_PyLong_Digits(x);
            assert(__Pyx_PyLong_DigitCount(x) > 1);
            switch (__Pyx_PyLong_DigitCount(x)) {
                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 && PY_VERSION_HEX < 0x030C00A7
        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
        if (__Pyx_PyLong_IsCompact(x)) {
            __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x))
        } else {
            const digit* digits = __Pyx_PyLong_Digits(x);
            assert(__Pyx_PyLong_DigitCount(x) > 1);
            switch (__Pyx_PyLong_SignedDigitCount(x)) {
                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
        }
    }
    {
        int val;
        int ret = -1;
#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API
        Py_ssize_t bytes_copied = PyLong_AsNativeBytes(
            x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0));
        if (unlikely(bytes_copied == -1)) {
        } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) {
            goto raise_overflow;
        } else {
            ret = 0;
        }
#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray)
        int one = 1; int is_little = (int)*(unsigned char *)&one;
        unsigned char *bytes = (unsigned char *)&val;
        ret = _PyLong_AsByteArray((PyLongObject *)x,
                                    bytes, sizeof(val),
                                    is_little, !is_unsigned);
#else
        PyObject *v;
        PyObject *stepval = NULL, *mask = NULL, *shift = NULL;
        int bits, remaining_bits, is_negative = 0;
        int chunk_size = (sizeof(long) < 8) ? 30 : 62;
        if (likely(PyLong_CheckExact(x))) {
            v = __Pyx_NewRef(x);
        } else {
            v = PyNumber_Long(x);
            if (unlikely(!v)) return (int) -1;
            assert(PyLong_CheckExact(v));
        }
        {
            int result = PyObject_RichCompareBool(v, Py_False, Py_LT);
            if (unlikely(result < 0)) {
                Py_DECREF(v);
                return (int) -1;
            }
            is_negative = result == 1;
        }
        if (is_unsigned && unlikely(is_negative)) {
            Py_DECREF(v);
            goto raise_neg_overflow;
        } else if (is_negative) {
            stepval = PyNumber_Invert(v);
            Py_DECREF(v);
            if (unlikely(!stepval))
                return (int) -1;
        } else {
            stepval = v;
        }
        v = NULL;
        val = (int) 0;
        mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done;
        shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done;
        for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) {
            PyObject *tmp, *digit;
            long idigit;
            digit = PyNumber_And(stepval, mask);
            if (unlikely(!digit)) goto done;
            idigit = PyLong_AsLong(digit);
            Py_DECREF(digit);
            if (unlikely(idigit < 0)) goto done;
            val |= ((int) idigit) << bits;
            tmp = PyNumber_Rshift(stepval, shift);
            if (unlikely(!tmp)) goto done;
            Py_DECREF(stepval); stepval = tmp;
        }
        Py_DECREF(shift); shift = NULL;
        Py_DECREF(mask); mask = NULL;
        {
            long idigit = PyLong_AsLong(stepval);
            if (unlikely(idigit < 0)) goto done;
            remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1);
            if (unlikely(idigit >= (1L << remaining_bits)))
                goto raise_overflow;
            val |= ((int) idigit) << bits;
        }
        if (!is_unsigned) {
            if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1))))
                goto raise_overflow;
            if (is_negative)
                val = ~val;
        }
        ret = 0;
    done:
        Py_XDECREF(shift);
        Py_XDECREF(mask);
        Py_XDECREF(stepval);
#endif
        if (unlikely(ret))
            return (int) -1;
        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;
}

/* FastTypeChecks */
#if CYTHON_COMPILING_IN_CPYTHON
static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) {
    while (a) {
        a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*);
        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);
}
static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) {
    PyObject *mro;
    if (cls == a || cls == b) return 1;
    mro = cls->tp_mro;
    if (likely(mro)) {
        Py_ssize_t i, n;
        n = PyTuple_GET_SIZE(mro);
        for (i = 0; i < n; i++) {
            PyObject *base = PyTuple_GET_ITEM(mro, i);
            if (base == (PyObject *)a || base == (PyObject *)b)
                return 1;
        }
        return 0;
    }
    return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, 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) {
    if (exc_type1) {
        return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2);
    } else {
        return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2);
    }
}
#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; i<n; i++) {
        if (exc_type == PyTuple_GET_ITEM(tuple, i)) return 1;
    }
#endif
    for (i=0; i<n; i++) {
        PyObject *t = PyTuple_GET_ITEM(tuple, i);
        #if PY_MAJOR_VERSION < 3
        if (likely(exc_type == t)) return 1;
        #endif
        if (likely(PyExceptionClass_Check(t))) {
            if (__Pyx_inner_PyErr_GivenExceptionMatches2(exc_type, NULL, t)) return 1;
        } else {
        }
    }
    return 0;
}
static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) {
    if (likely(err == exc_type)) return 1;
    if (likely(PyExceptionClass_Check(err))) {
        if (likely(PyExceptionClass_Check(exc_type))) {
            return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type);
        } else if (likely(PyTuple_Check(exc_type))) {
            return __Pyx_PyErr_GivenExceptionMatchesTuple(err, exc_type);
        } else {
        }
    }
    return PyErr_GivenExceptionMatches(err, exc_type);
}
static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) {
    assert(PyExceptionClass_Check(exc_type1));
    assert(PyExceptionClass_Check(exc_type2));
    if (likely(err == exc_type1 || err == exc_type2)) return 1;
    if (likely(PyExceptionClass_Check(err))) {
        return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2);
    }
    return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2));
}
#endif

/* RaiseException */
#if PY_MAJOR_VERSION < 3
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
    __Pyx_PyThreadState_declare
    CYTHON_UNUSED_VAR(cause);
    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 PY_VERSION_HEX >= 0x030C00A6
        PyException_SetTraceback(value, tb);
      #elif CYTHON_FAST_THREAD_STATE
        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);
        }
#else
        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);
#endif
    }
bad:
    Py_XDECREF(owned_instance);
    return;
}
#endif

/* CoroutineBase */
#include <frameobject.h>
#if PY_VERSION_HEX >= 0x030b00a6 && !defined(PYPY_VERSION)
  #ifndef Py_BUILD_CORE
    #define Py_BUILD_CORE 1
  #endif
  #include "internal/pycore_frame.h"
#endif
#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *__pyx_tstate, PyObject **pvalue) {
    PyObject *et, *ev, *tb;
    PyObject *value = NULL;
    CYTHON_UNUSED_VAR(__pyx_tstate);
    __Pyx_ErrFetch(&et, &ev, &tb);
    if (!et) {
        Py_XDECREF(tb);
        Py_XDECREF(ev);
        Py_INCREF(Py_None);
        *pvalue = Py_None;
        return 0;
    }
    if (likely(et == PyExc_StopIteration)) {
        if (!ev) {
            Py_INCREF(Py_None);
            value = Py_None;
        }
#if PY_VERSION_HEX >= 0x030300A0
        else if (likely(__Pyx_IS_TYPE(ev, (PyTypeObject*)PyExc_StopIteration))) {
            value = ((PyStopIterationObject *)ev)->value;
            Py_INCREF(value);
            Py_DECREF(ev);
        }
#endif
        else if (unlikely(PyTuple_Check(ev))) {
            if (PyTuple_GET_SIZE(ev) >= 1) {
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
                value = PyTuple_GET_ITEM(ev, 0);
                Py_INCREF(value);
#else
                value = PySequence_ITEM(ev, 0);
#endif
            } else {
                Py_INCREF(Py_None);
                value = Py_None;
            }
            Py_DECREF(ev);
        }
        else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) {
            value = ev;
        }
        if (likely(value)) {
            Py_XDECREF(tb);
            Py_DECREF(et);
            *pvalue = value;
            return 0;
        }
    } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) {
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
    }
    PyErr_NormalizeException(&et, &ev, &tb);
    if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) {
        __Pyx_ErrRestore(et, ev, tb);
        return -1;
    }
    Py_XDECREF(tb);
    Py_DECREF(et);
#if PY_VERSION_HEX >= 0x030300A0
    value = ((PyStopIterationObject *)ev)->value;
    Py_INCREF(value);
    Py_DECREF(ev);
#else
    {
        PyObject* args = __Pyx_PyObject_GetAttrStr(ev, __pyx_n_s_args);
        Py_DECREF(ev);
        if (likely(args)) {
            value = PySequence_GetItem(args, 0);
            Py_DECREF(args);
        }
        if (unlikely(!value)) {
            __Pyx_ErrRestore(NULL, NULL, NULL);
            Py_INCREF(Py_None);
            value = Py_None;
        }
    }
#endif
    *pvalue = value;
    return 0;
}
static CYTHON_INLINE
void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) {
#if PY_VERSION_HEX >= 0x030B00a4
    Py_CLEAR(exc_state->exc_value);
#else
    PyObject *t, *v, *tb;
    t = exc_state->exc_type;
    v = exc_state->exc_value;
    tb = exc_state->exc_traceback;
    exc_state->exc_type = NULL;
    exc_state->exc_value = NULL;
    exc_state->exc_traceback = NULL;
    Py_XDECREF(t);
    Py_XDECREF(v);
    Py_XDECREF(tb);
#endif
}
#define __Pyx_Coroutine_AlreadyRunningError(gen)  (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL)
static void __Pyx__Coroutine_AlreadyRunningError(__pyx_CoroutineObject *gen) {
    const char *msg;
    CYTHON_MAYBE_UNUSED_VAR(gen);
    if ((0)) {
    #ifdef __Pyx_Coroutine_USED
    } else if (__Pyx_Coroutine_Check((PyObject*)gen)) {
        msg = "coroutine already executing";
    #endif
    #ifdef __Pyx_AsyncGen_USED
    } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) {
        msg = "async generator already executing";
    #endif
    } else {
        msg = "generator already executing";
    }
    PyErr_SetString(PyExc_ValueError, msg);
}
#define __Pyx_Coroutine_NotStartedError(gen)  (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL)
static void __Pyx__Coroutine_NotStartedError(PyObject *gen) {
    const char *msg;
    CYTHON_MAYBE_UNUSED_VAR(gen);
    if ((0)) {
    #ifdef __Pyx_Coroutine_USED
    } else if (__Pyx_Coroutine_Check(gen)) {
        msg = "can't send non-None value to a just-started coroutine";
    #endif
    #ifdef __Pyx_AsyncGen_USED
    } else if (__Pyx_AsyncGen_CheckExact(gen)) {
        msg = "can't send non-None value to a just-started async generator";
    #endif
    } else {
        msg = "can't send non-None value to a just-started generator";
    }
    PyErr_SetString(PyExc_TypeError, msg);
}
#define __Pyx_Coroutine_AlreadyTerminatedError(gen, value, closing)  (__Pyx__Coroutine_AlreadyTerminatedError(gen, value, closing), (PyObject*)NULL)
static void __Pyx__Coroutine_AlreadyTerminatedError(PyObject *gen, PyObject *value, int closing) {
    CYTHON_MAYBE_UNUSED_VAR(gen);
    CYTHON_MAYBE_UNUSED_VAR(closing);
    #ifdef __Pyx_Coroutine_USED
    if (!closing && __Pyx_Coroutine_Check(gen)) {
        PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine");
    } else
    #endif
    if (value) {
        #ifdef __Pyx_AsyncGen_USED
        if (__Pyx_AsyncGen_CheckExact(gen))
            PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration);
        else
        #endif
        PyErr_SetNone(PyExc_StopIteration);
    }
}
static
PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) {
    __Pyx_PyThreadState_declare
    PyThreadState *tstate;
    __Pyx_ExcInfoStruct *exc_state;
    PyObject *retval;
    assert(!self->is_running);
    if (unlikely(self->resume_label == 0)) {
        if (unlikely(value && value != Py_None)) {
            return __Pyx_Coroutine_NotStartedError((PyObject*)self);
        }
    }
    if (unlikely(self->resume_label == -1)) {
        return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing);
    }
#if CYTHON_FAST_THREAD_STATE
    __Pyx_PyThreadState_assign
    tstate = __pyx_tstate;
#else
    tstate = __Pyx_PyThreadState_Current;
#endif
    exc_state = &self->gi_exc_state;
    if (exc_state->exc_value) {
        #if CYTHON_COMPILING_IN_PYPY
        #else
        PyObject *exc_tb;
        #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON
        exc_tb = PyException_GetTraceback(exc_state->exc_value);
        #elif PY_VERSION_HEX >= 0x030B00a4
        exc_tb = ((PyBaseExceptionObject*) exc_state->exc_value)->traceback;
        #else
        exc_tb = exc_state->exc_traceback;
        #endif
        if (exc_tb) {
            PyTracebackObject *tb = (PyTracebackObject *) exc_tb;
            PyFrameObject *f = tb->tb_frame;
            assert(f->f_back == NULL);
            #if PY_VERSION_HEX >= 0x030B00A1
            f->f_back = PyThreadState_GetFrame(tstate);
            #else
            Py_XINCREF(tstate->frame);
            f->f_back = tstate->frame;
            #endif
            #if PY_VERSION_HEX >= 0x030B00a4 && !CYTHON_COMPILING_IN_CPYTHON
            Py_DECREF(exc_tb);
            #endif
        }
        #endif
    }
#if CYTHON_USE_EXC_INFO_STACK
    exc_state->previous_item = tstate->exc_info;
    tstate->exc_info = exc_state;
#else
    if (exc_state->exc_type) {
        __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback);
    } else {
        __Pyx_Coroutine_ExceptionClear(exc_state);
        __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback);
    }
#endif
    self->is_running = 1;
    retval = self->body(self, tstate, value);
    self->is_running = 0;
#if CYTHON_USE_EXC_INFO_STACK
    exc_state = &self->gi_exc_state;
    tstate->exc_info = exc_state->previous_item;
    exc_state->previous_item = NULL;
    __Pyx_Coroutine_ResetFrameBackpointer(exc_state);
#endif
    return retval;
}
static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) {
#if CYTHON_COMPILING_IN_PYPY
    CYTHON_UNUSED_VAR(exc_state);
#else
    PyObject *exc_tb;
    #if PY_VERSION_HEX >= 0x030B00a4
    if (!exc_state->exc_value) return;
    exc_tb = PyException_GetTraceback(exc_state->exc_value);
    #else
    exc_tb = exc_state->exc_traceback;
    #endif
    if (likely(exc_tb)) {
        PyTracebackObject *tb = (PyTracebackObject *) exc_tb;
        PyFrameObject *f = tb->tb_frame;
        Py_CLEAR(f->f_back);
        #if PY_VERSION_HEX >= 0x030B00a4
        Py_DECREF(exc_tb);
        #endif
    }
#endif
}
static CYTHON_INLINE
PyObject *__Pyx_Coroutine_MethodReturn(PyObject* gen, PyObject *retval) {
    CYTHON_MAYBE_UNUSED_VAR(gen);
    if (unlikely(!retval)) {
        __Pyx_PyThreadState_declare
        __Pyx_PyThreadState_assign
        if (!__Pyx_PyErr_Occurred()) {
            PyObject *exc = PyExc_StopIteration;
            #ifdef __Pyx_AsyncGen_USED
            if (__Pyx_AsyncGen_CheckExact(gen))
                exc = __Pyx_PyExc_StopAsyncIteration;
            #endif
            __Pyx_PyErr_SetNone(exc);
        }
    }
    return retval;
}
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3)
static CYTHON_INLINE
PyObject *__Pyx_PyGen_Send(PyGenObject *gen, PyObject *arg) {
#if PY_VERSION_HEX <= 0x030A00A1
    return _PyGen_Send(gen, arg);
#else
    PyObject *result;
    if (PyIter_Send((PyObject*)gen, arg ? arg : Py_None, &result) == PYGEN_RETURN) {
        if (PyAsyncGen_CheckExact(gen)) {
            assert(result == Py_None);
            PyErr_SetNone(PyExc_StopAsyncIteration);
        }
        else if (result == Py_None) {
            PyErr_SetNone(PyExc_StopIteration);
        }
        else {
#if PY_VERSION_HEX < 0x030d00A1
            _PyGen_SetStopIterationValue(result);
#else
            if (!PyTuple_Check(result) && !PyExceptionInstance_Check(result)) {
                PyErr_SetObject(PyExc_StopIteration, result);
            } else {
                PyObject *exc = __Pyx_PyObject_CallOneArg(PyExc_StopIteration, result);
                if (likely(exc != NULL)) {
                    PyErr_SetObject(PyExc_StopIteration, exc);
                    Py_DECREF(exc);
                }
            }
#endif
        }
        Py_DECREF(result);
        result = NULL;
    }
    return result;
#endif
}
#endif
static CYTHON_INLINE
PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) {
    PyObject *ret;
    PyObject *val = NULL;
    __Pyx_Coroutine_Undelegate(gen);
    __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val);
    ret = __Pyx_Coroutine_SendEx(gen, val, 0);
    Py_XDECREF(val);
    return ret;
}
static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) {
    PyObject *retval;
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
    PyObject *yf = gen->yieldfrom;
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
    if (yf) {
        PyObject *ret;
        gen->is_running = 1;
        #ifdef __Pyx_Generator_USED
        if (__Pyx_Generator_CheckExact(yf)) {
            ret = __Pyx_Coroutine_Send(yf, value);
        } else
        #endif
        #ifdef __Pyx_Coroutine_USED
        if (__Pyx_Coroutine_Check(yf)) {
            ret = __Pyx_Coroutine_Send(yf, value);
        } else
        #endif
        #ifdef __Pyx_AsyncGen_USED
        if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
            ret = __Pyx_async_gen_asend_send(yf, value);
        } else
        #endif
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3)
        if (PyGen_CheckExact(yf)) {
            ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
        } else
        #endif
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact) && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3)
        if (PyCoro_CheckExact(yf)) {
            ret = __Pyx_PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value);
        } else
        #endif
        {
            if (value == Py_None)
                ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf);
            else
                ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value);
        }
        gen->is_running = 0;
        if (likely(ret)) {
            return ret;
        }
        retval = __Pyx_Coroutine_FinishDelegation(gen);
    } else {
        retval = __Pyx_Coroutine_SendEx(gen, value, 0);
    }
    return __Pyx_Coroutine_MethodReturn(self, retval);
}
static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) {
    PyObject *retval = NULL;
    int err = 0;
    #ifdef __Pyx_Generator_USED
    if (__Pyx_Generator_CheckExact(yf)) {
        retval = __Pyx_Coroutine_Close(yf);
        if (!retval)
            return -1;
    } else
    #endif
    #ifdef __Pyx_Coroutine_USED
    if (__Pyx_Coroutine_Check(yf)) {
        retval = __Pyx_Coroutine_Close(yf);
        if (!retval)
            return -1;
    } else
    if (__Pyx_CoroutineAwait_CheckExact(yf)) {
        retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL);
        if (!retval)
            return -1;
    } else
    #endif
    #ifdef __Pyx_AsyncGen_USED
    if (__pyx_PyAsyncGenASend_CheckExact(yf)) {
        retval = __Pyx_async_gen_asend_close(yf, NULL);
    } else
    if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) {
        retval = __Pyx_async_gen_athrow_close(yf, NULL);
    } else
    #endif
    {
        PyObject *meth;
        gen->is_running = 1;
        meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_close);
        if (unlikely(!meth)) {
            if (unlikely(PyErr_Occurred())) {
                PyErr_WriteUnraisable(yf);
            }
        } else {
            retval = __Pyx_PyObject_CallNoArg(meth);
            Py_DECREF(meth);
            if (unlikely(!retval))
                err = -1;
        }
        gen->is_running = 0;
    }
    Py_XDECREF(retval);
    return err;
}
static PyObject *__Pyx_Generator_Next(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self;
    PyObject *yf = gen->yieldfrom;
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
    if (yf) {
        PyObject *ret;
        gen->is_running = 1;
        #ifdef __Pyx_Generator_USED
        if (__Pyx_Generator_CheckExact(yf)) {
            ret = __Pyx_Generator_Next(yf);
        } else
        #endif
        #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3)
        if (PyGen_CheckExact(yf)) {
            ret = __Pyx_PyGen_Send((PyGenObject*)yf, NULL);
        } else
        #endif
        #ifdef __Pyx_Coroutine_USED
        if (__Pyx_Coroutine_Check(yf)) {
            ret = __Pyx_Coroutine_Send(yf, Py_None);
        } else
        #endif
            ret = __Pyx_PyObject_GetIterNextFunc(yf)(yf);
        gen->is_running = 0;
        if (likely(ret)) {
            return ret;
        }
        return __Pyx_Coroutine_FinishDelegation(gen);
    }
    return __Pyx_Coroutine_SendEx(gen, Py_None, 0);
}
static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, PyObject *arg) {
    CYTHON_UNUSED_VAR(arg);
    return __Pyx_Coroutine_Close(self);
}
static PyObject *__Pyx_Coroutine_Close(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
    PyObject *retval, *raised_exception;
    PyObject *yf = gen->yieldfrom;
    int err = 0;
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
    if (yf) {
        Py_INCREF(yf);
        err = __Pyx_Coroutine_CloseIter(gen, yf);
        __Pyx_Coroutine_Undelegate(gen);
        Py_DECREF(yf);
    }
    if (err == 0)
        PyErr_SetNone(PyExc_GeneratorExit);
    retval = __Pyx_Coroutine_SendEx(gen, NULL, 1);
    if (unlikely(retval)) {
        const char *msg;
        Py_DECREF(retval);
        if ((0)) {
        #ifdef __Pyx_Coroutine_USED
        } else if (__Pyx_Coroutine_Check(self)) {
            msg = "coroutine ignored GeneratorExit";
        #endif
        #ifdef __Pyx_AsyncGen_USED
        } else if (__Pyx_AsyncGen_CheckExact(self)) {
#if PY_VERSION_HEX < 0x03060000
            msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)";
#else
            msg = "async generator ignored GeneratorExit";
#endif
        #endif
        } else {
            msg = "generator ignored GeneratorExit";
        }
        PyErr_SetString(PyExc_RuntimeError, msg);
        return NULL;
    }
    raised_exception = PyErr_Occurred();
    if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) {
        if (raised_exception) PyErr_Clear();
        Py_INCREF(Py_None);
        return Py_None;
    }
    return NULL;
}
static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb,
                                        PyObject *args, int close_on_genexit) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
    PyObject *yf = gen->yieldfrom;
    if (unlikely(gen->is_running))
        return __Pyx_Coroutine_AlreadyRunningError(gen);
    if (yf) {
        PyObject *ret;
        Py_INCREF(yf);
        if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) {
            int err = __Pyx_Coroutine_CloseIter(gen, yf);
            Py_DECREF(yf);
            __Pyx_Coroutine_Undelegate(gen);
            if (err < 0)
                return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0));
            goto throw_here;
        }
        gen->is_running = 1;
        if (0
        #ifdef __Pyx_Generator_USED
            || __Pyx_Generator_CheckExact(yf)
        #endif
        #ifdef __Pyx_Coroutine_USED
            || __Pyx_Coroutine_Check(yf)
        #endif
            ) {
            ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit);
        #ifdef __Pyx_Coroutine_USED
        } else if (__Pyx_CoroutineAwait_CheckExact(yf)) {
            ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit);
        #endif
        } else {
            PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, __pyx_n_s_throw);
            if (unlikely(!meth)) {
                Py_DECREF(yf);
                if (unlikely(PyErr_Occurred())) {
                    gen->is_running = 0;
                    return NULL;
                }
                __Pyx_Coroutine_Undelegate(gen);
                gen->is_running = 0;
                goto throw_here;
            }
            if (likely(args)) {
                ret = __Pyx_PyObject_Call(meth, args, NULL);
            } else {
                PyObject *cargs[4] = {NULL, typ, val, tb};
                ret = __Pyx_PyObject_FastCall(meth, cargs+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET);
            }
            Py_DECREF(meth);
        }
        gen->is_running = 0;
        Py_DECREF(yf);
        if (!ret) {
            ret = __Pyx_Coroutine_FinishDelegation(gen);
        }
        return __Pyx_Coroutine_MethodReturn(self, ret);
    }
throw_here:
    __Pyx_Raise(typ, val, tb, NULL);
    return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0));
}
static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) {
    PyObject *typ;
    PyObject *val = NULL;
    PyObject *tb = NULL;
    if (unlikely(!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)))
        return NULL;
    return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1);
}
static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) {
#if PY_VERSION_HEX >= 0x030B00a4
    Py_VISIT(exc_state->exc_value);
#else
    Py_VISIT(exc_state->exc_type);
    Py_VISIT(exc_state->exc_value);
    Py_VISIT(exc_state->exc_traceback);
#endif
    return 0;
}
static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) {
    Py_VISIT(gen->closure);
    Py_VISIT(gen->classobj);
    Py_VISIT(gen->yieldfrom);
    return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg);
}
static int __Pyx_Coroutine_clear(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
    Py_CLEAR(gen->closure);
    Py_CLEAR(gen->classobj);
    Py_CLEAR(gen->yieldfrom);
    __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state);
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(self)) {
        Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer);
    }
#endif
    Py_CLEAR(gen->gi_code);
    Py_CLEAR(gen->gi_frame);
    Py_CLEAR(gen->gi_name);
    Py_CLEAR(gen->gi_qualname);
    Py_CLEAR(gen->gi_modulename);
    return 0;
}
static void __Pyx_Coroutine_dealloc(PyObject *self) {
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
    PyObject_GC_UnTrack(gen);
    if (gen->gi_weakreflist != NULL)
        PyObject_ClearWeakRefs(self);
    if (gen->resume_label >= 0) {
        PyObject_GC_Track(self);
#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE
        if (unlikely(PyObject_CallFinalizerFromDealloc(self)))
#else
        Py_TYPE(gen)->tp_del(self);
        if (unlikely(Py_REFCNT(self) > 0))
#endif
        {
            return;
        }
        PyObject_GC_UnTrack(self);
    }
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(self)) {
        /* We have to handle this case for asynchronous generators
           right here, because this code has to be between UNTRACK
           and GC_Del. */
        Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer);
    }
#endif
    __Pyx_Coroutine_clear(self);
    __Pyx_PyHeapTypeObject_GC_Del(gen);
}
static void __Pyx_Coroutine_del(PyObject *self) {
    PyObject *error_type, *error_value, *error_traceback;
    __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self;
    __Pyx_PyThreadState_declare
    if (gen->resume_label < 0) {
        return;
    }
#if !CYTHON_USE_TP_FINALIZE
    assert(self->ob_refcnt == 0);
    __Pyx_SET_REFCNT(self, 1);
#endif
    __Pyx_PyThreadState_assign
    __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
#ifdef __Pyx_AsyncGen_USED
    if (__Pyx_AsyncGen_CheckExact(self)) {
        __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self;
        PyObject *finalizer = agen->ag_finalizer;
        if (finalizer && !agen->ag_closed) {
            PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self);
            if (unlikely(!res)) {
                PyErr_WriteUnraisable(self);
            } else {
                Py_DECREF(res);
            }
            __Pyx_ErrRestore(error_type, error_value, error_traceback);
            return;
        }
    }
#endif
    if (unlikely(gen->resume_label == 0 && !error_value)) {
#ifdef __Pyx_Coroutine_USED
#ifdef __Pyx_Generator_USED
    if (!__Pyx_Generator_CheckExact(self))
#endif
        {
        PyObject_GC_UnTrack(self);
#if PY_MAJOR_VERSION >= 3  || defined(PyErr_WarnFormat)
        if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0))
            PyErr_WriteUnraisable(self);
#else
        {PyObject *msg;
        char *cmsg;
        #if CYTHON_COMPILING_IN_PYPY
        msg = NULL;
        cmsg = (char*) "coroutine was never awaited";
        #else
        char *cname;
        PyObject *qualname;
        qualname = gen->gi_qualname;
        cname = PyString_AS_STRING(qualname);
        msg = PyString_FromFormat("coroutine '%.50s' was never awaited", cname);
        if (unlikely(!msg)) {
            PyErr_Clear();
            cmsg = (char*) "coroutine was never awaited";
        } else {
            cmsg = PyString_AS_STRING(msg);
        }
        #endif
        if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0))
            PyErr_WriteUnraisable(self);
        Py_XDECREF(msg);}
#endif
        PyObject_GC_Track(self);
        }
#endif
    } else {
        PyObject *res = __Pyx_Coroutine_Close(self);
        if (unlikely(!res)) {
            if (PyErr_Occurred())
                PyErr_WriteUnraisable(self);
        } else {
            Py_DECREF(res);
        }
    }
    __Pyx_ErrRestore(error_type, error_value, error_traceback);
#if !CYTHON_USE_TP_FINALIZE
    assert(Py_REFCNT(self) > 0);
    if (likely(--self->ob_refcnt == 0)) {
        return;
    }
    {
        Py_ssize_t refcnt = Py_REFCNT(self);
        _Py_NewReference(self);
        __Pyx_SET_REFCNT(self, refcnt);
    }
#if CYTHON_COMPILING_IN_CPYTHON
    assert(PyType_IS_GC(Py_TYPE(self)) &&
           _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
    _Py_DEC_REFTOTAL;
#endif
#ifdef COUNT_ALLOCS
    --Py_TYPE(self)->tp_frees;
    --Py_TYPE(self)->tp_allocs;
#endif
#endif
}
static PyObject *
__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, void *context)
{
    PyObject *name = self->gi_name;
    CYTHON_UNUSED_VAR(context);
    if (unlikely(!name)) name = Py_None;
    Py_INCREF(name);
    return name;
}
static int
__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, void *context)
{
    CYTHON_UNUSED_VAR(context);
#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;
    }
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(self->gi_name, value);
    return 0;
}
static PyObject *
__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, void *context)
{
    PyObject *name = self->gi_qualname;
    CYTHON_UNUSED_VAR(context);
    if (unlikely(!name)) name = Py_None;
    Py_INCREF(name);
    return name;
}
static int
__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, void *context)
{
    CYTHON_UNUSED_VAR(context);
#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;
    }
    Py_INCREF(value);
    __Pyx_Py_XDECREF_SET(self->gi_qualname, value);
    return 0;
}
static PyObject *
__Pyx_Coroutine_get_frame(__pyx_CoroutineObject *self, void *context)
{
    PyObject *frame = self->gi_frame;
    CYTHON_UNUSED_VAR(context);
    if (!frame) {
        if (unlikely(!self->gi_code)) {
            Py_RETURN_NONE;
        }
        frame = (PyObject *) PyFrame_New(
            PyThreadState_Get(),            /*PyThreadState *tstate,*/
            (PyCodeObject*) self->gi_code,  /*PyCodeObject *code,*/
            __pyx_d,                 /*PyObject *globals,*/
            0                               /*PyObject *locals*/
        );
        if (unlikely(!frame))
            return NULL;
        self->gi_frame = frame;
    }
    Py_INCREF(frame);
    return frame;
}
static __pyx_CoroutineObject *__Pyx__Coroutine_New(
            PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
            PyObject *name, PyObject *qualname, PyObject *module_name) {
    __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type);
    if (unlikely(!gen))
        return NULL;
    return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name);
}
static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit(
            __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure,
            PyObject *name, PyObject *qualname, PyObject *module_name) {
    gen->body = body;
    gen->closure = closure;
    Py_XINCREF(closure);
    gen->is_running = 0;
    gen->resume_label = 0;
    gen->classobj = NULL;
    gen->yieldfrom = NULL;
    #if PY_VERSION_HEX >= 0x030B00a4
    gen->gi_exc_state.exc_value = NULL;
    #else
    gen->gi_exc_state.exc_type = NULL;
    gen->gi_exc_state.exc_value = NULL;
    gen->gi_exc_state.exc_traceback = NULL;
    #endif
#if CYTHON_USE_EXC_INFO_STACK
    gen->gi_exc_state.previous_item = NULL;
#endif
    gen->gi_weakreflist = NULL;
    Py_XINCREF(qualname);
    gen->gi_qualname = qualname;
    Py_XINCREF(name);
    gen->gi_name = name;
    Py_XINCREF(module_name);
    gen->gi_modulename = module_name;
    Py_XINCREF(code);
    gen->gi_code = code;
    gen->gi_frame = NULL;
    PyObject_GC_Track(gen);
    return gen;
}

/* PatchModuleWithCoroutine */
static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) {
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
    int result;
    PyObject *globals, *result_obj;
    globals = PyDict_New();  if (unlikely(!globals)) goto ignore;
    result = PyDict_SetItemString(globals, "_cython_coroutine_type",
    #ifdef __Pyx_Coroutine_USED
        (PyObject*)__pyx_CoroutineType);
    #else
        Py_None);
    #endif
    if (unlikely(result < 0)) goto ignore;
    result = PyDict_SetItemString(globals, "_cython_generator_type",
    #ifdef __Pyx_Generator_USED
        (PyObject*)__pyx_GeneratorType);
    #else
        Py_None);
    #endif
    if (unlikely(result < 0)) goto ignore;
    if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore;
    if (unlikely(PyDict_SetItemString(globals, "__builtins__", __pyx_b) < 0)) goto ignore;
    result_obj = PyRun_String(py_code, Py_file_input, globals, globals);
    if (unlikely(!result_obj)) goto ignore;
    Py_DECREF(result_obj);
    Py_DECREF(globals);
    return module;
ignore:
    Py_XDECREF(globals);
    PyErr_WriteUnraisable(module);
    if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) {
        Py_DECREF(module);
        module = NULL;
    }
#else
    py_code++;
#endif
    return module;
}

/* PatchGeneratorABC */
#ifndef CYTHON_REGISTER_ABCS
#define CYTHON_REGISTER_ABCS 1
#endif
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
static PyObject* __Pyx_patch_abc_module(PyObject *module);
static PyObject* __Pyx_patch_abc_module(PyObject *module) {
    module = __Pyx_Coroutine_patch_module(
        module, ""
"if _cython_generator_type is not None:\n"
"    try: Generator = _module.Generator\n"
"    except AttributeError: pass\n"
"    else: Generator.register(_cython_generator_type)\n"
"if _cython_coroutine_type is not None:\n"
"    try: Coroutine = _module.Coroutine\n"
"    except AttributeError: pass\n"
"    else: Coroutine.register(_cython_coroutine_type)\n"
    );
    return module;
}
#endif
static int __Pyx_patch_abc(void) {
#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
    static int abc_patched = 0;
    if (CYTHON_REGISTER_ABCS && !abc_patched) {
        PyObject *module;
        module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections");
        if (unlikely(!module)) {
            PyErr_WriteUnraisable(NULL);
            if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning,
                    ((PY_MAJOR_VERSION >= 3) ?
                        "Cython module failed to register with collections.abc module" :
                        "Cython module failed to register with collections module"), 1) < 0)) {
                return -1;
            }
        } else {
            module = __Pyx_patch_abc_module(module);
            abc_patched = 1;
            if (unlikely(!module))
                return -1;
            Py_DECREF(module);
        }
        module = PyImport_ImportModule("backports_abc");
        if (module) {
            module = __Pyx_patch_abc_module(module);
            Py_XDECREF(module);
        }
        if (!module) {
            PyErr_Clear();
        }
    }
#else
    if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL);
#endif
    return 0;
}

/* Generator */
static PyMethodDef __pyx_Generator_methods[] = {
    {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O,
     (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")},
    {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS,
     (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")},
    {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS,
     (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")},
    {0, 0, 0, 0}
};
static PyMemberDef __pyx_Generator_memberlist[] = {
    {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL},
    {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY,
     (char*) PyDoc_STR("object being iterated by 'yield from', or None")},
    {(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL},
    {(char *) "__module__", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_modulename), 0, 0},
#if CYTHON_USE_TYPE_SPECS
    {(char *) "__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CoroutineObject, gi_weakreflist), READONLY, 0},
#endif
    {0, 0, 0, 0, 0}
};
static PyGetSetDef __pyx_Generator_getsets[] = {
    {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name,
     (char*) PyDoc_STR("name of the generator"), 0},
    {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname,
     (char*) PyDoc_STR("qualified name of the generator"), 0},
    {(char *) "gi_frame", (getter)__Pyx_Coroutine_get_frame, NULL,
     (char*) PyDoc_STR("Frame of the generator"), 0},
    {0, 0, 0, 0, 0}
};
#if CYTHON_USE_TYPE_SPECS
static PyType_Slot __pyx_GeneratorType_slots[] = {
    {Py_tp_dealloc, (void *)__Pyx_Coroutine_dealloc},
    {Py_tp_traverse, (void *)__Pyx_Coroutine_traverse},
    {Py_tp_iter, (void *)PyObject_SelfIter},
    {Py_tp_iternext, (void *)__Pyx_Generator_Next},
    {Py_tp_methods, (void *)__pyx_Generator_methods},
    {Py_tp_members, (void *)__pyx_Generator_memberlist},
    {Py_tp_getset, (void *)__pyx_Generator_getsets},
    {Py_tp_getattro, (void *) __Pyx_PyObject_GenericGetAttrNoDict},
#if CYTHON_USE_TP_FINALIZE
    {Py_tp_finalize, (void *)__Pyx_Coroutine_del},
#endif
    {0, 0},
};
static PyType_Spec __pyx_GeneratorType_spec = {
    __PYX_TYPE_MODULE_PREFIX "generator",
    sizeof(__pyx_CoroutineObject),
    0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
    __pyx_GeneratorType_slots
};
#else
static PyTypeObject __pyx_GeneratorType_type = {
    PyVarObject_HEAD_INIT(0, 0)
    __PYX_TYPE_MODULE_PREFIX "generator",
    sizeof(__pyx_CoroutineObject),
    0,
    (destructor) __Pyx_Coroutine_dealloc,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
    0,
    (traverseproc) __Pyx_Coroutine_traverse,
    0,
    0,
    offsetof(__pyx_CoroutineObject, gi_weakreflist),
    0,
    (iternextfunc) __Pyx_Generator_Next,
    __pyx_Generator_methods,
    __pyx_Generator_memberlist,
    __pyx_Generator_getsets,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
#if CYTHON_USE_TP_FINALIZE
    0,
#else
    __Pyx_Coroutine_del,
#endif
    0,
#if CYTHON_USE_TP_FINALIZE
    __Pyx_Coroutine_del,
#elif PY_VERSION_HEX >= 0x030400a1
    0,
#endif
#if PY_VERSION_HEX >= 0x030800b1 && (!CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07030800)
    0,
#endif
#if __PYX_NEED_TP_PRINT_SLOT
    0,
#endif
#if PY_VERSION_HEX >= 0x030C0000
    0,
#endif
#if PY_VERSION_HEX >= 0x030d00A4
    0,
#endif
#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
    0,
#endif
};
#endif
static int __pyx_Generator_init(PyObject *module) {
#if CYTHON_USE_TYPE_SPECS
    __pyx_GeneratorType = __Pyx_FetchCommonTypeFromSpec(module, &__pyx_GeneratorType_spec, NULL);
#else
    CYTHON_UNUSED_VAR(module);
    __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
    __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
    __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
#endif
    if (unlikely(!__pyx_GeneratorType)) {
        return -1;
    }
    return 0;
}

/* CheckBinaryVersion */
static unsigned long __Pyx_get_runtime_version(void) {
#if __PYX_LIMITED_VERSION_HEX >= 0x030B00A4
    return Py_Version & ~0xFFUL;
#else
    const char* rt_version = Py_GetVersion();
    unsigned long version = 0;
    unsigned long factor = 0x01000000UL;
    unsigned int digit = 0;
    int i = 0;
    while (factor) {
        while ('0' <= rt_version[i] && rt_version[i] <= '9') {
            digit = digit * 10 + (unsigned int) (rt_version[i] - '0');
            ++i;
        }
        version += factor * digit;
        if (rt_version[i] != '.')
            break;
        digit = 0;
        factor >>= 8;
        ++i;
    }
    return version;
#endif
}
static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) {
    const unsigned long MAJOR_MINOR = 0xFFFF0000UL;
    if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR))
        return 0;
    if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR)))
        return 1;
    {
        char message[200];
        PyOS_snprintf(message, sizeof(message),
                      "compile time Python version %d.%d "
                      "of module '%.100s' "
                      "%s "
                      "runtime version %d.%d",
                       (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF),
                       __Pyx_MODULE_NAME,
                       (allow_newer) ? "was newer than" : "does not match",
                       (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF)
       );
        return PyErr_WarnEx(NULL, message, 1);
    }
}

/* InitStrings */
#if PY_MAJOR_VERSION >= 3
static int __Pyx_InitString(__Pyx_StringTabEntry t, PyObject **str) {
    if (t.is_unicode | t.is_str) {
        if (t.intern) {
            *str = PyUnicode_InternFromString(t.s);
        } else if (t.encoding) {
            *str = PyUnicode_Decode(t.s, t.n - 1, t.encoding, NULL);
        } else {
            *str = PyUnicode_FromStringAndSize(t.s, t.n - 1);
        }
    } else {
        *str = PyBytes_FromStringAndSize(t.s, t.n - 1);
    }
    if (!*str)
        return -1;
    if (PyObject_Hash(*str) == -1)
        return -1;
    return 0;
}
#endif
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
    while (t->p) {
        #if PY_MAJOR_VERSION >= 3
        __Pyx_InitString(*t, t->p);
        #else
        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);
        }
        if (!*t->p)
            return -1;
        if (PyObject_Hash(*t->p) == -1)
            return -1;
        #endif
        ++t;
    }
    return 0;
}

#include <string.h>
static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) {
    size_t len = strlen(s);
    if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) {
        PyErr_SetString(PyExc_OverflowError, "byte string is too long");
        return -1;
    }
    return (Py_ssize_t) len;
}
static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
    Py_ssize_t len = __Pyx_ssize_strlen(c_str);
    if (unlikely(len < 0)) return NULL;
    return __Pyx_PyUnicode_FromStringAndSize(c_str, len);
}
static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) {
    Py_ssize_t len = __Pyx_ssize_strlen(c_str);
    if (unlikely(len < 0)) return NULL;
    return PyByteArray_FromStringAndSize(c_str, len);
}
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 && !CYTHON_COMPILING_IN_LIMITED_API) || (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) {
    __Pyx_TypeName result_type_name = __Pyx_PyType_GetName(Py_TYPE(result));
#if PY_MAJOR_VERSION >= 3
    if (PyLong_Check(result)) {
        if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
                "__int__ returned non-int (type " __Pyx_FMT_TYPENAME ").  "
                "The ability to return an instance of a strict subclass of int is deprecated, "
                "and may be removed in a future version of Python.",
                result_type_name)) {
            __Pyx_DECREF_TypeName(result_type_name);
            Py_DECREF(result);
            return NULL;
        }
        __Pyx_DECREF_TypeName(result_type_name);
        return result;
    }
#endif
    PyErr_Format(PyExc_TypeError,
                 "__%.4s__ returned non-%.4s (type " __Pyx_FMT_TYPENAME ")",
                 type_name, type_name, result_type_name);
    __Pyx_DECREF_TypeName(result_type_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
    if (likely(__Pyx_PyLong_IsCompact(b))) {
        return __Pyx_PyLong_CompactValue(b);
    } else {
      const digit* digits = __Pyx_PyLong_Digits(b);
      const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b);
      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);
}


/* #### Code section: utility_code_pragmas_end ### */
#ifdef _MSC_VER
#pragma warning( pop )
#endif



/* #### Code section: end ### */
#endif /* Py_PYTHON_H */
