diff options
| author | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
|---|---|---|
| committer | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
| commit | d4be68e361f4258cf0848fc70018dfe37a2acc24 (patch) | |
| tree | 153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Modules/_sqlite/statement.c | |
| parent | 260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff) | |
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Modules/_sqlite/statement.c')
| -rw-r--r-- | contrib/tools/python3/src/Modules/_sqlite/statement.c | 170 |
1 files changed, 94 insertions, 76 deletions
diff --git a/contrib/tools/python3/src/Modules/_sqlite/statement.c b/contrib/tools/python3/src/Modules/_sqlite/statement.c index 0272ce11207..3bc86420aa0 100644 --- a/contrib/tools/python3/src/Modules/_sqlite/statement.c +++ b/contrib/tools/python3/src/Modules/_sqlite/statement.c @@ -48,7 +48,8 @@ typedef enum { TYPE_UNKNOWN } parameter_type; -int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql) +pysqlite_Statement * +pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) { const char* tail; int rc; @@ -56,28 +57,36 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con Py_ssize_t sql_cstr_len; const char* p; - self->st = NULL; - self->in_use = 0; - assert(PyUnicode_Check(sql)); sql_cstr = PyUnicode_AsUTF8AndSize(sql, &sql_cstr_len); if (sql_cstr == NULL) { - rc = PYSQLITE_SQL_WRONG_TYPE; - return rc; + PyErr_Format(pysqlite_Warning, + "SQL is of wrong type ('%s'). Must be string.", + Py_TYPE(sql)->tp_name); + return NULL; } if (strlen(sql_cstr) != (size_t)sql_cstr_len) { - PyErr_SetString(PyExc_ValueError, "the query contains a null character"); - return PYSQLITE_SQL_WRONG_TYPE; + PyErr_SetString(PyExc_ValueError, + "the query contains a null character"); + return NULL; + } + + pysqlite_Statement *self = PyObject_GC_New(pysqlite_Statement, + pysqlite_StatementType); + if (self == NULL) { + return NULL; } + self->db = connection->db; + self->st = NULL; + self->sql = Py_NewRef(sql); + self->in_use = 0; + self->is_dml = 0; self->in_weakreflist = NULL; - Py_INCREF(sql); - self->sql = sql; /* Determine if the statement is a DML statement. SELECT is the only exception. See #9924. */ - self->is_dml = 0; for (p = sql_cstr; *p != 0; p++) { switch (*p) { case ' ': @@ -95,22 +104,33 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con } Py_BEGIN_ALLOW_THREADS - rc = sqlite3_prepare_v2(connection->db, + rc = sqlite3_prepare_v2(self->db, sql_cstr, -1, &self->st, &tail); Py_END_ALLOW_THREADS - self->db = connection->db; + PyObject_GC_Track(self); + + if (rc != SQLITE_OK) { + _pysqlite_seterror(self->db, NULL); + goto error; + } if (rc == SQLITE_OK && pysqlite_check_remaining_sql(tail)) { (void)sqlite3_finalize(self->st); self->st = NULL; - rc = PYSQLITE_TOO_MUCH_SQL; + PyErr_SetString(pysqlite_Warning, + "You can only execute one statement at a time."); + goto error; } - return rc; + return self; + +error: + Py_DECREF(self); + return NULL; } int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) @@ -247,11 +267,11 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para } for (i = 0; i < num_params; i++) { if (PyTuple_CheckExact(parameters)) { - current_param = PyTuple_GET_ITEM(parameters, i); - Py_INCREF(current_param); + PyObject *item = PyTuple_GET_ITEM(parameters, i); + current_param = Py_NewRef(item); } else if (PyList_CheckExact(parameters)) { - current_param = PyList_GetItem(parameters, i); - Py_XINCREF(current_param); + PyObject *item = PyList_GetItem(parameters, i); + current_param = Py_XNewRef(item); } else { current_param = PySequence_GetItem(parameters, i); } @@ -262,7 +282,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; @@ -297,15 +317,15 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para return; } if (PyDict_CheckExact(parameters)) { - current_param = PyDict_GetItemWithError(parameters, binding_name_obj); - Py_XINCREF(current_param); + PyObject *item = PyDict_GetItemWithError(parameters, binding_name_obj); + current_param = Py_XNewRef(item); } else { current_param = PyObject_GetItem(parameters, binding_name_obj); } Py_DECREF(binding_name_obj); if (!current_param) { if (!PyErr_Occurred() || PyErr_ExceptionMatches(PyExc_LookupError)) { - PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding %d.", i); + PyErr_Format(pysqlite_ProgrammingError, "You did not supply a value for binding parameter :%s.", binding_name); } return; } @@ -313,7 +333,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; @@ -376,23 +396,38 @@ void pysqlite_statement_mark_dirty(pysqlite_Statement* self) self->in_use = 1; } -void pysqlite_statement_dealloc(pysqlite_Statement* self) +static void +stmt_dealloc(pysqlite_Statement *self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + if (self->in_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*)self); + } if (self->st) { Py_BEGIN_ALLOW_THREADS sqlite3_finalize(self->st); Py_END_ALLOW_THREADS + self->st = 0; } + tp->tp_clear((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); +} - self->st = NULL; - - Py_XDECREF(self->sql); - - if (self->in_weakreflist != NULL) { - PyObject_ClearWeakRefs((PyObject*)self); - } +static int +stmt_clear(pysqlite_Statement *self) +{ + Py_CLEAR(self->sql); + return 0; +} - Py_TYPE(self)->tp_free((PyObject*)self); +static int +stmt_traverse(pysqlite_Statement *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->sql); + return 0; } /* @@ -465,50 +500,33 @@ static int pysqlite_check_remaining_sql(const char* tail) return 0; } -PyTypeObject pysqlite_StatementType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Statement", /* tp_name */ - sizeof(pysqlite_Statement), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_statement_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Statement, in_weakreflist), /* 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 */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyMemberDef stmt_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Statement, in_weakreflist), READONLY}, + {NULL}, +}; +static PyType_Slot stmt_slots[] = { + {Py_tp_members, stmt_members}, + {Py_tp_dealloc, stmt_dealloc}, + {Py_tp_traverse, stmt_traverse}, + {Py_tp_clear, stmt_clear}, + {0, NULL}, +}; + +static PyType_Spec stmt_spec = { + .name = MODULE_NAME ".Statement", + .basicsize = sizeof(pysqlite_Statement), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = stmt_slots, }; +PyTypeObject *pysqlite_StatementType = NULL; -extern int pysqlite_statement_setup_types(void) +int +pysqlite_statement_setup_types(PyObject *module) { - pysqlite_StatementType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_StatementType); + pysqlite_StatementType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &stmt_spec, NULL); + if (pysqlite_StatementType == NULL) { + return -1; + } + return 0; } |
