[python-sybase] Re: This routine cannot be called because another command structure has results pending

Greg Ward gward-pysybase at python.net
Thu Jul 6 02:47:25 EST 2006


On 22 June 2006, I said:
> Back in May 2002, Ralph Heinkel reported a mysterious error, "This
> routine cannot be called because another command structure has results
> pending".  Here's his post:
> 
>   http://www.object-craft.com.au/pipermail/python-sybase/2002-May/000034.html
> 
> He posted a test program that reproduces the problem, and it still
> reproduces perfectly for me.  It appears that any error on a connection
> renders that connection unusable, or at least un-commit()able and
> un-rollback()able.  I'm connecting to Sybase ASE 11.0.3.3 (using
> libct.so and libcs.so supplied with the Sybase engine) and python-sybase
> 0.37.

I've done a bit more digging into this problem and discovered a crude
workaround.  All I have to do is add one line of code after my failed
query but before closing the cursor:

  cur = db.cursor()
  try:
      # produce an error - THE TABLE 'DUMMY' DOES NOT EXIST
      cur.execute('select * from dummy')
      print "WTF?!?  select should have failed!"
  except Sybase.Error, err:
      print "select failed as expected: %s" % err

  cur._fetcher._close()              <--- CRUDE WORKAROUND

  cur.close()
  db.commit()

That suggests to me that the bug lies in python-sybase rather than in my
code or in ctlib.  I think the bug is that Sybase.py assumes that

  self._fetcher = None

is sufficient to close the fetcher object and release all of its
resources, most importantly by calling ct_cancel() on the underlying
ctlib command structure.  Here's a narrow-minded patch that fixes the
particular problem I'm seeing:

--- Sybase.py.orig      2005-04-06 18:46:43.000000000 -0400
+++ Sybase.py.hacked    2006-07-05 12:41:55.000000000 -0400
@@ -735,10 +735,12 @@
     def close(self):
         '''DB-API Cursor.close()
         '''
         if self._closed:
             raise ProgrammingError('cursor is closed')
+        if self._fetcher:
+            self._fetcher._close()
         self._fetcher = None
         self._closed = 1

     def execute(self, sql, params = {}):
         '''DB-API Cursor.execute()

However, I suspect a more appropriate fix would be to factor out a
_close_fetcher() method of Cursor:

  def _close_fetcher(self):
      if self._fetcher:
          self._fetcher._close()
      self._fetcher = None

and replace every occurence of "self._fetcher = None" with
"self._close_fetcher()".

Does this sound close?  If so, I'll happily provide a patch.

        Greg


More information about the Python-sybase mailing list