HiveQLが参照しているDBとテーブルをクエリから見つけるRubyスクリプトを書いてみました。
HiveQLからfrom句を見つけるRubyスクリプト
簡単に言うと、正規表現を使ってfromの後をパースしてるだけです。
# -*- coding: utf-8 -*-
class Hiveql
def initialize(hiveql)
@hiveql = hiveql
end
attr_reader :hiveql
# 文字列からインスタンスを作る
def self.load(str)
return Hiveql.new(str)
end
# ファイルの絶対パスからインスタンスを作る
def self.load_file(file)
return load(`cat #{file}`)
end
# hiveql内のfrom句をパースし、db.tableをユニークな配列にして返す
def source_tables
tables = Array.new
split(hiveql).each{|hiveql|
from_expressions = search_from_expressions(hiveql)
next if from_expressions.empty?
from_expressions.each{|table|
tables.concat(table)
}
}
tables.uniq
end
# クエリをセミコロンで分割する
def split(hiveql)
hiveql.split(';')
end
# from句を見つける
# db.table を正規表現で見つける。db名の省略にも対応している
def search_from_expressions(hiveql)
return [] if (hiveql =~ /use\\s+\\w+\\s*;/mi) # use db; を見つける正規表現
# from db_name.table_name を見つける正規表現
regexp = /from\\s+((?:\\w+\\.)?\\w+)\\s+/mi
if (hiveql =~ regexp)
return hiveql.scan(regexp).uniq
end
return []
end
end
# ここから実行開始
hiveql = Hiveql.load_file(ARGV[0])
puts hiveql.source_tables
ざっくり正規表現解説
/from\\s+((?:\\w+\\.)?\\w+)\\s+/mi
from句を見つける正規表現です。ちょっとだけややこしいので細部を解説します。
\\s
空白、タブ、改行に一致する正規表現です。[ \\t\\n\\r\\f] と同じです。
\\w
英数字とアンダーバーに一致する正規表現です。[0-9A-Za-z_] と同じです。
(?:regexp)
丸カッコは通常、後方参照するときに使うのですが、後方参照する必要がない場合はこのように書きます。
m
複数行モードの指定です。正規表現は通常一行のみの文字列に使いますが、m を指定すると複数行の文字列にも使えるようになります。といっても、. が改行文字にも一致するようになるだけです。
まとめ
Ruby便利!
