Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
SpannerのSQL解析ライブラリ "memefish" の紹介/gcpug-memefis...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
TSUYUSATO Kitsune
February 06, 2020
Programming
1.6k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
SpannerのSQL解析ライブラリ "memefish" の紹介/gcpug-memefish-introduction
GCPUG Tokyo Handy Spanner Day February 2020 (2020/02/06)での発表資料
TSUYUSATO Kitsune
February 06, 2020
More Decks by TSUYUSATO Kitsune
See All by TSUYUSATO Kitsune
dewasm - WebAssembly to Source Code translator
makenowjust
0
83
(Re)make Regexp in Ruby: Democratizing internals for the JIT
makenowjust
3
2k
「正規表現をつくる」をつくる / make "make regex"
makenowjust
1
1.8k
最近の研究とか、RubyへのContributionとか / Recent My Study and Ruby Contributions
makenowjust
2
340
Make Parsers Compatible Using Automata Learning
makenowjust
3
13k
YAPC::Japan::Online 2022で発表して WEB+DB PRESSに記事を寄稿した話
makenowjust
0
90
Regular Expressions, REXML, Automata Learning
makenowjust
0
500
オートマトン学習しろ / Do automata learning
makenowjust
3
640
#kaigieffect LT 2024 - rexml-css_selector: A REXML extension for supporting CSS selector
makenowjust
1
510
Other Decks in Programming
See All in Programming
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2.4k
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
540
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
310
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
250
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
250
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
4
3.5k
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
170
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
130
一人だけ、Kiroが静止する日
hideg
0
130
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
290
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
200
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
270
Featured
See All Featured
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
280
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
390
WENDY [Excerpt]
tessaabrams
14
39k
Darren the Foodie - Storyboard
khoart
PRO
4
3.9k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
610
Rails Girls Zürich Keynote
gr2m
96
14k
Building Applications with DynamoDB
mza
96
7.2k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
550
The Invisible Side of Design
smashingmag
301
52k
Transcript
SpannerのSQL解析ライブラリ "memefish" の紹介 @MakeNowJust at GCPUG Tokyo Handy Spanner Day
February 2020 (2020/02/06) SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 1
⾃⼰紹介 HN: MakeNowJust 学⽣ 去年の夏にメルカリのインターンに参加していた 今回紹介するものも、インターンで開発したもの SpannerのSQL解析ライブラリ "memefish" の紹介 by
@MakeNowJust 2
SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 3
紹介するもの SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 4
méméfish méméfish méméfish https://makenowjust.github.io/memefish SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 5
memefish Spannerで使えるSQLを解析するためのGo⾔語のライブラリ (OSS) https://github.com/MakeNowJust/memefishで公開されている 主な機能 1. SQLのパース 2. 構⽂⽊からのSQLの⽣成 3.
SQLの意味解析・型チェック SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 6
memefishを使っているプロジェクト gcpug/handy-spanner mercari/yo SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 7
パッケージ構成 github.com/MakeNowJust/memefish/pkg 以下の重要なパッケージ token : パースに使うトークンやファイルの構造体を定義したパッケージ ast : パース結果のAST (抽象構⽂⽊)を定義したパッケージ
parser : パーサーの実装があるパッケージ analyzer : 型チェッカーのあるパッケージ go/token, go/ast, go/parser などのパッケージを参考にしている SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 8
主な機能 1. SQLのパース 2. 構⽂⽊からのSQLの⽣成 3. SQLの意味解析・型チェック 今⽇の主題 これらの機能がどのようなものなのか memefishでそれらの機能をどうやって使うのか
を説明します (前提知識: Go⾔語を知ってること) SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 9
1. SQLのパース・2. 構⽂⽊からのSQLの⽣成 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 10
パースとは 与えられた⽂字列をSQLとして解釈して、対応する抽象構⽂⽊を組み⽴てること。 例: パースしたい⽂字列 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 11
パース: Lexer そのまま抽象構⽂⽊を組み⽴てるのは難しいので、 まず意味のある最⼩の単位(トークン)に⽂字列を分割する。 トークンには、その部分の役割(キーワードか?識別⼦か?⽂字列リテラルか?など)も 記録されている。 SpannerのSQL解析ライブラリ "memefish" の紹介 by
@MakeNowJust 12
パース: Lexer この処理を⾏うオブジェクトを Lexer と呼ぶ。 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust
13
パース: Parser Lexer によって分割されたトークンの列から抽象構⽂⽊を組み⽴てていく。 抽象構⽂⽊: SQLの各要素に対応する構造体 (⽊構造) この処理を⾏うオブジェクトを Parser と呼ぶ。
SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 14
使い⽅: import ⽂ まずは import 。 ast, token, parser を使う。
import ( "fmt" "log" "github.com/MakenowJust/memefish/pkg/ast" "github.com/MakenowJust/memefish/pkg/parser" "github.com/MakenowJust/memefish/pkg/token" ) SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 15
使い⽅: Parser の組み⽴て Parser は構造体なので必要なフィールドを埋めていく。 必要なフィールドは Lexer だけ。 ( Parser
が Lexer を使うので) また、パースしたい⽂字列は File という構造体に包む。 file := &token.File{ Buffer: "SELECT * FROM Singers WHERE FirstName = \"Foo\"", } p := &parser.Parser{ Lexer: &parser.Lexer{File: file}, } SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 16
使い⽅: ParseQuery の呼び出し 実際のパースは ParseQuery メソッドの呼び出しで⾏なわれる。 ParseQuery の返り値は抽象構⽂⽊とパース時のエラー。 stmt, err
:= p.ParseQuery() if err != nil { log.Fatal(err) } あとは、この stmt を使ってやりたいことをする。 stmt.Query.(*ast.Select).From.Source.(*ast.TableName).Table.Name == "Singers" // => true SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 17
使い⽅: まとめ パースしたい⽂字列を構造体 File に包む ↑を使って Lexer 、 Parser を作る
ParseQuery を呼び出してパースを実⾏する (DMLのパースなら ParseDML 、DDLのパースなら ParseDDL が使える) 結果の抽象構⽂⽊を使ってごにょごにょする SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 18
SQLの⽣成 抽象構⽂⽊の型 ast.Node の定義 type Node interface { Pos() token.Pos
End() token.Pos // Convert AST node into SQL source string (a.k.a. Unparse). SQL() string } この SQL() メソッドで、抽象構⽂⽊からSQLの⽂字列を⽣成できる。 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 19
例: SQLの⽣成 さきほどまでのパースの例の続き // Singers の部分を Albums に差し替える stmt.Query.(*ast.Select).From.Source.(*ast.TableName).Table.Name =
"Albums" fmt.Println(stmt.SQL()) // Output: // SELECT * FROM Albums WHERE FirstName = "Foo" SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 20
3. SQLの意味解析・型チェック SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 21
意味解析・型チェック SQL中の 識別⼦がテーブル・カラム・変数名のどれなのか? 具体的には何を指しているのか? 式の結果がどのような型になるか? を求める機能。 (パースなどと⽐べるとやや不安定です……) SpannerのSQL解析ライブラリ "memefish" の紹介
by @MakeNowJust 22
意味解析・型チェック 意味解析の途中で、 存在しないテーブル・カラムを参照している おかしな操作をしている 例: ⽂字列と数値を⾜し合わせようとしている 例: WHERE の式が BOOL
値を返していない などのエラーが分かる。 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 23
意味解析・型チェック: 疑問 Q. 実際にSpanner送って実⾏計画を⾒るなりすれば、それらのエラーは分かるのでは? memefishで意味解析をする場合、 1. ローカルで全て完結する (通信を伴わない) 2. 型情報や参照の情報をプログラムから利⽤できる
といったメリットがある。特に2番が重要。 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 24
意味解析・型チェック: 使⽤イメージ 例えば、意味解析ではクエリの結果の各カラムがどのような名前・型なのかを取得できる。 これを利⽤すると、クエリからその結果に⼀致する構造体を⾃動⽣成する、 といったことができる。 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust
25
意味解析・型チェック: 使⽤イメージ 例: SELECT CONCAT(FirstName, " ", LastName) AS Name,
BirthDate FROM Singers から type Result struct { Name string BirthDate time.Time } を⾃動⽣成 SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 26
→次のスライドから、これを作っていきます SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 27
使い⽅: import ⽂ 意味解析は抽象構⽂⽊に対して⾏うので、 parser, token のインポートも必要 import ( "fmt"
"log" "github.com/MakeNowJust/memefish/pkg/analyzer" "github.com/MakeNowJust/memefish/pkg/parser" "github.com/MakeNowJust/memefish/pkg/token" ) SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 28
使い⽅: パース まずはパースをする。(さっきと同じ) file := &token.File{ Buffer: "SELECT CONCAT(FirstName, \"
\", LastName) AS Name, BirthDate FROM Singers", } p := &parser.Parser{ Lexer: &parser.Lexer{File: file}, } stmt, err := p.ParseQuery() if err != nil { log.Fatal(err) } SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 29
使い⽅: Catalog の組み⽴て テーブルのスキーマ定義をまとめたものを Catalog と呼ぶ。 catalog := &analyzer.Catalog{ Tables:
map[string]*analyzer.TableSchema{ "SINGERS": { Name: "Singers", Columns: []*analyzer.ColumnSchema{ {Name: "FirstName", Type: analyzer.StringType}, {Name: "LastName", Type: analyzer.StringType}, {Name: "BirthDate", Type: analyzer.DateType}, }, }, }, } SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 30
使い⽅: Analyzer の組み⽴て Catalog と File を渡す必要がある。 File はエラー位置を実際のソースコードに対応させるために必要。 a
:= &analyzer.Analyzer{ File: file, Catalog: catalog, } SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 31
使い⽅: 意味解析の実⾏ AnalyzeQueryStatement に解析したい抽象構⽂⽊を渡すことで意味解析を実⾏できる。 返り値はエラーのみで、意味解析の結果は Analyzer ⾃⾝に保存される。 err = a.AnalyzeQueryStatement(stmt)
if err != nil { log.Fatal(err) } SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 32
使い⽅: 意味解析の結果を使う 例えば、 a.NameList には結果の各カラムの情報が保存されている。 これを使って、SQLの結果に対応する構造体の定義を出⼒する。 columns := a.NameLists[stmt.Query] fmt.Printf("type
Result struct {\n"); for _, column := range columns { fmt.Printf("\t%-9s %s\n", column.Text, mapSQLType(column.Type)) } fmt.Printf("}\n"); ( mapSQLType はSQLの型をGo⾔語の型に対応させる関数。省略) SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 33
使い⽅: まとめ 解析したいSQLをパースする スキーマをまとめた Catalog を組み⽴てる Catalog と File から
Analyzer を組み⽴てる AnalyzeQueryStatement に解析したい抽象構⽂⽊を渡す 意味解析の結果は Analyzer ⾃⾝に保存されている 他には Types フィールドに各式の型が保存されていたりする。 今回の例の全体は次のGo Playgroundから確認できます。 https://play.golang.org/p/PN5JuJKB-Mo SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 34
今回のまとめ SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 35
今回のまとめ memefishはSpannerのSQLをパース・意味解析できるGo⾔語のライブラリ SQL⽂をプログラムで扱うことができる ⾊々と⾯⽩いことに使えると思うので、記憶に⽚隅にでも留めてもらえたら その他、希望など memefishはOSSなので、バグ報告・修正などはいつでもウェルカムです memefishを使って何か作ったよ、みたいな報告もありがたいです ただ、 analyzer 周りはやや開発途中な部分があるので、
後⽅互換性の無い変更などあるかもしれません (悪しからず) SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 36
Q&A? SpannerのSQL解析ライブラリ "memefish" の紹介 by @MakeNowJust 37