diff options
Diffstat (limited to 'lib/sqlalchemy/databases')
-rw-r--r-- | lib/sqlalchemy/databases/firebird.py | 37 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/mssql.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/mysql.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/oracle.py | 5 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/postgres.py | 47 | ||||
-rw-r--r-- | lib/sqlalchemy/databases/sqlite.py | 5 |
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 |