real_data_tests 0.3.6 → 0.3.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 179a591f6a485c397255c0cbec27e18757e2f7fdc450f7292f279cd681f91e0b
4
- data.tar.gz: bb9b9f4f60b609f2ea8a901689b4b9b8d5ddfdc7d36e867c18ebbe24855cb5aa
3
+ metadata.gz: 573f1753777e04a6168a09385b8332cedbb4d521d11f1807012a25b8b846013c
4
+ data.tar.gz: b884098abbc9134a22479d5e9211a2d8bb153622022ba9116acb0057419cbe4a
5
5
  SHA512:
6
- metadata.gz: a47d49d690958e70cd324ede48dadce7d3e9e7bd39471ee052879d6fe5646ad308aebbf05f79cb92ebe3c9b7ede94b0163c74efdddf3f518ef47518a489a2ee6
7
- data.tar.gz: a4c6a97cff1bd02096064fd1da67580dd9307ce29f4e7d5a8be4d82c9f352b97009ef1fc22eb555dc39b1b87599947680a61bc2bc376c2cd14a7f8cc5397892d
6
+ metadata.gz: 1d4bcb84f7d3ab3ee0901ae46763c912f3c86935930cc17607d500ae7a2e26649f8c6ff629e8215437d8f08ae93d482870e253b294e84e720971c9bf681c7b50
7
+ data.tar.gz: 67cad3bda841d3e1de61d61dd30121ef3b6ddfc96a3162438a2b25f904185e6e4c59206d2626e6b40d44a72d123ed123e4073a4fdfe10d04fea807a8702bf689
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.8] - 2025-01-14
4
+ ### Fixed
5
+ - Enhanced SQL statement parsing in native loader
6
+ - Improved handling of complex ON CONFLICT clauses with multiple closing parentheses
7
+ - Fixed spacing issues between VALUES and ON CONFLICT clauses
8
+ - Enhanced regex pattern for more precise conflict clause extraction
9
+ - Added proper statement reassembly for complex SQL structures
10
+
11
+ ## [0.3.7] - 2025-01-14
12
+ ### Fixed
13
+ - Corrected SQL value handling in native loader
14
+ - Fixed boolean value handling, particularly at the end of VALUES clauses
15
+ - Improved handling of NULL values and numbers
16
+ - Added proper whitespace cleaning for values
17
+ - Enhanced value type detection for correct quoting
18
+
3
19
  ## [0.3.6] - 2025-01-14
4
20
  ### Fixed
5
21
  - Further enhanced SQL statement handling in native loader
@@ -103,81 +103,86 @@ module RealDataTests
103
103
  statements
104
104
  end
105
105
 
106
- def clean_sql_statement(statement)
107
- # Handle VALUES clause formatting
108
- if statement.include?('VALUES')
109
- # Split into pre-VALUES and VALUES parts
110
- parts = statement.split(/VALUES\s*\(/i, 2)
111
- if parts.length == 2
112
- # Get the column names from the first part
113
- column_names = parts[0].scan(/\((.*?)\)/).flatten.first&.split(',')&.map(&:strip) || []
114
-
115
- # Split values into individual items
116
- values_part = parts[1]
117
- values = split_values(values_part)
118
-
119
- # Process each value according to its column and position
120
- values.each_with_index do |value, i|
121
- # Skip if already properly quoted
122
- next if value.start_with?("'") && value.end_with?("'")
123
-
124
- # Quote UUIDs
125
- if value.match?(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
126
- values[i] = "'#{value}'"
127
- # Quote any non-NULL string values that contain spaces or special characters
128
- elsif !['NULL', 'true', 'false'].include?(value) &&
129
- !value.match?(/^\d+$/) && # not a number
130
- !value.start_with?("'{") && # not a JSON object
131
- !value.start_with?("'") # not already quoted
132
- values[i] = "'#{value}'"
133
- end
134
- end
106
+ def extract_conflict_clause(statement)
107
+ # Use a more precise regex that handles multiple closing parentheses
108
+ if statement =~ /(.+?\))\s*(ON\s+CONFLICT\s+.*?)(?:;?\s*$)/i
109
+ [$1, $2.strip]
110
+ else
111
+ [statement.sub(/;?\s*$/, ''), nil]
112
+ end
113
+ end
135
114
 
136
- # Reassemble the statement with any trailing ON CONFLICT clause
137
- remainder = values_part.match(/\)\s*(ON\s+CONFLICT.*?)(;?\s*$)/i)
138
- statement = parts[0] + 'VALUES (' + values.join(', ') + ')'
139
- statement += " #{remainder[1]};" if remainder
140
- end
141
- end
115
+ def clean_sql_statement(statement)
116
+ # Extract the ON CONFLICT clause if it exists
117
+ statement, conflict_clause = extract_conflict_clause(statement)
118
+
119
+ # Handle VALUES clause formatting
120
+ if statement.include?('VALUES')
121
+ # Split into pre-VALUES and VALUES parts
122
+ parts = statement.split(/VALUES\s*\(/i, 2)
123
+ if parts.length == 2
124
+ # Clean and process the values
125
+ values = clean_values(parts[1].split(/\)\s*$/)[0])
142
126
 
143
- statement
127
+ # Make sure we properly close the VALUES parentheses
128
+ statement = "#{parts[0]}VALUES (#{values})"
129
+ end
144
130
  end
145
131
 
146
- def split_values(values_part)
147
- values = []
148
- current_value = ''
149
- in_quotes = false
150
- in_json = false
151
- depth = 0
152
-
153
- values_part.chars.each_with_index do |char, i|
154
- case char
155
- when "'"
156
- # Toggle quote state if not escaped
157
- if i == 0 || values_part[i-1] != '\\'
158
- in_quotes = !in_quotes
159
- end
160
- when '{'
161
- depth += 1 unless in_quotes
162
- in_json = true unless in_quotes
163
- when '}'
164
- depth -= 1 unless in_quotes
165
- when ','
166
- if !in_quotes && depth == 0
167
- values << current_value.strip
168
- current_value = ''
169
- next
170
- end
132
+ # Add back the conflict clause if it existed
133
+ statement = "#{statement}#{conflict_clause ? ' ' + conflict_clause : ''}"
134
+
135
+ # Ensure the statement ends with a semicolon
136
+ statement += ";" unless statement.end_with?(';')
137
+
138
+ statement
139
+ end
140
+
141
+ def clean_values(values_str)
142
+ values = []
143
+ current_value = ''
144
+ in_quotes = false
145
+ nested_level = 0
146
+
147
+ values_str.chars.each do |char|
148
+ case char
149
+ when "'"
150
+ in_quotes = !in_quotes
151
+ current_value << char
152
+ when '{'
153
+ nested_level += 1
154
+ current_value << char
155
+ when '}'
156
+ nested_level -= 1
157
+ current_value << char
158
+ when ','
159
+ if !in_quotes && nested_level == 0
160
+ values << clean_value(current_value.strip)
161
+ current_value = ''
162
+ else
163
+ current_value << char
171
164
  end
165
+ else
172
166
  current_value << char
173
167
  end
168
+ end
169
+
170
+ values << clean_value(current_value.strip)
171
+ values.join(', ')
172
+ end
174
173
 
175
- # Add the last value (remove trailing ';' or ')')
176
- last_value = current_value.strip
177
- last_value = last_value[0..-2] if last_value.end_with?(';', ')')
178
- values << last_value
174
+ def clean_value(value)
175
+ return value if value.start_with?("'") # Already quoted
176
+ return value if value.start_with?("'{") # JSON object
177
+ return 'NULL' if value.upcase == 'NULL'
178
+ return value.downcase if ['true', 'false'].include?(value.downcase)
179
+ return value if value.match?(/^\d+$/) # Numbers
179
180
 
180
- values
181
+ if value.match?(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
182
+ "'#{value}'" # UUID
183
+ else
184
+ "'#{value}'" # Other strings
181
185
  end
186
+ end
182
187
  end
183
188
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RealDataTests
4
- VERSION = "0.3.6"
4
+ VERSION = "0.3.8"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: real_data_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Dias