Skip to content

Commit 0df5c41

Browse files
committed
Monkey-patch Oracle adapter to fix illegal zero-length identifier
ORA-01741: illegal zero-length identifier This error is caused by composite key feature: rails/rails@c18a95e PR to fix it in oracle-enhanced: rsim/oracle-enhanced#2471
1 parent eefe45d commit 0df5c41

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

config/initializers/oracle.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@ def _quote(value)
5252
super
5353
end
5454
end
55+
56+
# Fixing OCIError: ORA-01741: illegal zero-length identifier
57+
# because of https://github.com/rails/rails/commit/c18a95e38e9860953236aed94c1bfb877fa3be84
58+
# the value of `columns` is [ "\"ACCOUNTS\".\"ID\"" ] which forms an incorrect query
59+
# ... OVER (PARTITION BY ["\"ACCOUNTS\".\"ID\""] ORDER BY "ACCOUNTS"."ID") ...
60+
# Will not be needed after https://github.com/rsim/oracle-enhanced/pull/2471 is merged and Rails upgraded
61+
def columns_for_distinct(columns, orders) # :nodoc:
62+
# construct a valid columns name for DISTINCT clause,
63+
# ie. one that includes the ORDER BY columns, using FIRST_VALUE such that
64+
# the inclusion of these columns doesn't invalidate the DISTINCT
65+
#
66+
# It does not construct DISTINCT clause. Just return column names for distinct.
67+
orders.reject(&:blank?).map { |s|
68+
s = visitor.compile(s) unless s.is_a?(String)
69+
# remove any ASC/DESC modifiers
70+
s.gsub(/\s+(ASC|DESC)\s*?/i, "")
71+
}.reject(&:blank?).map.with_index { |column, i|
72+
"FIRST_VALUE(#{column}) OVER (PARTITION BY #{columns.join(', ')} ORDER BY #{column}) AS alias_#{i}__"
73+
}
74+
end
5575
end)
5676
end
5777

@@ -177,7 +197,7 @@ def set_database_settings(settings)
177197
end
178198
end)
179199

180-
ActiveRecord::ConnectionAdapters::OracleEnhanced::SchemaStatements.module_eval do
200+
ActiveRecord::ConnectionAdapters::OracleEnhanced::SchemaStatements.module_eval do
181201
def add_index(table_name, column_name, **options) #:nodoc:
182202
# All this code is exactly the same as the original except the line of the ALTER TABLE, which adds an additional USING INDEX #{quote_column_name(index_name)}
183203
# The reason of this is otherwise it picks the first index that finds that contains that column name, even if it is shared with other columns and it is not unique.

0 commit comments

Comments
 (0)