BosCollege-SimpleDB-查詢執(zhí)行

Author: Sixing Yan

相關(guān)信息
What is BosCollege-SimpleDB? see this.
What is BosCollege-SimpleDB v3.0? see this.

前提提要
這一節(jié)將分析Client端發(fā)送SQL語(yǔ)句垛吗,Server端執(zhí)行SQL語(yǔ)句的全過(guò)程去件。 我們首先從FindMajors.java入手,探究SimpleDB如何執(zhí)行一條select查詢語(yǔ)句睬澡。本文涉及的文件

Step 0

客戶端執(zhí)行一條SQL語(yǔ)句治宣,將該SQL傳入Server端并獲得結(jié)果集退个,循環(huán)訪問(wèn)結(jié)果集獲取數(shù)據(jù)記錄同眯。
/studentClient/simpledb/FindMajors.java

public class FindMajors {
    public static void main(String[] args) {
        ...
        Connection conn = null;
        try {
            // Step 1: connect to database server
            ...
            // Step 2: execute the query
            Statement stmt = conn.createStatement();
            String qry = "select sname, gradyear "
                       + "from student, dept "
                       + "where did = majorid "
                       + "and dname = '" + major + "'";
            ResultSet rs = stmt.executeQuery(qry);

            // Step 3: loop through the result set
            while (rs.next()) {
                String sname = rs.getString("sname");
                int gradyear = rs.getInt("gradyear");
                System.out.println(sname + "\t" + gradyear);}
            rs.close();
        }...}}

Step 1

stage 1-1

(a) pre-request

Obtain sstmt, an instance of SimpleStatement class
生成一個(gè)SimpleStatement類的變量stmt,它實(shí)際封裝了RemoteStatement類的變量rstmt

  • SimpleStatement(rstmt) <- SimpleConnection.createStatement()
    rstmt <= RemoteStatementImpl(rconn)
    • SimpleConnection封裝了RemoteConnectionImpl
    • 實(shí)際執(zhí)行 rstmt:RemoteStatement <- rconn.createStatement()

(b) process

Obtain srs, an instance of SimpleResultSet class
rstmt執(zhí)行executeQuery(queryString)芭商,生成由SimpleResultSet封裝的RemoteResultSetImpl類的變量

RemoteStatementImpl.java

  public RemoteResultSet executeQuery(String qry) throws RemoteException {
      try {
         Transaction tx = rconn.getTransaction();
         Plan pln = SimpleDB.planner().createQueryPlan(qry, tx);
         return new RemoteResultSetImpl(pln, rconn);
      }...}
  • SimpleResultSet(rrs)<-rstmt.executeQuery(qry)
  • rrs <= RemoteResultSetImpl(pln,rconn)
    • tx:Transaction <- rconn.getTransaction()
    • pln:Plan <- SimpleDB.planner().createQueryPlan(qry, tx)
    • rrs has 3 members:
      • s:Scan <- pln.open()
      • sch:Schema <- pln.schema()
      • rconn <- rconn

接下來(lái)我們看SimpleDB.planner().createQueryPlan(queryString, transaction)完成了哪些工作

stage 1-2

what SimpleDB.planner().createQueryPlan(qry, tx) do?
我們首先看SimpleDB.planner()的工作派草,它負(fù)責(zé)初始化server端的planner類實(shí)例。
/server/SimpleDB.java

  public static Planner planner() {
      QueryPlanner  qplanner = new BasicQueryPlanner();
      UpdatePlanner uplanner = new BasicUpdatePlanner();
      return new Planner(qplanner, uplanner);
   }

這里實(shí)際上是由BasicQueryPlanner類的實(shí)例來(lái)構(gòu)造Query plan的工作(如果是create/update等操作則使用BasicUpdatePlanner類)铛楣。

  • pln <- qplanner.createQueryPlan(qry, tx)
    • data:QueryData <- Parser(qry).query()
    • qplanner <- BasicQueryPlanner(data, tx)

首先使用Parser類(/parse/Parser.java)來(lái)解析SQL語(yǔ)句近迁,形成QueryTree以方便調(diào)用。

現(xiàn)在探究“創(chuàng)建Plan”到底做了什么簸州。
/planner/BasicQueryPlanner.java

public class BasicQueryPlanner implements QueryPlanner {
   public Plan createPlan(QueryData data, Transaction tx) {
      //Step 1: Create a plan for each mentioned table or view
      List<Plan> plans = new ArrayList<Plan>();
      for (String tblname : data.tables()) {
         String viewdef = SimpleDB.mdMgr().getViewDef(tblname, tx);
         if (viewdef != null) plans.add(SimpleDB.planner().createQueryPlan(viewdef, tx));
         else plans.add(new TablePlan(tblname, tx)); }
      //Step 2: Create the product of all table plans
      Plan p = plans.remove(0);
      for (Plan nextplan : plans) p = new ProductPlan(p, nextplan);
      //Step 3: Add a selection plan for the predicate
      p = new SelectPlan(p, data.pred());
      //Step 4: Project on the field names
      p = new ProjectPlan(p, data.fields());
      return p;}}

總體來(lái)看鉴竭,createPlan()輸入SQL語(yǔ)句的QueryTree(data)以及當(dāng)前的事務(wù)信息(tx),輸出一個(gè)ProjectPlan類的實(shí)例岸浑。

首先搏存,遞歸生成SQL中涉及TablePlan
這一步分別生成SQL中涉及的表的Plan,即是TablePlan

      List<Plan> plans = new ArrayList<Plan>();
      for (String tblname : data.tables()) {
         String viewdef = SimpleDB.mdMgr().getViewDef(tblname, tx);
         if (viewdef != null) plans.add(SimpleDB.planner().createQueryPlan(viewdef, tx));
         else plans.add(new TablePlan(tblname, tx)); }

如果可以查詢到tblname相關(guān)的視圖定義矢洲,則遞歸分析該視圖(視圖的定義相當(dāng)于一段select語(yǔ)句)璧眠,抽取它的最后Plan結(jié)果。如果不能查詢到相應(yīng)的視圖定義(說(shuō)明tblname指的是一個(gè)table),則為其創(chuàng)建TablePlan類實(shí)例责静。

我們來(lái)看TablePlan類是什么袁滥,

  • tplist <- ArrayList<TablePlan>
    • tblplan <- TablePlan(tblname, tx), it has two members:
      • ti:TableInfo <- SimpleDB.mdMgr().getTableInfo(tblname, tx)
      • si:StatInfo <- SimpleDB.mdMgr().getStatInfo(tblname, ti, tx)
    • Attention to mdMgr
      • mdMgr:metadataMgr <- SimpleDB.mdMgr()
      • mdMgr has 4 members:
        • tblmgr -> getTableInfo():TableInfo & createTable():void
        • statmgr -> getStatInfo():StatInfo
        • idxmgr -> getIndexInfo():Map<String, IndexInfo>
        • viewmgr -> getViewInfo():String (一條SQL語(yǔ)句,描述View的定義)

接下來(lái)看ProductPlan完成的工作灾螃。
接著將所有的TablePlan類實(shí)例進(jìn)行Product操作题翻。

  • ProductPlan(p1:TablePlan, p2:TablePlan)初始化,它包含一個(gè)schema:Schema 成員
    • Schema類的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)是HashMap<String,FieldInfo>
      • key 是 fieldname:String, value 是 FieldInfo
      • FieldInfo類有兩個(gè) 整型 屬性腰鬼,type & length
    • 初始化時(shí)嵌赠,完成schema.addAll(p1.schema()) & schema.addAll(p2.schema())
      • TablePlan用getTableInfo(tblname,tx)生成 TableInfo(tblname, sch, offsets, reclen)
      • TablePlan的schema()返回sch變量
    • schema.addAll(p.schema()) 只是把p的schema的HashMap數(shù)據(jù)結(jié)構(gòu)和自己的HashMap合并,
    • 所以這里的操作就是把p1和p2的schema合并

第三步是SelectPlan垃喊,完成數(shù)據(jù)的選擇
對(duì)Product后生成的一個(gè)聯(lián)合大表進(jìn)行Selection操作。

  • 使用前面生成的Plan類(其實(shí)是繼承了Plan接口的ProductPlan類)生成SelectPlan類
    • 初始化SelectPlan(p:ProductPlan, data.pred())
    • 這里data:QueryData, data.pred() 返回了一個(gè)Predicate類

最后一步是ProjectPlan
記錄哪些field需要保留袜炕,相當(dāng)于SQL語(yǔ)句中的“select field1, field2, ...” 部分本谜。


約定用語(yǔ)

a->function() a is the real executor of that function
a<-function() a is generated by that function
a:A a is an instance of class A

類的實(shí)例
rstmt RemoteStatement //
rrs RemoteResultSet //
pln Plan //
qry String //
tx Transaction //
ti TableInfo
si StatInfo
sch Schema
s Scan

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市偎窘,隨后出現(xiàn)的幾起案子乌助,更是在濱河造成了極大的恐慌,老刑警劉巖陌知,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件他托,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡仆葡,警方通過(guò)查閱死者的電腦和手機(jī)赏参,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沿盅,“玉大人把篓,你說(shuō)我怎么就攤上這事⊙В” “怎么了韧掩?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)窖铡。 經(jīng)常有香客問(wèn)我疗锐,道長(zhǎng),這世上最難降的妖魔是什么费彼? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任滑臊,我火速辦了婚禮,結(jié)果婚禮上箍铲,老公的妹妹穿的比我還像新娘简珠。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布聋庵。 她就那樣靜靜地躺著膘融,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祭玉。 梳的紋絲不亂的頭發(fā)上氧映,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音脱货,去河邊找鬼岛都。 笑死,一個(gè)胖子當(dāng)著我的面吹牛振峻,可吹牛的內(nèi)容都是我干的臼疫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼扣孟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼烫堤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起凤价,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸽斟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后利诺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體富蓄,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年慢逾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了立倍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侣滩,死狀恐怖帐萎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胜卤,我是刑警寧澤疆导,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站葛躏,受9級(jí)特大地震影響澈段,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舰攒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一败富、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧摩窃,春花似錦兽叮、人聲如沸芬骄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)账阻。三九已至,卻和暖如春泽本,著一層夾襖步出監(jiān)牢的瞬間淘太,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工规丽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒲牧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓赌莺,卻偏偏與公主長(zhǎng)得像冰抢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艘狭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345