Apply upstream fix for bpo-39652

This commit is contained in:
Charles Leifer 2020-05-21 10:08:21 -05:00
parent 2d4a1c3df2
commit b811276962
4 changed files with 26 additions and 11 deletions

View file

@ -193,22 +193,30 @@ pysqlite_build_row_cast_map(pysqlite_Cursor* self)
} }
static PyObject * static PyObject *
_pysqlite_build_column_name(const char* colname) _pysqlite_build_column_name(pysqlite_Cursor *self, const char *colname)
{ {
const char* pos; const char* pos;
Py_ssize_t len;
if (!colname) { if (!colname) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
for (pos = colname;; pos++) { if (self->connection->detect_types & PARSE_COLNAMES) {
if (*pos == 0 || *pos == '[') { for (pos = colname; *pos; pos++) {
if ((*pos == '[') && (pos > colname) && (*(pos-1) == ' ')) { if (*pos == '[') {
pos--; if ((pos != colname) && (*(pos-1) == ' ')) {
pos--;
}
break;
} }
return PyUnicode_FromStringAndSize(colname, pos - colname);
} }
len = pos - colname;
} }
else {
len = strlen(colname);
}
return PyUnicode_FromStringAndSize(colname, len);
} }
/* /*
@ -370,6 +378,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
PyObject* result; PyObject* result;
int numcols; int numcols;
PyObject* descriptor; PyObject* descriptor;
PyObject* column_name;
PyObject* second_argument = NULL; PyObject* second_argument = NULL;
sqlite_int64 lastrowid; sqlite_int64 lastrowid;
@ -536,7 +545,13 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
if (!descriptor) { if (!descriptor) {
goto error; goto error;
} }
PyTuple_SetItem(descriptor, 0, _pysqlite_build_column_name(sqlite3_column_name(self->statement->st, i))); column_name = _pysqlite_build_column_name(self,
sqlite3_column_name(self->statement->st, i));
if (!column_name) {
Py_DECREF(descriptor);
goto error;
}
PyTuple_SetItem(descriptor, 0, column_name);
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 1, Py_None);
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 2, Py_None);
Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None); Py_INCREF(Py_None); PyTuple_SetItem(descriptor, 3, Py_None);

View file

@ -68,7 +68,7 @@ class RegressionTests(unittest.TestCase):
def CheckColumnNameWithSpaces(self): def CheckColumnNameWithSpaces(self):
cur = self.con.cursor() cur = self.con.cursor()
cur.execute('select 1 as "foo bar [datetime]"') cur.execute('select 1 as "foo bar [datetime]"')
self.assertEqual(cur.description[0][0], "foo bar") self.assertEqual(cur.description[0][0], "foo bar [datetime]")
cur.execute('select 1 as "foo baz"') cur.execute('select 1 as "foo baz"')
self.assertEqual(cur.description[0][0], "foo baz") self.assertEqual(cur.description[0][0], "foo baz")

View file

@ -275,13 +275,13 @@ class ColNamesTests(unittest.TestCase):
def CheckColName(self): def CheckColName(self):
self.cur.execute("insert into test(x) values (?)", ("xxx",)) self.cur.execute("insert into test(x) values (?)", ("xxx",))
self.cur.execute('select x as "x [bar]" from test') self.cur.execute('select x as "x y [bar]" from test')
val = self.cur.fetchone()[0] val = self.cur.fetchone()[0]
self.assertEqual(val, "<xxx>") self.assertEqual(val, "<xxx>")
# Check if the stripping of colnames works. Everything after the first # Check if the stripping of colnames works. Everything after the first
# whitespace should be stripped. # whitespace should be stripped.
self.assertEqual(self.cur.description[0][0], "x") self.assertEqual(self.cur.description[0][0], "x y")
def CheckCaseInConverterName(self): def CheckCaseInConverterName(self):
self.cur.execute("select 'other' as \"x [b1b1]\"") self.cur.execute("select 'other' as \"x [b1b1]\"")

View file

@ -286,7 +286,7 @@ class FunctionTests(unittest.TestCase):
def CheckFuncDeterministic(self): def CheckFuncDeterministic(self):
mock = unittest.mock.Mock(return_value=None) mock = unittest.mock.Mock(return_value=None)
self.con.create_function("deterministic", 0, mock, True) self.con.create_function("deterministic", 0, mock, True)
self.con.execute("select deterministic() = deterministic()") self.con.execute("select 1 where deterministic() AND deterministic()")
self.assertEqual(mock.call_count, 1) self.assertEqual(mock.call_count, 1)
@unittest.skipIf(sqlite.sqlite_version_info >= (3, 8, 3), "SQLite < 3.8.3 needed") @unittest.skipIf(sqlite.sqlite_version_info >= (3, 8, 3), "SQLite < 3.8.3 needed")