Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions jaydebeapiarrow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ def _get_iter(self):

def fetchone(self):
if not self._rs:
raise Error()
return None

if self._buffer:
return self._buffer.pop(0)
Expand All @@ -677,7 +677,7 @@ def fetchone(self):

def fetchmany(self, size=None):
if not self._rs:
raise Error()
return []

if size is None:
size = self.arraysize
Expand All @@ -704,7 +704,7 @@ def fetchmany(self, size=None):

def fetchall(self):
if not self._rs:
raise Error()
return []

result = []
if self._buffer:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,4 +498,12 @@ public final void mockMultiColumnResult(int[] sqlTypes, Object[] values) throws

Mockito.when(this.prepareStatement(Mockito.any())).thenReturn(mockPreparedStatement);
}

/** Simulate a DDL/DML statement that returns no ResultSet (e.g. CREATE TABLE). */
public final void mockDDLResult(int updateCount) throws SQLException {
PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
Mockito.when(mockPreparedStatement.execute()).thenReturn(false);
Mockito.when(mockPreparedStatement.getUpdateCount()).thenReturn(updateCount);
Mockito.when(this.prepareStatement(Mockito.any())).thenReturn(mockPreparedStatement);
}
}
31 changes: 31 additions & 0 deletions test/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,37 @@ def test_rollback_with_autocommit_disabled(self):
self.conn.jconn.setAutoCommit(False)
self.conn.rollback()

def test_fetchone_after_ddl_returns_none(self):
"""fetchone() after a DDL statement (CREATE TABLE) should return None."""
with self.conn.cursor() as cursor:
cursor.execute("DROP TABLE IF EXISTS ddl_test")
cursor.execute("CREATE TABLE ddl_test (id INTEGER)")
result = cursor.fetchone()
self.assertIsNone(result)

def test_fetchall_after_ddl_returns_empty(self):
"""fetchall() after a DDL statement (CREATE TABLE) should return []."""
with self.conn.cursor() as cursor:
cursor.execute("DROP TABLE IF EXISTS ddl_test2")
cursor.execute("CREATE TABLE ddl_test2 (id INTEGER)")
result = cursor.fetchall()
self.assertEqual(result, [])

def test_fetchmany_after_ddl_returns_empty(self):
"""fetchmany() after a DDL statement (CREATE TABLE) should return []."""
with self.conn.cursor() as cursor:
cursor.execute("DROP TABLE IF EXISTS ddl_test3")
cursor.execute("CREATE TABLE ddl_test3 (id INTEGER)")
result = cursor.fetchmany(5)
self.assertEqual(result, [])

def test_description_after_ddl_is_none(self):
"""cursor.description should be None after a DDL statement."""
with self.conn.cursor() as cursor:
cursor.execute("DROP TABLE IF EXISTS ddl_test4")
cursor.execute("CREATE TABLE ddl_test4 (id INTEGER)")
self.assertIsNone(cursor.description)


class PostgresTest(IntegrationTestBase, unittest.TestCase):

Expand Down
41 changes: 40 additions & 1 deletion test/test_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,6 @@ def test_rollback_called_when_autocommit_disabled(self):
self.conn.jconn.mockAutoCommit(False)
self.conn.rollback()


def test_lastrowid_exists_and_is_none(self):
"""PEP-249: lastrowid attribute must exist on cursor (fixes #84)."""
with self.conn.cursor() as cursor:
Expand All @@ -1273,6 +1272,46 @@ def test_lastrowid_none_after_executemany(self):
"""lastrowid should be None after executemany (mock driver limitation: skip)."""
self.skipTest("Mock driver executeBatch returns None; covered by integration test")

# --- DDL statement tests (issue #76) ---

def test_fetchone_after_ddl_returns_none(self):
"""fetchone() after a DDL statement (no ResultSet) should return None, not raise."""
self.conn.jconn.mockDDLResult(0)
with self.conn.cursor() as cursor:
cursor.execute("CREATE TABLE test (id INTEGER)")
result = cursor.fetchone()
self.assertIsNone(result)

def test_fetchall_after_ddl_returns_empty(self):
"""fetchall() after a DDL statement (no ResultSet) should return [], not raise."""
self.conn.jconn.mockDDLResult(0)
with self.conn.cursor() as cursor:
cursor.execute("CREATE TABLE test (id INTEGER)")
result = cursor.fetchall()
self.assertEqual(result, [])

def test_fetchmany_after_ddl_returns_empty(self):
"""fetchmany() after a DDL statement (no ResultSet) should return [], not raise."""
self.conn.jconn.mockDDLResult(0)
with self.conn.cursor() as cursor:
cursor.execute("CREATE TABLE test (id INTEGER)")
result = cursor.fetchmany(5)
self.assertEqual(result, [])

def test_description_after_ddl_is_none(self):
"""cursor.description should be None after a DDL statement."""
self.conn.jconn.mockDDLResult(0)
with self.conn.cursor() as cursor:
cursor.execute("CREATE TABLE test (id INTEGER)")
self.assertIsNone(cursor.description)

def test_rowcount_after_ddl(self):
"""cursor.rowcount should reflect the update count after DDL."""
self.conn.jconn.mockDDLResult(0)
with self.conn.cursor() as cursor:
cursor.execute("CREATE TABLE test (id INTEGER)")
self.assertEqual(cursor.rowcount, 0)


class JarPathSpacesTest(unittest.TestCase):
"""Tests for JAR file paths containing spaces (issue #86).
Expand Down
Loading