From: Greg W. <gwa...@py...> - 2006-06-23 12:54:34
|
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. Here's my slight variation on Ralph's test program: -- syberror ------------------------------------------------------------ #!/usr/bin/python # Attempt to reproduce the mysterious "This routine cannot be called # because another command structure has results pending." error. # # Based on code seen in this mailing list post: # http://www.object-craft.com.au/pipermail/python-sybase/2002-May/000034.html import sys import Sybase Sybase._ctx.debug = 1 args = sys.argv[1:] if len(args) != 3: sys.exit("usage: syberror server username password") (server, username, password) = args db = Sybase.connect(server, username, password) print "successfully connected to %s" % server 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.close() db.commit() ------------------------------------------------------------------------ The most important change is that I added "_ctx.debug = 1", as requested by Dave Cole in a followup. And here is the output I get from running this program (username and password censored): ------------------------------------------------------------------------ ct_con_alloc(ctx0, &conn) -> CS_SUCCEED, conn0 ct_con_props(conn0, CS_SET, CS_USERNAME, "***", CS_NULLTERM, NULL) -> CS_SUCCEEDct_con_props(conn0, CS_SET, CS_PASSWORD, "********", CS_NULLTERM, NULL) -> CS_SUCCEED servermsg_cb ct_connect(conn0, "MIRA321", CS_NULLTERM) -> CS_SUCCEED ct_options(conn0, CS_SET, CS_OPT_CHAINXACTS, 1, CS_UNUSED, NULL) -> CS_SUCCEED successfully connected to MIRA321 Cursor.execute _lock: count -> 1 ct_cmd_alloc(conn0, &cmd) -> CS_SUCCEED, cmd0 _lock: count -> 2 _set_state: _LAZY_IDLE _unlock: count -> 1 ct_command(cmd0, CS_LANG_CMD, "select * from dummy", CS_NULLTERM, CS_UNUSED) -> CS_SUCCEED _set_state: _LAZY_FETCHING ct_send(cmd0) -> CS_SUCCEED _start_results servermsg_cb Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'dummy'. ct_results(cmd0, &result) -> CS_SUCCEED, CS_CMD_FAIL select failed as expected: Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'dummy'. ct_cmd_alloc(conn0, &cmd) -> CS_SUCCEED, cmd1 ct_command(cmd1, CS_LANG_CMD, "commit transaction", CS_NULLTERM, CS_UNUSED) -> CS_SUCCEED clientmsg_cb Layer: 1, Origin: 1 ct_send(): user api layer: external error: This routine cannot be called because another command structure has results pending.ct_send(cmd1) -> CS_FAIL ct_cancel(conn0, NULL, CS_CANCEL_ALL) -> CS_SUCCEED _unlock: count -> 0 ct_cmd_drop(cmd0) -> CS_SUCCEED Traceback (most recent call last): File "./syberror", line 30, in ? db.commit() File "/usr/local/Intelerad/3rd_Party/python/lib/python2.3/site-packages/Sybase.py", line 971, in commit self.execute('commit transaction') File "/usr/local/Intelerad/3rd_Party/python/lib/python2.3/site-packages/Sybase.py", line 996, in execute fetcher.start(self.arraysize) File "/usr/local/Intelerad/3rd_Party/python/lib/python2.3/site-packages/Sybase.py", line 307, in start status = self._cmd.ct_send() File "/usr/local/Intelerad/3rd_Party/python/lib/python2.3/site-packages/Sybase.py", line 184, in _clientmsg_cb raise DatabaseError(_fmt_client(msg)) Sybase.DatabaseError: Layer: 1, Origin: 1 ct_send(): user api layer: external error: This routine cannot be called because another command structure has results pending. ct_cmd_drop(cmd1) -> CS_SUCCEED ct_con_props(conn0, CS_GET, CS_CON_STATUS, &value, CS_UNUSED, NULL) -> CS_SUCCEED, CS_CONSTAT_CONNECTED ct_close(conn0, CS_FORCE_CLOSE) -> CS_SUCCEED ct_con_drop(conn0) -> CS_SUCCEED ------------------------------------------------------------------------ Does anyone understand what's going on here? For the longest time, I have assumed this was a subtle bug in my code, but now that I have this simple test script I really doubt that. How can one error make it impossible to commit() or rollback() the current transaction? (Same result if the last line is db.rollback(), by the way.) Is this a bug in python-sybase? or in ctlib? or elsewhere? Thanks -- Greg |