Save 37% off PRO during our Black Friday Sale! »

Golangで作るSQL Language Server(sqls)

Golangで作るSQL Language Server(sqls)

Go Conference 2021 Autumn Track A

A12373843afc54857a845404bdd5f5cb?s=128

Toshikazu Ohashi

November 13, 2021
Tweet

Transcript

  1. GolangͰ࡞Δ SQL Language Server(sqls) Go Conference 2021 Autumn Track A

    lighttiger2505@גࣜձࣾMobility Technologies
  2. ࣗݾ঺հ lighttiger2505 / Toshikazu Ohashi • גࣜձࣾMobility Technologiesॴଐ • αʔόʔαΠυΤϯδχΞ

    • ޷͖ͳΤσΟλ͸Vim/NeoVim
  3. ΠϯτϩμΫγϣϯ

  4. sqls An implementation of the Language Server Protocol for SQL.

  5. sqlsͱ͸ • Language Server Protocol(ҎԼ LSP)Λ༻͍ͯΤσΟλͱ௨৴͢ΔSQL ͷLanguage Server(ҎԼ ݴޠαʔόʔ) •

    LSPͱ͸ϓϩάϥϜݴޠͷ։ൃࢧԉػೳ(ҎԼ ΠϯςϦηϯε)ΛΤ σΟλʹఏڙ͢Δαʔόɺ͓Αͼͦͷ௨৴಺༰Λنఆͨ͠ϓϩτί ϧɻMicrosoft࡞
  6. HPQMT(PMBOH DMBOHE$MBOH TRMT42- -BOHVBHF4FSWFS1SPUPDPM MTQ LSΫϥΠΞϯτ͕͋ΔΤσΟλͰ͋Ε͹ͲͷΤσΟλͰ΋ ݴޠͷΠϯςϦηϯεͷԸܙΛड͚Δ͜ͱ͕Ͱ͖Δ

  7. ࣗಈิ׬

  8. αϒΫΤϦ΋ࣗಈิ׬

  9. ఆٛࢀর

  10. Πϯαʔτ஋ೖྗิॿ

  11. ΫΤϦ࣮ߦ

  12. ຊ೔ͷΰʔϧ GoݴޠͰ࡞Γํ͕Α͘Θ͔Βͳ͍΋ͷΛ࡞Δํ๏Λڞ༗͢Δ ⊗ ࣅͨΑ͏ͳ͜ͱΛࣗ෼Ͱ΋Ͱ͖Δͱࢥͬͯ΋Β͏ ⊗ GoͰ࡞ΒΕͨศརπʔϧ͕ੈքʹ૿͑Δ

  13. ΞδΣϯμ લఏ • ᶃͳͥͭ͘Δͷ͔ɻͦͷಈػ • ᶄͲ͏ͭ͘Δͷ͔ɻͦͷํ਑ ࣮ફฤ • ᶅΤσΟλͱLSPͰ௨৴͢ΔͨΊʹ͸Ͳ͏ͨ͠Β •

    ᶆSQLΛͲ͏΍ͬͯղੳ͢Ε͹͍͍͔ • ᶇෳ਺ͷσʔλϕʔεʹͲ͏ରԠ͢Ε͹͍͍͔ ·ͱΊ
  14. ᶃͳͥͭ͘Δͷ͔ɻͦͷಈػ

  15. ੈͷதʹ͸SQLͷΠϯςϦηϯε͕গͳ͍ • SQLΛૢ࡞͢Δͱ͖ࣗಈิ׬΍ఆٛࢀরͰ͖ͳ͍ͷ͕ෆຬ • ิ׬Ͱ͖ͯ΋஗͍ • ਖ਼֬͡Όͳ͍ • SELECT Expr͸ิ׬ͯ͠΋ଞͰ͸ิ׬͠ͳ͍౳

    • DBπʔϧਾ͑෇͚ͷΤσΟλ্Ͱ͔͠ΠϯςϦηϯε͕ಈ࡞͠ͳ͍
  16. dbcli͚͕ͩٹ͍ͩͬͨ • DBeaver, DataGripͱൺֱͯ͠΋ิ׬ ͕ਖ਼͔֬ͭߴ଎ • λʔϛφϧ͔Βଈ࣌ىಈ • ීஈ࢓ࣄͰ࢖͏Α͏ͳDB͸αϙʔτ •

    DB઀ଓ؅ཧ͕໘౗ • ࣗ෼ͰπʔϧΛ࡞ͬͨ
  17. Ұ೥΄ͲdbcliΛ࢖ͬͨ݁Ռͷෆຬ఺ • 1ϥΠϯΤσΟλͳͷͰෳ਺ߦͷΫΤϦฤू͸ͮ͠Β͍ • αϒΫΤϦͳͲͷෳࡶͳΫΤϦͷิ׬͸Ͱ͖ͳ͍ • ΧϥϜͷৄࡉ΍ςʔϒϧͷৄࡉΛࢀর͢Δͱ͖ɺςʔϒϧৄࡉΛௐ΂ Δผ΢Οϯυ΢Λ։͍ͯࢀর͢Δඞཁ͕͋Δ

  18. ݴޠαʔόʔͱLSP • ౰࣌(2018೥ͷౙࠒ)gopls͕։ൃ͞ΕɺGoͷࣗಈิ׬͸ݴޠαʔόʔ Λ࢖͏ͷ͕ྑ͍ͱ͍͏ঢ়گʹ • ΤσΟλʔ͕ΠϯςϦηϯεΛಘΔͱ͖ݴޠαʔόʔ͕ୈҰީิʹͳ Δͱ͍͏ྲྀΕ • SQLͷݴޠαʔόʔ͕͋Ε͹ɺ͢΂ͯͷ໰୊͸͢΂ͯղܾ͢ΔͷͰ͸ ͱ͍͏ண૝

  19. ᶄͲ͏ͭ͘Δͷ͔ɻͦͷํ਑

  20. ࠷খཁ݅Λ·ͱΊΔ • LSPʹ४ڌͨ͠ϦΫΤετ/ϨεϙϯεΛฦͤΔ • SQLͷจ຺ΛཧղͰ͖Δ • ͦΕʹΑͬͯࣗಈิ׬͕Ͱ͖Δ • ෳ਺छྨͷσʔλϕʔεʹରԠ͢Δ͜ͱ͕Ͱ͖Δ •

    ॳظஈ֊Ͱ͸MySQLͷΈ
  21. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    ղܾ͠ͳ͚Ε͹͍͚ͳ͍՝୊͕̏ͭ TRMEBUBCBTF SQLϑΝΠϧ
  22. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    ΤσΟλͱLSPͰ௨৴͢ΔͨΊʹ͸Ͳ͏ͨ͠Β͍͍͔ TRMEBUBCBTF SQLϑΝΠϧ
  23. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    TRMEBUBCBTF SQLΛղੳ͢Δʹ͸Ͳ͏͢Ε͹͍͍͔ SQLϑΝΠϧ
  24. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    TRMEBUBCBTF ෳ਺ͷσʔλϕʔεʹͲ͏ରԠ͢Ε͹͍͍͔ SQLϑΝΠϧ
  25. Θ͔ΒΜ͚Ͳ ͱΓ͋͑ͣ ࡞Ζ͏

  26. ҠಈͰਓΛ޾ͤʹɻ ϞϏϦςΟςΫϊϩδʔζ ఏɹɹڙ ϓϩϞʔγϣϯΛؚΈ·͢

  27. ʮҠಈͰਓΛ޾ͤʹɻʯΛϛογϣϯʹ No.1*λΫγʔΞϓϦʮGOʯ΍AIυϥϨ ίαʔϏεʮDRIVE CHARTʯͳͲΛ։ൃ ͍ͯ͠·͢ *App Annieௐ΂ʛλΫγʔ഑ंؔ࿈ΞϓϦʹ͓͚Δ೔ຊࠃ಺μ΢ϯϩʔυ਺(iOS/ Google Play߹ࢉ஋) ௐࠪظؒɿ2020೥10݄1೔ʙ2021೥9݄30೔

    ϓϩϞʔγϣϯΛؚΈ·͢
  28. ͸GoΤϯδχΞ ΛઈࢍืूதͰ͢ ϓϩϞʔγϣϯΛؚΈ·͢

  29. ᶅΤσΟλͱLSPͰ ௨৴͢ΔͨΊʹ͸Ͳ͏ͨ͠Β͍͍͔

  30. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    ΤσΟλͱLSPͰ௨৴͢ΔͨΊʹ͸Ͳ͏ͨ͠Β͍͍͔ TRMEBUBCBTF SQLϑΝΠϧ
  31. LSPʹΑΔΤσΟλͱͷ௨৴ • ΤσΟλͱݴޠαʔόʔ͸JSON-RPC 2.0Ͱ௨৴͢Δ • RPC(Remote Procedure Callͷུ)͸ݺͼग़͠ݩͱ͸ผͷϓϩάϥϜ ͷϝιουΛݺͼग़͢ •

    JSON-RPC͸ϝιουͷίʔϧͱϨεϙϯεΛJSONͰߦ͏ • ݴޠαʔόʔͱ͸ݴ͏͕ΤσΟλͱಉ͡PC্ʹ্ཱͪ͛ͯιέοτܦ ༝Ͱ௨৴͢Δͷ͕ओ
  32. JSON-RPCͷ௨৴ྫ(ఆٛݩδϟϯϓ) { "jsonrpc": "2.0" , "id" : 1 , "method":

    "textDocument/definition" , "params": { "textDocument": { "uri": "file:///cpp/use.cpp " } , "position": { "line": 3 , "character": 1 2 } } } { "jsonrpc": "2.0" , "id": 1 , "result": { "uri": "file:///cpp/provide.cpp" , "range": { "start": { "line": 0 , "character": 4 } , "end": { "line": 0 , "character": 1 1 } } } } ΤσΟλ ϦΫΤετ ݴޠαʔόʔ Ϩεϙϯε
  33. GolangͰͷJSON-RPCͷ࣮૷ํ๏ • Goͷ͍͍ͱ͜Ζ͸ࣅͨΑ͏ͳιϑτ΢ΣΞ͕΋͏͢Ͱʹ͋Δ ݴޠαʔόʔ ղઆ HPQMT (Pͷ։ൃνʔϜ͕։ൃ͍ͯ͠Δ(PMBOHެࣜͷݴޠαʔόʔ CJOHP TBJCJOHࢯ͕։ൃɻHPQMTҎલ͔Β͋Δ(PMBOHͷݴޠαʔόʔɻݱࡏ͸HPQMTʹ ౷߹ɻHPQMTΑΓػೳ͕গͳ͘γϯϓϧɻ࣮͸ॳظ͸ͬͪ͜Λࢀߟʹͨ͠

    FGNMBOHTFSWFS NBUUOࢯ͕։ൃɻMJOUFSͷ࣮ߦ݁ՌΛύʔεͯ͠MTQܗࣜͷMJOU݁Ռ EJBHOPTUJDT ͱ͍͏ ʹม׵͠+40/31$ܗࣜͰ౉͢൚༻ݴޠαʔόʔ
  34. JSON-RPCߏஙͷஈऔΓ • Ͳͷαʔόʔ΋JSON-RPC2ͷ࣮૷ʹ͸sourcegraph/jsonrpc2Λ࢖͍ͬͯΔ • efm-langserver͔Βݴޠαʔόʔͱͯ͠࠷௿ݶ੒ΓཱͭίʔυΛҾ༻ • ࠷΋γϯϓϧͳ࡞ΓͩͬͨͨΊ • sourcegraph/jsonrpc2ͱbingo͔ΒJSON-RPC2ͷςετίʔυΛҾ༻ͯ͠ ୯ମςετߏங

    • ࣮ࡍʹLSΫϥΠΞϯτͱૄ௨ͯ͠ਖ਼ৗಈ࡞͢Δ͜ͱΛ֬ೝ
  35. ᶆSQLΛղੳ͢Δʹ͸ Ͳ͏͢Ε͹͍͍͔

  36. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    TRMEBUBCBTF SQLΛղੳ͢Δʹ͸Ͳ͏͢Ε͹͍͍͔ SQLϑΝΠϧ
  37. SQLΛղੳ͢Δʹ͸ • Golangͷgo/astύοέʔδͷΑ͏ͳղੳϥΠϒϥϦ͕ඞཁ • ϥΠϒϥϦΛ୳͢ͱҎԼͷΑ͏ͳ΋ͷ͕ݟ͔ͭΔ ύʔαʔ ղઆ YXC TRMQBSTFS 7JUFTTͱ͍͏.Z42-ͷΫϥελΛߏங͢ΔγεςϜͰར༻͞Ε͍ͯΔύʔαʔ

    ΛϥΠϒϥϦԽͨ͠΋ͷ BLJUP YTRMQBSTFS 3VTU੡ͷBOEZHSPWFTRMQBSTFSSTΛࢀߟʹ࡞ΒΕͨύʔαʔɻTRMTͰ͸௚઀ ࢖͍ͬͯͳ͍͕MFYFS͸΄΅͜ΕΛࢀߟʹ͍ͯ͠Δ
  38. ͲͷΑ͏ͳಈ͖Λ͢Δ͔ݕূ͢Δ • SQLΛύʔεͯ͠ߏ଄ମΛprint͢Δ͚ͩͷ؆қCLIΛ࡞ͬͯݕূ package mai n import ( "fmt "

    "os " "github.com/k0kubun/pp " "github.com/xwb1989/sqlparser " ) func main() { stmt, err := sqlparser.Parse(os.Args[0] ) if err != nil { fmt.Println("parse error:", err ) retur n } pp.Print(stmt ) }
  39. ͜ͷͱ͖͸͜͏ࢥ͍ͬͯ·ͨ͠ ͳΜͩ؆୯͡Όͳ͍͔ɻ ͜ΕͳΒࣗಈิ׬΋͙ͩͧ͢ɻ

  40. ݕূͷ݁Ռࣗಈิ׬ʹ͸࢖͑ͳ͍͜ͱ͕Θ͔Δ • ݕূͨ݁͠Ռɺsqls༻్Ͱ͸طଘύʔαʔ͸࢖͑ͳ͍͜ͱ͕Θ͔Δ SELECT id, | FROM city INSERT INTO

    city (id, |) UPDATE city SET CountryCode='USA', |
  41. GOͷߏจ package mai n import "fmt " func main() {

    msg := "hello world " fmt.Sprintln(| } SELECT `ID` , | FROM `city ` WHERE `CountryCode` = 'USA ' ORDER BY `District` SQLͷߏจ
  42. GOͷߏจ package mai n import "fmt " func main() {

    msg := "hello world " fmt.Sprintln(| } SELECT `ID` , | FROM `city ` WHERE `CountryCode` = 'USA ' ORDER BY `District` SQLͷߏจ • ߏจͷؔ܎্ɺ1Statement͕௕͍ • 1Statementͷதʹ(ςʔϒϧ౳)ఆٛ৘ใؚ͕·Ε͍ͯΔ
  43. GOͷߏจ package mai n import "fmt " func main() {

    msg := "hello world " fmt.Sprintln(| } SELECT `ID` , | FROM `city ` WHERE `CountryCode` = 'USA ' ORDER BY `District` SQLͷߏจ • ߏจͷؔ܎্ɺ1Statement͕௕͍ • 1Statementͷதʹ(ςʔϒϧ౳)ఆٛ৘ใؚ͕·Ε͍ͯΔ
  44. GOͷߏจ package mai n import "fmt " func main() {

    msg := "hello world " fmt.Println(| } SELECT `ID` , | FROM `city ` WHERE `CountryCode` = 'USA ' ORDER BY `District` SQLͷߏจ • ଞݴޠͳΒύʔεࣦഊͨ͠1StatementΛಡΈඈ͹ͯ͠ऴΘΓ • SQL͸1StatementதͷΤϥʔΛ෼ׂͯ͠ղऍ͢Δඞཁ͕͋Δ
  45. ݱࡏSQLͷࣗಈิ׬͕Ͱ͖͍ͯΔOSS • dbcliγϦʔζɻPython੡ɻ֤DBͷCLIίϚϯυͷ୅ΘΓʹ࢖͏͜ͱͰ CLI্ͰΫΤϦͷࣗಈิ׬͕Ͱ͖Δ ίϚϯυ ղઆ QHDMJ QPTUHSF42-ͷ$-*ίϚϯυ୅ସ NZDMJ .Z42-ͷ$-*ίϚϯυ୅ସ

    MJUFDMJ 42-JUFͷ$-*ίϚϯυ୅ସ NTTRMDMJ .JDSPTPGU42-4FSWFSͷ$-*ίϚϯυ୅ସ
  46. dbcliγϦʔζ͕ར༻͍ͯ͠ΔSQLύʔαʔ • andialbrecht/sqlparse • ͍Θ͘sqlparse is a non-validating SQL parser

    for Python. • Goͷύʔαʔͷͱ͖ͱಉ༷ʹSQLͷύʔε݁ՌΛඳը͢Δ͚ͩͷCLI ίϚϯυΛ࡞ͬͯࢼ͢ • ΤϥʔΛಡΈඈ͹ͤΔఔ౓·Ͱจ຺ͷղੳΛεΩοϓ͍ͯͨ͠
  47. طଘͷSQLύʔε

  48. non-validatingͳSQLύʔε

  49. di f

  50. di f จ຺ΛऔΒͳ͍ɻSelectͰදࣔ͢ΔΧϥϜͱ͔ςʔϒϧͷఆٛ

  51. ϝϦσϝ • ϝϦοτ • ଟগͷΤϥʔ͕͋ͬͯ΋໰୊ͳ͘ύʔεͰ͖Δ • σϝϦοτ • From۟Ͱఆٛ͞ΕͨςʔϒϧΛҾ͖ग़͢ͳͲͷॲཧ͕໘౗ •

    lintͷ࣮૷ͱ͔௒ΊΜͲ͍͘͞(ͳͷͰ΍͍ͬͯͳ͍) • αϒΫΤϦ΍࿦ཧԋࢉࢠͳͲ࠶ؼతͳॲཧ͕೉͍͠ • αϒΫΤϦղੳͷίʔυ͸ࠓͰ΋ݟͨ͘ͳ͍
  52. ཧ۶͸Θ͔͕ͬͨɺ׬શʹࣗݾྲྀͰ࣮૷͢Δͷ͸ා ͍ͷͰɺύʔαʔͮ͘ΓͷษڧΛ͢Δ͜ͱʹͨ͠ ௒͓͢͢Ίʂʂʂ

  53. ̍ϲ݄ษڧͯ͠Θ͔ͬͨ͜ͱ • ߏจΛղੳ͢ΔͨΊʹࣈ۟ղੳث(Lexer),ߏจղੳث(Parser)͕ඞཁ • ύʔαʔΛ࡞ΔͨΊʹύʔαʔδΣωϨʔλͳΔศརπʔϧ͕͋Δ • DSLΛఆٛͯ͠ಡΈࠐΉͱύʔαʔ(৔߹ʹΑͬͯ͸ϨΩαʔ΋)Λ ੜ੒ ࣈ۟ղੳث -FYFS

    ߏจղੳث 1BSTFS τʔΫϯྻ AST ιʔείʔυ
  54. sqlsͷΞϓϩʔν • ύʔαʔδΣωϨʔλʔ vs ࣗ࡞ύʔαʔ • ͲͷδΣωϨʔλʔͳΒnon-validatingͳύʔαʔ͕࡞ΕΔ͔ෆ໌ • ࣗ࡞ͰύʔαʔͳΒࣗ࡞ͳͷͰͳΜͰ΋Ͱ͖Δ •

    ࠓࢥ͑͹tree-sitterͱ͔͋ͬͨɻษڧෆ଍ • ࣗ࡞ύʔαʔͷ࡞੒Λܾҙ • ϨΩαʔ͸xsqlparserΛࢀߟʹ͢Ε͹ͦΜͳʹ࿑ྗͳ͘࡞Εͦ͏
  55. ύʔαʔ࡞Γํߨ࠲(ͦͷ̍) • andialbrecht/sqlparse͔ΒύʔεͷςετίʔυΛݟ͚ͭΔ • ҎԼΛsqlparseͱಉ౳ͷ݁Ռ͕ಘΒΕΔ·Ͱ܁Γฦ͢ 1. ύʔε͢Δର৅ΛܾΊΔ(ΧϥϜྻͱ͔) 2. ର৅Λύʔε͢ΔςετίʔυΛsqlsʹҠ২ 3.

    ςετίʔυͷظ଴஋Λຬͨ͢
  56. ύʔαʔ࡞Γํߨ࠲(ͦͷ̎) • ςετ͠·͢ • ςετ͠·͢ • ςετ͠·͢ • ςετ͠·͢ •

    ςετ͠·͢ • ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠· ͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠ ·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢…
  57. ॳΊͯsqlsͰࣗಈิ׬Λ͍ͯ͠Δ༷ࢠ

  58. ᶇෳ਺ͷσʔλϕʔεʹ Ͳ͏ରԠ͢Ε͹͍͍͔

  59. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    TRMEBUBCBTF ෳ਺ͷσʔλϕʔεʹͲ͏ରԠ͢Ε͹͍͍͔ SQLϑΝΠϧ
  60. ੍໿ͱϧʔϧΛઃ͚Δ • sqls͸͋͘·Ͱࣗ෼ͷͨΊͷπʔϧ • ༗ঈͷDB੡඼ʹ͸ରԠ͠ͳ͍ • ։ൃऀ͍ͩ͠Ͱ઀ଓݕূ͕Ͱ͖ͳ͘ͳΔ • BigQuery •

    Snow fl ake • database/sqlʹޓ׵ͷ͋ΔDriver͕ͳ͍΋ͷʹ͸ରԠ͠ͳ͍
  61. ΠϯλϑΣʔεΛ༻ҙ type DBRepository interface { Driver() dialect.DatabaseDrive r CurrentDatabase(ctx context.Context)

    (string, error ) Databases(ctx context.Context) ([]string, error ) CurrentSchema(ctx context.Context) (string, error ) Schemas(ctx context.Context) ([]string, error ) SchemaTables(ctx context.Context) (map[string][]string, error ) DescribeDatabaseTable(ctx context.Context) ([]*ColumnDesc, error ) DescribeDatabaseTableBySchema(ctx context.Context, schemaName string) ([]*ColumnDesc, error ) Exec(ctx context.Context, query string) (sql.Result, error ) Query(ctx context.Context, query string) (*sql.Rows, error ) }
  62. ͳͥΠϯλϑΣʔε͕ඞཁ͔ • υϥΠό௥Ճʹඞཁͳ߲໨Λ໌ࣔ • ςʔϒϧͳͲͷϝλ৘ใͷऔಘํ๏͕DB͝ͱʹҧ͏ • mysql, postgresqlͳΒinformation_schema • sqlite3ͳΒsqlite_master

  63. ΠϯλϑΣʔεΘ͚ͨ͠੒Ռ • ࣗ෼Ͱ࣮૷ͨ͠ͷ͸DB઀ଓ͸MySQL͚ͩ • PostgreSQLͱSQLite3͸mattn͞Μ • Microsoft SQL Server͸alexhokl͞Μ •

    ༗ঈͷDB੡඼Λ௥Ճͨ͠PullRequest͕དྷΔ͕Ϛʔδ͸͠ͳ͍
  64. ·ͱΊ • ڧ͍ಈػ(VimͰSQLͷิ׬͕͍ͨ͠)͕͋Ε͹ؤுΕΔ • ࡞Γํ͕Θ͔Βͳ͍ͱ͖ɺࣅͨ՝୊Λղܾ͢Δπʔϧ͸୳ͤ͹͋Δ • طଘπʔϧ/ϥΠϒϥϦ͕՝୊ʹϑΟοτ͠ͳ͚Ε͹ࣗ࡞΋ࢹ໺ʹೖΕΔ • ೰ΜͰ͍Δؒʹॻ͚ͨΓ΋͢Δ͠ɺବ໨Ͱ΋৽͍͠՝୊͕ݟ͑Δ •

    ෦෼ద༻Ͱ͖Δ΋ͷ͸͋ΔͷͰίʔυΛಡΉ͜ͱΛڪΕͳ͍ • ॳظείʔϓ͸Ͱ͖Δ͚ͩখ͘͢͞Δ
  65. See you again όΠόΠ