Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Invalidate PS cache on a DDL statement
This is because a change to the DB structure might invalidate prepared statements.
- Loading branch information
Showing
5 changed files
with
48 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,7 @@ | |
from pg8000.errors import ( | ||
NotSupportedError, ProgrammingError, InternalError, IntegrityError, | ||
OperationalError, DatabaseError, InterfaceError, Error, | ||
CopyQueryOrTableRequiredError, CursorClosedError, QueryParameterParseError, | ||
CopyQueryOrTableRequiredError, QueryParameterParseError, | ||
ArrayContentNotHomogenousError, ArrayContentEmptyError, | ||
ArrayDimensionsNotConsistentError, ArrayContentNotSupportedError, Warning, | ||
CopyQueryWithoutStreamError) | ||
|
@@ -85,6 +85,9 @@ def dst(self, dt): | |
FC_TEXT = 0 | ||
FC_BINARY = 1 | ||
|
||
BINARY_SPACE = b(" ") | ||
DDL_COMMANDS = b("ALTER"), b("CREATE") | ||
|
||
|
||
def convert_paramstyle(style, query): | ||
# I don't see any way to avoid scanning the query string char by char, | ||
|
@@ -251,14 +254,6 @@ def make_args(vals): | |
return ''.join(output_query), make_args | ||
|
||
|
||
def require_open_cursor(fn): | ||
def _fn(self, *args, **kwargs): | ||
if self._c is None: | ||
raise CursorClosedError() | ||
return fn(self, *args, **kwargs) | ||
return _fn | ||
|
||
|
||
EPOCH = datetime.datetime(2000, 1, 1) | ||
EPOCH_TZ = EPOCH.replace(tzinfo=utc) | ||
EPOCH_SECONDS = timegm(EPOCH.timetuple()) | ||
|
@@ -598,42 +593,23 @@ def fetchone(self): | |
# Stability: Part of the DBAPI 2.0 specification. | ||
# @param size The number of rows to fetch when called. If not provided, | ||
# the arraysize property value is used instead. | ||
if IS_JYTHON: | ||
def fetchmany(self, num=None): | ||
if self._stmt is None: | ||
raise ProgrammingError("attempting to use unexecuted cursor") | ||
else: | ||
try: | ||
return tuple( | ||
islice(self, self.arraysize if num is None else num)) | ||
except TypeError: | ||
raise ProgrammingError( | ||
"attempting to use unexecuted cursor") | ||
else: | ||
def fetchmany(self, num=None): | ||
try: | ||
return tuple( | ||
islice(self, self.arraysize if num is None else num)) | ||
except TypeError: | ||
raise ProgrammingError("attempting to use unexecuted cursor") | ||
def fetchmany(self, num=None): | ||
try: | ||
return tuple( | ||
islice(self, self.arraysize if num is None else num)) | ||
except TypeError: | ||
raise ProgrammingError("attempting to use unexecuted cursor") | ||
|
||
## | ||
# Fetch all remaining rows of a query result, returning them as a sequence | ||
# of sequences. | ||
# <p> | ||
# Stability: Part of the DBAPI 2.0 specification. | ||
if IS_JYTHON: | ||
def fetchall(self): | ||
if self._stmt is None: | ||
raise ProgrammingError("attempting to use unexecuted cursor") | ||
else: | ||
return tuple(self) | ||
else: | ||
def fetchall(self): | ||
try: | ||
return tuple(self) | ||
except TypeError: | ||
raise ProgrammingError("attempting to use unexecuted cursor") | ||
def fetchall(self): | ||
try: | ||
return tuple(self) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
tlocke
Author
Collaborator
|
||
except TypeError: | ||
raise ProgrammingError("attempting to use unexecuted cursor") | ||
|
||
## | ||
# Close the cursor. | ||
|
@@ -1607,13 +1583,17 @@ def handle_NO_DATA(self, msg, ps): | |
pass | ||
|
||
def handle_COMMAND_COMPLETE(self, data, cursor): | ||
values = data[:-1].split(b(" ")) | ||
if values[0] in self._commands_with_count: | ||
values = data[:-1].split(BINARY_SPACE) | ||
command = values[0] | ||
if command in self._commands_with_count: | ||
row_count = int(values[-1]) | ||
if cursor._row_count == -1: | ||
cursor._row_count = row_count | ||
else: | ||
cursor._row_count += row_count | ||
if command in DDL_COMMANDS: | ||
for k in self._caches: | ||
self._caches[k]['ps'].clear() | ||
|
||
def handle_DATA_ROW(self, data, cursor): | ||
data_idx = 2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,2 @@ | ||
jython run_25.py | ||
jython run_25_cache.py | ||
python2.5 run_25.py | ||
python2.5 run_25_cache.py |
This file was deleted.
Oops, something went wrong.
shouldn't fetchall return a mutable, e.g, a list of tuples instead of a tuple of lists? The DBAPI 2.0 spec isn't strict on that:
However the majority of providers return a list of tuples, e.g, sqlite, psycopg2, ...