ar-sybase-jdbc-adapter 0.2.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +21 -48
- data/lib/arjdbc/sybase/sybase_adapter_java.jar +0 -0
- metadata +30 -63
- data/test/helper.rb +0 -31
- data/test/support/fake_record.rb +0 -91
- data/test/test_connection.rb +0 -42
- data/test/test_visitor.rb +0 -60
data/README.rdoc
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
= ar-sybase-jdbc-adapter
|
2
2
|
|
3
|
-
ar-sybase-jdbc-adapter enhances activerecord-jdbc-adapter (Rails 3) to support
|
3
|
+
ar-sybase-jdbc-adapter enhances activerecord-jdbc-adapter (Rails 3) to support <tt>.limit</tt> and <tt>offset</tt> for Sybase ASE DB.
|
4
4
|
|
5
|
-
|
6
|
-
Once the project reaches "close to production" functionality I will try to merge it with activerecord-jdbc-adapter
|
5
|
+
At the moment Sybase ASE version 15 or grater is required. If you need it work for ASE version 12, please open an Issue[https://github.com/arkadiyk/ar-sybase-jdbc-adapter/issues]
|
7
6
|
|
7
|
+
<em>This project is a proof of concept that Sybase ASE can work nicely with Rails</em>. Once the project reaches "close to production" functionality I will try to merge it with activerecord-jdbc-adapter
|
8
|
+
|
9
|
+
If you have any issues with the adapter please add an Issue[https://github.com/arkadiyk/ar-sybase-jdbc-adapter/issues] or fork the project and send a pull request.
|
8
10
|
|
9
11
|
== Usage
|
10
12
|
1. Install
|
11
|
-
|
12
|
-
gem install ar-sybase-jdbc-adapter
|
13
|
+
gem install ar-sybase-jdbc-adapter
|
13
14
|
|
14
15
|
2. Configuration
|
15
16
|
To use this gem, set the "dialect" configuration parameter to "sybase_jtds".
|
@@ -24,22 +25,19 @@ Example:
|
|
24
25
|
driver: net.sourceforge.jtds.jdbc.Driver
|
25
26
|
url: jdbc:jtds:sybase://host:port/db_name
|
26
27
|
|
28
|
+
== Implementation notes
|
29
|
+
If <tt>.limit</tt> with no <tt>.offset</tt> or <tt>.count</tt> methods is used, the adapter simply adds "TOP" keyword to SQL and sends it to the Sybase server:
|
30
|
+
User.limit(10)
|
31
|
+
produces:
|
32
|
+
SELECT TOP 10 users.* FROM users
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
select top <limit + offset> * into #tt from (<original query with NO order by>) t ORDER BY <original order> ASC
|
35
|
-
select top <limit> * from #tt into #tt_sorted ORDER BY <original order> DESC
|
36
|
-
select * from #tt_sorted ORDER BY <original order>
|
37
|
-
|
38
|
-
There are 2 major drawbacks here.
|
39
|
-
1. If the offset is a large number, the space taken by the temptable can fill up the tempdb.
|
40
|
-
2. The original query should be parsed to strip out "ORDER BY"
|
34
|
+
The adapter has to rely on Java code to implement <tt>.offset</tt> or when <tt>.count</tt> is used together with <tt>.offset</tt> or <tt>.limit</tt>. In this case adapter will generate SQL like it was MySQL query:
|
35
|
+
User.limit(10).offset(20)
|
36
|
+
produces
|
37
|
+
SELECT users.* FROM users LIMIT 10 OFFSET 21
|
38
|
+
This can be confusing if you are looking at the log file.
|
41
39
|
|
42
|
-
|
40
|
+
Java layer parses the SQL and executes it as multistep scrollable cursor query:
|
43
41
|
|
44
42
|
declare crsr insensitive scroll cursor for
|
45
43
|
select * from <original query>
|
@@ -52,40 +50,15 @@ There are 2 major drawbacks here.
|
|
52
50
|
close crsr
|
53
51
|
deallocate crsr
|
54
52
|
|
55
|
-
The problems here are:
|
56
|
-
1. Scrollable cursor works for Sybase ASE starting from version 15.
|
57
|
-
2. Cursors are not very efficient in Sybase ASE, and very inefficient in Sybase IQ.
|
58
|
-
|
59
|
-
I am not a Sybase expert, so *Please let me know if you are aware of more efficient ways to do limit and offset.*
|
60
|
-
|
61
|
-
== Limit and Count in Sybase ASE
|
62
|
-
|
63
|
-
There is another interesting issue with Sybase DB I have just discovered. To implement "limit" I add "TOP <limit>" to the
|
64
|
-
query and it works fine. To check how many records this query returns the obvios thing is to run something like
|
65
|
-
|
66
|
-
select count(*) from (select top 10 * from table_name) t -- DOES NOT WORK!
|
67
|
-
|
68
|
-
But it does not work! The result of this query will be total number of rows in the table. So the only solution will be to
|
69
|
-
fall back to `cursor` and get `@@rowcount` to get the number of rows.
|
70
53
|
|
71
|
-
|
72
|
-
select * from <original query>
|
73
|
-
go
|
74
|
-
open crsr
|
75
|
-
|
76
|
-
set cursor rows <limit> for crsr
|
77
|
-
fetch absolute <offset> from crsr
|
78
|
-
|
79
|
-
select @@rowcount
|
80
|
-
|
81
|
-
close crsr
|
82
|
-
deallocate crsr
|
54
|
+
Unfortunately this approach is not very efficient for very large OFFSET values. Also scrollable cursor works for Sybase ASE starting from version 15.
|
83
55
|
|
56
|
+
I am not a Sybase expert, so <em>Please let me know if you are aware of more efficient ways to do limit and offset.</em>
|
84
57
|
|
85
58
|
|
86
59
|
== Known issues
|
87
60
|
|
88
|
-
I am aware of a very strange issue where the
|
61
|
+
I am aware of a very strange issue where the adapter does not work when the very first query uses "limit()".
|
89
62
|
|
90
63
|
e.g.
|
91
64
|
$ rails c
|
@@ -93,7 +66,7 @@ e.g.
|
|
93
66
|
irb(main):001:0> Client.limit(10).to_sql
|
94
67
|
=> "SELECT clients.* FROM clients LIMIT 10"
|
95
68
|
|
96
|
-
Otherwise, the
|
69
|
+
Otherwise, the adapter works fine by adding the "TOP" keyword to your SQL query:
|
97
70
|
|
98
71
|
e.g.
|
99
72
|
$ rails c
|
Binary file
|
metadata
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar-sybase-jdbc-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 2
|
8
|
-
- 0
|
9
|
-
version: 0.2.0
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.2
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- arkadiy kraportov
|
@@ -14,45 +10,38 @@ autorequire:
|
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
12
|
|
17
|
-
date: 2011-
|
13
|
+
date: 2011-06-15 00:00:00 +09:00
|
18
14
|
default_executable:
|
19
15
|
dependencies:
|
20
16
|
- !ruby/object:Gem::Dependency
|
21
17
|
name: bundler
|
22
18
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
23
20
|
requirements:
|
24
21
|
- - ~>
|
25
22
|
- !ruby/object:Gem::Version
|
26
|
-
|
27
|
-
- 1
|
28
|
-
- 0
|
29
|
-
- 0
|
30
|
-
version: 1.0.0
|
23
|
+
version: 1.0.15
|
31
24
|
requirement: *id001
|
32
25
|
prerelease: false
|
33
26
|
type: :development
|
34
27
|
- !ruby/object:Gem::Dependency
|
35
28
|
name: jeweler
|
36
29
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
37
31
|
requirements:
|
38
32
|
- - ~>
|
39
33
|
- !ruby/object:Gem::Version
|
40
|
-
|
41
|
-
- 1
|
42
|
-
- 5
|
43
|
-
- 1
|
44
|
-
version: 1.5.1
|
34
|
+
version: 1.6.2
|
45
35
|
requirement: *id002
|
46
36
|
prerelease: false
|
47
37
|
type: :development
|
48
38
|
- !ruby/object:Gem::Dependency
|
49
39
|
name: rcov
|
50
40
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
51
42
|
requirements:
|
52
43
|
- - ">="
|
53
44
|
- !ruby/object:Gem::Version
|
54
|
-
segments:
|
55
|
-
- 0
|
56
45
|
version: "0"
|
57
46
|
requirement: *id003
|
58
47
|
prerelease: false
|
@@ -60,11 +49,10 @@ dependencies:
|
|
60
49
|
- !ruby/object:Gem::Dependency
|
61
50
|
name: minitest
|
62
51
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
63
53
|
requirements:
|
64
54
|
- - ">="
|
65
55
|
- !ruby/object:Gem::Version
|
66
|
-
segments:
|
67
|
-
- 0
|
68
56
|
version: "0"
|
69
57
|
requirement: *id004
|
70
58
|
prerelease: false
|
@@ -72,27 +60,21 @@ dependencies:
|
|
72
60
|
- !ruby/object:Gem::Dependency
|
73
61
|
name: arel
|
74
62
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
75
64
|
requirements:
|
76
|
-
- -
|
65
|
+
- - ~>
|
77
66
|
- !ruby/object:Gem::Version
|
78
|
-
|
79
|
-
- 2
|
80
|
-
- 0
|
81
|
-
- 7
|
82
|
-
version: 2.0.7
|
67
|
+
version: 2.0.10
|
83
68
|
requirement: *id005
|
84
69
|
prerelease: false
|
85
70
|
type: :development
|
86
71
|
- !ruby/object:Gem::Dependency
|
87
72
|
name: activerecord-jdbc-adapter
|
88
73
|
version_requirements: &id006 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
89
75
|
requirements:
|
90
76
|
- - "="
|
91
77
|
- !ruby/object:Gem::Version
|
92
|
-
segments:
|
93
|
-
- 1
|
94
|
-
- 1
|
95
|
-
- 1
|
96
78
|
version: 1.1.1
|
97
79
|
requirement: *id006
|
98
80
|
prerelease: false
|
@@ -100,27 +82,21 @@ dependencies:
|
|
100
82
|
- !ruby/object:Gem::Dependency
|
101
83
|
name: activerecord
|
102
84
|
version_requirements: &id007 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
103
86
|
requirements:
|
104
|
-
- -
|
87
|
+
- - ~>
|
105
88
|
- !ruby/object:Gem::Version
|
106
|
-
|
107
|
-
- 3
|
108
|
-
- 0
|
109
|
-
- 3
|
110
|
-
version: 3.0.3
|
89
|
+
version: 3.0.7
|
111
90
|
requirement: *id007
|
112
91
|
prerelease: false
|
113
92
|
type: :development
|
114
93
|
- !ruby/object:Gem::Dependency
|
115
94
|
name: activerecord-jdbc-adapter
|
116
95
|
version_requirements: &id008 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
117
97
|
requirements:
|
118
|
-
- -
|
98
|
+
- - ~>
|
119
99
|
- !ruby/object:Gem::Version
|
120
|
-
segments:
|
121
|
-
- 1
|
122
|
-
- 1
|
123
|
-
- 1
|
124
100
|
version: 1.1.1
|
125
101
|
requirement: *id008
|
126
102
|
prerelease: false
|
@@ -128,13 +104,10 @@ dependencies:
|
|
128
104
|
- !ruby/object:Gem::Dependency
|
129
105
|
name: arel
|
130
106
|
version_requirements: &id009 !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
131
108
|
requirements:
|
132
|
-
- -
|
109
|
+
- - ~>
|
133
110
|
- !ruby/object:Gem::Version
|
134
|
-
segments:
|
135
|
-
- 2
|
136
|
-
- 0
|
137
|
-
- 7
|
138
111
|
version: 2.0.7
|
139
112
|
requirement: *id009
|
140
113
|
prerelease: false
|
@@ -142,11 +115,10 @@ dependencies:
|
|
142
115
|
- !ruby/object:Gem::Dependency
|
143
116
|
name: jdbc-jtds
|
144
117
|
version_requirements: &id010 !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
145
119
|
requirements:
|
146
120
|
- - ">="
|
147
121
|
- !ruby/object:Gem::Version
|
148
|
-
segments:
|
149
|
-
- 0
|
150
122
|
version: "0"
|
151
123
|
requirement: *id010
|
152
124
|
prerelease: false
|
@@ -154,14 +126,11 @@ dependencies:
|
|
154
126
|
- !ruby/object:Gem::Dependency
|
155
127
|
name: minitest
|
156
128
|
version_requirements: &id011 !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
157
130
|
requirements:
|
158
|
-
- -
|
131
|
+
- - ~>
|
159
132
|
- !ruby/object:Gem::Version
|
160
|
-
|
161
|
-
- 2
|
162
|
-
- 0
|
163
|
-
- 0
|
164
|
-
version: 2.0.0
|
133
|
+
version: 2.2.2
|
165
134
|
requirement: *id011
|
166
135
|
prerelease: false
|
167
136
|
type: :development
|
@@ -192,28 +161,26 @@ rdoc_options: []
|
|
192
161
|
require_paths:
|
193
162
|
- lib
|
194
163
|
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
195
165
|
requirements:
|
196
166
|
- - ">="
|
197
167
|
- !ruby/object:Gem::Version
|
168
|
+
hash: 2
|
198
169
|
segments:
|
199
170
|
- 0
|
200
171
|
version: "0"
|
201
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
202
174
|
requirements:
|
203
175
|
- - ">="
|
204
176
|
- !ruby/object:Gem::Version
|
205
|
-
segments:
|
206
|
-
- 0
|
207
177
|
version: "0"
|
208
178
|
requirements: []
|
209
179
|
|
210
180
|
rubyforge_project:
|
211
|
-
rubygems_version: 1.
|
181
|
+
rubygems_version: 1.5.1
|
212
182
|
signing_key:
|
213
183
|
specification_version: 3
|
214
184
|
summary: Adds support for limit and offset for Rails 3 and Sybase JDBC driver
|
215
|
-
test_files:
|
216
|
-
|
217
|
-
- test/support/fake_record.rb
|
218
|
-
- test/test_connection.rb
|
219
|
-
- test/test_visitor.rb
|
185
|
+
test_files: []
|
186
|
+
|
data/test/helper.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
|
4
|
-
begin
|
5
|
-
Bundler.setup(:default, :development)
|
6
|
-
rescue Bundler::BundlerError => e
|
7
|
-
$stderr.puts e.message
|
8
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
-
exit e.status_code
|
10
|
-
end
|
11
|
-
|
12
|
-
|
13
|
-
require 'minitest/autorun'
|
14
|
-
require 'fileutils'
|
15
|
-
require 'arel'
|
16
|
-
|
17
|
-
|
18
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
19
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
20
|
-
|
21
|
-
require 'ar-sybase-jdbc-adapter'
|
22
|
-
require 'support/fake_record'
|
23
|
-
|
24
|
-
|
25
|
-
Arel::Table.engine = Arel::Sql::Engine.new(FakeRecord::Base.new)
|
26
|
-
|
27
|
-
class Object
|
28
|
-
def must_be_like other
|
29
|
-
gsub(/\s+/, ' ').strip.must_equal other.gsub(/\s+/, ' ').strip
|
30
|
-
end
|
31
|
-
end
|
data/test/support/fake_record.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
module FakeRecord
|
2
|
-
class Column < Struct.new(:name, :type)
|
3
|
-
end
|
4
|
-
|
5
|
-
class Connection
|
6
|
-
attr_reader :tables
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@tables = %w{ users photos developers }
|
10
|
-
@columns = {
|
11
|
-
'users' => [
|
12
|
-
Column.new('id', :integer),
|
13
|
-
Column.new('name', :string),
|
14
|
-
Column.new('bool', :boolean),
|
15
|
-
Column.new('created_at', :date),
|
16
|
-
]
|
17
|
-
}
|
18
|
-
@primary_keys = {
|
19
|
-
'users' => 'id'
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
|
-
def primary_key name
|
24
|
-
@primary_keys[name.to_s]
|
25
|
-
end
|
26
|
-
|
27
|
-
def table_exists? name
|
28
|
-
@tables.include? name.to_s
|
29
|
-
end
|
30
|
-
|
31
|
-
def columns name, message = nil
|
32
|
-
@columns[name.to_s]
|
33
|
-
end
|
34
|
-
|
35
|
-
def quote_table_name name
|
36
|
-
"\"#{name.to_s}\""
|
37
|
-
end
|
38
|
-
|
39
|
-
def quote_column_name name
|
40
|
-
"\"#{name.to_s}\""
|
41
|
-
end
|
42
|
-
|
43
|
-
def quote thing, column = nil
|
44
|
-
if column && column.type == :integer
|
45
|
-
return 'NULL' if thing.nil?
|
46
|
-
return thing.to_i
|
47
|
-
end
|
48
|
-
|
49
|
-
case thing
|
50
|
-
when true
|
51
|
-
"'t'"
|
52
|
-
when false
|
53
|
-
"'f'"
|
54
|
-
when nil
|
55
|
-
'NULL'
|
56
|
-
when Numeric
|
57
|
-
thing
|
58
|
-
else
|
59
|
-
"'#{thing}'"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class ConnectionPool
|
65
|
-
class Spec < Struct.new(:config)
|
66
|
-
end
|
67
|
-
|
68
|
-
attr_reader :spec, :connection
|
69
|
-
|
70
|
-
def initialize
|
71
|
-
@spec = Spec.new(:adapter => 'america')
|
72
|
-
@connection = Connection.new
|
73
|
-
end
|
74
|
-
|
75
|
-
def with_connection
|
76
|
-
yield connection
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
class Base
|
81
|
-
attr_accessor :connection_pool
|
82
|
-
|
83
|
-
def initialize
|
84
|
-
@connection_pool = ConnectionPool.new
|
85
|
-
end
|
86
|
-
|
87
|
-
def connection
|
88
|
-
connection_pool.connection
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
data/test/test_connection.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require 'arjdbc'
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
#module ActiveRecord
|
5
|
-
# module ConnectionAdapters
|
6
|
-
# class JdbcAdapter < AbstractAdapter
|
7
|
-
# def initialize
|
8
|
-
# end
|
9
|
-
# end
|
10
|
-
# end
|
11
|
-
#end
|
12
|
-
|
13
|
-
module ConnectionTests
|
14
|
-
class MockConnection
|
15
|
-
def adapter=(adapt)
|
16
|
-
end
|
17
|
-
def jndi_connection?
|
18
|
-
false
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe 'the sybase jtds connection' do
|
23
|
-
before do
|
24
|
-
@config = {
|
25
|
-
:driver => 'net.sourceforge.jtds.Driver',
|
26
|
-
:url => "jdbc:jtds:sybase://test:1234/database",
|
27
|
-
:dialect => 'sybase_jtds'
|
28
|
-
}
|
29
|
-
@adapter = ActiveRecord::ConnectionAdapters::JdbcAdapter.new MockConnection.new, nil, @config
|
30
|
-
end
|
31
|
-
|
32
|
-
it "instantiate correct adapter when using 'sybase_jtds' dialect" do
|
33
|
-
@adapter.must_be_kind_of(::ArJdbc::SybaseJtds)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should configure arel2 visitors for SybaseJtds" do
|
37
|
-
::Arel::Visitors::VISITORS.must_include('sybase_jtds')
|
38
|
-
visitor = ::Arel::Visitors::VISITORS['sybase_jtds']
|
39
|
-
visitor.must_equal(::Arel::Visitors::SybaseJtds)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/test/test_visitor.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
require 'arel/visitors/sybase_jtds'
|
3
|
-
|
4
|
-
module Arel
|
5
|
-
module Visitors
|
6
|
-
describe 'the sybase jtds visitor' do
|
7
|
-
before do
|
8
|
-
@visitor = SybaseJtds.new Table.engine
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
describe Nodes::SelectStatement do
|
13
|
-
it "should not have 'LIMIT' keyword" do
|
14
|
-
stmt = Nodes::SelectStatement.new
|
15
|
-
stmt.cores.first.projections << 'first_field'
|
16
|
-
stmt.limit = 10
|
17
|
-
sql = @visitor.accept stmt
|
18
|
-
sql.wont_match /LIMIT 10/
|
19
|
-
end
|
20
|
-
|
21
|
-
describe 'limit with no offset and no "DISTINCT"' do
|
22
|
-
it 'adds a TOP keyword after "SELECT"' do
|
23
|
-
stmt = Nodes::SelectStatement.new
|
24
|
-
stmt.cores.first.projections << 'first_field'
|
25
|
-
stmt.limit = 10
|
26
|
-
sql = @visitor.accept stmt
|
27
|
-
sql.must_be_like %{ SELECT TOP 10 'first_field' }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe 'limit with no offset and "DISTINCT"' do
|
32
|
-
it 'adds a TOP keyword after "DISTINCT"' do
|
33
|
-
stmt = Nodes::SelectStatement.new
|
34
|
-
stmt.cores.first.projections << Nodes::SqlLiteral.new('DISTINCT id')
|
35
|
-
stmt.limit = 10
|
36
|
-
sql = @visitor.accept stmt
|
37
|
-
sql.must_be_like %{ SELECT DISTINCT TOP 10 id }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
#
|
42
|
-
# describe 'only offset' do
|
43
|
-
# it 'creates a select from subquery with rownum condition' do
|
44
|
-
# stmt = Nodes::SelectStatement.new
|
45
|
-
# stmt.offset = Nodes::Offset.new(10)
|
46
|
-
# sql = @visitor.accept stmt
|
47
|
-
# sql.must_be_like %{
|
48
|
-
# SELECT * FROM (
|
49
|
-
# SELECT raw_sql_.*, rownum raw_rnum_
|
50
|
-
# FROM (SELECT ) raw_sql_
|
51
|
-
# )
|
52
|
-
# WHERE raw_rnum_ > 10
|
53
|
-
# }
|
54
|
-
# end
|
55
|
-
# end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|