Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Golangで作るSQL Language Server(sqls)

Golangで作るSQL Language Server(sqls)

Go Conference 2021 Autumn Track A

Toshikazu Ohashi

November 13, 2021
Tweet

More Decks by Toshikazu Ohashi

Other Decks in Programming

Transcript

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

    lighttiger2505@גࣜձࣾMobility Technologies
  2. sqlsͱ͸ • Language Server Protocol(ҎԼ LSP)Λ༻͍ͯΤσΟλͱ௨৴͢ΔSQL ͷLanguage Server(ҎԼ ݴޠαʔόʔ) •

    LSPͱ͸ϓϩάϥϜݴޠͷ։ൃࢧԉػೳ(ҎԼ ΠϯςϦηϯε)ΛΤ σΟλʹఏڙ͢Δαʔόɺ͓Αͼͦͷ௨৴಺༰Λنఆͨ͠ϓϩτί ϧɻMicrosoft࡞
  3. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

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

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

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

    TRMEBUBCBTF ෳ਺ͷσʔλϕʔεʹͲ͏ରԠ͢Ε͹͍͍͔ SQLϑΝΠϧ
  7. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

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

    JSON-RPC͸ϝιουͷίʔϧͱϨεϙϯεΛJSONͰߦ͏ • ݴޠαʔόʔͱ͸ݴ͏͕ΤσΟλͱಉ͡PC্ʹ্ཱͪ͛ͯιέοτܦ ༝Ͱ௨৴͢Δͷ͕ओ
  9. 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 } } } } ΤσΟλ ϦΫΤετ ݴޠαʔόʔ Ϩεϙϯε
  10. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

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

    ΛϥΠϒϥϦԽͨ͠΋ͷ BLJUP YTRMQBSTFS 3VTU੡ͷBOEZHSPWFTRMQBSTFSSTΛࢀߟʹ࡞ΒΕͨύʔαʔɻTRMTͰ͸௚઀ ࢖͍ͬͯͳ͍͕MFYFS͸΄΅͜ΕΛࢀߟʹ͍ͯ͠Δ
  12. ͲͷΑ͏ͳಈ͖Λ͢Δ͔ݕূ͢Δ • 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 ) }
  13. GOͷߏจ package mai n import "fmt " func main() {

    msg := "hello world " fmt.Sprintln(| } SELECT `ID` , | FROM `city ` WHERE `CountryCode` = 'USA ' ORDER BY `District` SQLͷߏจ
  14. 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ͷதʹ(ςʔϒϧ౳)ఆٛ৘ใؚ͕·Ε͍ͯΔ
  15. 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ͷதʹ(ςʔϒϧ౳)ఆٛ৘ใؚ͕·Ε͍ͯΔ
  16. 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தͷΤϥʔΛ෼ׂͯ͠ղऍ͢Δඞཁ͕͋Δ
  17. dbcliγϦʔζ͕ར༻͍ͯ͠ΔSQLύʔαʔ • andialbrecht/sqlparse • ͍Θ͘sqlparse is a non-validating SQL parser

    for Python. • Goͷύʔαʔͷͱ͖ͱಉ༷ʹSQLͷύʔε݁ՌΛඳը͢Δ͚ͩͷCLI ίϚϯυΛ࡞ͬͯࢼ͢ • ΤϥʔΛಡΈඈ͹ͤΔఔ౓·Ͱจ຺ͷղੳΛεΩοϓ͍ͯͨ͠
  18. ϝϦσϝ • ϝϦοτ • ଟগͷΤϥʔ͕͋ͬͯ΋໰୊ͳ͘ύʔεͰ͖Δ • σϝϦοτ • From۟Ͱఆٛ͞ΕͨςʔϒϧΛҾ͖ग़͢ͳͲͷॲཧ͕໘౗ •

    lintͷ࣮૷ͱ͔௒ΊΜͲ͍͘͞(ͳͷͰ΍͍ͬͯͳ͍) • αϒΫΤϦ΍࿦ཧԋࢉࢠͳͲ࠶ؼతͳॲཧ͕೉͍͠ • αϒΫΤϦղੳͷίʔυ͸ࠓͰ΋ݟͨ͘ͳ͍
  19. sqlsͷΞϓϩʔν • ύʔαʔδΣωϨʔλʔ vs ࣗ࡞ύʔαʔ • ͲͷδΣωϨʔλʔͳΒnon-validatingͳύʔαʔ͕࡞ΕΔ͔ෆ໌ • ࣗ࡞ͰύʔαʔͳΒࣗ࡞ͳͷͰͳΜͰ΋Ͱ͖Δ •

    ࠓࢥ͑͹tree-sitterͱ͔͋ͬͨɻษڧෆ଍ • ࣗ࡞ύʔαʔͷ࡞੒Λܾҙ • ϨΩαʔ͸xsqlparserΛࢀߟʹ͢Ε͹ͦΜͳʹ࿑ྗͳ͘࡞Εͦ͏
  20. ύʔαʔ࡞Γํߨ࠲(ͦͷ̎) • ςετ͠·͢ • ςετ͠·͢ • ςετ͠·͢ • ςετ͠·͢ •

    ςετ͠·͢ • ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠· ͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠ ·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢ςετ͠·͢…
  21. TRMT .Z42- 1PTUHSF 42- TRMJUF MTQ MTQ MTQ TRMEBUBCBTF TRMEBUBCBTF

    TRMEBUBCBTF ෳ਺ͷσʔλϕʔεʹͲ͏ରԠ͢Ε͹͍͍͔ SQLϑΝΠϧ
  22. ΠϯλϑΣʔεΛ༻ҙ 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 ) }