diff --git a/ibm_db.c b/ibm_db.c index 13d53f20..04883aee 100644 --- a/ibm_db.c +++ b/ibm_db.c @@ -17328,9 +17328,9 @@ static PyObject *ibm_db_fetchmany(PyObject *self, PyObject *args) } if (PyList_Size(result_list) == 0) { - LogMsg(DEBUG, "No rows fetched, returning None"); - Py_XDECREF(result_list); - Py_RETURN_NONE; + LogMsg(DEBUG, "No rows fetched, returning empty list"); + LogMsg(INFO, "exit fetchmany()"); + return result_list; } snprintf(messageStr, sizeof(messageStr), "Returning %zd rows", PyList_Size(result_list)); LogMsg(DEBUG, messageStr); @@ -17376,9 +17376,9 @@ static PyObject *ibm_db_fetchall(PyObject *self, PyObject *args) } if (PyList_Size(result_list) == 0) { - LogMsg(DEBUG, "No rows fetched, returning None"); - Py_XDECREF(result_list); - Py_RETURN_NONE; + LogMsg(DEBUG, "No rows fetched, returning empty list"); + LogMsg(INFO, "exit fetchall()"); + return result_list; } snprintf(messageStr, sizeof(messageStr), "Returning %zd rows", PyList_Size(result_list)); LogMsg(DEBUG, messageStr); diff --git a/ibm_db_tests/test_319_FetchMethods_DBI.py b/ibm_db_tests/test_319_FetchMethods_DBI.py new file mode 100644 index 00000000..b454e8dd --- /dev/null +++ b/ibm_db_tests/test_319_FetchMethods_DBI.py @@ -0,0 +1,91 @@ +# +# Licensed Materials - Property of IBM +# +# (c) Copyright IBM Corp. 2025 +# + +from __future__ import print_function +import sys +import unittest +import ibm_db +import ibm_db_dbi +import config +from testfunctions import IbmDbTestFunctions + + +class IbmDbTestCase(unittest.TestCase): + + def test_319_FetchMethods_DBI(self): + obj = IbmDbTestFunctions() + obj.assert_expect(self.run_test_319) + + def run_test_319(self): + conn = ibm_db.connect(config.database, config.user, config.password) + + ibm_db.autocommit(conn, ibm_db.SQL_AUTOCOMMIT_OFF) + + dbi_conn = ibm_db_dbi.Connection(conn) + + # Drop the test table, in case it exists + drop = 'DROP TABLE dbiEmployees' + try: + cur = dbi_conn.cursor() + cur.execute(drop) + except: + pass + + # Create the test table + create = 'CREATE TABLE dbiEmployees (id INT PRIMARY KEY NOT NULL, name VARCHAR(255), age INT)' + cur = dbi_conn.cursor() + cur.execute(create) + + # Insert rows into the table + insert_sql = 'INSERT INTO dbiEmployees (id, name, age) VALUES (?, ?, ?)' + employees = [ + (1, 'Alice', 30), + (2, 'Bob', 24), + (3, 'Charlie', 29), + (4, 'Diana', 35), + (5, 'Eve', 40) + ] + for emp in employees: + cur.execute(insert_sql, emp) + + dbi_conn.commit() + + # 1) fetchone example + cur1 = dbi_conn.cursor() + cur1.execute('SELECT * FROM dbiEmployees ORDER BY id') + row = cur1.fetchone() + print("fetchone():", row) + + # 2) fetchmany example + cur2 = dbi_conn.cursor() + cur2.execute('SELECT * FROM dbiEmployees ORDER BY id') + rows = cur2.fetchmany(2) + print("fetchmany(2):", rows) + + # 3) fetchall example + cur3 = dbi_conn.cursor() + cur3.execute('SELECT * FROM dbiEmployees ORDER BY id') + all_rows = cur3.fetchall() + print("fetchall():", all_rows) + +#__END__ +#__LUW_EXPECTED__ +#fetchone(): (1, 'Alice', 30) +#fetchmany(2): [(1, 'Alice', 30), (2, 'Bob', 24)] +#fetchall(): [(1, 'Alice', 30), (2, 'Bob', 24), (3, 'Charlie', 29), (4, 'Diana', 35), (5, 'Eve', 40)] +#__ZOS_EXPECTED__ +#fetchone(): (1, 'Alice', 30) +#fetchmany(2): [(1, 'Alice', 30), (2, 'Bob', 24)] +#fetchall(): [(1, 'Alice', 30), (2, 'Bob', 24), (3, 'Charlie', 29), (4, 'Diana', 35), (5, 'Eve', 40)] +#__SYSTEMI_EXPECTED__ +#fetchone(): (1, 'Alice', 30) +#fetchmany(2): [(1, 'Alice', 30), (2, 'Bob', 24)] +#fetchall(): [(1, 'Alice', 30), (2, 'Bob', 24), (3, 'Charlie', 29), (4, 'Diana', 35), (5, 'Eve', 40)] +#__IDS_EXPECTED__ +#fetchone(): (1, 'Alice', 30) +#fetchmany(2): [(1, 'Alice', 30), (2, 'Bob', 24)] +#fetchall(): [(1, 'Alice', 30), (2, 'Bob', 24), (3, 'Charlie', 29), (4, 'Diana', 35), (5, 'Eve', 40)] + diff --git a/ibm_db_tests/test_320_EmptyFetchMethods_DBI.py b/ibm_db_tests/test_320_EmptyFetchMethods_DBI.py new file mode 100644 index 00000000..39e31b41 --- /dev/null +++ b/ibm_db_tests/test_320_EmptyFetchMethods_DBI.py @@ -0,0 +1,78 @@ +# +# Licensed Materials - Property of IBM +# +# (c) Copyright IBM Corp. 2025 +# + +from __future__ import print_function +import sys +import unittest +import ibm_db +import ibm_db_dbi +import config +from testfunctions import IbmDbTestFunctions + + +class IbmDbTestCase(unittest.TestCase): + + def test_320_EmptyFetchMethods_DBI(self): + obj = IbmDbTestFunctions() + obj.assert_expect(self.run_test_320) + + def run_test_320(self): + conn = ibm_db.connect(config.database, config.user, config.password) + + ibm_db.autocommit(conn, ibm_db.SQL_AUTOCOMMIT_OFF) + + dbi_conn = ibm_db_dbi.Connection(conn) + + # Drop the test table, if exists + drop = 'DROP TABLE dbiEmployeesEmpty' + try: + cur = dbi_conn.cursor() + cur.execute(drop) + except: + pass + + # Create the test table (empty) + create = 'CREATE TABLE dbiEmployeesEmpty (id INT PRIMARY KEY NOT NULL, name VARCHAR(255), age INT)' + cur = dbi_conn.cursor() + cur.execute(create) + + dbi_conn.commit() + + # 1) fetchone example on empty table + cur1 = dbi_conn.cursor() + cur1.execute('SELECT * FROM dbiEmployeesEmpty ORDER BY id') + row = cur1.fetchone() + print("fetchone():", row) + + # 2) fetchmany example on empty table + cur2 = dbi_conn.cursor() + cur2.execute('SELECT * FROM dbiEmployeesEmpty ORDER BY id') + rows = cur2.fetchmany(2) + print("fetchmany(2):", rows) + + # 3) fetchall example on empty table + cur3 = dbi_conn.cursor() + cur3.execute('SELECT * FROM dbiEmployeesEmpty ORDER BY id') + all_rows = cur3.fetchall() + print("fetchall():", all_rows) + +#__END__ +#__LUW_EXPECTED__ +#fetchone(): None +#fetchmany(2): [] +#fetchall(): [] +#__ZOS_EXPECTED__ +#fetchone(): None +#fetchmany(2): [] +#fetchall(): [] +#__SYSTEMI_EXPECTED__ +#fetchone(): None +#fetchmany(2): [] +#fetchall(): [] +#__IDS_EXPECTED__ +#fetchone(): None +#fetchmany(2): [] +#fetchall(): []