17db96d56Sopenharmony_ci/* cursor.c - the cursor type
27db96d56Sopenharmony_ci *
37db96d56Sopenharmony_ci * Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
47db96d56Sopenharmony_ci *
57db96d56Sopenharmony_ci * This file is part of pysqlite.
67db96d56Sopenharmony_ci *
77db96d56Sopenharmony_ci * This software is provided 'as-is', without any express or implied
87db96d56Sopenharmony_ci * warranty.  In no event will the authors be held liable for any damages
97db96d56Sopenharmony_ci * arising from the use of this software.
107db96d56Sopenharmony_ci *
117db96d56Sopenharmony_ci * Permission is granted to anyone to use this software for any purpose,
127db96d56Sopenharmony_ci * including commercial applications, and to alter it and redistribute it
137db96d56Sopenharmony_ci * freely, subject to the following restrictions:
147db96d56Sopenharmony_ci *
157db96d56Sopenharmony_ci * 1. The origin of this software must not be misrepresented; you must not
167db96d56Sopenharmony_ci *    claim that you wrote the original software. If you use this software
177db96d56Sopenharmony_ci *    in a product, an acknowledgment in the product documentation would be
187db96d56Sopenharmony_ci *    appreciated but is not required.
197db96d56Sopenharmony_ci * 2. Altered source versions must be plainly marked as such, and must not be
207db96d56Sopenharmony_ci *    misrepresented as being the original software.
217db96d56Sopenharmony_ci * 3. This notice may not be removed or altered from any source distribution.
227db96d56Sopenharmony_ci */
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci#include "cursor.h"
257db96d56Sopenharmony_ci#include "microprotocols.h"
267db96d56Sopenharmony_ci#include "module.h"
277db96d56Sopenharmony_ci#include "util.h"
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_citypedef enum {
307db96d56Sopenharmony_ci    TYPE_LONG,
317db96d56Sopenharmony_ci    TYPE_FLOAT,
327db96d56Sopenharmony_ci    TYPE_UNICODE,
337db96d56Sopenharmony_ci    TYPE_BUFFER,
347db96d56Sopenharmony_ci    TYPE_UNKNOWN
357db96d56Sopenharmony_ci} parameter_type;
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self)))
387db96d56Sopenharmony_ci#include "clinic/cursor.c.h"
397db96d56Sopenharmony_ci#undef clinic_state
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_cistatic inline int
427db96d56Sopenharmony_cicheck_cursor_locked(pysqlite_Cursor *cur)
437db96d56Sopenharmony_ci{
447db96d56Sopenharmony_ci    if (cur->locked) {
457db96d56Sopenharmony_ci        PyErr_SetString(cur->connection->ProgrammingError,
467db96d56Sopenharmony_ci                        "Recursive use of cursors not allowed.");
477db96d56Sopenharmony_ci        return 0;
487db96d56Sopenharmony_ci    }
497db96d56Sopenharmony_ci    return 1;
507db96d56Sopenharmony_ci}
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci/*[clinic input]
537db96d56Sopenharmony_cimodule _sqlite3
547db96d56Sopenharmony_ciclass _sqlite3.Cursor "pysqlite_Cursor *" "clinic_state()->CursorType"
557db96d56Sopenharmony_ci[clinic start generated code]*/
567db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c5b8115c5cf30f1]*/
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci/*
597db96d56Sopenharmony_ci * Registers a cursor with the connection.
607db96d56Sopenharmony_ci *
617db96d56Sopenharmony_ci * 0 => error; 1 => ok
627db96d56Sopenharmony_ci */
637db96d56Sopenharmony_cistatic int
647db96d56Sopenharmony_ciregister_cursor(pysqlite_Connection *connection, PyObject *cursor)
657db96d56Sopenharmony_ci{
667db96d56Sopenharmony_ci    PyObject *weakref = PyWeakref_NewRef((PyObject *)cursor, NULL);
677db96d56Sopenharmony_ci    if (weakref == NULL) {
687db96d56Sopenharmony_ci        return 0;
697db96d56Sopenharmony_ci    }
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci    if (PyList_Append(connection->cursors, weakref) < 0) {
727db96d56Sopenharmony_ci        Py_CLEAR(weakref);
737db96d56Sopenharmony_ci        return 0;
747db96d56Sopenharmony_ci    }
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci    Py_DECREF(weakref);
777db96d56Sopenharmony_ci    return 1;
787db96d56Sopenharmony_ci}
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci/*[clinic input]
817db96d56Sopenharmony_ci_sqlite3.Cursor.__init__ as pysqlite_cursor_init
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci    connection: object(type='pysqlite_Connection *', subclass_of='clinic_state()->ConnectionType')
847db96d56Sopenharmony_ci    /
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci[clinic start generated code]*/
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_cistatic int
897db96d56Sopenharmony_cipysqlite_cursor_init_impl(pysqlite_Cursor *self,
907db96d56Sopenharmony_ci                          pysqlite_Connection *connection)
917db96d56Sopenharmony_ci/*[clinic end generated code: output=ac59dce49a809ca8 input=23d4265b534989fb]*/
927db96d56Sopenharmony_ci{
937db96d56Sopenharmony_ci    if (!check_cursor_locked(self)) {
947db96d56Sopenharmony_ci        return -1;
957db96d56Sopenharmony_ci    }
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci    Py_INCREF(connection);
987db96d56Sopenharmony_ci    Py_XSETREF(self->connection, connection);
997db96d56Sopenharmony_ci    Py_CLEAR(self->statement);
1007db96d56Sopenharmony_ci    Py_CLEAR(self->row_cast_map);
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci    Py_INCREF(Py_None);
1037db96d56Sopenharmony_ci    Py_XSETREF(self->description, Py_None);
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci    Py_INCREF(Py_None);
1067db96d56Sopenharmony_ci    Py_XSETREF(self->lastrowid, Py_None);
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci    self->arraysize = 1;
1097db96d56Sopenharmony_ci    self->closed = 0;
1107db96d56Sopenharmony_ci    self->rowcount = -1L;
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci    Py_INCREF(Py_None);
1137db96d56Sopenharmony_ci    Py_XSETREF(self->row_factory, Py_None);
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci    if (!pysqlite_check_thread(self->connection)) {
1167db96d56Sopenharmony_ci        return -1;
1177db96d56Sopenharmony_ci    }
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci    if (!register_cursor(connection, (PyObject *)self)) {
1207db96d56Sopenharmony_ci        return -1;
1217db96d56Sopenharmony_ci    }
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_ci    self->initialized = 1;
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci    return 0;
1267db96d56Sopenharmony_ci}
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_cistatic inline int
1297db96d56Sopenharmony_cistmt_reset(pysqlite_Statement *self)
1307db96d56Sopenharmony_ci{
1317db96d56Sopenharmony_ci    int rc = SQLITE_OK;
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci    if (self->in_use && self->st) {
1347db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
1357db96d56Sopenharmony_ci        rc = sqlite3_reset(self->st);
1367db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci        if (rc == SQLITE_OK) {
1397db96d56Sopenharmony_ci            self->in_use = 0;
1407db96d56Sopenharmony_ci        }
1417db96d56Sopenharmony_ci    }
1427db96d56Sopenharmony_ci
1437db96d56Sopenharmony_ci    return rc;
1447db96d56Sopenharmony_ci}
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_cistatic int
1477db96d56Sopenharmony_cicursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg)
1487db96d56Sopenharmony_ci{
1497db96d56Sopenharmony_ci    Py_VISIT(Py_TYPE(self));
1507db96d56Sopenharmony_ci    Py_VISIT(self->connection);
1517db96d56Sopenharmony_ci    Py_VISIT(self->description);
1527db96d56Sopenharmony_ci    Py_VISIT(self->row_cast_map);
1537db96d56Sopenharmony_ci    Py_VISIT(self->lastrowid);
1547db96d56Sopenharmony_ci    Py_VISIT(self->row_factory);
1557db96d56Sopenharmony_ci    Py_VISIT(self->statement);
1567db96d56Sopenharmony_ci    return 0;
1577db96d56Sopenharmony_ci}
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_cistatic int
1607db96d56Sopenharmony_cicursor_clear(pysqlite_Cursor *self)
1617db96d56Sopenharmony_ci{
1627db96d56Sopenharmony_ci    Py_CLEAR(self->connection);
1637db96d56Sopenharmony_ci    Py_CLEAR(self->description);
1647db96d56Sopenharmony_ci    Py_CLEAR(self->row_cast_map);
1657db96d56Sopenharmony_ci    Py_CLEAR(self->lastrowid);
1667db96d56Sopenharmony_ci    Py_CLEAR(self->row_factory);
1677db96d56Sopenharmony_ci    if (self->statement) {
1687db96d56Sopenharmony_ci        /* Reset the statement if the user has not closed the cursor */
1697db96d56Sopenharmony_ci        stmt_reset(self->statement);
1707db96d56Sopenharmony_ci        Py_CLEAR(self->statement);
1717db96d56Sopenharmony_ci    }
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci    return 0;
1747db96d56Sopenharmony_ci}
1757db96d56Sopenharmony_ci
1767db96d56Sopenharmony_cistatic void
1777db96d56Sopenharmony_cicursor_dealloc(pysqlite_Cursor *self)
1787db96d56Sopenharmony_ci{
1797db96d56Sopenharmony_ci    PyTypeObject *tp = Py_TYPE(self);
1807db96d56Sopenharmony_ci    PyObject_GC_UnTrack(self);
1817db96d56Sopenharmony_ci    if (self->in_weakreflist != NULL) {
1827db96d56Sopenharmony_ci        PyObject_ClearWeakRefs((PyObject*)self);
1837db96d56Sopenharmony_ci    }
1847db96d56Sopenharmony_ci    tp->tp_clear((PyObject *)self);
1857db96d56Sopenharmony_ci    tp->tp_free(self);
1867db96d56Sopenharmony_ci    Py_DECREF(tp);
1877db96d56Sopenharmony_ci}
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_cistatic PyObject *
1907db96d56Sopenharmony_ci_pysqlite_get_converter(pysqlite_state *state, const char *keystr,
1917db96d56Sopenharmony_ci                        Py_ssize_t keylen)
1927db96d56Sopenharmony_ci{
1937db96d56Sopenharmony_ci    PyObject *key;
1947db96d56Sopenharmony_ci    PyObject *upcase_key;
1957db96d56Sopenharmony_ci    PyObject *retval;
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci    key = PyUnicode_FromStringAndSize(keystr, keylen);
1987db96d56Sopenharmony_ci    if (!key) {
1997db96d56Sopenharmony_ci        return NULL;
2007db96d56Sopenharmony_ci    }
2017db96d56Sopenharmony_ci    upcase_key = PyObject_CallMethodNoArgs(key, state->str_upper);
2027db96d56Sopenharmony_ci    Py_DECREF(key);
2037db96d56Sopenharmony_ci    if (!upcase_key) {
2047db96d56Sopenharmony_ci        return NULL;
2057db96d56Sopenharmony_ci    }
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci    retval = PyDict_GetItemWithError(state->converters, upcase_key);
2087db96d56Sopenharmony_ci    Py_DECREF(upcase_key);
2097db96d56Sopenharmony_ci
2107db96d56Sopenharmony_ci    return retval;
2117db96d56Sopenharmony_ci}
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_cistatic int
2147db96d56Sopenharmony_cipysqlite_build_row_cast_map(pysqlite_Cursor* self)
2157db96d56Sopenharmony_ci{
2167db96d56Sopenharmony_ci    int i;
2177db96d56Sopenharmony_ci    const char* pos;
2187db96d56Sopenharmony_ci    const char* decltype;
2197db96d56Sopenharmony_ci    PyObject* converter;
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci    if (!self->connection->detect_types) {
2227db96d56Sopenharmony_ci        return 0;
2237db96d56Sopenharmony_ci    }
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ci    Py_XSETREF(self->row_cast_map, PyList_New(0));
2267db96d56Sopenharmony_ci    if (!self->row_cast_map) {
2277db96d56Sopenharmony_ci        return -1;
2287db96d56Sopenharmony_ci    }
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci    for (i = 0; i < sqlite3_column_count(self->statement->st); i++) {
2317db96d56Sopenharmony_ci        converter = NULL;
2327db96d56Sopenharmony_ci
2337db96d56Sopenharmony_ci        if (self->connection->detect_types & PARSE_COLNAMES) {
2347db96d56Sopenharmony_ci            const char *colname = sqlite3_column_name(self->statement->st, i);
2357db96d56Sopenharmony_ci            if (colname == NULL) {
2367db96d56Sopenharmony_ci                PyErr_NoMemory();
2377db96d56Sopenharmony_ci                Py_CLEAR(self->row_cast_map);
2387db96d56Sopenharmony_ci                return -1;
2397db96d56Sopenharmony_ci            }
2407db96d56Sopenharmony_ci            const char *type_start = NULL;
2417db96d56Sopenharmony_ci            for (pos = colname; *pos != 0; pos++) {
2427db96d56Sopenharmony_ci                if (*pos == '[') {
2437db96d56Sopenharmony_ci                    type_start = pos + 1;
2447db96d56Sopenharmony_ci                }
2457db96d56Sopenharmony_ci                else if (*pos == ']' && type_start != NULL) {
2467db96d56Sopenharmony_ci                    pysqlite_state *state = self->connection->state;
2477db96d56Sopenharmony_ci                    converter = _pysqlite_get_converter(state, type_start,
2487db96d56Sopenharmony_ci                                                        pos - type_start);
2497db96d56Sopenharmony_ci                    if (!converter && PyErr_Occurred()) {
2507db96d56Sopenharmony_ci                        Py_CLEAR(self->row_cast_map);
2517db96d56Sopenharmony_ci                        return -1;
2527db96d56Sopenharmony_ci                    }
2537db96d56Sopenharmony_ci                    break;
2547db96d56Sopenharmony_ci                }
2557db96d56Sopenharmony_ci            }
2567db96d56Sopenharmony_ci        }
2577db96d56Sopenharmony_ci
2587db96d56Sopenharmony_ci        if (!converter && self->connection->detect_types & PARSE_DECLTYPES) {
2597db96d56Sopenharmony_ci            decltype = sqlite3_column_decltype(self->statement->st, i);
2607db96d56Sopenharmony_ci            if (decltype) {
2617db96d56Sopenharmony_ci                for (pos = decltype;;pos++) {
2627db96d56Sopenharmony_ci                    /* Converter names are split at '(' and blanks.
2637db96d56Sopenharmony_ci                     * This allows 'INTEGER NOT NULL' to be treated as 'INTEGER' and
2647db96d56Sopenharmony_ci                     * 'NUMBER(10)' to be treated as 'NUMBER', for example.
2657db96d56Sopenharmony_ci                     * In other words, it will work as people expect it to work.*/
2667db96d56Sopenharmony_ci                    if (*pos == ' ' || *pos == '(' || *pos == 0) {
2677db96d56Sopenharmony_ci                        pysqlite_state *state = self->connection->state;
2687db96d56Sopenharmony_ci                        converter = _pysqlite_get_converter(state, decltype,
2697db96d56Sopenharmony_ci                                                            pos - decltype);
2707db96d56Sopenharmony_ci                        if (!converter && PyErr_Occurred()) {
2717db96d56Sopenharmony_ci                            Py_CLEAR(self->row_cast_map);
2727db96d56Sopenharmony_ci                            return -1;
2737db96d56Sopenharmony_ci                        }
2747db96d56Sopenharmony_ci                        break;
2757db96d56Sopenharmony_ci                    }
2767db96d56Sopenharmony_ci                }
2777db96d56Sopenharmony_ci            }
2787db96d56Sopenharmony_ci        }
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci        if (!converter) {
2817db96d56Sopenharmony_ci            converter = Py_None;
2827db96d56Sopenharmony_ci        }
2837db96d56Sopenharmony_ci
2847db96d56Sopenharmony_ci        if (PyList_Append(self->row_cast_map, converter) != 0) {
2857db96d56Sopenharmony_ci            Py_CLEAR(self->row_cast_map);
2867db96d56Sopenharmony_ci            return -1;
2877db96d56Sopenharmony_ci        }
2887db96d56Sopenharmony_ci    }
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci    return 0;
2917db96d56Sopenharmony_ci}
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_cistatic PyObject *
2947db96d56Sopenharmony_ci_pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname)
2957db96d56Sopenharmony_ci{
2967db96d56Sopenharmony_ci    const char* pos;
2977db96d56Sopenharmony_ci    Py_ssize_t len;
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_ci    if (self->connection->detect_types & PARSE_COLNAMES) {
3007db96d56Sopenharmony_ci        for (pos = colname; *pos; pos++) {
3017db96d56Sopenharmony_ci            if (*pos == '[') {
3027db96d56Sopenharmony_ci                if ((pos != colname) && (*(pos-1) == ' ')) {
3037db96d56Sopenharmony_ci                    pos--;
3047db96d56Sopenharmony_ci                }
3057db96d56Sopenharmony_ci                break;
3067db96d56Sopenharmony_ci            }
3077db96d56Sopenharmony_ci        }
3087db96d56Sopenharmony_ci        len = pos - colname;
3097db96d56Sopenharmony_ci    }
3107db96d56Sopenharmony_ci    else {
3117db96d56Sopenharmony_ci        len = strlen(colname);
3127db96d56Sopenharmony_ci    }
3137db96d56Sopenharmony_ci    return PyUnicode_FromStringAndSize(colname, len);
3147db96d56Sopenharmony_ci}
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci/*
3177db96d56Sopenharmony_ci * Returns a row from the currently active SQLite statement
3187db96d56Sopenharmony_ci *
3197db96d56Sopenharmony_ci * Precondidition:
3207db96d56Sopenharmony_ci * - sqlite3_step() has been called before and it returned SQLITE_ROW.
3217db96d56Sopenharmony_ci */
3227db96d56Sopenharmony_cistatic PyObject *
3237db96d56Sopenharmony_ci_pysqlite_fetch_one_row(pysqlite_Cursor* self)
3247db96d56Sopenharmony_ci{
3257db96d56Sopenharmony_ci    int i, numcols;
3267db96d56Sopenharmony_ci    PyObject* row;
3277db96d56Sopenharmony_ci    int coltype;
3287db96d56Sopenharmony_ci    PyObject* converter;
3297db96d56Sopenharmony_ci    PyObject* converted;
3307db96d56Sopenharmony_ci    Py_ssize_t nbytes;
3317db96d56Sopenharmony_ci    char buf[200];
3327db96d56Sopenharmony_ci    const char* colname;
3337db96d56Sopenharmony_ci    PyObject* error_msg;
3347db96d56Sopenharmony_ci
3357db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
3367db96d56Sopenharmony_ci    numcols = sqlite3_data_count(self->statement->st);
3377db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci    row = PyTuple_New(numcols);
3407db96d56Sopenharmony_ci    if (!row)
3417db96d56Sopenharmony_ci        return NULL;
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci    sqlite3 *db = self->connection->db;
3447db96d56Sopenharmony_ci    for (i = 0; i < numcols; i++) {
3457db96d56Sopenharmony_ci        if (self->connection->detect_types
3467db96d56Sopenharmony_ci                && self->row_cast_map != NULL
3477db96d56Sopenharmony_ci                && i < PyList_GET_SIZE(self->row_cast_map))
3487db96d56Sopenharmony_ci        {
3497db96d56Sopenharmony_ci            converter = PyList_GET_ITEM(self->row_cast_map, i);
3507db96d56Sopenharmony_ci        }
3517db96d56Sopenharmony_ci        else {
3527db96d56Sopenharmony_ci            converter = Py_None;
3537db96d56Sopenharmony_ci        }
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ci        /*
3567db96d56Sopenharmony_ci         * Note, sqlite3_column_bytes() must come after sqlite3_column_blob()
3577db96d56Sopenharmony_ci         * or sqlite3_column_text().
3587db96d56Sopenharmony_ci         *
3597db96d56Sopenharmony_ci         * See https://sqlite.org/c3ref/column_blob.html for details.
3607db96d56Sopenharmony_ci         */
3617db96d56Sopenharmony_ci        if (converter != Py_None) {
3627db96d56Sopenharmony_ci            const void *blob = sqlite3_column_blob(self->statement->st, i);
3637db96d56Sopenharmony_ci            if (blob == NULL) {
3647db96d56Sopenharmony_ci                if (sqlite3_errcode(db) == SQLITE_NOMEM) {
3657db96d56Sopenharmony_ci                    PyErr_NoMemory();
3667db96d56Sopenharmony_ci                    goto error;
3677db96d56Sopenharmony_ci                }
3687db96d56Sopenharmony_ci                converted = Py_NewRef(Py_None);
3697db96d56Sopenharmony_ci            }
3707db96d56Sopenharmony_ci            else {
3717db96d56Sopenharmony_ci                nbytes = sqlite3_column_bytes(self->statement->st, i);
3727db96d56Sopenharmony_ci                PyObject *item = PyBytes_FromStringAndSize(blob, nbytes);
3737db96d56Sopenharmony_ci                if (item == NULL) {
3747db96d56Sopenharmony_ci                    goto error;
3757db96d56Sopenharmony_ci                }
3767db96d56Sopenharmony_ci                converted = PyObject_CallOneArg(converter, item);
3777db96d56Sopenharmony_ci                Py_DECREF(item);
3787db96d56Sopenharmony_ci            }
3797db96d56Sopenharmony_ci        } else {
3807db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
3817db96d56Sopenharmony_ci            coltype = sqlite3_column_type(self->statement->st, i);
3827db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
3837db96d56Sopenharmony_ci            if (coltype == SQLITE_NULL) {
3847db96d56Sopenharmony_ci                converted = Py_NewRef(Py_None);
3857db96d56Sopenharmony_ci            } else if (coltype == SQLITE_INTEGER) {
3867db96d56Sopenharmony_ci                converted = PyLong_FromLongLong(sqlite3_column_int64(self->statement->st, i));
3877db96d56Sopenharmony_ci            } else if (coltype == SQLITE_FLOAT) {
3887db96d56Sopenharmony_ci                converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
3897db96d56Sopenharmony_ci            } else if (coltype == SQLITE_TEXT) {
3907db96d56Sopenharmony_ci                const char *text = (const char*)sqlite3_column_text(self->statement->st, i);
3917db96d56Sopenharmony_ci                if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) {
3927db96d56Sopenharmony_ci                    PyErr_NoMemory();
3937db96d56Sopenharmony_ci                    goto error;
3947db96d56Sopenharmony_ci                }
3957db96d56Sopenharmony_ci
3967db96d56Sopenharmony_ci                nbytes = sqlite3_column_bytes(self->statement->st, i);
3977db96d56Sopenharmony_ci                if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) {
3987db96d56Sopenharmony_ci                    converted = PyUnicode_FromStringAndSize(text, nbytes);
3997db96d56Sopenharmony_ci                    if (!converted && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
4007db96d56Sopenharmony_ci                        PyErr_Clear();
4017db96d56Sopenharmony_ci                        colname = sqlite3_column_name(self->statement->st, i);
4027db96d56Sopenharmony_ci                        if (colname == NULL) {
4037db96d56Sopenharmony_ci                            PyErr_NoMemory();
4047db96d56Sopenharmony_ci                            goto error;
4057db96d56Sopenharmony_ci                        }
4067db96d56Sopenharmony_ci                        PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column '%s' with text '%s'",
4077db96d56Sopenharmony_ci                                     colname , text);
4087db96d56Sopenharmony_ci                        error_msg = PyUnicode_Decode(buf, strlen(buf), "ascii", "replace");
4097db96d56Sopenharmony_ci
4107db96d56Sopenharmony_ci                        PyObject *exc = self->connection->OperationalError;
4117db96d56Sopenharmony_ci                        if (!error_msg) {
4127db96d56Sopenharmony_ci                            PyErr_SetString(exc, "Could not decode to UTF-8");
4137db96d56Sopenharmony_ci                        } else {
4147db96d56Sopenharmony_ci                            PyErr_SetObject(exc, error_msg);
4157db96d56Sopenharmony_ci                            Py_DECREF(error_msg);
4167db96d56Sopenharmony_ci                        }
4177db96d56Sopenharmony_ci                    }
4187db96d56Sopenharmony_ci                } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) {
4197db96d56Sopenharmony_ci                    converted = PyBytes_FromStringAndSize(text, nbytes);
4207db96d56Sopenharmony_ci                } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) {
4217db96d56Sopenharmony_ci                    converted = PyByteArray_FromStringAndSize(text, nbytes);
4227db96d56Sopenharmony_ci                } else {
4237db96d56Sopenharmony_ci                    converted = PyObject_CallFunction(self->connection->text_factory, "y#", text, nbytes);
4247db96d56Sopenharmony_ci                }
4257db96d56Sopenharmony_ci            } else {
4267db96d56Sopenharmony_ci                /* coltype == SQLITE_BLOB */
4277db96d56Sopenharmony_ci                const void *blob = sqlite3_column_blob(self->statement->st, i);
4287db96d56Sopenharmony_ci                if (blob == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) {
4297db96d56Sopenharmony_ci                    PyErr_NoMemory();
4307db96d56Sopenharmony_ci                    goto error;
4317db96d56Sopenharmony_ci                }
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_ci                nbytes = sqlite3_column_bytes(self->statement->st, i);
4347db96d56Sopenharmony_ci                converted = PyBytes_FromStringAndSize(blob, nbytes);
4357db96d56Sopenharmony_ci            }
4367db96d56Sopenharmony_ci        }
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_ci        if (!converted) {
4397db96d56Sopenharmony_ci            goto error;
4407db96d56Sopenharmony_ci        }
4417db96d56Sopenharmony_ci        PyTuple_SET_ITEM(row, i, converted);
4427db96d56Sopenharmony_ci    }
4437db96d56Sopenharmony_ci
4447db96d56Sopenharmony_ci    if (PyErr_Occurred())
4457db96d56Sopenharmony_ci        goto error;
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ci    return row;
4487db96d56Sopenharmony_ci
4497db96d56Sopenharmony_cierror:
4507db96d56Sopenharmony_ci    Py_DECREF(row);
4517db96d56Sopenharmony_ci    return NULL;
4527db96d56Sopenharmony_ci}
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ci/*
4557db96d56Sopenharmony_ci * Checks if a cursor object is usable.
4567db96d56Sopenharmony_ci *
4577db96d56Sopenharmony_ci * 0 => error; 1 => ok
4587db96d56Sopenharmony_ci */
4597db96d56Sopenharmony_cistatic int check_cursor(pysqlite_Cursor* cur)
4607db96d56Sopenharmony_ci{
4617db96d56Sopenharmony_ci    if (!cur->initialized) {
4627db96d56Sopenharmony_ci        pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(cur));
4637db96d56Sopenharmony_ci        PyErr_SetString(state->ProgrammingError,
4647db96d56Sopenharmony_ci                        "Base Cursor.__init__ not called.");
4657db96d56Sopenharmony_ci        return 0;
4667db96d56Sopenharmony_ci    }
4677db96d56Sopenharmony_ci
4687db96d56Sopenharmony_ci    if (cur->closed) {
4697db96d56Sopenharmony_ci        PyErr_SetString(cur->connection->state->ProgrammingError,
4707db96d56Sopenharmony_ci                        "Cannot operate on a closed cursor.");
4717db96d56Sopenharmony_ci        return 0;
4727db96d56Sopenharmony_ci    }
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ci    return (pysqlite_check_thread(cur->connection)
4757db96d56Sopenharmony_ci            && pysqlite_check_connection(cur->connection)
4767db96d56Sopenharmony_ci            && check_cursor_locked(cur));
4777db96d56Sopenharmony_ci}
4787db96d56Sopenharmony_ci
4797db96d56Sopenharmony_cistatic int
4807db96d56Sopenharmony_cibegin_transaction(pysqlite_Connection *self)
4817db96d56Sopenharmony_ci{
4827db96d56Sopenharmony_ci    assert(self->isolation_level != NULL);
4837db96d56Sopenharmony_ci    int rc;
4847db96d56Sopenharmony_ci
4857db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
4867db96d56Sopenharmony_ci    sqlite3_stmt *statement;
4877db96d56Sopenharmony_ci    char begin_stmt[16] = "BEGIN ";
4887db96d56Sopenharmony_ci#ifdef Py_DEBUG
4897db96d56Sopenharmony_ci    size_t len = strlen(self->isolation_level);
4907db96d56Sopenharmony_ci    assert(len <= 9);
4917db96d56Sopenharmony_ci#endif
4927db96d56Sopenharmony_ci    (void)strcat(begin_stmt, self->isolation_level);
4937db96d56Sopenharmony_ci    rc = sqlite3_prepare_v2(self->db, begin_stmt, -1, &statement, NULL);
4947db96d56Sopenharmony_ci    if (rc == SQLITE_OK) {
4957db96d56Sopenharmony_ci        (void)sqlite3_step(statement);
4967db96d56Sopenharmony_ci        rc = sqlite3_finalize(statement);
4977db96d56Sopenharmony_ci    }
4987db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
4997db96d56Sopenharmony_ci
5007db96d56Sopenharmony_ci    if (rc != SQLITE_OK) {
5017db96d56Sopenharmony_ci        (void)_pysqlite_seterror(self->state, self->db);
5027db96d56Sopenharmony_ci        return -1;
5037db96d56Sopenharmony_ci    }
5047db96d56Sopenharmony_ci
5057db96d56Sopenharmony_ci    return 0;
5067db96d56Sopenharmony_ci}
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_cistatic PyObject *
5097db96d56Sopenharmony_ciget_statement_from_cache(pysqlite_Cursor *self, PyObject *operation)
5107db96d56Sopenharmony_ci{
5117db96d56Sopenharmony_ci    PyObject *args[] = { NULL, operation, };  // Borrowed ref.
5127db96d56Sopenharmony_ci    PyObject *cache = self->connection->statement_cache;
5137db96d56Sopenharmony_ci    size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
5147db96d56Sopenharmony_ci    return PyObject_Vectorcall(cache, args + 1, nargsf, NULL);
5157db96d56Sopenharmony_ci}
5167db96d56Sopenharmony_ci
5177db96d56Sopenharmony_cistatic inline int
5187db96d56Sopenharmony_cistmt_step(sqlite3_stmt *statement)
5197db96d56Sopenharmony_ci{
5207db96d56Sopenharmony_ci    int rc;
5217db96d56Sopenharmony_ci
5227db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
5237db96d56Sopenharmony_ci    rc = sqlite3_step(statement);
5247db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
5257db96d56Sopenharmony_ci
5267db96d56Sopenharmony_ci    return rc;
5277db96d56Sopenharmony_ci}
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_cistatic int
5307db96d56Sopenharmony_cibind_param(pysqlite_state *state, pysqlite_Statement *self, int pos,
5317db96d56Sopenharmony_ci           PyObject *parameter)
5327db96d56Sopenharmony_ci{
5337db96d56Sopenharmony_ci    int rc = SQLITE_OK;
5347db96d56Sopenharmony_ci    const char *string;
5357db96d56Sopenharmony_ci    Py_ssize_t buflen;
5367db96d56Sopenharmony_ci    parameter_type paramtype;
5377db96d56Sopenharmony_ci
5387db96d56Sopenharmony_ci    if (parameter == Py_None) {
5397db96d56Sopenharmony_ci        rc = sqlite3_bind_null(self->st, pos);
5407db96d56Sopenharmony_ci        goto final;
5417db96d56Sopenharmony_ci    }
5427db96d56Sopenharmony_ci
5437db96d56Sopenharmony_ci    if (PyLong_CheckExact(parameter)) {
5447db96d56Sopenharmony_ci        paramtype = TYPE_LONG;
5457db96d56Sopenharmony_ci    } else if (PyFloat_CheckExact(parameter)) {
5467db96d56Sopenharmony_ci        paramtype = TYPE_FLOAT;
5477db96d56Sopenharmony_ci    } else if (PyUnicode_CheckExact(parameter)) {
5487db96d56Sopenharmony_ci        paramtype = TYPE_UNICODE;
5497db96d56Sopenharmony_ci    } else if (PyLong_Check(parameter)) {
5507db96d56Sopenharmony_ci        paramtype = TYPE_LONG;
5517db96d56Sopenharmony_ci    } else if (PyFloat_Check(parameter)) {
5527db96d56Sopenharmony_ci        paramtype = TYPE_FLOAT;
5537db96d56Sopenharmony_ci    } else if (PyUnicode_Check(parameter)) {
5547db96d56Sopenharmony_ci        paramtype = TYPE_UNICODE;
5557db96d56Sopenharmony_ci    } else if (PyObject_CheckBuffer(parameter)) {
5567db96d56Sopenharmony_ci        paramtype = TYPE_BUFFER;
5577db96d56Sopenharmony_ci    } else {
5587db96d56Sopenharmony_ci        paramtype = TYPE_UNKNOWN;
5597db96d56Sopenharmony_ci    }
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci    switch (paramtype) {
5627db96d56Sopenharmony_ci        case TYPE_LONG: {
5637db96d56Sopenharmony_ci            sqlite_int64 value = _pysqlite_long_as_int64(parameter);
5647db96d56Sopenharmony_ci            if (value == -1 && PyErr_Occurred())
5657db96d56Sopenharmony_ci                rc = -1;
5667db96d56Sopenharmony_ci            else
5677db96d56Sopenharmony_ci                rc = sqlite3_bind_int64(self->st, pos, value);
5687db96d56Sopenharmony_ci            break;
5697db96d56Sopenharmony_ci        }
5707db96d56Sopenharmony_ci        case TYPE_FLOAT: {
5717db96d56Sopenharmony_ci            double value = PyFloat_AsDouble(parameter);
5727db96d56Sopenharmony_ci            if (value == -1 && PyErr_Occurred()) {
5737db96d56Sopenharmony_ci                rc = -1;
5747db96d56Sopenharmony_ci            }
5757db96d56Sopenharmony_ci            else {
5767db96d56Sopenharmony_ci                rc = sqlite3_bind_double(self->st, pos, value);
5777db96d56Sopenharmony_ci            }
5787db96d56Sopenharmony_ci            break;
5797db96d56Sopenharmony_ci        }
5807db96d56Sopenharmony_ci        case TYPE_UNICODE:
5817db96d56Sopenharmony_ci            string = PyUnicode_AsUTF8AndSize(parameter, &buflen);
5827db96d56Sopenharmony_ci            if (string == NULL)
5837db96d56Sopenharmony_ci                return -1;
5847db96d56Sopenharmony_ci            if (buflen > INT_MAX) {
5857db96d56Sopenharmony_ci                PyErr_SetString(PyExc_OverflowError,
5867db96d56Sopenharmony_ci                                "string longer than INT_MAX bytes");
5877db96d56Sopenharmony_ci                return -1;
5887db96d56Sopenharmony_ci            }
5897db96d56Sopenharmony_ci            rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT);
5907db96d56Sopenharmony_ci            break;
5917db96d56Sopenharmony_ci        case TYPE_BUFFER: {
5927db96d56Sopenharmony_ci            Py_buffer view;
5937db96d56Sopenharmony_ci            if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) {
5947db96d56Sopenharmony_ci                return -1;
5957db96d56Sopenharmony_ci            }
5967db96d56Sopenharmony_ci            if (view.len > INT_MAX) {
5977db96d56Sopenharmony_ci                PyErr_SetString(PyExc_OverflowError,
5987db96d56Sopenharmony_ci                                "BLOB longer than INT_MAX bytes");
5997db96d56Sopenharmony_ci                PyBuffer_Release(&view);
6007db96d56Sopenharmony_ci                return -1;
6017db96d56Sopenharmony_ci            }
6027db96d56Sopenharmony_ci            rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT);
6037db96d56Sopenharmony_ci            PyBuffer_Release(&view);
6047db96d56Sopenharmony_ci            break;
6057db96d56Sopenharmony_ci        }
6067db96d56Sopenharmony_ci        case TYPE_UNKNOWN:
6077db96d56Sopenharmony_ci            PyErr_Format(state->ProgrammingError,
6087db96d56Sopenharmony_ci                    "Error binding parameter %d: type '%s' is not supported",
6097db96d56Sopenharmony_ci                    pos, Py_TYPE(parameter)->tp_name);
6107db96d56Sopenharmony_ci            rc = -1;
6117db96d56Sopenharmony_ci    }
6127db96d56Sopenharmony_ci
6137db96d56Sopenharmony_cifinal:
6147db96d56Sopenharmony_ci    return rc;
6157db96d56Sopenharmony_ci}
6167db96d56Sopenharmony_ci
6177db96d56Sopenharmony_ci/* returns 0 if the object is one of Python's internal ones that don't need to be adapted */
6187db96d56Sopenharmony_cistatic inline int
6197db96d56Sopenharmony_cineed_adapt(pysqlite_state *state, PyObject *obj)
6207db96d56Sopenharmony_ci{
6217db96d56Sopenharmony_ci    if (state->BaseTypeAdapted) {
6227db96d56Sopenharmony_ci        return 1;
6237db96d56Sopenharmony_ci    }
6247db96d56Sopenharmony_ci
6257db96d56Sopenharmony_ci    if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj)
6267db96d56Sopenharmony_ci          || PyUnicode_CheckExact(obj) || PyByteArray_CheckExact(obj)) {
6277db96d56Sopenharmony_ci        return 0;
6287db96d56Sopenharmony_ci    } else {
6297db96d56Sopenharmony_ci        return 1;
6307db96d56Sopenharmony_ci    }
6317db96d56Sopenharmony_ci}
6327db96d56Sopenharmony_ci
6337db96d56Sopenharmony_cistatic void
6347db96d56Sopenharmony_cibind_parameters(pysqlite_state *state, pysqlite_Statement *self,
6357db96d56Sopenharmony_ci                PyObject *parameters)
6367db96d56Sopenharmony_ci{
6377db96d56Sopenharmony_ci    PyObject* current_param;
6387db96d56Sopenharmony_ci    PyObject* adapted;
6397db96d56Sopenharmony_ci    const char* binding_name;
6407db96d56Sopenharmony_ci    int i;
6417db96d56Sopenharmony_ci    int rc;
6427db96d56Sopenharmony_ci    int num_params_needed;
6437db96d56Sopenharmony_ci    Py_ssize_t num_params;
6447db96d56Sopenharmony_ci
6457db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
6467db96d56Sopenharmony_ci    num_params_needed = sqlite3_bind_parameter_count(self->st);
6477db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
6487db96d56Sopenharmony_ci
6497db96d56Sopenharmony_ci    if (PyTuple_CheckExact(parameters) || PyList_CheckExact(parameters) || (!PyDict_Check(parameters) && PySequence_Check(parameters))) {
6507db96d56Sopenharmony_ci        /* parameters passed as sequence */
6517db96d56Sopenharmony_ci        if (PyTuple_CheckExact(parameters)) {
6527db96d56Sopenharmony_ci            num_params = PyTuple_GET_SIZE(parameters);
6537db96d56Sopenharmony_ci        } else if (PyList_CheckExact(parameters)) {
6547db96d56Sopenharmony_ci            num_params = PyList_GET_SIZE(parameters);
6557db96d56Sopenharmony_ci        } else {
6567db96d56Sopenharmony_ci            num_params = PySequence_Size(parameters);
6577db96d56Sopenharmony_ci            if (num_params == -1) {
6587db96d56Sopenharmony_ci                return;
6597db96d56Sopenharmony_ci            }
6607db96d56Sopenharmony_ci        }
6617db96d56Sopenharmony_ci        if (num_params != num_params_needed) {
6627db96d56Sopenharmony_ci            PyErr_Format(state->ProgrammingError,
6637db96d56Sopenharmony_ci                         "Incorrect number of bindings supplied. The current "
6647db96d56Sopenharmony_ci                         "statement uses %d, and there are %zd supplied.",
6657db96d56Sopenharmony_ci                         num_params_needed, num_params);
6667db96d56Sopenharmony_ci            return;
6677db96d56Sopenharmony_ci        }
6687db96d56Sopenharmony_ci        for (i = 0; i < num_params; i++) {
6697db96d56Sopenharmony_ci            if (PyTuple_CheckExact(parameters)) {
6707db96d56Sopenharmony_ci                PyObject *item = PyTuple_GET_ITEM(parameters, i);
6717db96d56Sopenharmony_ci                current_param = Py_NewRef(item);
6727db96d56Sopenharmony_ci            } else if (PyList_CheckExact(parameters)) {
6737db96d56Sopenharmony_ci                PyObject *item = PyList_GetItem(parameters, i);
6747db96d56Sopenharmony_ci                current_param = Py_XNewRef(item);
6757db96d56Sopenharmony_ci            } else {
6767db96d56Sopenharmony_ci                current_param = PySequence_GetItem(parameters, i);
6777db96d56Sopenharmony_ci            }
6787db96d56Sopenharmony_ci            if (!current_param) {
6797db96d56Sopenharmony_ci                return;
6807db96d56Sopenharmony_ci            }
6817db96d56Sopenharmony_ci
6827db96d56Sopenharmony_ci            if (!need_adapt(state, current_param)) {
6837db96d56Sopenharmony_ci                adapted = current_param;
6847db96d56Sopenharmony_ci            } else {
6857db96d56Sopenharmony_ci                PyObject *protocol = (PyObject *)state->PrepareProtocolType;
6867db96d56Sopenharmony_ci                adapted = pysqlite_microprotocols_adapt(state, current_param,
6877db96d56Sopenharmony_ci                                                        protocol,
6887db96d56Sopenharmony_ci                                                        current_param);
6897db96d56Sopenharmony_ci                Py_DECREF(current_param);
6907db96d56Sopenharmony_ci                if (!adapted) {
6917db96d56Sopenharmony_ci                    return;
6927db96d56Sopenharmony_ci                }
6937db96d56Sopenharmony_ci            }
6947db96d56Sopenharmony_ci
6957db96d56Sopenharmony_ci            rc = bind_param(state, self, i + 1, adapted);
6967db96d56Sopenharmony_ci            Py_DECREF(adapted);
6977db96d56Sopenharmony_ci
6987db96d56Sopenharmony_ci            if (rc != SQLITE_OK) {
6997db96d56Sopenharmony_ci                PyObject *exc, *val, *tb;
7007db96d56Sopenharmony_ci                PyErr_Fetch(&exc, &val, &tb);
7017db96d56Sopenharmony_ci                sqlite3 *db = sqlite3_db_handle(self->st);
7027db96d56Sopenharmony_ci                _pysqlite_seterror(state, db);
7037db96d56Sopenharmony_ci                _PyErr_ChainExceptions(exc, val, tb);
7047db96d56Sopenharmony_ci                return;
7057db96d56Sopenharmony_ci            }
7067db96d56Sopenharmony_ci        }
7077db96d56Sopenharmony_ci    } else if (PyDict_Check(parameters)) {
7087db96d56Sopenharmony_ci        /* parameters passed as dictionary */
7097db96d56Sopenharmony_ci        for (i = 1; i <= num_params_needed; i++) {
7107db96d56Sopenharmony_ci            PyObject *binding_name_obj;
7117db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
7127db96d56Sopenharmony_ci            binding_name = sqlite3_bind_parameter_name(self->st, i);
7137db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
7147db96d56Sopenharmony_ci            if (!binding_name) {
7157db96d56Sopenharmony_ci                PyErr_Format(state->ProgrammingError,
7167db96d56Sopenharmony_ci                             "Binding %d has no name, but you supplied a "
7177db96d56Sopenharmony_ci                             "dictionary (which has only names).", i);
7187db96d56Sopenharmony_ci                return;
7197db96d56Sopenharmony_ci            }
7207db96d56Sopenharmony_ci
7217db96d56Sopenharmony_ci            binding_name++; /* skip first char (the colon) */
7227db96d56Sopenharmony_ci            binding_name_obj = PyUnicode_FromString(binding_name);
7237db96d56Sopenharmony_ci            if (!binding_name_obj) {
7247db96d56Sopenharmony_ci                return;
7257db96d56Sopenharmony_ci            }
7267db96d56Sopenharmony_ci            if (PyDict_CheckExact(parameters)) {
7277db96d56Sopenharmony_ci                PyObject *item = PyDict_GetItemWithError(parameters, binding_name_obj);
7287db96d56Sopenharmony_ci                current_param = Py_XNewRef(item);
7297db96d56Sopenharmony_ci            } else {
7307db96d56Sopenharmony_ci                current_param = PyObject_GetItem(parameters, binding_name_obj);
7317db96d56Sopenharmony_ci            }
7327db96d56Sopenharmony_ci            Py_DECREF(binding_name_obj);
7337db96d56Sopenharmony_ci            if (!current_param) {
7347db96d56Sopenharmony_ci                if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) {
7357db96d56Sopenharmony_ci                    PyErr_Format(state->ProgrammingError,
7367db96d56Sopenharmony_ci                                 "You did not supply a value for binding "
7377db96d56Sopenharmony_ci                                 "parameter :%s.", binding_name);
7387db96d56Sopenharmony_ci                }
7397db96d56Sopenharmony_ci                return;
7407db96d56Sopenharmony_ci            }
7417db96d56Sopenharmony_ci
7427db96d56Sopenharmony_ci            if (!need_adapt(state, current_param)) {
7437db96d56Sopenharmony_ci                adapted = current_param;
7447db96d56Sopenharmony_ci            } else {
7457db96d56Sopenharmony_ci                PyObject *protocol = (PyObject *)state->PrepareProtocolType;
7467db96d56Sopenharmony_ci                adapted = pysqlite_microprotocols_adapt(state, current_param,
7477db96d56Sopenharmony_ci                                                        protocol,
7487db96d56Sopenharmony_ci                                                        current_param);
7497db96d56Sopenharmony_ci                Py_DECREF(current_param);
7507db96d56Sopenharmony_ci                if (!adapted) {
7517db96d56Sopenharmony_ci                    return;
7527db96d56Sopenharmony_ci                }
7537db96d56Sopenharmony_ci            }
7547db96d56Sopenharmony_ci
7557db96d56Sopenharmony_ci            rc = bind_param(state, self, i, adapted);
7567db96d56Sopenharmony_ci            Py_DECREF(adapted);
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_ci            if (rc != SQLITE_OK) {
7597db96d56Sopenharmony_ci                PyObject *exc, *val, *tb;
7607db96d56Sopenharmony_ci                PyErr_Fetch(&exc, &val, &tb);
7617db96d56Sopenharmony_ci                sqlite3 *db = sqlite3_db_handle(self->st);
7627db96d56Sopenharmony_ci                _pysqlite_seterror(state, db);
7637db96d56Sopenharmony_ci                _PyErr_ChainExceptions(exc, val, tb);
7647db96d56Sopenharmony_ci                return;
7657db96d56Sopenharmony_ci           }
7667db96d56Sopenharmony_ci        }
7677db96d56Sopenharmony_ci    } else {
7687db96d56Sopenharmony_ci        PyErr_SetString(state->ProgrammingError,
7697db96d56Sopenharmony_ci                        "parameters are of unsupported type");
7707db96d56Sopenharmony_ci    }
7717db96d56Sopenharmony_ci}
7727db96d56Sopenharmony_ci
7737db96d56Sopenharmony_cistatic inline void
7747db96d56Sopenharmony_cistmt_mark_dirty(pysqlite_Statement *self)
7757db96d56Sopenharmony_ci{
7767db96d56Sopenharmony_ci    self->in_use = 1;
7777db96d56Sopenharmony_ci}
7787db96d56Sopenharmony_ci
7797db96d56Sopenharmony_ciPyObject *
7807db96d56Sopenharmony_ci_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument)
7817db96d56Sopenharmony_ci{
7827db96d56Sopenharmony_ci    PyObject* parameters_list = NULL;
7837db96d56Sopenharmony_ci    PyObject* parameters_iter = NULL;
7847db96d56Sopenharmony_ci    PyObject* parameters = NULL;
7857db96d56Sopenharmony_ci    int i;
7867db96d56Sopenharmony_ci    int rc;
7877db96d56Sopenharmony_ci    int numcols;
7887db96d56Sopenharmony_ci    PyObject* column_name;
7897db96d56Sopenharmony_ci
7907db96d56Sopenharmony_ci    if (!check_cursor(self)) {
7917db96d56Sopenharmony_ci        goto error;
7927db96d56Sopenharmony_ci    }
7937db96d56Sopenharmony_ci
7947db96d56Sopenharmony_ci    self->locked = 1;
7957db96d56Sopenharmony_ci
7967db96d56Sopenharmony_ci    if (multiple) {
7977db96d56Sopenharmony_ci        if (PyIter_Check(second_argument)) {
7987db96d56Sopenharmony_ci            /* iterator */
7997db96d56Sopenharmony_ci            parameters_iter = Py_NewRef(second_argument);
8007db96d56Sopenharmony_ci        } else {
8017db96d56Sopenharmony_ci            /* sequence */
8027db96d56Sopenharmony_ci            parameters_iter = PyObject_GetIter(second_argument);
8037db96d56Sopenharmony_ci            if (!parameters_iter) {
8047db96d56Sopenharmony_ci                goto error;
8057db96d56Sopenharmony_ci            }
8067db96d56Sopenharmony_ci        }
8077db96d56Sopenharmony_ci    } else {
8087db96d56Sopenharmony_ci        parameters_list = PyList_New(0);
8097db96d56Sopenharmony_ci        if (!parameters_list) {
8107db96d56Sopenharmony_ci            goto error;
8117db96d56Sopenharmony_ci        }
8127db96d56Sopenharmony_ci
8137db96d56Sopenharmony_ci        if (second_argument == NULL) {
8147db96d56Sopenharmony_ci            second_argument = PyTuple_New(0);
8157db96d56Sopenharmony_ci            if (!second_argument) {
8167db96d56Sopenharmony_ci                goto error;
8177db96d56Sopenharmony_ci            }
8187db96d56Sopenharmony_ci        } else {
8197db96d56Sopenharmony_ci            Py_INCREF(second_argument);
8207db96d56Sopenharmony_ci        }
8217db96d56Sopenharmony_ci        if (PyList_Append(parameters_list, second_argument) != 0) {
8227db96d56Sopenharmony_ci            Py_DECREF(second_argument);
8237db96d56Sopenharmony_ci            goto error;
8247db96d56Sopenharmony_ci        }
8257db96d56Sopenharmony_ci        Py_DECREF(second_argument);
8267db96d56Sopenharmony_ci
8277db96d56Sopenharmony_ci        parameters_iter = PyObject_GetIter(parameters_list);
8287db96d56Sopenharmony_ci        if (!parameters_iter) {
8297db96d56Sopenharmony_ci            goto error;
8307db96d56Sopenharmony_ci        }
8317db96d56Sopenharmony_ci    }
8327db96d56Sopenharmony_ci
8337db96d56Sopenharmony_ci    if (self->statement != NULL) {
8347db96d56Sopenharmony_ci        /* There is an active statement */
8357db96d56Sopenharmony_ci        stmt_reset(self->statement);
8367db96d56Sopenharmony_ci    }
8377db96d56Sopenharmony_ci
8387db96d56Sopenharmony_ci    /* reset description */
8397db96d56Sopenharmony_ci    Py_INCREF(Py_None);
8407db96d56Sopenharmony_ci    Py_SETREF(self->description, Py_None);
8417db96d56Sopenharmony_ci
8427db96d56Sopenharmony_ci    if (self->statement) {
8437db96d56Sopenharmony_ci        (void)stmt_reset(self->statement);
8447db96d56Sopenharmony_ci    }
8457db96d56Sopenharmony_ci
8467db96d56Sopenharmony_ci    PyObject *stmt = get_statement_from_cache(self, operation);
8477db96d56Sopenharmony_ci    Py_XSETREF(self->statement, (pysqlite_Statement *)stmt);
8487db96d56Sopenharmony_ci    if (!self->statement) {
8497db96d56Sopenharmony_ci        goto error;
8507db96d56Sopenharmony_ci    }
8517db96d56Sopenharmony_ci
8527db96d56Sopenharmony_ci    pysqlite_state *state = self->connection->state;
8537db96d56Sopenharmony_ci    if (multiple && sqlite3_stmt_readonly(self->statement->st)) {
8547db96d56Sopenharmony_ci        PyErr_SetString(state->ProgrammingError,
8557db96d56Sopenharmony_ci                        "executemany() can only execute DML statements.");
8567db96d56Sopenharmony_ci        goto error;
8577db96d56Sopenharmony_ci    }
8587db96d56Sopenharmony_ci
8597db96d56Sopenharmony_ci    if (self->statement->in_use) {
8607db96d56Sopenharmony_ci        Py_SETREF(self->statement,
8617db96d56Sopenharmony_ci                  pysqlite_statement_create(self->connection, operation));
8627db96d56Sopenharmony_ci        if (self->statement == NULL) {
8637db96d56Sopenharmony_ci            goto error;
8647db96d56Sopenharmony_ci        }
8657db96d56Sopenharmony_ci    }
8667db96d56Sopenharmony_ci
8677db96d56Sopenharmony_ci    stmt_reset(self->statement);
8687db96d56Sopenharmony_ci    stmt_mark_dirty(self->statement);
8697db96d56Sopenharmony_ci    self->rowcount = self->statement->is_dml ? 0L : -1L;
8707db96d56Sopenharmony_ci
8717db96d56Sopenharmony_ci    /* We start a transaction implicitly before a DML statement.
8727db96d56Sopenharmony_ci       SELECT is the only exception. See #9924. */
8737db96d56Sopenharmony_ci    if (self->connection->isolation_level
8747db96d56Sopenharmony_ci        && self->statement->is_dml
8757db96d56Sopenharmony_ci        && sqlite3_get_autocommit(self->connection->db))
8767db96d56Sopenharmony_ci    {
8777db96d56Sopenharmony_ci        if (begin_transaction(self->connection) < 0) {
8787db96d56Sopenharmony_ci            goto error;
8797db96d56Sopenharmony_ci        }
8807db96d56Sopenharmony_ci    }
8817db96d56Sopenharmony_ci
8827db96d56Sopenharmony_ci    while (1) {
8837db96d56Sopenharmony_ci        parameters = PyIter_Next(parameters_iter);
8847db96d56Sopenharmony_ci        if (!parameters) {
8857db96d56Sopenharmony_ci            break;
8867db96d56Sopenharmony_ci        }
8877db96d56Sopenharmony_ci
8887db96d56Sopenharmony_ci        stmt_mark_dirty(self->statement);
8897db96d56Sopenharmony_ci
8907db96d56Sopenharmony_ci        bind_parameters(state, self->statement, parameters);
8917db96d56Sopenharmony_ci        if (PyErr_Occurred()) {
8927db96d56Sopenharmony_ci            goto error;
8937db96d56Sopenharmony_ci        }
8947db96d56Sopenharmony_ci
8957db96d56Sopenharmony_ci        rc = stmt_step(self->statement->st);
8967db96d56Sopenharmony_ci        if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
8977db96d56Sopenharmony_ci            if (PyErr_Occurred()) {
8987db96d56Sopenharmony_ci                /* there was an error that occurred in a user-defined callback */
8997db96d56Sopenharmony_ci                if (state->enable_callback_tracebacks) {
9007db96d56Sopenharmony_ci                    PyErr_Print();
9017db96d56Sopenharmony_ci                } else {
9027db96d56Sopenharmony_ci                    PyErr_Clear();
9037db96d56Sopenharmony_ci                }
9047db96d56Sopenharmony_ci            }
9057db96d56Sopenharmony_ci            (void)stmt_reset(self->statement);
9067db96d56Sopenharmony_ci            _pysqlite_seterror(state, self->connection->db);
9077db96d56Sopenharmony_ci            goto error;
9087db96d56Sopenharmony_ci        }
9097db96d56Sopenharmony_ci
9107db96d56Sopenharmony_ci        if (pysqlite_build_row_cast_map(self) != 0) {
9117db96d56Sopenharmony_ci            _PyErr_FormatFromCause(state->OperationalError,
9127db96d56Sopenharmony_ci                                   "Error while building row_cast_map");
9137db96d56Sopenharmony_ci            goto error;
9147db96d56Sopenharmony_ci        }
9157db96d56Sopenharmony_ci
9167db96d56Sopenharmony_ci        assert(rc == SQLITE_ROW || rc == SQLITE_DONE);
9177db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
9187db96d56Sopenharmony_ci        numcols = sqlite3_column_count(self->statement->st);
9197db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
9207db96d56Sopenharmony_ci        if (self->description == Py_None && numcols > 0) {
9217db96d56Sopenharmony_ci            Py_SETREF(self->description, PyTuple_New(numcols));
9227db96d56Sopenharmony_ci            if (!self->description) {
9237db96d56Sopenharmony_ci                goto error;
9247db96d56Sopenharmony_ci            }
9257db96d56Sopenharmony_ci            for (i = 0; i < numcols; i++) {
9267db96d56Sopenharmony_ci                const char *colname;
9277db96d56Sopenharmony_ci                colname = sqlite3_column_name(self->statement->st, i);
9287db96d56Sopenharmony_ci                if (colname == NULL) {
9297db96d56Sopenharmony_ci                    PyErr_NoMemory();
9307db96d56Sopenharmony_ci                    goto error;
9317db96d56Sopenharmony_ci                }
9327db96d56Sopenharmony_ci                column_name = _pysqlite_build_column_name(self, colname);
9337db96d56Sopenharmony_ci                if (column_name == NULL) {
9347db96d56Sopenharmony_ci                    goto error;
9357db96d56Sopenharmony_ci                }
9367db96d56Sopenharmony_ci                PyObject *descriptor = PyTuple_Pack(7, column_name,
9377db96d56Sopenharmony_ci                                                    Py_None, Py_None, Py_None,
9387db96d56Sopenharmony_ci                                                    Py_None, Py_None, Py_None);
9397db96d56Sopenharmony_ci                Py_DECREF(column_name);
9407db96d56Sopenharmony_ci                if (descriptor == NULL) {
9417db96d56Sopenharmony_ci                    goto error;
9427db96d56Sopenharmony_ci                }
9437db96d56Sopenharmony_ci                PyTuple_SET_ITEM(self->description, i, descriptor);
9447db96d56Sopenharmony_ci            }
9457db96d56Sopenharmony_ci        }
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci        if (rc == SQLITE_DONE && !multiple) {
9487db96d56Sopenharmony_ci            if (self->statement->is_dml) {
9497db96d56Sopenharmony_ci                self->rowcount = (long)sqlite3_changes(self->connection->db);
9507db96d56Sopenharmony_ci            }
9517db96d56Sopenharmony_ci            stmt_reset(self->statement);
9527db96d56Sopenharmony_ci            Py_CLEAR(self->statement);
9537db96d56Sopenharmony_ci        }
9547db96d56Sopenharmony_ci
9557db96d56Sopenharmony_ci        if (multiple) {
9567db96d56Sopenharmony_ci            if (self->statement->is_dml && rc == SQLITE_DONE) {
9577db96d56Sopenharmony_ci                self->rowcount += (long)sqlite3_changes(self->connection->db);
9587db96d56Sopenharmony_ci            }
9597db96d56Sopenharmony_ci            stmt_reset(self->statement);
9607db96d56Sopenharmony_ci        }
9617db96d56Sopenharmony_ci        Py_XDECREF(parameters);
9627db96d56Sopenharmony_ci    }
9637db96d56Sopenharmony_ci
9647db96d56Sopenharmony_ci    if (!multiple) {
9657db96d56Sopenharmony_ci        sqlite_int64 lastrowid;
9667db96d56Sopenharmony_ci
9677db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
9687db96d56Sopenharmony_ci        lastrowid = sqlite3_last_insert_rowid(self->connection->db);
9697db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
9707db96d56Sopenharmony_ci
9717db96d56Sopenharmony_ci        Py_SETREF(self->lastrowid, PyLong_FromLongLong(lastrowid));
9727db96d56Sopenharmony_ci        // Fall through on error.
9737db96d56Sopenharmony_ci    }
9747db96d56Sopenharmony_ci
9757db96d56Sopenharmony_cierror:
9767db96d56Sopenharmony_ci    Py_XDECREF(parameters);
9777db96d56Sopenharmony_ci    Py_XDECREF(parameters_iter);
9787db96d56Sopenharmony_ci    Py_XDECREF(parameters_list);
9797db96d56Sopenharmony_ci
9807db96d56Sopenharmony_ci    self->locked = 0;
9817db96d56Sopenharmony_ci
9827db96d56Sopenharmony_ci    if (PyErr_Occurred()) {
9837db96d56Sopenharmony_ci        self->rowcount = -1L;
9847db96d56Sopenharmony_ci        return NULL;
9857db96d56Sopenharmony_ci    } else {
9867db96d56Sopenharmony_ci        return Py_NewRef((PyObject *)self);
9877db96d56Sopenharmony_ci    }
9887db96d56Sopenharmony_ci}
9897db96d56Sopenharmony_ci
9907db96d56Sopenharmony_ci/*[clinic input]
9917db96d56Sopenharmony_ci_sqlite3.Cursor.execute as pysqlite_cursor_execute
9927db96d56Sopenharmony_ci
9937db96d56Sopenharmony_ci    sql: unicode
9947db96d56Sopenharmony_ci    parameters: object(c_default = 'NULL') = ()
9957db96d56Sopenharmony_ci    /
9967db96d56Sopenharmony_ci
9977db96d56Sopenharmony_ciExecutes an SQL statement.
9987db96d56Sopenharmony_ci[clinic start generated code]*/
9997db96d56Sopenharmony_ci
10007db96d56Sopenharmony_cistatic PyObject *
10017db96d56Sopenharmony_cipysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql,
10027db96d56Sopenharmony_ci                             PyObject *parameters)
10037db96d56Sopenharmony_ci/*[clinic end generated code: output=d81b4655c7c0bbad input=a8e0200a11627f94]*/
10047db96d56Sopenharmony_ci{
10057db96d56Sopenharmony_ci    return _pysqlite_query_execute(self, 0, sql, parameters);
10067db96d56Sopenharmony_ci}
10077db96d56Sopenharmony_ci
10087db96d56Sopenharmony_ci/*[clinic input]
10097db96d56Sopenharmony_ci_sqlite3.Cursor.executemany as pysqlite_cursor_executemany
10107db96d56Sopenharmony_ci
10117db96d56Sopenharmony_ci    sql: unicode
10127db96d56Sopenharmony_ci    seq_of_parameters: object
10137db96d56Sopenharmony_ci    /
10147db96d56Sopenharmony_ci
10157db96d56Sopenharmony_ciRepeatedly executes an SQL statement.
10167db96d56Sopenharmony_ci[clinic start generated code]*/
10177db96d56Sopenharmony_ci
10187db96d56Sopenharmony_cistatic PyObject *
10197db96d56Sopenharmony_cipysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql,
10207db96d56Sopenharmony_ci                                 PyObject *seq_of_parameters)
10217db96d56Sopenharmony_ci/*[clinic end generated code: output=2c65a3c4733fb5d8 input=0d0a52e5eb7ccd35]*/
10227db96d56Sopenharmony_ci{
10237db96d56Sopenharmony_ci    return _pysqlite_query_execute(self, 1, sql, seq_of_parameters);
10247db96d56Sopenharmony_ci}
10257db96d56Sopenharmony_ci
10267db96d56Sopenharmony_ci/*[clinic input]
10277db96d56Sopenharmony_ci_sqlite3.Cursor.executescript as pysqlite_cursor_executescript
10287db96d56Sopenharmony_ci
10297db96d56Sopenharmony_ci    sql_script: str
10307db96d56Sopenharmony_ci    /
10317db96d56Sopenharmony_ci
10327db96d56Sopenharmony_ciExecutes multiple SQL statements at once.
10337db96d56Sopenharmony_ci[clinic start generated code]*/
10347db96d56Sopenharmony_ci
10357db96d56Sopenharmony_cistatic PyObject *
10367db96d56Sopenharmony_cipysqlite_cursor_executescript_impl(pysqlite_Cursor *self,
10377db96d56Sopenharmony_ci                                   const char *sql_script)
10387db96d56Sopenharmony_ci/*[clinic end generated code: output=8fd726dde1c65164 input=78f093be415a8a2c]*/
10397db96d56Sopenharmony_ci{
10407db96d56Sopenharmony_ci    if (!check_cursor(self)) {
10417db96d56Sopenharmony_ci        return NULL;
10427db96d56Sopenharmony_ci    }
10437db96d56Sopenharmony_ci
10447db96d56Sopenharmony_ci    size_t sql_len = strlen(sql_script);
10457db96d56Sopenharmony_ci    int max_length = sqlite3_limit(self->connection->db,
10467db96d56Sopenharmony_ci                                   SQLITE_LIMIT_SQL_LENGTH, -1);
10477db96d56Sopenharmony_ci    if (sql_len > (unsigned)max_length) {
10487db96d56Sopenharmony_ci        PyErr_SetString(self->connection->DataError,
10497db96d56Sopenharmony_ci                        "query string is too large");
10507db96d56Sopenharmony_ci        return NULL;
10517db96d56Sopenharmony_ci    }
10527db96d56Sopenharmony_ci
10537db96d56Sopenharmony_ci    // Commit if needed
10547db96d56Sopenharmony_ci    sqlite3 *db = self->connection->db;
10557db96d56Sopenharmony_ci    if (!sqlite3_get_autocommit(db)) {
10567db96d56Sopenharmony_ci        int rc = SQLITE_OK;
10577db96d56Sopenharmony_ci
10587db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
10597db96d56Sopenharmony_ci        rc = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
10607db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
10617db96d56Sopenharmony_ci
10627db96d56Sopenharmony_ci        if (rc != SQLITE_OK) {
10637db96d56Sopenharmony_ci            goto error;
10647db96d56Sopenharmony_ci        }
10657db96d56Sopenharmony_ci    }
10667db96d56Sopenharmony_ci
10677db96d56Sopenharmony_ci    while (1) {
10687db96d56Sopenharmony_ci        int rc;
10697db96d56Sopenharmony_ci        const char *tail;
10707db96d56Sopenharmony_ci
10717db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
10727db96d56Sopenharmony_ci        sqlite3_stmt *stmt;
10737db96d56Sopenharmony_ci        rc = sqlite3_prepare_v2(db, sql_script, (int)sql_len + 1, &stmt,
10747db96d56Sopenharmony_ci                                &tail);
10757db96d56Sopenharmony_ci        if (rc == SQLITE_OK) {
10767db96d56Sopenharmony_ci            do {
10777db96d56Sopenharmony_ci                rc = sqlite3_step(stmt);
10787db96d56Sopenharmony_ci            } while (rc == SQLITE_ROW);
10797db96d56Sopenharmony_ci            rc = sqlite3_finalize(stmt);
10807db96d56Sopenharmony_ci        }
10817db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
10827db96d56Sopenharmony_ci
10837db96d56Sopenharmony_ci        if (rc != SQLITE_OK) {
10847db96d56Sopenharmony_ci            goto error;
10857db96d56Sopenharmony_ci        }
10867db96d56Sopenharmony_ci
10877db96d56Sopenharmony_ci        if (*tail == (char)0) {
10887db96d56Sopenharmony_ci            break;
10897db96d56Sopenharmony_ci        }
10907db96d56Sopenharmony_ci        sql_len -= (tail - sql_script);
10917db96d56Sopenharmony_ci        sql_script = tail;
10927db96d56Sopenharmony_ci    }
10937db96d56Sopenharmony_ci
10947db96d56Sopenharmony_ci    return Py_NewRef((PyObject *)self);
10957db96d56Sopenharmony_ci
10967db96d56Sopenharmony_cierror:
10977db96d56Sopenharmony_ci    _pysqlite_seterror(self->connection->state, db);
10987db96d56Sopenharmony_ci    return NULL;
10997db96d56Sopenharmony_ci}
11007db96d56Sopenharmony_ci
11017db96d56Sopenharmony_cistatic PyObject *
11027db96d56Sopenharmony_cipysqlite_cursor_iternext(pysqlite_Cursor *self)
11037db96d56Sopenharmony_ci{
11047db96d56Sopenharmony_ci    if (!check_cursor(self)) {
11057db96d56Sopenharmony_ci        return NULL;
11067db96d56Sopenharmony_ci    }
11077db96d56Sopenharmony_ci
11087db96d56Sopenharmony_ci    if (self->statement == NULL) {
11097db96d56Sopenharmony_ci        return NULL;
11107db96d56Sopenharmony_ci    }
11117db96d56Sopenharmony_ci
11127db96d56Sopenharmony_ci    sqlite3_stmt *stmt = self->statement->st;
11137db96d56Sopenharmony_ci    assert(stmt != NULL);
11147db96d56Sopenharmony_ci    if (sqlite3_data_count(stmt) == 0) {
11157db96d56Sopenharmony_ci        (void)stmt_reset(self->statement);
11167db96d56Sopenharmony_ci        Py_CLEAR(self->statement);
11177db96d56Sopenharmony_ci        return NULL;
11187db96d56Sopenharmony_ci    }
11197db96d56Sopenharmony_ci
11207db96d56Sopenharmony_ci    self->locked = 1;  // GH-80254: Prevent recursive use of cursors.
11217db96d56Sopenharmony_ci    PyObject *row = _pysqlite_fetch_one_row(self);
11227db96d56Sopenharmony_ci    self->locked = 0;
11237db96d56Sopenharmony_ci    if (row == NULL) {
11247db96d56Sopenharmony_ci        return NULL;
11257db96d56Sopenharmony_ci    }
11267db96d56Sopenharmony_ci    int rc = stmt_step(stmt);
11277db96d56Sopenharmony_ci    if (rc == SQLITE_DONE) {
11287db96d56Sopenharmony_ci        if (self->statement->is_dml) {
11297db96d56Sopenharmony_ci            self->rowcount = (long)sqlite3_changes(self->connection->db);
11307db96d56Sopenharmony_ci        }
11317db96d56Sopenharmony_ci        (void)stmt_reset(self->statement);
11327db96d56Sopenharmony_ci        Py_CLEAR(self->statement);
11337db96d56Sopenharmony_ci    }
11347db96d56Sopenharmony_ci    else if (rc != SQLITE_ROW) {
11357db96d56Sopenharmony_ci        (void)_pysqlite_seterror(self->connection->state,
11367db96d56Sopenharmony_ci                                 self->connection->db);
11377db96d56Sopenharmony_ci        (void)stmt_reset(self->statement);
11387db96d56Sopenharmony_ci        Py_CLEAR(self->statement);
11397db96d56Sopenharmony_ci        Py_DECREF(row);
11407db96d56Sopenharmony_ci        return NULL;
11417db96d56Sopenharmony_ci    }
11427db96d56Sopenharmony_ci    if (!Py_IsNone(self->row_factory)) {
11437db96d56Sopenharmony_ci        PyObject *factory = self->row_factory;
11447db96d56Sopenharmony_ci        PyObject *args[] = { (PyObject *)self, row, };
11457db96d56Sopenharmony_ci        PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL);
11467db96d56Sopenharmony_ci        Py_DECREF(row);
11477db96d56Sopenharmony_ci        row = new_row;
11487db96d56Sopenharmony_ci    }
11497db96d56Sopenharmony_ci    return row;
11507db96d56Sopenharmony_ci}
11517db96d56Sopenharmony_ci
11527db96d56Sopenharmony_ci/*[clinic input]
11537db96d56Sopenharmony_ci_sqlite3.Cursor.fetchone as pysqlite_cursor_fetchone
11547db96d56Sopenharmony_ci
11557db96d56Sopenharmony_ciFetches one row from the resultset.
11567db96d56Sopenharmony_ci[clinic start generated code]*/
11577db96d56Sopenharmony_ci
11587db96d56Sopenharmony_cistatic PyObject *
11597db96d56Sopenharmony_cipysqlite_cursor_fetchone_impl(pysqlite_Cursor *self)
11607db96d56Sopenharmony_ci/*[clinic end generated code: output=4bd2eabf5baaddb0 input=e78294ec5980fdba]*/
11617db96d56Sopenharmony_ci{
11627db96d56Sopenharmony_ci    PyObject* row;
11637db96d56Sopenharmony_ci
11647db96d56Sopenharmony_ci    row = pysqlite_cursor_iternext(self);
11657db96d56Sopenharmony_ci    if (!row && !PyErr_Occurred()) {
11667db96d56Sopenharmony_ci        Py_RETURN_NONE;
11677db96d56Sopenharmony_ci    }
11687db96d56Sopenharmony_ci
11697db96d56Sopenharmony_ci    return row;
11707db96d56Sopenharmony_ci}
11717db96d56Sopenharmony_ci
11727db96d56Sopenharmony_ci/*[clinic input]
11737db96d56Sopenharmony_ci_sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany
11747db96d56Sopenharmony_ci
11757db96d56Sopenharmony_ci    size as maxrows: int(c_default='self->arraysize') = 1
11767db96d56Sopenharmony_ci        The default value is set by the Cursor.arraysize attribute.
11777db96d56Sopenharmony_ci
11787db96d56Sopenharmony_ciFetches several rows from the resultset.
11797db96d56Sopenharmony_ci[clinic start generated code]*/
11807db96d56Sopenharmony_ci
11817db96d56Sopenharmony_cistatic PyObject *
11827db96d56Sopenharmony_cipysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows)
11837db96d56Sopenharmony_ci/*[clinic end generated code: output=a8ef31fea64d0906 input=c26e6ca3f34debd0]*/
11847db96d56Sopenharmony_ci{
11857db96d56Sopenharmony_ci    PyObject* row;
11867db96d56Sopenharmony_ci    PyObject* list;
11877db96d56Sopenharmony_ci    int counter = 0;
11887db96d56Sopenharmony_ci
11897db96d56Sopenharmony_ci    list = PyList_New(0);
11907db96d56Sopenharmony_ci    if (!list) {
11917db96d56Sopenharmony_ci        return NULL;
11927db96d56Sopenharmony_ci    }
11937db96d56Sopenharmony_ci
11947db96d56Sopenharmony_ci    while ((row = pysqlite_cursor_iternext(self))) {
11957db96d56Sopenharmony_ci        if (PyList_Append(list, row) < 0) {
11967db96d56Sopenharmony_ci            Py_DECREF(row);
11977db96d56Sopenharmony_ci            break;
11987db96d56Sopenharmony_ci        }
11997db96d56Sopenharmony_ci        Py_DECREF(row);
12007db96d56Sopenharmony_ci
12017db96d56Sopenharmony_ci        if (++counter == maxrows) {
12027db96d56Sopenharmony_ci            break;
12037db96d56Sopenharmony_ci        }
12047db96d56Sopenharmony_ci    }
12057db96d56Sopenharmony_ci
12067db96d56Sopenharmony_ci    if (PyErr_Occurred()) {
12077db96d56Sopenharmony_ci        Py_DECREF(list);
12087db96d56Sopenharmony_ci        return NULL;
12097db96d56Sopenharmony_ci    } else {
12107db96d56Sopenharmony_ci        return list;
12117db96d56Sopenharmony_ci    }
12127db96d56Sopenharmony_ci}
12137db96d56Sopenharmony_ci
12147db96d56Sopenharmony_ci/*[clinic input]
12157db96d56Sopenharmony_ci_sqlite3.Cursor.fetchall as pysqlite_cursor_fetchall
12167db96d56Sopenharmony_ci
12177db96d56Sopenharmony_ciFetches all rows from the resultset.
12187db96d56Sopenharmony_ci[clinic start generated code]*/
12197db96d56Sopenharmony_ci
12207db96d56Sopenharmony_cistatic PyObject *
12217db96d56Sopenharmony_cipysqlite_cursor_fetchall_impl(pysqlite_Cursor *self)
12227db96d56Sopenharmony_ci/*[clinic end generated code: output=d5da12aca2da4b27 input=f5d401086a8df25a]*/
12237db96d56Sopenharmony_ci{
12247db96d56Sopenharmony_ci    PyObject* row;
12257db96d56Sopenharmony_ci    PyObject* list;
12267db96d56Sopenharmony_ci
12277db96d56Sopenharmony_ci    list = PyList_New(0);
12287db96d56Sopenharmony_ci    if (!list) {
12297db96d56Sopenharmony_ci        return NULL;
12307db96d56Sopenharmony_ci    }
12317db96d56Sopenharmony_ci
12327db96d56Sopenharmony_ci    while ((row = pysqlite_cursor_iternext(self))) {
12337db96d56Sopenharmony_ci        if (PyList_Append(list, row) < 0) {
12347db96d56Sopenharmony_ci            Py_DECREF(row);
12357db96d56Sopenharmony_ci            break;
12367db96d56Sopenharmony_ci        }
12377db96d56Sopenharmony_ci        Py_DECREF(row);
12387db96d56Sopenharmony_ci    }
12397db96d56Sopenharmony_ci
12407db96d56Sopenharmony_ci    if (PyErr_Occurred()) {
12417db96d56Sopenharmony_ci        Py_DECREF(list);
12427db96d56Sopenharmony_ci        return NULL;
12437db96d56Sopenharmony_ci    } else {
12447db96d56Sopenharmony_ci        return list;
12457db96d56Sopenharmony_ci    }
12467db96d56Sopenharmony_ci}
12477db96d56Sopenharmony_ci
12487db96d56Sopenharmony_ci/*[clinic input]
12497db96d56Sopenharmony_ci_sqlite3.Cursor.setinputsizes as pysqlite_cursor_setinputsizes
12507db96d56Sopenharmony_ci
12517db96d56Sopenharmony_ci    sizes: object
12527db96d56Sopenharmony_ci    /
12537db96d56Sopenharmony_ci
12547db96d56Sopenharmony_ciRequired by DB-API. Does nothing in sqlite3.
12557db96d56Sopenharmony_ci[clinic start generated code]*/
12567db96d56Sopenharmony_ci
12577db96d56Sopenharmony_cistatic PyObject *
12587db96d56Sopenharmony_cipysqlite_cursor_setinputsizes(pysqlite_Cursor *self, PyObject *sizes)
12597db96d56Sopenharmony_ci/*[clinic end generated code: output=893c817afe9d08ad input=de7950a3aec79bdf]*/
12607db96d56Sopenharmony_ci{
12617db96d56Sopenharmony_ci    Py_RETURN_NONE;
12627db96d56Sopenharmony_ci}
12637db96d56Sopenharmony_ci
12647db96d56Sopenharmony_ci/*[clinic input]
12657db96d56Sopenharmony_ci_sqlite3.Cursor.setoutputsize as pysqlite_cursor_setoutputsize
12667db96d56Sopenharmony_ci
12677db96d56Sopenharmony_ci    size: object
12687db96d56Sopenharmony_ci    column: object = None
12697db96d56Sopenharmony_ci    /
12707db96d56Sopenharmony_ci
12717db96d56Sopenharmony_ciRequired by DB-API. Does nothing in sqlite3.
12727db96d56Sopenharmony_ci[clinic start generated code]*/
12737db96d56Sopenharmony_ci
12747db96d56Sopenharmony_cistatic PyObject *
12757db96d56Sopenharmony_cipysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size,
12767db96d56Sopenharmony_ci                                   PyObject *column)
12777db96d56Sopenharmony_ci/*[clinic end generated code: output=018d7e9129d45efe input=607a6bece8bbb273]*/
12787db96d56Sopenharmony_ci{
12797db96d56Sopenharmony_ci    Py_RETURN_NONE;
12807db96d56Sopenharmony_ci}
12817db96d56Sopenharmony_ci
12827db96d56Sopenharmony_ci/*[clinic input]
12837db96d56Sopenharmony_ci_sqlite3.Cursor.close as pysqlite_cursor_close
12847db96d56Sopenharmony_ci
12857db96d56Sopenharmony_ciCloses the cursor.
12867db96d56Sopenharmony_ci[clinic start generated code]*/
12877db96d56Sopenharmony_ci
12887db96d56Sopenharmony_cistatic PyObject *
12897db96d56Sopenharmony_cipysqlite_cursor_close_impl(pysqlite_Cursor *self)
12907db96d56Sopenharmony_ci/*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/
12917db96d56Sopenharmony_ci{
12927db96d56Sopenharmony_ci    if (!check_cursor_locked(self)) {
12937db96d56Sopenharmony_ci        return NULL;
12947db96d56Sopenharmony_ci    }
12957db96d56Sopenharmony_ci
12967db96d56Sopenharmony_ci    if (!self->connection) {
12977db96d56Sopenharmony_ci        PyTypeObject *tp = Py_TYPE(self);
12987db96d56Sopenharmony_ci        pysqlite_state *state = pysqlite_get_state_by_type(tp);
12997db96d56Sopenharmony_ci        PyErr_SetString(state->ProgrammingError,
13007db96d56Sopenharmony_ci                        "Base Cursor.__init__ not called.");
13017db96d56Sopenharmony_ci        return NULL;
13027db96d56Sopenharmony_ci    }
13037db96d56Sopenharmony_ci    if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
13047db96d56Sopenharmony_ci        return NULL;
13057db96d56Sopenharmony_ci    }
13067db96d56Sopenharmony_ci
13077db96d56Sopenharmony_ci    if (self->statement) {
13087db96d56Sopenharmony_ci        (void)stmt_reset(self->statement);
13097db96d56Sopenharmony_ci        Py_CLEAR(self->statement);
13107db96d56Sopenharmony_ci    }
13117db96d56Sopenharmony_ci
13127db96d56Sopenharmony_ci    self->closed = 1;
13137db96d56Sopenharmony_ci
13147db96d56Sopenharmony_ci    Py_RETURN_NONE;
13157db96d56Sopenharmony_ci}
13167db96d56Sopenharmony_ci
13177db96d56Sopenharmony_cistatic PyMethodDef cursor_methods[] = {
13187db96d56Sopenharmony_ci    PYSQLITE_CURSOR_CLOSE_METHODDEF
13197db96d56Sopenharmony_ci    PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF
13207db96d56Sopenharmony_ci    PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF
13217db96d56Sopenharmony_ci    PYSQLITE_CURSOR_EXECUTE_METHODDEF
13227db96d56Sopenharmony_ci    PYSQLITE_CURSOR_FETCHALL_METHODDEF
13237db96d56Sopenharmony_ci    PYSQLITE_CURSOR_FETCHMANY_METHODDEF
13247db96d56Sopenharmony_ci    PYSQLITE_CURSOR_FETCHONE_METHODDEF
13257db96d56Sopenharmony_ci    PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF
13267db96d56Sopenharmony_ci    PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF
13277db96d56Sopenharmony_ci    {NULL, NULL}
13287db96d56Sopenharmony_ci};
13297db96d56Sopenharmony_ci
13307db96d56Sopenharmony_cistatic struct PyMemberDef cursor_members[] =
13317db96d56Sopenharmony_ci{
13327db96d56Sopenharmony_ci    {"connection", T_OBJECT, offsetof(pysqlite_Cursor, connection), READONLY},
13337db96d56Sopenharmony_ci    {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), READONLY},
13347db96d56Sopenharmony_ci    {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0},
13357db96d56Sopenharmony_ci    {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY},
13367db96d56Sopenharmony_ci    {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY},
13377db96d56Sopenharmony_ci    {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0},
13387db96d56Sopenharmony_ci    {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Cursor, in_weakreflist), READONLY},
13397db96d56Sopenharmony_ci    {NULL}
13407db96d56Sopenharmony_ci};
13417db96d56Sopenharmony_ci
13427db96d56Sopenharmony_cistatic const char cursor_doc[] =
13437db96d56Sopenharmony_ciPyDoc_STR("SQLite database cursor class.");
13447db96d56Sopenharmony_ci
13457db96d56Sopenharmony_cistatic PyType_Slot cursor_slots[] = {
13467db96d56Sopenharmony_ci    {Py_tp_dealloc, cursor_dealloc},
13477db96d56Sopenharmony_ci    {Py_tp_doc, (void *)cursor_doc},
13487db96d56Sopenharmony_ci    {Py_tp_iter, PyObject_SelfIter},
13497db96d56Sopenharmony_ci    {Py_tp_iternext, pysqlite_cursor_iternext},
13507db96d56Sopenharmony_ci    {Py_tp_methods, cursor_methods},
13517db96d56Sopenharmony_ci    {Py_tp_members, cursor_members},
13527db96d56Sopenharmony_ci    {Py_tp_init, pysqlite_cursor_init},
13537db96d56Sopenharmony_ci    {Py_tp_traverse, cursor_traverse},
13547db96d56Sopenharmony_ci    {Py_tp_clear, cursor_clear},
13557db96d56Sopenharmony_ci    {0, NULL},
13567db96d56Sopenharmony_ci};
13577db96d56Sopenharmony_ci
13587db96d56Sopenharmony_cistatic PyType_Spec cursor_spec = {
13597db96d56Sopenharmony_ci    .name = MODULE_NAME ".Cursor",
13607db96d56Sopenharmony_ci    .basicsize = sizeof(pysqlite_Cursor),
13617db96d56Sopenharmony_ci    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
13627db96d56Sopenharmony_ci              Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
13637db96d56Sopenharmony_ci    .slots = cursor_slots,
13647db96d56Sopenharmony_ci};
13657db96d56Sopenharmony_ci
13667db96d56Sopenharmony_ciint
13677db96d56Sopenharmony_cipysqlite_cursor_setup_types(PyObject *module)
13687db96d56Sopenharmony_ci{
13697db96d56Sopenharmony_ci    PyObject *type = PyType_FromModuleAndSpec(module, &cursor_spec, NULL);
13707db96d56Sopenharmony_ci    if (type == NULL) {
13717db96d56Sopenharmony_ci        return -1;
13727db96d56Sopenharmony_ci    }
13737db96d56Sopenharmony_ci    pysqlite_state *state = pysqlite_get_state(module);
13747db96d56Sopenharmony_ci    state->CursorType = (PyTypeObject *)type;
13757db96d56Sopenharmony_ci    return 0;
13767db96d56Sopenharmony_ci}
1377