dwh 0.1.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 (104) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +36 -0
  3. data/CHANGELOG.md +5 -0
  4. data/LICENSE +21 -0
  5. data/README.md +130 -0
  6. data/Rakefile +42 -0
  7. data/docs/DWH/Adapters/Adapter.html +3053 -0
  8. data/docs/DWH/Adapters/Athena.html +1704 -0
  9. data/docs/DWH/Adapters/Boolean.html +121 -0
  10. data/docs/DWH/Adapters/Druid.html +1626 -0
  11. data/docs/DWH/Adapters/DuckDb.html +2012 -0
  12. data/docs/DWH/Adapters/MySql.html +1704 -0
  13. data/docs/DWH/Adapters/OpenAuthorizable/ClassMethods.html +265 -0
  14. data/docs/DWH/Adapters/OpenAuthorizable.html +1102 -0
  15. data/docs/DWH/Adapters/Postgres.html +2000 -0
  16. data/docs/DWH/Adapters/Snowflake.html +1662 -0
  17. data/docs/DWH/Adapters/SqlServer.html +2084 -0
  18. data/docs/DWH/Adapters/Trino.html +1835 -0
  19. data/docs/DWH/Adapters.html +129 -0
  20. data/docs/DWH/AuthenticationError.html +142 -0
  21. data/docs/DWH/Behaviors.html +767 -0
  22. data/docs/DWH/Capabilities.html +748 -0
  23. data/docs/DWH/Column.html +1115 -0
  24. data/docs/DWH/ConfigError.html +143 -0
  25. data/docs/DWH/ConnectionError.html +143 -0
  26. data/docs/DWH/DWHError.html +138 -0
  27. data/docs/DWH/ExecutionError.html +143 -0
  28. data/docs/DWH/Factory.html +1133 -0
  29. data/docs/DWH/Functions/Arrays.html +505 -0
  30. data/docs/DWH/Functions/Dates.html +1644 -0
  31. data/docs/DWH/Functions/ExtractDatePart.html +804 -0
  32. data/docs/DWH/Functions/Nulls.html +377 -0
  33. data/docs/DWH/Functions.html +846 -0
  34. data/docs/DWH/Logger.html +258 -0
  35. data/docs/DWH/OAuthError.html +138 -0
  36. data/docs/DWH/Settings.html +658 -0
  37. data/docs/DWH/StreamingStats.html +804 -0
  38. data/docs/DWH/Table.html +1260 -0
  39. data/docs/DWH/TableStats.html +583 -0
  40. data/docs/DWH/TokenExpiredError.html +142 -0
  41. data/docs/DWH/UnsupportedCapability.html +135 -0
  42. data/docs/DWH.html +220 -0
  43. data/docs/_index.html +471 -0
  44. data/docs/class_list.html +54 -0
  45. data/docs/css/common.css +1 -0
  46. data/docs/css/full_list.css +58 -0
  47. data/docs/css/style.css +503 -0
  48. data/docs/file.README.html +210 -0
  49. data/docs/file.adapters.html +514 -0
  50. data/docs/file.creating-adapters.html +497 -0
  51. data/docs/file.getting-started.html +288 -0
  52. data/docs/file.usage.html +446 -0
  53. data/docs/file_list.html +79 -0
  54. data/docs/frames.html +22 -0
  55. data/docs/guides/adapters.md +445 -0
  56. data/docs/guides/creating-adapters.md +430 -0
  57. data/docs/guides/getting-started.md +225 -0
  58. data/docs/guides/usage.md +378 -0
  59. data/docs/index.html +210 -0
  60. data/docs/js/app.js +344 -0
  61. data/docs/js/full_list.js +242 -0
  62. data/docs/js/jquery.js +4 -0
  63. data/docs/method_list.html +2038 -0
  64. data/docs/top-level-namespace.html +110 -0
  65. data/lib/dwh/adapters/athena.rb +359 -0
  66. data/lib/dwh/adapters/druid.rb +267 -0
  67. data/lib/dwh/adapters/duck_db.rb +235 -0
  68. data/lib/dwh/adapters/my_sql.rb +235 -0
  69. data/lib/dwh/adapters/open_authorizable.rb +215 -0
  70. data/lib/dwh/adapters/postgres.rb +250 -0
  71. data/lib/dwh/adapters/snowflake.rb +489 -0
  72. data/lib/dwh/adapters/sql_server.rb +257 -0
  73. data/lib/dwh/adapters/trino.rb +213 -0
  74. data/lib/dwh/adapters.rb +363 -0
  75. data/lib/dwh/behaviors.rb +67 -0
  76. data/lib/dwh/capabilities.rb +39 -0
  77. data/lib/dwh/column.rb +79 -0
  78. data/lib/dwh/errors.rb +29 -0
  79. data/lib/dwh/factory.rb +125 -0
  80. data/lib/dwh/functions/arrays.rb +42 -0
  81. data/lib/dwh/functions/dates.rb +162 -0
  82. data/lib/dwh/functions/extract_date_part.rb +70 -0
  83. data/lib/dwh/functions/nulls.rb +31 -0
  84. data/lib/dwh/functions.rb +86 -0
  85. data/lib/dwh/logger.rb +50 -0
  86. data/lib/dwh/settings/athena.yml +77 -0
  87. data/lib/dwh/settings/base.yml +81 -0
  88. data/lib/dwh/settings/databricks.yml +51 -0
  89. data/lib/dwh/settings/druid.yml +59 -0
  90. data/lib/dwh/settings/duckdb.yml +44 -0
  91. data/lib/dwh/settings/mysql.yml +67 -0
  92. data/lib/dwh/settings/postgres.yml +30 -0
  93. data/lib/dwh/settings/redshift.yml +52 -0
  94. data/lib/dwh/settings/snowflake.yml +45 -0
  95. data/lib/dwh/settings/sqlserver.yml +80 -0
  96. data/lib/dwh/settings/trino.yml +77 -0
  97. data/lib/dwh/settings.rb +79 -0
  98. data/lib/dwh/streaming_stats.rb +69 -0
  99. data/lib/dwh/table.rb +105 -0
  100. data/lib/dwh/table_stats.rb +51 -0
  101. data/lib/dwh/version.rb +5 -0
  102. data/lib/dwh.rb +54 -0
  103. data/sig/dwh.rbs +4 -0
  104. metadata +231 -0
@@ -0,0 +1,42 @@
1
+ module DWH
2
+ module Functions
3
+ # Operations on array columns. Mostly used in where clauses
4
+ module Arrays
5
+ # Generates sql test to see if any values from the passed
6
+ # in list is in the array column/exp.
7
+ #
8
+ # @param exp [String] - sql expression
9
+ # @param list [String] - comma separated list
10
+ # @raise UnsupportedCapability if the db doesn't support array functions.
11
+ def array_in_list(exp, list)
12
+ raise UnsupportedCapability unless supports_array_functions?
13
+
14
+ gsk(:array_in_list).gsub(/@exp/i, exp).gsub(/@list/i, list)
15
+ end
16
+
17
+ # Generates sql test to see if any values from the passed
18
+ # in list is NOT in the array column/exp.
19
+ #
20
+ # @param exp [String] - sql expression
21
+ # @param list [String] - comma separated list
22
+ # @raise UnsupportedCapability if the db doesn't support array functions.
23
+ def array_exclude_list(exp, list)
24
+ raise UnsupportedCapability unless supports_array_functions?
25
+
26
+ gsk(:array_exclude_list).gsub(/@exp/i, exp).gsub(/@list/i, list)
27
+ end
28
+
29
+ # Explode an array. This should be used in a join expression.
30
+ # @param exp [String] the column/expression that will be Explode
31
+ # @param table_alias [String] the alias of the exploded array
32
+ # @raise UnsupportedCapability if the db doesn't support array functions.
33
+ def array_unnest_join(exp, table_alias)
34
+ raise UnsupportedCapability unless supports_array_functions?
35
+
36
+ gsk(:array_unnest_join)
37
+ .gsub(/@exp/i, exp)
38
+ .gsub(/@alias/i, table_alias)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,162 @@
1
+ module DWH
2
+ module Functions
3
+ # Standard date functions except for those dealing with extracting
4
+ # a date part.
5
+ module Dates
6
+ # Ruby format string that is compatible for the target database.
7
+ def date_format
8
+ settings[:date_format]
9
+ end
10
+
11
+ # Ruby format string that is compatible timestamp format
12
+ # for the target db.
13
+ def date_time_format
14
+ settings[:date_time_format]
15
+ end
16
+
17
+ # Ruby format string that is compatible timestamp with timezone
18
+ # format for the target db.
19
+ def date_time_tz_format
20
+ settings[:date_time_tz_format]
21
+ end
22
+
23
+ # The native date storage type of the db.
24
+ def date_data_type
25
+ settings[:data_type]
26
+ end
27
+
28
+ # Whether the db uses an int format store dates natively
29
+ def date_int?
30
+ date_data_type =~ /int/i
31
+ end
32
+
33
+ # The native function to return current date
34
+ def current_date
35
+ settings[:current_date]
36
+ end
37
+
38
+ # The native function to return current time
39
+ def current_time
40
+ settings[:current_time]
41
+ end
42
+
43
+ # The native function to return current timestamp
44
+ def current_timestamp
45
+ settings[:current_timestamp]
46
+ end
47
+
48
+ TIMESTAMPABLE_UNITS = %w[millisecond second minute hour].freeze
49
+
50
+ # Given a date expression, truncate it to a given level.
51
+ # The SQL output of a truncation is still date or timestamp.
52
+ #
53
+ # @param unit [String] the unit to truncate to
54
+ # @param exp [String] the expression to truncate
55
+ #
56
+ # @example Truncate date to the week start day
57
+ # truncate_date('week', 'my_date_col')
58
+ # Postgres ==> DATE_TRUNC('week', 'my_date_col')
59
+ # SQL Server ==> DATETRUNC(week, 'my_date_col')
60
+ #
61
+ # @note When truncating a literal date rather than an
62
+ # expression, the date_literal function should be called on
63
+ # it first. e.g. truncate_date('week', date_lit('2025-08-06'))
64
+ # For many dbs it won't matter, but some require date literals
65
+ # to be specified.
66
+ def truncate_date(unit, exp)
67
+ unit = unit.strip.downcase
68
+ res = if unit == 'week' && adjust_week_start_day?
69
+ gsk("#{settings[:week_start_day].downcase}_week_start_day")
70
+ .gsub(/@exp/i, exp)
71
+ else
72
+ gsk(:truncate_date)
73
+ .gsub(/@unit/i, unit)
74
+ .gsub(/@exp/i, exp)
75
+
76
+ end
77
+
78
+ # If we are truncating above the timestamp level ie days, years etc
79
+ # then we can cast the result to date
80
+ if TIMESTAMPABLE_UNITS.include?(unit)
81
+ res
82
+ else
83
+ cast(res, 'DATE')
84
+ end
85
+ end
86
+
87
+ # Add some interval of time to a given date expression.
88
+ # @param unit [String] the units we are adding i.e day, month, week etc
89
+ # @param val [Integer] the number of said units
90
+ # @param exp [String] the target expression being operated on
91
+ def date_add(unit, val, exp)
92
+ gsk(:date_add)
93
+ .gsub(/@unit/i, unit)
94
+ .gsub(/@val/i, val.to_s)
95
+ .gsub(/@exp/i, exp)
96
+ end
97
+
98
+ # Differnect between two dates in terms of the given unit.
99
+ # @param unit [String] i.e day, month, hour etc
100
+ # @param start_exp [String] starting date expression
101
+ # @param end_exp [String] ending date expression
102
+ def date_diff(unit, start_exp, end_exp)
103
+ gsk(:date_diff)
104
+ .gsub(/@unit/i, unit)
105
+ .gsub(/@start_exp/i, start_exp)
106
+ .gsub(/@end_exp/i, end_exp)
107
+ end
108
+
109
+ # Applies the given format to the target date expression
110
+ def date_format_sql(exp, format)
111
+ gsk(:date_format_sql)
112
+ .gsub(/@exp/i, exp)
113
+ .gsub(/@format/i, format)
114
+ end
115
+
116
+ DATE_CLASSES = [Date, DateTime, Time].freeze
117
+
118
+ # Generates a valid date literal string. Most db's
119
+ # this is just single quoted value while others require
120
+ # a date declaration.
121
+ # @param val [String, Date, DateTime, Time]
122
+ def date_literal(val)
123
+ val = DATE_CLASSES.include?(val.class) ? val.strftime(date_format) : val
124
+ gsk(:date_literal).gsub(/@val/i, val)
125
+ end
126
+
127
+ # @param val [String, Date, DateTime, Time]
128
+ def date_time_literal(val)
129
+ val = DATE_CLASSES.include?(val.class) ? val.strftime(date_time_format) : val
130
+ gsk(:date_time_literal).gsub(/@val/i, val)
131
+ end
132
+
133
+ # The current default week start day. This is how
134
+ # the db is currently setup. Should be either monday or sunday
135
+ def default_week_start_day
136
+ gsk(:default_week_start_day)
137
+ end
138
+
139
+ # The desired week start day. Could be diff from the db setting.
140
+ def week_start_day
141
+ gsk(:week_start_day)
142
+ end
143
+
144
+ # Whether we need to adjust the week start day. If its different
145
+ # from the default, we need to adjust
146
+ def adjust_week_start_day?
147
+ week_start_day.strip != default_week_start_day.strip
148
+ end
149
+
150
+ # Apply translation to desired week start day
151
+ def adjust_week_start_day(exp)
152
+ gsk("#{settings[:week_start_day].downcase}_week_start_day")
153
+ .gsub(/@exp/i, exp)
154
+ end
155
+
156
+ # Does the week start on sunday?
157
+ def week_starts_on_sunday?
158
+ gsk(:week_start_day) == 'SUNDAY'
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,70 @@
1
+ module DWH
2
+ module Functions
3
+ # All date functions related to extracting part of date
4
+ # from a date or timestamp.
5
+ module ExtractDatePart
6
+ def extract_year(exp)
7
+ gsk(:extract_year).gsub(/@exp/i, exp)
8
+ end
9
+
10
+ def extract_month(exp)
11
+ gsk(:extract_month).gsub(/@exp/i, exp)
12
+ end
13
+
14
+ def extract_quarter(exp)
15
+ gsk(:extract_quarter).gsub(/@exp/i, exp)
16
+ end
17
+
18
+ def extract_day_of_year(exp)
19
+ gsk(:extract_day_of_year).gsub(/@exp/i, exp)
20
+ end
21
+
22
+ def extract_day_of_month(exp)
23
+ gsk(:extract_day_of_month).gsub(/@exp/i, exp)
24
+ end
25
+
26
+ def extract_day_of_week(exp)
27
+ gsk(:extract_day_of_week).gsub(/@exp/i, exp)
28
+ end
29
+
30
+ def extract_week_of_year(exp)
31
+ gsk(:extract_week_of_year).gsub(/@exp/i, exp)
32
+ end
33
+
34
+ def extract_hour(exp)
35
+ gsk(:extract_hour).gsub(/@exp/i, exp)
36
+ end
37
+
38
+ def extract_minute(exp)
39
+ gsk(:extract_minute).gsub(/@exp/i, exp)
40
+ end
41
+
42
+ def extract_year_month(exp)
43
+ gsk(:extract_year_month).gsub(/@exp/i, exp)
44
+ end
45
+
46
+ def extract_day_name(exp, abbreviate: false)
47
+ upper_case(
48
+ if abbreviate
49
+ date_format_sql(exp,
50
+ gsk(:abbreviated_day_name_format))
51
+ else
52
+ date_format_sql(exp, gsk(:day_name_format))
53
+ end
54
+ )
55
+ end
56
+
57
+ def extract_month_name(exp, abbreviate: false)
58
+ upper_case(
59
+ if abbreviate
60
+ date_format_sql(exp,
61
+ gsk(:abbreviated_month_name_format))
62
+ else
63
+ date_format_sql(exp,
64
+ gsk(:month_name_format))
65
+ end
66
+ )
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,31 @@
1
+ module DWH
2
+ module Functions
3
+ # Manages translations to Null handling Functions
4
+ module Nulls
5
+ # If the provided expression is null
6
+ # then return the second expression.
7
+ # @param exp [String] - target expression
8
+ # @param exp_if_null [String] - exp if target is null
9
+ def if_null(exp, exp_if_null)
10
+ gsk(:if_null)
11
+ .sub(/@exp/i, exp.to_s)
12
+ .sub(/@when_null/i, exp_if_null.to_s)
13
+ end
14
+
15
+ # Returns Null if the given expression
16
+ # equals the target expression.
17
+ def null_if(exp, target_exp)
18
+ gsk(:null_if)
19
+ .sub(/@exp/i, exp.to_s)
20
+ .sub(/@target/i, target_exp.to_s)
21
+ end
22
+
23
+ # Returns Null if the given expression
24
+ # evaluates to zero.
25
+ def null_if_zero(exp)
26
+ gsk(:null_if_zero)
27
+ .sub(/@exp/i, exp.to_s)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,86 @@
1
+ require_relative 'functions/dates'
2
+ require_relative 'functions/extract_date_part'
3
+ require_relative 'functions/nulls'
4
+ require_relative 'functions/arrays'
5
+
6
+ module DWH
7
+ # The Functions module adds a translation layer between this library
8
+ # and native database functions. It relies on the adapters settings
9
+ # file to map standard function to its native counterpart.
10
+ #
11
+ # @example Truncate date to the week start day
12
+ # truncate_date('week', 'my_date_col')
13
+ # Postgres ==> DATE_TRUNC('week', 'my_date_col')
14
+ # SQL Server ==> DATETRUNC(week, 'my_date_col')
15
+ #
16
+ # @example Output a date string as a valid date literal
17
+ # date_literal('2025-08-06')
18
+ # Postgres ==> '2025-08-06'::DATE
19
+ # SQL Server ==> '2025-08-06'
20
+ module Functions
21
+ include Dates
22
+ include ExtractDatePart
23
+ include Nulls
24
+ include Arrays
25
+
26
+ # Casts an expresion/literal to the target datatype.
27
+ # Datatype should be valid for the target db.
28
+ #
29
+ # @param exp [String] sql expression
30
+ # @param type [String] valid type for target db
31
+ def cast(exp, type)
32
+ gsk(:cast).gsub(/@exp/i, exp)
33
+ .gsub(/@type/i, type)
34
+ end
35
+
36
+ def trim(exp)
37
+ gsk(:trim).gsub(/@exp/i, exp)
38
+ end
39
+
40
+ def lower_case(exp)
41
+ gsk(:lower_case).gsub(/@exp/i, exp)
42
+ end
43
+
44
+ def upper_case(exp)
45
+ gsk(:upper_case).gsub(/@exp/i, exp)
46
+ end
47
+
48
+ # Applies adapter specific quotes around the given
49
+ # expression. The expression is usually a column name, alias,
50
+ # or table alias.
51
+ #
52
+ # @param exp [String] - column, alias, table name
53
+ def quote(exp)
54
+ gsk(:quote).sub(/@exp/i, exp)
55
+ end
56
+
57
+ # Applies adapter specific string literal translation around the given
58
+ # expression. The expression is usually a string value.
59
+ #
60
+ # @param exp [String] some string value
61
+ def string_lit(exp)
62
+ gsk(:string_literal).sub(/@exp/i, exp.gsub("'", "''"))
63
+ end
64
+
65
+ # Applies adapter specific cross join expression
66
+ # This takes the target table. Ie if you are joining
67
+ # table a with table b.. You will pass in the table b
68
+ # name expression here.
69
+ #
70
+ # @example
71
+ # adapter.cross_join("schema.table_b")
72
+ #
73
+ # @param relation [String] - table name or table exp
74
+ def cross_join(relation)
75
+ gsk(:cross_join).sub(/@relation/i, relation)
76
+ end
77
+
78
+ # Shortcut to get settings value
79
+ # by key.
80
+ # @param key [Symbol,String]
81
+ # @return [String] upcased value
82
+ def gsk(key)
83
+ settings[key.to_sym]
84
+ end
85
+ end
86
+ end
data/lib/dwh/logger.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'logger'
2
+
3
+ module DWH
4
+ # Access a default logger for the gem.
5
+ module Logger
6
+ def logger
7
+ DWH::Logger.logger
8
+ end
9
+
10
+ class << self
11
+ def logger
12
+ @logger ||= create_logger
13
+ end
14
+
15
+ private
16
+
17
+ def create_logger
18
+ if rails_logger_available?
19
+ Rails.logger
20
+ else
21
+ standalone_logger
22
+ end
23
+ end
24
+
25
+ def rails_logger_available?
26
+ defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
27
+ end
28
+
29
+ def standalone_logger
30
+ logger = ::Logger.new($stdout)
31
+ logger.level = log_level
32
+ logger.formatter = proc do |severity, datetime, _progname, msg|
33
+ "[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] #{severity} DWH: #{msg}\n"
34
+ end
35
+ logger
36
+ end
37
+
38
+ def log_level
39
+ case ENV['DWH_LOG_LEVEL']&.downcase
40
+ when 'debug' then ::Logger::DEBUG
41
+ when 'info' then ::Logger::INFO
42
+ when 'warn' then ::Logger::WARN
43
+ when 'error' then ::Logger::ERROR
44
+ when 'fatal' then ::Logger::FATAL
45
+ else ::Logger::INFO
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,77 @@
1
+
2
+ # Date Literal Formats
3
+ date_format: "%Y-%m-%d"
4
+ date_time_format: "%Y-%m-%d %H:%M:%S"
5
+ date_time_tz_format: "%Y-%m-%d %H:%M:%S %Z"
6
+ date_type: "string" # alternative is int, integer, dateint
7
+ day_name_format: "%W"
8
+ abbreviated_day_name_format: "%a"
9
+ month_name_format: "%M"
10
+ abbreviated_month_name_format: "%b"
11
+
12
+ # Date functions patterns
13
+ current_date: "CURRENT_DATE"
14
+ current_time: "CURRENT_TIME"
15
+ current_timestamp: "CURRENT_TIMESTAMP"
16
+ truncate_date: "DATE_TRUNC('@unit', @exp)"
17
+ date_add: "DATE_ADD('@unit', @val, @exp)"
18
+ date_diff: "DATE_DIFF('@unit', @start_exp, @end_exp)"
19
+ date_format_sql: "DATE_FORMAT(@exp, '@format')"
20
+ date_literal: "DATE '@val'"
21
+ date_time_literal: "TIMESTAMP '@val'"
22
+ extract_year: 'YEAR(@exp)'
23
+ extract_month: 'MONTH(@exp)'
24
+ extract_quarter: 'QUARTER(@exp)'
25
+ extract_day_of_year: 'DAY_OF_YEAR(@exp)'
26
+ extract_day_of_month: 'DAY(@exp)'
27
+ extract_day_of_week: 'DAY_OF_WEEK(@exp)'
28
+ extract_week_of_year: 'WEEK(@exp)'
29
+ extract_hour: 'HOUR(@exp)'
30
+ extract_minute: 'MINUTE(@exp)'
31
+ extract_year_month: "CAST(FORMAT('%04d%02d', year(@exp), month(@exp)) AS INTEGER)"
32
+ default_week_start_day: "monday"
33
+ week_start_day: "monday"
34
+ sunday_week_start_day: "DATE_ADD('day', -1,DATE_TRUNC('week', DATE_ADD('day',1, @exp)))"
35
+ monday_week_start_day: "DATE_ADD('day', 1, DATE_TRUNC('week', DATE_ADD('day',-1, @exp)))"
36
+
37
+ cast: "CAST(@exp AS @type)"
38
+
39
+ # string functions
40
+ trim: "TRIM(@exp)"
41
+ lower_case: "LOWER(@exp)"
42
+ upper_case: "UPPER(@exp)"
43
+
44
+ # null handling
45
+ if_null: "COALESCE(@exp, @when_null)"
46
+ null_if: "NULLIF(@exp, @target)"
47
+ null_if_zero: "NULLIF(@exp, 0)"
48
+
49
+ # Relevant db capabilities for query gen
50
+ supports_array_functions: true
51
+ supports_table_join: true
52
+ supports_full_join: true
53
+ supports_cross_join: true
54
+ supports_sub_queries: true
55
+ supports_common_table_expressions: true
56
+ supports_temp_tables: true
57
+ create_temp_table_template: "CREATE TEMPORARY TABLE @table AS \n@sql"
58
+ supports_window_functions: true
59
+ extend_ending_date_to_last_hour_of_day: false # druid needs this for inclusive filtering
60
+
61
+ # array operations
62
+ array_in_list: "ANY_MATCH(@exp, x -> x IN (@list)" # list is comma separated
63
+ array_exclude_list: "NONE_MATCH(@exp, x -> x IN (@list)" # list is comma separated
64
+ array_unnest_join: "CROSS JOIN UNNEST(@exp) @alias"
65
+
66
+ # joins
67
+ cross_join: "CROSS JOIN @relation"
68
+
69
+ # sql output behavior
70
+ temp_table_type: "cte" # options cte, subquery, temp
71
+ temp_table_prefix: ""
72
+ # Determines how measures across fact universes are combined.
73
+ # Default is full join when supported.
74
+ final_pass_measure_join_type: "full" # inner left right etc
75
+ apply_advanced_filtering_on_array_projections: false # druid needs a having clause or un-nesting
76
+ greedy_apply_date_filters: true
77
+ cross_universe_measure_filtering_strategy: "both" # both, final, intermediate
@@ -0,0 +1,81 @@
1
+
2
+ # quotes and string lit
3
+ quote: "\"@exp\""
4
+ string_literal: "'@exp'"
5
+
6
+ # Date Literal Formats
7
+ date_format: "%Y-%m-%d"
8
+ date_time_format: "%Y-%m-%d %H:%M:%S"
9
+ date_time_tz_format: "%Y-%m-%d %H:%M:%S %Z"
10
+ date_type: "string" # alternative is int, integer, dateint
11
+ day_name_format: "%W"
12
+ abbreviated_day_name_format: "%a"
13
+ month_name_format: "%M"
14
+ abbreviated_month_name_format: "%b"
15
+
16
+ # Date functions patterns
17
+ current_date: "CURRENT_DATE"
18
+ current_time: "CURRENT_TIME"
19
+ current_timestamp: "CURRENT_TIMESTAMP"
20
+ truncate_date: "DATE_TRUNC('@unit', @exp)"
21
+ date_add: "DATE_ADD('@unit', @val, @exp)"
22
+ date_diff: "DATE_DIFF('@unit', @start_exp, @end_exp)"
23
+ date_format_sql: "DATE_FORMAT(@exp, '@format')"
24
+ date_literal: "'@val'"
25
+ date_time_literal: "'@val'"
26
+ extract_year: 'YEAR(@exp)'
27
+ extract_month: 'MONTH(@exp)'
28
+ extract_quarter: 'QUARTER(@exp)'
29
+ extract_day_of_year: 'DAY_OF_YEAR(@exp)'
30
+ extract_day_of_month: 'DAY(@exp)'
31
+ extract_day_of_week: 'DAY_OF_WEEK(@exp)'
32
+ extract_week_of_year: 'WEEK(@exp)'
33
+ extract_hour: 'HOUR(@exp)'
34
+ extract_minute: 'MINUTE(@exp)'
35
+ extract_year_month: 'CAST((year(@exp) || month(@exp)) as integer)'
36
+ default_week_start_day: "monday"
37
+ week_start_day: "monday"
38
+ sunday_week_start_day: "DATE_ADD('day', -1,DATE_TRUNC('week', DATE_ADD('day',1, @exp)))"
39
+ monday_week_start_day: "DATE_ADD('day', 1, DATE_TRUNC('week', DATE_ADD('day',-1, @exp)))"
40
+
41
+ cast: "CAST(@exp AS @type)"
42
+
43
+ # string functions
44
+ trim: "TRIM(@exp)"
45
+ lower_case: "LOWER(@exp)"
46
+ upper_case: "UPPER(@exp)"
47
+
48
+ # null handling
49
+ if_null: "COALESCE(@exp, @when_null)"
50
+ null_if: "NULLIF(@exp, @target)"
51
+ null_if_zero: "NULLIF(@exp, 0)"
52
+
53
+ # Relevant db capabilities for query gen
54
+ supports_array_functions: true
55
+ supports_table_join: true
56
+ supports_full_join: true
57
+ supports_cross_join: true
58
+ supports_sub_queries: true
59
+ supports_common_table_expressions: true
60
+ supports_temp_tables: true
61
+ create_temp_table_template: "CREATE TEMPORARY TABLE @table AS \n@sql"
62
+ supports_window_functions: true
63
+ extend_ending_date_to_last_hour_of_day: false # druid needs this for inclusive filtering
64
+
65
+ # array operations
66
+ array_in_list: "ANY_MATCH(@exp, x -> x IN (@list)" # list is comma separated
67
+ array_exclude_list: "NONE_MATCH(@exp, x -> x IN (@list)" # list is comma separated
68
+ array_unnest_join: "CROSS JOIN UNNEST(@exp) @alias"
69
+
70
+ # joins
71
+ cross_join: "CROSS JOIN @relation"
72
+
73
+ # sql output behavior
74
+ temp_table_type: "cte" # options cte, subquery, temp
75
+ temp_table_prefix: ""
76
+ # Determines how measures across fact universes are combined.
77
+ # Default is full join when supported.
78
+ final_pass_measure_join_type: "full" # inner left right etc
79
+ apply_advanced_filtering_on_array_projections: false # druid needs a having clause or un-nesting
80
+ greedy_apply_date_filters: true
81
+ cross_universe_measure_filtering_strategy: "both" # both, final, intermediate
@@ -0,0 +1,51 @@
1
+
2
+ # quotes and string lit
3
+ quote: "\"@exp\""
4
+ string_literal: "'@exp'"
5
+
6
+ # Date Literal Formats
7
+ date_format: "%Y-%m-%d"
8
+ date_time_format: "%Y-%m-%d %H:%M:%S"
9
+ date_time_tz_format: "%Y-%m-%d %H:%M:%S %Z"
10
+ date_type: "string" # alternative is int, integer, dateint
11
+ day_name_format: "EEEE"
12
+ abbreviated_day_name_format: "EEE"
13
+ month_name_format: "MMMM"
14
+ abbreviated_month_name_format: "MMM"
15
+
16
+ date_add: "date_add(@unit, @val, @exp)"
17
+ date_diff: "date_diff(@unit, @start_exp, @end_exp)"
18
+ date_format_sql: "date_format(@exp, '@format')"
19
+ extract_day_of_year: 'dayofyear(@exp)'
20
+ extract_day_of_week: 'dayofweek(@exp)'
21
+ extract_week_of_year: 'weekofyear(@exp)'
22
+ extract_year_month: 'cast(concat(year(@exp), lpad(month(@exp), 2, "0")) as int)'
23
+
24
+ cast: "CAST(@exp AS @type)"
25
+
26
+ # string functions
27
+ trim: "trim(@exp)"
28
+ lower_case: "lower(@exp)"
29
+ upper_case: "upper(@exp)"
30
+
31
+ # null handling
32
+ if_null: "COALESCE(@exp, @when_null)"
33
+ null_if: "NULLIF(@exp, @target)"
34
+ null_if_zero: "NULLIF(@exp, 0)"
35
+
36
+ # Relevant db capabilities for query gen
37
+ supports_table_join: true
38
+ supports_full_join: true
39
+ supports_cross_join: true
40
+ supports_sub_queries: true
41
+ supports_common_table_expressions: true
42
+ supports_temp_tables: true
43
+ create_temp_table_template: "CREATE TEMPORARY TABLE @table AS \n@sql"
44
+ supports_window_functions: true
45
+ extend_ending_date_to_last_hour_of_day: false # druid needs this for inclusive filtering
46
+
47
+ # array operations
48
+ array_in_list: "exists(@exp, x -> x IN (@list))"
49
+ array_exclude_list: "not exists(@exp, x -> x IN (@list))"
50
+ array_unnest_join: "LATERAL VIEW explode(@exp) AS @alias"
51
+