arel_extensions 0.8.0

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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +46 -0
  4. data/Gemfile +10 -0
  5. data/MIT-LICENSE.txt +20 -0
  6. data/README.md +101 -0
  7. data/Rakefile +14 -0
  8. data/arel_extensions.gemspec +32 -0
  9. data/functions.html +344 -0
  10. data/gemfiles/Gemfile.rails3 +10 -0
  11. data/gemfiles/Gemfile.rails5 +10 -0
  12. data/init/mssql.sql +6 -0
  13. data/init/mysql.sql +0 -0
  14. data/init/oracle.sql +31 -0
  15. data/init/postgresql.sql +12 -0
  16. data/init/sqlite.sql +1 -0
  17. data/lib/arel_extensions.rb +84 -0
  18. data/lib/arel_extensions/attributes.rb +26 -0
  19. data/lib/arel_extensions/comparators.rb +59 -0
  20. data/lib/arel_extensions/date_duration.rb +28 -0
  21. data/lib/arel_extensions/insert_manager.rb +33 -0
  22. data/lib/arel_extensions/math.rb +48 -0
  23. data/lib/arel_extensions/math_functions.rb +35 -0
  24. data/lib/arel_extensions/nodes.rb +27 -0
  25. data/lib/arel_extensions/nodes/abs.rb +6 -0
  26. data/lib/arel_extensions/nodes/ceil.rb +6 -0
  27. data/lib/arel_extensions/nodes/coalesce.rb +22 -0
  28. data/lib/arel_extensions/nodes/concat.rb +33 -0
  29. data/lib/arel_extensions/nodes/date_diff.rb +106 -0
  30. data/lib/arel_extensions/nodes/duration.rb +30 -0
  31. data/lib/arel_extensions/nodes/find_in_set.rb +16 -0
  32. data/lib/arel_extensions/nodes/floor.rb +6 -0
  33. data/lib/arel_extensions/nodes/function.rb +17 -0
  34. data/lib/arel_extensions/nodes/isnull.rb +30 -0
  35. data/lib/arel_extensions/nodes/length.rb +6 -0
  36. data/lib/arel_extensions/nodes/locate.rb +33 -0
  37. data/lib/arel_extensions/nodes/ltrim.rb +28 -0
  38. data/lib/arel_extensions/nodes/matches.rb +22 -0
  39. data/lib/arel_extensions/nodes/rand.rb +23 -0
  40. data/lib/arel_extensions/nodes/replace.rb +36 -0
  41. data/lib/arel_extensions/nodes/round.rb +15 -0
  42. data/lib/arel_extensions/nodes/rtrim.rb +29 -0
  43. data/lib/arel_extensions/nodes/soundex.rb +23 -0
  44. data/lib/arel_extensions/nodes/sum.rb +23 -0
  45. data/lib/arel_extensions/nodes/trim.rb +26 -0
  46. data/lib/arel_extensions/nodes/wday.rb +23 -0
  47. data/lib/arel_extensions/null_functions.rb +16 -0
  48. data/lib/arel_extensions/string_functions.rb +68 -0
  49. data/lib/arel_extensions/version.rb +4 -0
  50. data/lib/arel_extensions/visitors.rb +6 -0
  51. data/lib/arel_extensions/visitors/ibm_db.rb +206 -0
  52. data/lib/arel_extensions/visitors/mssql.rb +213 -0
  53. data/lib/arel_extensions/visitors/mysql.rb +184 -0
  54. data/lib/arel_extensions/visitors/oracle.rb +267 -0
  55. data/lib/arel_extensions/visitors/postgresql.rb +258 -0
  56. data/lib/arel_extensions/visitors/sqlite.rb +218 -0
  57. data/lib/arel_extensions/visitors/to_sql.rb +199 -0
  58. data/test/helper.rb +18 -0
  59. data/test/real_db_test.rb +251 -0
  60. data/test/support/fake_record.rb +137 -0
  61. data/test/test_comparators.rb +49 -0
  62. data/test/visitors/test_bulk_insert_oracle.rb +30 -0
  63. data/test/visitors/test_bulk_insert_sqlite.rb +31 -0
  64. data/test/visitors/test_bulk_insert_to_sql.rb +32 -0
  65. data/test/visitors/test_oracle.rb +105 -0
  66. data/test/visitors/test_to_sql.rb +148 -0
  67. data/test/with_ar/test_bulk_sqlite.rb +44 -0
  68. data/test/with_ar/test_math_sqlite.rb +59 -0
  69. data/test/with_ar/test_string_sqlite.rb +69 -0
  70. metadata +230 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 087006edf929bdce808d6e2ba04a9e39923caa51
4
+ data.tar.gz: 0aaa1834a9d6939366ce9bda87dbacc3e60db044
5
+ SHA512:
6
+ metadata.gz: 26248a966e70e85b6b4baf615e273d1fe80661be799f44d119ef244e83f3d8a37c09fe14e488746eda992bb84595a9e2821fcf1f3535648ccb3da0159c420c55
7
+ data.tar.gz: a4e60ee3fa48f9dbff4a50a3c73edec8ed3c172372b69e2cb1ef6587eabb1b03acef5c625a824c8b536a490b033f1785b1a4541152b6fcacf66cebeb095ac794
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ coverage/*
2
+ config/database.yml
3
+ spec/support/fixtures/*database*
4
+ *.DS_Store
5
+ debug.log
6
+ pkg
7
+ .bundle
8
+ *.swp
9
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,46 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ before_install:
5
+ # - sudo apt-get update -qq
6
+ # - sudo apt-get install -qq sqlite3
7
+ #addons:
8
+ # mariadb: '10.0'
9
+ services:
10
+ - mysql
11
+ - postgresql
12
+ before_script:
13
+ - mysql -e 'create database arext_test;'
14
+ - psql -c 'create database arext_test;' -U postgres
15
+ script:
16
+ - "bundle exec rake test"
17
+ # - "bundle exec rake test:sqlite3"
18
+ - "gem build arel_extensions.gemspec"
19
+ # - "ruby test/real_db_test.rb"
20
+ env:
21
+ global:
22
+ - JRUBY_OPTS='--dev -J-Xmx1024M'
23
+ rvm:
24
+ - rbx-2
25
+ - jruby-9.0.5.0
26
+ - jruby-head
27
+ - 2.0.0
28
+ - 2.1
29
+ - 2.2.5
30
+ - 2.3.1
31
+ - ruby-head
32
+ jdk:
33
+ - openjdk7
34
+ - oraclejdk7
35
+ - oraclejdk8
36
+ # - openjdk6
37
+ matrix:
38
+ fast_finish: true
39
+ # allow_failures:
40
+ # - rvm: jruby-9.0.5.0
41
+ # - rvm: jruby-head
42
+ # - rvm: ruby-head
43
+ # - rvm: jruby-head
44
+ bundler_args: --jobs 3 --retry 3
45
+ notifications:
46
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
7
+ # for JRuby
8
+ gem "jdbc-sqlite3", :platform => :jrubyend
9
+ gem 'activerecord', '~> 4.0'
10
+ end
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007-2016 Faveod
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Arel Extensions
2
+
3
+ Arel Extensions adds shortcuts, fixes and new ORM mappings (ruby to SQL) to Arel.
4
+ It aims to ensure pure ruby syntax for the biggest number of usual cases.
5
+ It allows to use more advanced SQL functions for any supported RDBMS.
6
+
7
+ Examples:
8
+ t is an Arel::Table for table my_table
9
+
10
+ ## Comparators
11
+
12
+ ```ruby
13
+ (t[:nb] > 42).to_sql # (same as (t[:nb].gt(42)).to_sql)
14
+ # => my_table.nb > 42
15
+ ```
16
+
17
+ ## Maths
18
+
19
+ Currently in Arel:
20
+ ```ruby
21
+ (t[:nb] + 42).to_sql
22
+ # => my_table.nb + 42
23
+ ```
24
+
25
+ But:
26
+ ```ruby
27
+ (t[:nb].sum + 42).to_sql
28
+ # => NoMethodError: undefined method `+' for #<Arel::Nodes::Sum>
29
+ ```
30
+
31
+ With Arel Extensions:
32
+ ```ruby
33
+ (t[:nb].sum + 42).to_sql
34
+ # => SUM(my_table.nb) + 42
35
+ ```
36
+
37
+ Other functions : ABS, RAND, ROUND, FLOOR, CEIL, MD5, FORMAT
38
+
39
+ ## String operations
40
+
41
+ ```ruby
42
+ (t[:name] + ' append').to_sql
43
+ # => CONCAT(my_table.name, ' append')
44
+
45
+ (t[:name].if_null('default')).to_sql
46
+ # => ISNULL(my_table.name, 'default')
47
+
48
+ (t[:name] =~ /\A[a-d_]+/).to_sql
49
+ # => my_table.name REGEXP '\^[a-d_]+'
50
+ ```
51
+
52
+ Other functions : SOUNDEX, LENGTH, REPLACE, LOCATE, TRIM
53
+
54
+ ### String Array operations
55
+
56
+ ```t[:list]``` is a classical varchar containing a comma separated list ("1,2,3,4")
57
+
58
+ ```ruby
59
+ (t[:list] & 3).to_sql
60
+ # => FIND_IN_SET('3', my_table.list)
61
+
62
+ (t[:list] & [2,3]).to_sql
63
+ # => FIND_IN_SET('2', my_table.list) OR FIND_IN_SET('3', my_table.list)
64
+ ```
65
+
66
+
67
+ ## Date & Time operations
68
+
69
+ ```ruby
70
+ (t[:birthdate] + 10.years).to_sql
71
+ # => ADDDATE(my_table.birthdate, INTERVAL 10 YEAR)
72
+
73
+ ((t[:birthdate] - Date.today) * -1).to_sql
74
+ # => DATEDIFF(my_table.birthdate, '2017-01-01') * -1
75
+
76
+ (t[:birthdate].week).to_sql
77
+ # => WEEK(my_table.birthdate)
78
+
79
+ t[:birthdate].month.to_sql
80
+ # => MONTH(my_table.birthdate)
81
+
82
+ t[:birthdate].year.to_sql
83
+ # => YEAR(my_table.birthdate)
84
+ ```
85
+
86
+ ## Unions (in next version)
87
+
88
+ ```ruby
89
+ (t.where(t[:name].eq('str')) + t.where(t[:name].eq('test'))).to_sql
90
+ # => SELECT * FROM my_table WHERE (name = 'str') UNION SELECT * FROM my_table WHERE (name= 'test')
91
+ ```
92
+
93
+ ## Stored Procedures and User-defined functions
94
+
95
+ To optimize queries, some classical functions are defined in databases missing any alternative native functions.
96
+ Examples :
97
+ - FIND_IN_SET
98
+
99
+ ## BULK INSERT / UPSERT
100
+
101
+ TODO
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+
6
+ desc "Default Task"
7
+ task default: [ :test ]
8
+
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/test_*.rb'
13
+ t.verbose = true
14
+ end
@@ -0,0 +1,32 @@
1
+ # # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ # require "arel_extensions"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "arel_extensions"
7
+ s.version = '0.8.0'
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Yann Azoury", "Mathilde Pechdi", "Félix Bellanger"]
10
+ s.email = ["yann.azoury@faveod.com", "mathilde.pechdimaldjian@gmail.com", "felix.bellanger@faveod.com"]
11
+ s.homepage = "https://github.com/Faveod/arel-extensions"
12
+ s.description = "Adds new features to Arel"
13
+ s.summary = "Extending Arel"
14
+ s.license = %q{MIT}
15
+
16
+ s.rdoc_options = ["--main", "README.md"]
17
+ s.extra_rdoc_files = ["MIT-LICENSE.txt", "README.md"]
18
+
19
+ # Manifest
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_dependency('arel', '~> 6.0')
25
+
26
+ s.add_development_dependency('minitest')
27
+ s.add_development_dependency('rdoc', '~> 4.0')
28
+ s.add_development_dependency('rake')
29
+ s.add_development_dependency('activesupport', '~> 4.0')
30
+ s.add_development_dependency('activemodel', '~> 4.0')
31
+ s.add_development_dependency('activerecord', '~> 4.0')
32
+ end
data/functions.html ADDED
@@ -0,0 +1,344 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Arel Extensions Features</title>
6
+ <style type="text/css">
7
+ .tg {border-collapse:collapse;border-spacing:0;}
8
+ .tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
9
+ .tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
10
+ .tg .tg-baqh{text-align:center;vertical-align:top}
11
+ .tg .tg-3oug{background-color:#fd6864;text-align:center;vertical-align:top}
12
+ .tg .tg-by3v{font-weight:bold;font-size:14px;text-align:center}
13
+ .tg .tg-jogk{font-style:italic;vertical-align:top}
14
+ .tg .tg-pjz5{font-weight:bold;font-size:14px;background-color:#f8a102;text-align:center;vertical-align:top}
15
+ .tg .tg-82sq{font-weight:bold;background-color:#ffce93;color:#330001;vertical-align:top}
16
+ .tg .tg-yw4l{vertical-align:top}
17
+ .tg .tg-j6lv{background-color:#96fffb;text-align:center;vertical-align:top}
18
+ .tg .tg-ffjm{font-weight:bold;background-color:#fffc9e;vertical-align:top}
19
+ .tg .tg-orpl{font-size:10px;background-color:#96fffb;vertical-align:top}
20
+ .tg .tg-4rp9{font-weight:bold;background-color:#ffffc7;vertical-align:top}
21
+ .tg .tg-72dn{font-weight:bold;background-color:#f7f6cd;vertical-align:top}
22
+ .tg .tg-9hbo{font-weight:bold;vertical-align:top}
23
+ </style>
24
+ </head>
25
+ <body>
26
+ <table class="tg">
27
+ <thead>
28
+ <tr>
29
+ <th class="tg-jogk"></th>
30
+ <th class="tg-by3v">Function / Example<br/>ToSql</th>
31
+ <th class="tg-pjz5">MySQL/MariaDB</th>
32
+ <th class="tg-pjz5">PostgreSQL</th>
33
+ <th class="tg-pjz5">SQLite</th>
34
+ <th class="tg-pjz5">Oracle</th>
35
+ <th class="tg-pjz5">MS SQL</th>
36
+ <th class="tg-pjz5">DB2</th>
37
+ </tr>
38
+ </thead>
39
+ <tr>
40
+ <td class="tg-82sq" rowspan="6"><br><br><br><br><br><br><br>Math<br>functions<br></td>
41
+ <td class="tg-yw4l">ABS<br>column.abs<br></td>
42
+ <td class="tg-baqh">✔</td>
43
+ <td class="tg-baqh">✔</td>
44
+ <td class="tg-baqh">✔</td>
45
+ <td class="tg-baqh">✔</td>
46
+ <td class="tg-baqh">✔</td>
47
+ <td class="tg-baqh">✔</td>
48
+ </tr>
49
+ <tr>
50
+ <td class="tg-yw4l">CEIL<br>column.ceil</td>
51
+ <td class="tg-baqh">✔</td>
52
+ <td class="tg-baqh">✔</td>
53
+ <td class="tg-3oug">require extension-functions.so</td>
54
+ <td class="tg-baqh">✔</td>
55
+ <td class="tg-j6lv">CEILING()</td>
56
+ <td class="tg-j6lv">CEILING()</td>
57
+ </tr>
58
+ <tr>
59
+ <td class="tg-yw4l">FLOOR<br>column.floor</td>
60
+ <td class="tg-baqh">✔</td>
61
+ <td class="tg-baqh">✔</td>
62
+ <td class="tg-3oug">require extension-functions.so</td>
63
+ <td class="tg-baqh">✔</td>
64
+ <td class="tg-baqh">✔</td>
65
+ <td class="tg-baqh">✔</td>
66
+ </tr>
67
+ <tr>
68
+ <td class="tg-yw4l">RAND<br>Arel.rand</td>
69
+ <td class="tg-baqh">✔</td>
70
+ <td class="tg-baqh">✔</td>
71
+ <td class="tg-j6lv">RANDOM()</td>
72
+ <td class="tg-j6lv">dbms_random.value()</td>
73
+ <td class="tg-baqh">✔</td>
74
+ <td class="tg-baqh">✔</td>
75
+ </tr>
76
+ <tr>
77
+ <td class="tg-yw4l">ROUND<br>column.round(precision = 0)</td>
78
+ <td class="tg-baqh">✔</td>
79
+ <td class="tg-baqh">✔</td>
80
+ <td class="tg-baqh">✔</td>
81
+ <td class="tg-baqh">✔</td>
82
+ <td class="tg-baqh">✔</td>
83
+ <td class="tg-baqh">✔</td>
84
+ </tr>
85
+ <tr>
86
+ <td class="tg-yw4l">SUM / AVG / MIN / MAX + x<br>column.sum + 42</td>
87
+ <td class="tg-baqh">✔</td>
88
+ <td class="tg-baqh">✔</td>
89
+ <td class="tg-baqh">✔</td>
90
+ <td class="tg-baqh">✔</td>
91
+ <td class="tg-baqh">✔</td>
92
+ <td class="tg-baqh">✔</td>
93
+ </tr>
94
+ <tr>
95
+ <td class="tg-ffjm" rowspan="11"><br><br><br><br><br><br><br><br><br>String <br>functions <br></td>
96
+ <td class="tg-yw4l">CONCAT<br>column + "string"</td>
97
+ <td class="tg-baqh">✔</td>
98
+ <td class="tg-baqh">✔</td>
99
+ <td class="tg-j6lv"> ||</td>
100
+ <td class="tg-baqh">✔</td>
101
+ <td class="tg-j6lv">+</td>
102
+ <td class="tg-baqh">✔</td>
103
+ </tr>
104
+ <tr>
105
+ <td class="tg-yw4l">LENGTH<br>column.length</td>
106
+ <td class="tg-baqh">✔</td>
107
+ <td class="tg-baqh">✔</td>
108
+ <td class="tg-baqh">✔</td>
109
+ <td class="tg-baqh">✔</td>
110
+ <td class="tg-j6lv">LEN()</td>
111
+ <td class="tg-baqh">✔</td>
112
+ </tr>
113
+ <tr>
114
+ <td class="tg-yw4l">LOCATE<br>column.locate("string")</td>
115
+ <td class="tg-baqh">✔</td>
116
+ <td class="tg-baqh">✔</td>
117
+ <td class="tg-j6lv">INSTR()</td>
118
+ <td class="tg-baqh">✔</td>
119
+ <td class="tg-j6lv">CHARINDEX()</td>
120
+ <td class="tg-baqh">✔</td>
121
+ </tr>
122
+ <tr>
123
+ <td class="tg-yw4l">FIND_IN_SET<br>column &amp; ("l")</td>
124
+ <td class="tg-baqh">✔</td>
125
+ <td class="tg-baqh">✔</td>
126
+ <td class="tg-orpl">db.create_function( "find_in_set", 1 ) <br>do |func, value1, value2|,<br>func.result =value1.index(value2)<br>end <br></td>
127
+ <td class="tg-baqh">✔</td>
128
+ <td class="tg-baqh">✔</td>
129
+ <td class="tg-baqh">✔</td>
130
+ </tr>
131
+ <tr>
132
+ <td class="tg-yw4l">SOUNDEX<br>column.soundex</td>
133
+ <td class="tg-baqh">✔</td>
134
+ <td class="tg-3oug">require fuzzystrmatch</td>
135
+ <td class="tg-baqh">✔</td>
136
+ <td class="tg-baqh">✔</td>
137
+ <td class="tg-baqh">✔</td>
138
+ <td class="tg-baqh">✔</td>
139
+ </tr>
140
+ <tr>
141
+ <td class="tg-yw4l">REPLACE<br>column.replace("s","X")</td>
142
+ <td class="tg-baqh">✔</td>
143
+ <td class="tg-baqh">✔</td>
144
+ <td class="tg-baqh">✔</td>
145
+ <td class="tg-baqh">✔</td>
146
+ <td class="tg-baqh">✔</td>
147
+ <td class="tg-baqh">✔</td>
148
+ </tr>
149
+ <tr>
150
+ <td class="tg-yw4l">REGEXP<br>column =~ "pattern"<br></td>
151
+ <td class="tg-baqh">✔</td>
152
+ <td class="tg-baqh">✔</td>
153
+ <td class="tg-3oug">require pcre.so</td>
154
+ <td class="tg-j6lv">REGEXP_LIKE()</td>
155
+ <td class="tg-j6lv">LIKE()<br></td>
156
+ <td class="tg-baqh">✔</td>
157
+ </tr>
158
+ <tr>
159
+ <td class="tg-yw4l">NOT_REGEXP<br>column != "pattern"</td>
160
+ <td class="tg-baqh">✔</td>
161
+ <td class="tg-baqh">✔<br></td>
162
+ <td class="tg-3oug">require pcre.so</td>
163
+ <td class="tg-j6lv">NOT REGEXP_LIKE()</td>
164
+ <td class="tg-j6lv">NOT LIKE()</td>
165
+ <td class="tg-baqh">✔</td>
166
+ </tr>
167
+ <tr>
168
+ <td class="tg-yw4l">TRIM (leading)<br>column.trim("LEADING","M")</td>
169
+ <td class="tg-baqh">✔</td>
170
+ <td class="tg-j6lv">LTRIM()</td>
171
+ <td class="tg-j6lv">LTRIM()</td>
172
+ <td class="tg-baqh">✔</td>
173
+ <td class="tg-baqh">✔</td>
174
+ <td class="tg-j6lv">LTRIM()</td>
175
+ </tr>
176
+ <tr>
177
+ <td class="tg-yw4l">TRIM (trailing)<br>column.trim("TRAILING","g")</td>
178
+ <td class="tg-baqh">✔</td>
179
+ <td class="tg-j6lv">RTRIM()</td>
180
+ <td class="tg-j6lv">RTRIM()</td>
181
+ <td class="tg-baqh">✔</td>
182
+ <td class="tg-baqh">✔</td>
183
+ <td class="tg-j6lv">Rtrim()</td>
184
+ </tr>
185
+ <tr>
186
+ <td class="tg-yw4l">TRIM (both)<br>column.trim("BOTH","e")</td>
187
+ <td class="tg-baqh">✔</td>
188
+ <td class="tg-j6lv">TRIM()<br></td>
189
+ <td class="tg-j6lv">TRIM()</td>
190
+ <td class="tg-baqh">✔</td>
191
+ <td class="tg-baqh">✔</td>
192
+ <td class="tg-j6lv">TRIM()</td>
193
+ </tr>
194
+ <tr>
195
+ <td class="tg-4rp9" rowspan="6"><br><br><br><br><br><br><br>Date <br>functions<br></td>
196
+ <td class="tg-yw4l">DATEADD<br>column + 2.year<br></td>
197
+ <td class="tg-j6lv">DATE_ADD()<br></td>
198
+ <td class="tg-baqh">✔</td>
199
+ <td class="tg-baqh">✔</td>
200
+ <td class="tg-baqh">✔</td>
201
+ <td class="tg-baqh">✔</td>
202
+ <td class="tg-j6lv">+</td>
203
+ </tr>
204
+ <tr>
205
+ <td class="tg-yw4l">DATEDIFF<br>column - date<br></td>
206
+ <td class="tg-j6lv">DATEDIFF()<br></td>
207
+ <td class="tg-baqh">✔</td>
208
+ <td class="tg-j6lv">JULIANDAY() - JULIANDAY()</td>
209
+ <td class="tg-j6lv"> -</td>
210
+ <td class="tg-baqh">✔</td>
211
+ <td class="tg-j6lv">DAY()</td>
212
+ </tr>
213
+ <tr>
214
+ <td class="tg-yw4l">DAY<br>column.day<br></td>
215
+ <td class="tg-baqh">✔</td>
216
+ <td class="tg-baqh">✔</td>
217
+ <td class="tg-j6lv">STRFTIME()</td>
218
+ <td class="tg-baqh">✔</td>
219
+ <td class="tg-baqh">✔</td>
220
+ <td class="tg-baqh">✔</td>
221
+ </tr>
222
+ <tr>
223
+ <td class="tg-yw4l">MONTH<br>column.month<br></td>
224
+ <td class="tg-baqh">✔</td>
225
+ <td class="tg-baqh">✔</td>
226
+ <td class="tg-j6lv">STRFTIME()</td>
227
+ <td class="tg-baqh">✔</td>
228
+ <td class="tg-baqh">✔</td>
229
+ <td class="tg-baqh">✔</td>
230
+ </tr>
231
+ <tr>
232
+ <td class="tg-yw4l">WEEK<br>column.week</td>
233
+ <td class="tg-baqh">✔</td>
234
+ <td class="tg-baqh">✔</td>
235
+ <td class="tg-j6lv">STRFTIME()</td>
236
+ <td class="tg-baqh">✔</td>
237
+ <td class="tg-baqh">✔</td>
238
+ <td class="tg-baqh">✔</td>
239
+ </tr>
240
+ <tr>
241
+ <td class="tg-yw4l">YEAR<br>column.year</td>
242
+ <td class="tg-baqh">✔</td>
243
+ <td class="tg-baqh">✔</td>
244
+ <td class="tg-j6lv">STRFTIME()</td>
245
+ <td class="tg-baqh">✔</td>
246
+ <td class="tg-baqh">✔</td>
247
+ <td class="tg-baqh">✔</td>
248
+ </tr>
249
+ <tr>
250
+ <td class="tg-72dn" rowspan="8"><br><br><br><br><br><br>Comparators<br>functions<br></td>
251
+ <td class="tg-yw4l">COALESCE<br>column.coalesce(var)</td>
252
+ <td class="tg-baqh">✔</td>
253
+ <td class="tg-baqh">✔</td>
254
+ <td class="tg-baqh">✔</td>
255
+ <td class="tg-baqh">✔</td>
256
+ <td class="tg-baqh">✔</td>
257
+ <td class="tg-baqh">✔</td>
258
+ </tr>
259
+ <tr>
260
+ <td class="tg-yw4l">ISNULL<br>column.isnull(var)</td>
261
+ <td class="tg-j6lv">IFNULL()<br></td>
262
+ <td class="tg-baqh">✔</td>
263
+ <td class="tg-baqh">✔</td>
264
+ <td class="tg-j6lv">NVC()</td>
265
+ <td class="tg-baqh">✔</td>
266
+ <td class="tg-baqh">✔</td>
267
+ </tr>
268
+ <tr>
269
+ <td class="tg-yw4l">==<br>column == integer<br></td>
270
+ <td class="tg-baqh">✔</td>
271
+ <td class="tg-baqh">✔</td>
272
+ <td class="tg-baqh">✔</td>
273
+ <td class="tg-baqh">✔</td>
274
+ <td class="tg-baqh">✔</td>
275
+ <td class="tg-baqh">✔</td>
276
+ </tr>
277
+ <tr>
278
+ <td class="tg-yw4l">!=<br>column != integer<br></td>
279
+ <td class="tg-baqh">✔</td>
280
+ <td class="tg-baqh">✔</td>
281
+ <td class="tg-baqh">✔</td>
282
+ <td class="tg-baqh">✔</td>
283
+ <td class="tg-baqh">✔</td>
284
+ <td class="tg-baqh">✔</td>
285
+ </tr>
286
+ <tr>
287
+ <td class="tg-yw4l">&gt;<br>column &gt; integer<br></td>
288
+ <td class="tg-baqh">✔</td>
289
+ <td class="tg-baqh">✔</td>
290
+ <td class="tg-baqh">✔</td>
291
+ <td class="tg-baqh">✔</td>
292
+ <td class="tg-baqh">✔</td>
293
+ <td class="tg-baqh">✔</td>
294
+ </tr>
295
+ <tr>
296
+ <td class="tg-yw4l">&gt;=<br>column &gt;= integer</td>
297
+ <td class="tg-baqh">✔</td>
298
+ <td class="tg-baqh">✔</td>
299
+ <td class="tg-baqh">✔</td>
300
+ <td class="tg-baqh">✔</td>
301
+ <td class="tg-baqh">✔</td>
302
+ <td class="tg-baqh">✔</td>
303
+ </tr>
304
+ <tr>
305
+ <td class="tg-yw4l">&lt; <br>column &lt; integer</td>
306
+ <td class="tg-baqh">✔</td>
307
+ <td class="tg-baqh">✔</td>
308
+ <td class="tg-baqh">✔</td>
309
+ <td class="tg-baqh">✔</td>
310
+ <td class="tg-baqh">✔</td>
311
+ <td class="tg-baqh">✔</td>
312
+ </tr>
313
+ <tr>
314
+ <td class="tg-yw4l">&lt;=<br>column &lt;= integer</td>
315
+ <td class="tg-baqh">✔</td>
316
+ <td class="tg-baqh">✔</td>
317
+ <td class="tg-baqh">✔</td>
318
+ <td class="tg-baqh">✔</td>
319
+ <td class="tg-baqh">✔</td>
320
+ <td class="tg-baqh">✔</td>
321
+ </tr>
322
+ <tr>
323
+ <td class="tg-9hbo" rowspan="2"><br><br>Boolean <br>functions<br></td>
324
+ <td class="tg-yw4l">OR ( ⋁ )<br>column.eq(var) ⋁ column.eq(var)</td>
325
+ <td class="tg-baqh">✔</td>
326
+ <td class="tg-baqh">✔</td>
327
+ <td class="tg-baqh">✔</td>
328
+ <td class="tg-baqh">✔</td>
329
+ <td class="tg-baqh">✔</td>
330
+ <td class="tg-baqh">✔</td>
331
+ </tr>
332
+ <tr>
333
+ <td class="tg-yw4l">AND ( ⋀ )<br>column.eq(var) ⋀ column.eq(var)</td>
334
+ <td class="tg-baqh">✔</td>
335
+ <td class="tg-baqh">✔</td>
336
+ <td class="tg-baqh">✔</td>
337
+ <td class="tg-baqh">✔</td>
338
+ <td class="tg-baqh">✔</td>
339
+ <td class="tg-baqh">✔</td>
340
+ </tr>
341
+ </table>
342
+ </table>
343
+ </body>
344
+ </html>