arel_toolkit 0.4.3 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/coverage.yml +48 -0
- data/.github/workflows/test.yml +68 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +2 -0
- data/.ruby-version +1 -1
- data/.tool-versions +1 -0
- data/Appraisals +4 -0
- data/CHANGELOG.md +49 -3
- data/Gemfile.lock +134 -84
- data/README.md +20 -3
- data/arel_toolkit.gemspec +3 -5
- data/bin/console +2 -1
- data/bin/setup +23 -2
- data/docker-compose.yml +11 -0
- data/gemfiles/active_record_6.gemfile +3 -3
- data/gemfiles/active_record_6.gemfile.lock +9 -7
- data/gemfiles/active_record_6_1.gemfile +7 -0
- data/gemfiles/active_record_6_1.gemfile.lock +263 -0
- data/gemfiles/arel_gems.gemfile.lock +9 -7
- data/gemfiles/default.gemfile.lock +9 -7
- data/lib/arel/enhance/context_enhancer/arel_table.rb +20 -0
- data/lib/arel/enhance/node.rb +20 -12
- data/lib/arel/enhance/visitor.rb +1 -1
- data/lib/arel/enhance.rb +2 -2
- data/lib/arel/extensions/conflict.rb +3 -3
- data/lib/arel/extensions/delete_statement.rb +19 -14
- data/lib/arel/extensions/infer.rb +2 -2
- data/lib/arel/extensions/insert_statement.rb +3 -3
- data/lib/arel/extensions/overlaps.rb +7 -1
- data/lib/arel/extensions/table.rb +7 -2
- data/lib/arel/extensions/transaction.rb +9 -9
- data/lib/arel/extensions/tree_manager.rb +0 -5
- data/lib/arel/extensions/update_statement.rb +8 -22
- data/lib/arel/sql_to_arel/pg_query_visitor/frame_options.rb +37 -5
- data/lib/arel/sql_to_arel/pg_query_visitor.rb +430 -521
- data/lib/arel/transformer/prefix_schema_name.rb +5 -3
- data/lib/arel/transformer.rb +0 -1
- data/lib/arel_toolkit/version.rb +1 -1
- metadata +15 -12
- data/.github/workflows/develop.yml +0 -90
- data/.github/workflows/master.yml +0 -67
- data/lib/arel/transformer/remove_active_record_info.rb +0 -40
@@ -42,11 +42,11 @@ module Arel
|
|
42
42
|
end
|
43
43
|
|
44
44
|
case o.override
|
45
|
-
when
|
45
|
+
when :OVERRIDING_KIND_UNDEFINED, :OVERRIDING_NOT_SET, nil
|
46
46
|
collector << ''
|
47
|
-
when
|
47
|
+
when :OVERRIDING_USER_VALUE
|
48
48
|
collector << ' OVERRIDING USER VALUE'
|
49
|
-
when
|
49
|
+
when :OVERRIDING_SYSTEM_VALUE
|
50
50
|
collector << ' OVERRIDING SYSTEM VALUE'
|
51
51
|
else
|
52
52
|
raise "Unknown override `#{o.override}`"
|
@@ -4,7 +4,13 @@
|
|
4
4
|
module Arel
|
5
5
|
module Nodes
|
6
6
|
# https://www.postgresql.org/docs/10/functions-string.html
|
7
|
-
|
7
|
+
inheritance_class = if Gem.loaded_specs['activerecord'].version < Gem::Version.new('6.1.0')
|
8
|
+
Arel::Nodes::Node
|
9
|
+
else
|
10
|
+
Arel::Nodes::InfixOperation
|
11
|
+
end
|
12
|
+
|
13
|
+
class Overlaps < inheritance_class
|
8
14
|
attr_reader :start1
|
9
15
|
attr_reader :end1
|
10
16
|
attr_reader :start2
|
@@ -15,7 +15,8 @@ module Arel
|
|
15
15
|
def initialize(
|
16
16
|
name,
|
17
17
|
as: nil,
|
18
|
-
|
18
|
+
klass: nil,
|
19
|
+
type_caster: klass&.type_caster,
|
19
20
|
only: false,
|
20
21
|
schema_name: nil,
|
21
22
|
relpersistence: 'p'
|
@@ -24,7 +25,11 @@ module Arel
|
|
24
25
|
@schema_name = schema_name
|
25
26
|
@relpersistence = relpersistence
|
26
27
|
|
27
|
-
|
28
|
+
if Gem.loaded_specs['activerecord'].version < Gem::Version.new('6.1.0')
|
29
|
+
super(name, as: as, type_caster: type_caster)
|
30
|
+
else
|
31
|
+
super(name, klass: klass, as: as, type_caster: type_caster)
|
32
|
+
end
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
@@ -16,21 +16,21 @@ module Arel
|
|
16
16
|
class ToSql
|
17
17
|
def visit_Arel_Nodes_Transaction(o, collector)
|
18
18
|
case o.type
|
19
|
-
when
|
19
|
+
when 1
|
20
20
|
collector << 'BEGIN'
|
21
|
-
when 2
|
22
|
-
collector << 'COMMIT'
|
23
21
|
when 3
|
24
|
-
collector << '
|
22
|
+
collector << 'COMMIT'
|
25
23
|
when 4
|
26
|
-
collector << '
|
27
|
-
collector << o.options.join(' ')
|
24
|
+
collector << 'ROLLBACK'
|
28
25
|
when 5
|
29
|
-
collector << '
|
30
|
-
collector << o.
|
26
|
+
collector << 'SAVEPOINT '
|
27
|
+
collector << o.right
|
31
28
|
when 6
|
29
|
+
collector << 'RELEASE SAVEPOINT '
|
30
|
+
collector << o.right
|
31
|
+
when 7
|
32
32
|
collector << 'ROLLBACK TO '
|
33
|
-
collector << o.
|
33
|
+
collector << o.right
|
34
34
|
else
|
35
35
|
raise "Unknown transaction type `#{o.type}`"
|
36
36
|
end
|
@@ -1,11 +1,6 @@
|
|
1
1
|
module Arel
|
2
2
|
class TreeManager
|
3
3
|
# Iterate through AST, nodes will be yielded depth-first
|
4
|
-
def each(&block)
|
5
|
-
return enum_for(:each) unless block_given?
|
6
|
-
|
7
|
-
::Arel::Visitors::DepthFirst.new(block).accept ast
|
8
|
-
end
|
9
4
|
|
10
5
|
def to_sql_and_binds(engine = Arel::Table.engine)
|
11
6
|
collector = engine.connection.send(:collector)
|
@@ -24,16 +24,17 @@ module Arel
|
|
24
24
|
|
25
25
|
module Visitors
|
26
26
|
class ToSql
|
27
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
28
27
|
# rubocop:disable Metrics/AbcSize
|
29
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
30
28
|
def visit_Arel_Nodes_UpdateStatement(o, collector)
|
31
29
|
if o.with
|
32
30
|
collector = visit o.with, collector
|
33
31
|
collector << ' '
|
34
32
|
end
|
35
33
|
|
36
|
-
wheres = if
|
34
|
+
wheres = if Gem.loaded_specs['activerecord'].version >= Gem::Version.new('6.0.0')
|
35
|
+
o = prepare_update_statement(o)
|
36
|
+
o.wheres
|
37
|
+
elsif o.orders.empty? && o.limit.nil?
|
37
38
|
o.wheres
|
38
39
|
else
|
39
40
|
[Nodes::In.new(o.key, [build_subselect(o.key, o)])]
|
@@ -41,31 +42,16 @@ module Arel
|
|
41
42
|
|
42
43
|
collector << 'UPDATE '
|
43
44
|
collector = visit o.relation, collector
|
44
|
-
unless o.values.empty?
|
45
|
-
collector << ' SET '
|
46
|
-
collector = inject_join o.values, collector, ', '
|
47
|
-
end
|
48
|
-
|
49
|
-
unless o.froms.empty?
|
50
|
-
collector << ' FROM '
|
51
|
-
collector = inject_join o.froms, collector, ', '
|
52
|
-
end
|
53
45
|
|
54
|
-
|
55
|
-
|
56
|
-
collector = inject_join wheres, collector, ' AND '
|
57
|
-
end
|
46
|
+
collect_nodes_for o.values, collector, ' SET '
|
47
|
+
collect_nodes_for o.froms, collector, ' FROM ', ', '
|
58
48
|
|
59
|
-
|
60
|
-
|
61
|
-
collector = inject_join o.returning, collector, ', '
|
62
|
-
end
|
49
|
+
collect_nodes_for wheres, collector, ' WHERE ', ' AND '
|
50
|
+
collect_nodes_for o.returning, collector, ' RETURNING ', ', '
|
63
51
|
|
64
52
|
collector
|
65
53
|
end
|
66
54
|
# rubocop:enable Metrics/AbcSize
|
67
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
68
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
69
55
|
end
|
70
56
|
|
71
57
|
class Dot
|
@@ -42,7 +42,7 @@ module Arel
|
|
42
42
|
# RANGE only unbounded
|
43
43
|
# ROWS all
|
44
44
|
# https://github.com/postgres/postgres/blob/REL_10_1/src/include/nodes/parsenodes.h
|
45
|
-
|
45
|
+
FRAMEOPTIONS_V10 = {
|
46
46
|
'FRAMEOPTION_NONDEFAULT' => 0x00001,
|
47
47
|
'FRAMEOPTION_RANGE' => 0x00002,
|
48
48
|
'FRAMEOPTION_ROWS' => 0x00004,
|
@@ -59,6 +59,38 @@ module Arel
|
|
59
59
|
'FRAMEOPTION_END_VALUE_FOLLOWING' => 0x02000,
|
60
60
|
}.freeze
|
61
61
|
|
62
|
+
FRAMEOPTIONS_V11_AND_UP = {
|
63
|
+
'FRAMEOPTION_NONDEFAULT' => 0x00001, # any specified? */
|
64
|
+
'FRAMEOPTION_RANGE' => 0x00002, # RANGE behavior */
|
65
|
+
'FRAMEOPTION_ROWS' => 0x00004, # ROWS behavior */
|
66
|
+
'FRAMEOPTION_GROUPS' => 0x00008, # GROUPS behavior */
|
67
|
+
'FRAMEOPTION_BETWEEN' => 0x00010, # BETWEEN given? */
|
68
|
+
'FRAMEOPTION_START_UNBOUNDED_PRECEDING' => 0x00020, # start is U. P. */
|
69
|
+
'FRAMEOPTION_END_UNBOUNDED_PRECEDING' => 0x00040, # (disallowed) */
|
70
|
+
'FRAMEOPTION_START_UNBOUNDED_FOLLOWING' => 0x00080, # (disallowed) */
|
71
|
+
'FRAMEOPTION_END_UNBOUNDED_FOLLOWING' => 0x00100, # end is U. F. */
|
72
|
+
'FRAMEOPTION_START_CURRENT_ROW' => 0x00200, # start is C. R. */
|
73
|
+
'FRAMEOPTION_END_CURRENT_ROW' => 0x00400, # end is C. R. */
|
74
|
+
'FRAMEOPTION_START_OFFSET_PRECEDING' => 0x00800, # start is O. P. */
|
75
|
+
'FRAMEOPTION_END_OFFSET_PRECEDING' => 0x01000, # end is O. P. */
|
76
|
+
'FRAMEOPTION_START_OFFSET_FOLLOWING' => 0x02000, # start is O. F. */
|
77
|
+
'FRAMEOPTION_END_OFFSET_FOLLOWING' => 0x04000, # end is O. F. */
|
78
|
+
'FRAMEOPTION_EXCLUDE_CURRENT_ROW' => 0x08000, # omit C.R. */
|
79
|
+
'FRAMEOPTION_EXCLUDE_GROUP' => 0x10000, # omit C.R. & peers */
|
80
|
+
'FRAMEOPTION_EXCLUDE_TIES' => 0x20000, # omit C.R.'s peers */
|
81
|
+
}.freeze
|
82
|
+
|
83
|
+
def frameoptions
|
84
|
+
case PG.library_version.to_s[0, 2]
|
85
|
+
when '09', '10'
|
86
|
+
FRAMEOPTIONS_V10
|
87
|
+
when '11', '12', '13', '14'
|
88
|
+
FRAMEOPTIONS_V11_AND_UP
|
89
|
+
else
|
90
|
+
boom "Version #{PG.library_version.to_s[0, 2]} not supported"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
62
94
|
def biggest_detractable_number(number, candidates)
|
63
95
|
high_to_low_candidates = candidates.sort { |a, b| b <=> a }
|
64
96
|
high_to_low_candidates.find do |candidate|
|
@@ -69,8 +101,8 @@ module Arel
|
|
69
101
|
def calculate_frame_option_names(frame_options, names = [])
|
70
102
|
return names if frame_options.zero?
|
71
103
|
|
72
|
-
number = biggest_detractable_number(frame_options,
|
73
|
-
name =
|
104
|
+
number = biggest_detractable_number(frame_options, frameoptions.values)
|
105
|
+
name = frameoptions.key(number)
|
74
106
|
calculate_frame_option_names(
|
75
107
|
frame_options - number, names + [name]
|
76
108
|
)
|
@@ -95,10 +127,10 @@ module Arel
|
|
95
127
|
when 'CURRENT_ROW'
|
96
128
|
Arel::Nodes::CurrentRow.new
|
97
129
|
|
98
|
-
when 'VALUE_PRECEDING'
|
130
|
+
when 'VALUE_PRECEDING', 'OFFSET_PRECEDING'
|
99
131
|
Arel::Nodes::Preceding.new offset
|
100
132
|
|
101
|
-
when 'VALUE_FOLLOWING'
|
133
|
+
when 'VALUE_FOLLOWING', 'OFFSET_FOLLOWING'
|
102
134
|
Arel::Nodes::Following.new offset
|
103
135
|
|
104
136
|
else
|