From 8607b2dd6a895b803f1ce08dda1abdcc114af2cf Mon Sep 17 00:00:00 2001 From: carlosdanielpohlod Date: Sat, 12 Apr 2025 11:44:27 -0300 Subject: [PATCH 1/2] add regex for extract_value_from_default regex and has_default_function? SQL functions --- .../connection_adapters/pinot_adapter.rb | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/active_record/connection_adapters/pinot_adapter.rb b/lib/active_record/connection_adapters/pinot_adapter.rb index 9762bdf..51730b0 100644 --- a/lib/active_record/connection_adapters/pinot_adapter.rb +++ b/lib/active_record/connection_adapters/pinot_adapter.rb @@ -13,6 +13,20 @@ def pinot_connection(config) module ConnectionAdapters class PinotAdapter < AbstractAdapter + NULL_REGEX = /^null$/i + SINGLE_QUOTED_STRING_REGEX = /^'([^|]*)'$/m + DOUBLE_QUOTED_STRING_REGEX = /^"([^|]*)"$/m + NUMERIC_REGEX = /\A-?\d+(\.\d*)?\z/ + BINARY_HEX_REGEX = /x'(.*)'/ + # Matches SQL functions or expressions (e.g., NOW(), CURRENT_DATE, or string concatenation) + SQL_FUNCTION_OR_EXPRESSION_REGEX = %r{ + \w+\(.*\) | # SQL functions like NOW(), uuid_generate_v4(), etc. + CURRENT_TIME | # special SQL keyword + CURRENT_DATE | # special SQL keyword + CURRENT_TIMESTAMP | # special SQL keyword + \|\| # SQL string concatenation operator + }x + TYPES = { "INT" => Type::Integer.new, "TIMESTAMP" => Type::DateTime.new, @@ -21,6 +35,7 @@ class PinotAdapter < AbstractAdapter "STRING" => Type::String.new, "JSON" => ActiveRecord::Type::Json.new } + def initialize(config = {}) @pinot_host = config.fetch(:host) @pinot_port = config.fetch(:port) @@ -84,23 +99,17 @@ def new_column_from_field(table_name, field, definitions = nil) def extract_value_from_default(default) case default - when /^null$/i + when NULL_REGEX nil - # Quoted types - when /^'([^|]*)'$/m + when SINGLE_QUOTED_STRING_REGEX $1.gsub("''", "'") - # Quoted types - when /^"([^|]*)"$/m + when DOUBLE_QUOTED_STRING_REGEX $1.gsub('""', '"') - # Numeric types - when /\A-?\d+(\.\d*)?\z/ + when NUMERIC_REGEX $& - # Binary columns - when /x'(.*)'/ + when BINARY_HEX_REGEX [$1].pack("H*") else - # Anything else is blank or some function - # and we can't know the value of that, so return nil. nil end end @@ -110,7 +119,7 @@ def extract_default_function(default_value, default) end def has_default_function?(default_value, default) - !default_value && %r{\w+\(.*\)|CURRENT_TIME|CURRENT_DATE|CURRENT_TIMESTAMP|\|\|}.match?(default) + !default_value && SQL_FUNCTION_OR_EXPRESSION_REGEX.match?(default) end INTEGER_REGEX = /integer/i From fb9d62b44ac7639d5464eb754ca2bbc187323b5b Mon Sep 17 00:00:00 2001 From: carlosdanielpohlod Date: Sat, 12 Apr 2025 12:08:15 -0300 Subject: [PATCH 2/2] use ::Regexp instead global variable as $1 and $& --- lib/active_record/connection_adapters/pinot_adapter.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/active_record/connection_adapters/pinot_adapter.rb b/lib/active_record/connection_adapters/pinot_adapter.rb index 51730b0..a975e98 100644 --- a/lib/active_record/connection_adapters/pinot_adapter.rb +++ b/lib/active_record/connection_adapters/pinot_adapter.rb @@ -102,15 +102,13 @@ def extract_value_from_default(default) when NULL_REGEX nil when SINGLE_QUOTED_STRING_REGEX - $1.gsub("''", "'") + ::Regexp.last_match(1).gsub("''", "'") when DOUBLE_QUOTED_STRING_REGEX - $1.gsub('""', '"') + ::Regexp.last_match(1).gsub('""', '"') when NUMERIC_REGEX - $& + ::Regexp.last_match(0) when BINARY_HEX_REGEX - [$1].pack("H*") - else - nil + [::Regexp.last_match(1)].pack('H*') end end