summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/_sqlite/statement.c
diff options
context:
space:
mode:
authorshadchin <[email protected]>2022-04-18 12:39:32 +0300
committershadchin <[email protected]>2022-04-18 12:39:32 +0300
commitd4be68e361f4258cf0848fc70018dfe37a2acc24 (patch)
tree153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Modules/_sqlite/statement.c
parent260c02f5ccf242d9d9b8a873afaf6588c00237d6 (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.c170
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;
}