再讀simpledb 之 SQL語句解析(2)

來源:互聯網
上載者:User

在(1)裡面提到,lexer作為一個工具,完成了對SQL字串的切割,將語句轉化成一個tokens數組。

Parser完成了SQL解析的後序部分:使用一個lexer對象作為工具,切出tokens,然後解析語義,綁定相關的系統介面。

在這裡先要回顧下simpledb的支援的SQL的文法,這個影響了它在解析字串時使用的方法。

<Query>      := SELECT <SelectList> FROM <TableList> [ WHERE <Predicate> ]

<SelectList> := <Field> [ , <SelectList> ]

<TableList>  := TableName [ , <TableList> ]

<Predicate>  := <Term> [ AND <Predicate> ]

<Term>       := <Expression> = <Expression>

<Expression> := <Field> | <Constant>

<Field>      := FieldName

<Constant>   := String | Integer

 

<Modify>     := <Insert> | <Delete> | <Update> 

<Insert>     := INSERT INTO TableName ( <FieldList> ) VALUES ( <ConstList> )

<FieldList>  := <Field> [ , <FieldList> ]

<ConstList>  := <Constant> [ , <Constant> ]

<Delete>     := DELETE FROM TableName [ WHERE <Predicate> ]

<Update>     := UPDATE TableName SET <Field> = <Expression> [ WHERE <Predicate> ]

 

<Create>     := <CreateTable> | <CreateView> | <CreateIndex>

<CreateTable>:= CREATE TABLE TableName ( <FieldDefs> )

<FieldDefs>  := <FieldDef> [ , <FieldDefs> ]

<FieldDef>   := FieldName <TypeDef>

<TypeDef>    := INT | VARCHAR ( Integer )

<CreateView> := CREATE VIEW ViewName AS <Query>

<CreateIndex>:= CREATE INDEX IndexName ON TableName ( <Field> )

Parser這裡實現的編譯技術中的“一趟編譯”,即通過lex順序掃描tokens數組,在掃描過程中完成對各個token元素的識別,按照

constant/field –> Expression –> Term –> Predicate

的層遞關係,完成參數封裝,輸出一個查詢關聯的資料類,如(1)中的類圖1所示。

首先,以(1)圖2的例子“select sid,sname from students where sid='10001' ”,給出一個parser解析過程中構建的文法樹:

圖1 樣本文法樹

以下是Query方法的代碼:

public QueryData query()

{

    lex.eatKeyword("select");

    List<string> fields = selectList();

    lex.eatKeyword("from");

    List<string> tables = tableList();

    Predicate pred = new Predicate();

    if (lex.matchKeyword("where"))

    {

        lex.eatKeyword("where");

        pred = predicate();

    }

    return new QueryData(fields, tables, pred);

}

由代碼和上面的文法樹看出來,simpledb在解析SQL語句的時候,嚴格按照文法中支援的類型,“卡住”關鍵字,從中解析出欄位列表fieldlist,表名列表tablelist,以及謂詞列表predicates,然後將這些查詢中實際用到的資料,封裝成相應的對象,SQL語句的解析就初步完成。以上面的例子為例,QueryData對象封裝完之後,會傳遞給查詢處理模組,通過query下的一些方法,根據fieldlist,tablelist,和predicates來完成查詢資料的讀取。

parser中create(), delete(), insert(),query(), modify()方法,對應了上面的幾類文法

作為SQL語句解析的入口,有如下的updateCMD方法,根據SQL語句首個token的不同,進行了分支:

public object updateCmd()

{

    if (lex.matchKeyword("insert")) 

        return insert();

    else if (lex.matchKeyword("delete"))

        return delete();

    else if (lex.matchKeyword("update"))

        return modify();

    else

        return create();

}

補充一點,注意下上面的query()的代碼,lex用match*()來檢測下一個token是否滿足匹配條件,用eat*()來講滿足條件的token處理掉:

public void eatDelim(char d);

public string eatId();

public int eatIntConstant()

public void eatKeyword(string w)

public string eatStringConstant()

 資料相關的,均有傳回值,返回處理後的結果;資料無關的,沒有傳回值,實際只是利用nextToken移動position指標。

關於tablelist、fieldlist的構建,使用了遞迴的方式實現:

private List<string> fieldList()

{

    List<string> l = new List<string>();

    l.Add(field());

    if (lex.matchDelim(','))

    {

        lex.eatDelim(',');

        l.AddRange(fieldList());

    }

    return l;

}

謂詞 predicates也是用了遞迴的形式:

private Predicate predicate()

{

    Predicate pred = new Predicate(term());

    if (lex.matchKeyword("and"))

    {

        lex.eatKeyword("and");

        pred.conjoinWith(predicate());

    }

    return pred;

}

 略有不同的是,在謂詞串連的時候,使用了Predicate類的conjoinwith方法,實際上,predicate對象下,維護了一個條件列表terms,這個方法就是把謂詞中的各個term轉存到一起。

 

本文和前一節只是扼要地描述了SQL語句解析的思路和過程,可以看到解析的結果就是產生了各種查詢data,這些data會傳遞給query模組,由query模組利用這些得到的data,完成資料的查詢。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.