summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/databases
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-11-04 17:28:26 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-11-04 17:28:26 +0000
commitc38e5d043f3d340f8e3cb3c82d2013739f35fc78 (patch)
tree9b63eb16b82b53392cbb0fd322836be57022695a /lib/sqlalchemy/databases
parent3f1e5e213d65375e89a23ecb4d50566c1f34b7b0 (diff)
downloadsqlalchemy-c38e5d043f3d340f8e3cb3c82d2013739f35fc78.tar.gz
- Simplified the check for ResultProxy "autoclose without results"
to be based solely on presence of cursor.description. All the regexp-based guessing about statements returning rows has been removed [ticket:1212].
Diffstat (limited to 'lib/sqlalchemy/databases')
-rw-r--r--lib/sqlalchemy/databases/firebird.py37
-rw-r--r--lib/sqlalchemy/databases/mssql.py6
-rw-r--r--lib/sqlalchemy/databases/mysql.py6
-rw-r--r--lib/sqlalchemy/databases/oracle.py5
-rw-r--r--lib/sqlalchemy/databases/postgres.py47
-rw-r--r--lib/sqlalchemy/databases/sqlite.py5
6 files changed, 7 insertions, 99 deletions
diff --git a/lib/sqlalchemy/databases/firebird.py b/lib/sqlalchemy/databases/firebird.py
index ccd4db3c7..7c7d4793b 100644
--- a/lib/sqlalchemy/databases/firebird.py
+++ b/lib/sqlalchemy/databases/firebird.py
@@ -261,45 +261,10 @@ ischema_names = {
'BLOB': lambda r: r['stype']==1 and FBText() or FBBinary()
}
-
-SELECT_RE = re.compile(
- r'\s*(?:SELECT|(UPDATE|INSERT|DELETE))',
- re.I | re.UNICODE)
-
-RETURNING_RE = re.compile(
- 'RETURNING',
- re.I | re.UNICODE)
-
-# This finds if the RETURNING is not inside a quoted/commented values. Handles string literals,
-# quoted identifiers, dollar quotes, SQL comments and C style multiline comments. This does not
-# handle correctly nested C style quotes, lets hope no one does the following:
-# UPDATE tbl SET x=y /* foo /* bar */ RETURNING */
-RETURNING_QUOTED_RE = re.compile(
- """\s*(?:UPDATE|INSERT|DELETE)\s
- (?: # handle quoted and commented tokens separately
- [^'"$/-] # non quote/comment character
- | -(?!-) # a dash that does not begin a comment
- | /(?!\*) # a slash that does not begin a comment
- | "(?:[^"]|"")*" # quoted literal
- | '(?:[^']|'')*' # quoted string
- | --[^\\n]*(?=\\n) # SQL comment, leave out line ending as that counts as whitespace
- # for the returning token
- | /\*([^*]|\*(?!/))*\*/ # C style comment, doesn't handle nesting
- )*
- \sRETURNING\s""", re.I | re.UNICODE | re.VERBOSE)
-
RETURNING_KW_NAME = 'firebird_returning'
class FBExecutionContext(default.DefaultExecutionContext):
- def returns_rows_text(self, statement):
- m = SELECT_RE.match(statement)
- return m and (not m.group(1) or (RETURNING_RE.search(statement)
- and RETURNING_QUOTED_RE.match(statement)))
-
- def returns_rows_compiled(self, compiled):
- return (isinstance(compiled.statement, sql.expression.Selectable) or
- ((compiled.isupdate or compiled.isinsert or compiled.isdelete) and
- RETURNING_KW_NAME in compiled.statement.kwargs))
+ pass
class FBDialect(default.DefaultDialect):
diff --git a/lib/sqlalchemy/databases/mssql.py b/lib/sqlalchemy/databases/mssql.py
index e6da0d3fc..f86a95548 100644
--- a/lib/sqlalchemy/databases/mssql.py
+++ b/lib/sqlalchemy/databases/mssql.py
@@ -337,12 +337,6 @@ class MSSQLExecutionContext(default.DefaultExecutionContext):
self._last_inserted_ids = [int(row[0])] + self._last_inserted_ids[1:]
super(MSSQLExecutionContext, self).post_exec()
- _ms_is_select = re.compile(r'\s*(?:SELECT|sp_columns|EXEC)',
- re.I | re.UNICODE)
-
- def returns_rows_text(self, statement):
- return self._ms_is_select.match(statement) is not None
-
class MSSQLExecutionContext_pyodbc (MSSQLExecutionContext):
def pre_exec(self):
diff --git a/lib/sqlalchemy/databases/mysql.py b/lib/sqlalchemy/databases/mysql.py
index b03ee5764..3dbb1797d 100644
--- a/lib/sqlalchemy/databases/mysql.py
+++ b/lib/sqlalchemy/databases/mysql.py
@@ -220,9 +220,6 @@ RESERVED_WORDS = set(
AUTOCOMMIT_RE = re.compile(
r'\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER|LOAD +DATA|REPLACE)',
re.I | re.UNICODE)
-SELECT_RE = re.compile(
- r'\s*(?:SELECT|SHOW|DESCRIBE|XA RECOVER|CALL|EXPLAIN)',
- re.I | re.UNICODE)
SET_RE = re.compile(
r'\s*SET\s+(?:(?:GLOBAL|SESSION)\s+)?\w',
re.I | re.UNICODE)
@@ -1463,9 +1460,6 @@ class MySQLExecutionContext(default.DefaultExecutionContext):
# which is probably a programming error anyhow.
self.connection.info.pop(('mysql', 'charset'), None)
- def returns_rows_text(self, statement):
- return SELECT_RE.match(statement)
-
def should_autocommit_text(self, statement):
return AUTOCOMMIT_RE.match(statement)
diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py
index ffd52c38c..15b18b1cb 100644
--- a/lib/sqlalchemy/databases/oracle.py
+++ b/lib/sqlalchemy/databases/oracle.py
@@ -123,8 +123,6 @@ from sqlalchemy.sql import operators as sql_operators, functions as sql_function
from sqlalchemy import types as sqltypes
-SELECT_REGEXP = re.compile(r'(\s*/\*\+.*?\*/)?\s*SELECT', re.I | re.UNICODE)
-
class OracleNumeric(sqltypes.Numeric):
def get_col_spec(self):
if self.precision is None:
@@ -321,9 +319,6 @@ class OracleExecutionContext(default.DefaultExecutionContext):
self.out_parameters[name] = self.cursor.var(dbtype)
self.parameters[0][name] = self.out_parameters[name]
- def returns_rows_text(self, statement):
- return SELECT_REGEXP.match(statement)
-
def create_cursor(self):
c = self._connection.connection.cursor()
if self.dialect.arraysize:
diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py
index c8abeb6db..69fad230d 100644
--- a/lib/sqlalchemy/databases/postgres.py
+++ b/lib/sqlalchemy/databases/postgres.py
@@ -225,60 +225,25 @@ ischema_names = {
'interval':PGInterval,
}
+# TODO: filter out 'FOR UPDATE' statements
SERVER_SIDE_CURSOR_RE = re.compile(
r'\s*SELECT',
re.I | re.UNICODE)
-SELECT_RE = re.compile(
- r'\s*(?:SELECT|FETCH|(UPDATE|INSERT))',
- re.I | re.UNICODE)
-
-RETURNING_RE = re.compile(
- 'RETURNING',
- re.I | re.UNICODE)
-
-# This finds if the RETURNING is not inside a quoted/commented values. Handles string literals,
-# quoted identifiers, dollar quotes, SQL comments and C style multiline comments. This does not
-# handle correctly nested C style quotes, lets hope no one does the following:
-# UPDATE tbl SET x=y /* foo /* bar */ RETURNING */
-RETURNING_QUOTED_RE = re.compile(
- """\s*(?:UPDATE|INSERT)\s
- (?: # handle quoted and commented tokens separately
- [^'"$/-] # non quote/comment character
- | -(?!-) # a dash that does not begin a comment
- | /(?!\*) # a slash that does not begin a comment
- | "(?:[^"]|"")*" # quoted literal
- | '(?:[^']|'')*' # quoted string
- | \$(?P<dquote>[^$]*)\$.*?\$(?P=dquote)\$ # dollar quotes
- | --[^\\n]*(?=\\n) # SQL comment, leave out line ending as that counts as whitespace
- # for the returning token
- | /\*([^*]|\*(?!/))*\*/ # C style comment, doesn't handle nesting
- )*
- \sRETURNING\s""", re.I | re.UNICODE | re.VERBOSE)
-
class PGExecutionContext(default.DefaultExecutionContext):
- def returns_rows_text(self, statement):
- m = SELECT_RE.match(statement)
- return m and (not m.group(1) or (RETURNING_RE.search(statement)
- and RETURNING_QUOTED_RE.match(statement)))
-
- def returns_rows_compiled(self, compiled):
- return isinstance(compiled.statement, expression.Selectable) or \
- (
- (compiled.isupdate or compiled.isinsert) and "postgres_returning" in compiled.statement.kwargs
- )
-
def create_cursor(self):
- self.__is_server_side = \
+ # TODO: coverage for server side cursors + select.for_update()
+ is_server_side = \
self.dialect.server_side_cursors and \
- ((self.compiled and isinstance(self.compiled.statement, expression.Selectable)) \
+ ((self.compiled and isinstance(self.compiled.statement, expression.Selectable) and not self.compiled.statement.for_update) \
or \
(
(not self.compiled or isinstance(self.compiled.statement, expression._TextClause))
and self.statement and SERVER_SIDE_CURSOR_RE.match(self.statement))
)
- if self.__is_server_side:
+ self.__is_server_side = is_server_side
+ if is_server_side:
# use server-side cursors:
# http://lists.initd.org/pipermail/psycopg/2007-January/005251.html
ident = "c_%s_%s" % (hex(id(self))[2:], hex(random.randint(0, 65535))[2:])
diff --git a/lib/sqlalchemy/databases/sqlite.py b/lib/sqlalchemy/databases/sqlite.py
index b3de98100..fd35f747f 100644
--- a/lib/sqlalchemy/databases/sqlite.py
+++ b/lib/sqlalchemy/databases/sqlite.py
@@ -14,8 +14,6 @@ import sqlalchemy.util as util
from sqlalchemy.sql import compiler, functions as sql_functions
from types import NoneType
-SELECT_REGEXP = re.compile(r'\s*(?:SELECT|PRAGMA)', re.I | re.UNICODE)
-
class SLNumeric(sqltypes.Numeric):
def bind_processor(self, dialect):
type_ = self.asdecimal and str or float
@@ -234,9 +232,6 @@ class SQLiteExecutionContext(default.DefaultExecutionContext):
if not len(self._last_inserted_ids) or self._last_inserted_ids[0] is None:
self._last_inserted_ids = [self.cursor.lastrowid] + self._last_inserted_ids[1:]
- def returns_rows_text(self, statement):
- return SELECT_REGEXP.match(statement)
-
class SQLiteDialect(default.DefaultDialect):
name = 'sqlite'
supports_alter = False