1. 程式人生 > >解析HiveSql語句中的所有表名

解析HiveSql語句中的所有表名

今天有個需求,解析我們hivesql語句中的表名,用來分析資料倉庫中所有表的使用頻率。

hive中有個語法分析器可以將sql語法轉換成語法樹,並且可以將語法樹轉換為字串。

例如一個hive的sql語句如下:

select t1.c1,t1.c2,t2.c1 
from 
lijie.table1 t1
left join 
lijie.table2 t2
on
t1.id = t2.id
where 
t1.age > 20

可以解析為如下的語法樹:

(TOK_QUERY (TOK_FROM (TOK_LEFTOUTERJOIN (TOK_TABREF (TOK_TABNAME table1) t1) (TOK_TABREF (TOK_TABNAME table2) t2) (= (. 
(TOK_TABLE_OR_COL t1) id
) (. (TOK_TABLE_OR_COL t2) id)))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (. (TOK_TABLE_OR_COL t1) c1)) (TOK_SELEXPR (. (TOK_TABLE_OR_COL t1) c2)) (TOK_SELEXPR (. (TOK_TABLE_OR_COL t2) c1))) (TOK_WHERE (> (. (TOK_TABLE_OR_COL t1) age) 20)))) <EOF>

解析的方法是使用hive自帶的解析器解析,我們只需要將hive中依賴的lib包匯入到工程裡即可,解析程式碼如下:

ParseDriver pd = new ParseDriver();

String ps= "select t1.c1,t1.c2,t2.c1 from table1 t1 left join table2 t2 on
 t1.id = t2.id where t1.age > 20";

ASTNode ast = pd.parse(ps);

String strTree = ast.toStringTree();

System.out.println(strTree);

根據解析出來的語法樹字串中的規律可以發現表名都是在“TOK_TABNAME”和”)”之間,最後可以使用一個自定義方法遞迴解析出裡面的表名(其中list是成員變數):

    /**
     * 遞迴擷取字串獲取表名
     * @param strTree
     * @return
     */
    public static List<String> getTableList(String strTree){
        int i1 = strTree.indexOf("TOK_TABNAME");
        String substring1 = "";
        String substring2 = "";
        if(i1>0){
            substring1 = strTree.substring(i1+12);
            int i2 = substring1.indexOf(")");
            substring2 = substring1.substring(0,i2);
            System.out.println(substring2);
            list.add(substring2);
            getTableList(substring1);
        }
        return list;
    }

測試上面hive sql的解析結果:
這裡寫圖片描述