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便利!