ついに登場 Postgres Language Server 初公開 SQL開発が激変か
引用元:https://news.ycombinator.com/item?id=43513996
へーい、HN!
Postgres Language Serverの最初のバージョンをリリースしたよ。2年くらい前から開発してたんだ[0]。リポジトリ[1]からバイナリをダウンロードして試してみて。npm、vscode extension、nvim-lspconfig、masonでも利用できるよ[2]。
色々な問題にぶつかったけど、なんとか解決してきた。今は実用的で、ちょっと単純な解決策を使ってる。
詳細はブログ[3]を見てね。
試してみて、バグとかあったら教えて。バグ報告、アイデア、コントリビューションは大歓迎だよー。特にRustをハックしたい人!
最後に、Biome[4]に感謝したい。彼らのコードをたくさん勉強して、多くのアプローチを取り入れたんだ。彼らの協力なしでは、ここにいなかったよ。
[0] Announcement Show HN:
https://news.ycombinator.com/item?id=37020610
[1] Repository:
https://github.com/supabase-community/postgres-language-serv…
[2] Installation Guides:
https://pgtools.dev/#installation
[3] Blog Post:
https://www.supabase.com/blog/postgres-language-server
[4] Biome:
https://biomejs.dev
READMEの紹介文にもう少しプロジェクトのスコープを詳しく書いてくれると助かるなー。「for postgres」だけだとちょっと曖昧だし、「開発者の体験と信頼性の高いSQLツールに焦点を当てている」だけじゃ、実際何ができるのかよくわかんない。
初めてこのプロジェクトに来た人がすぐに知りたいと思うのは、こんなことじゃないかな?
・どの言語のLanguage Serverなの?SQLだけ?PL/pgSQL?C extensionsの記述?
・PostgreSQL固有なのは何?PostgreSQLのSQL方言に従ってるってこと?
・データベースのスキーマを教える必要がある?データベース接続を教えるの?スキーマ定義ファイルを見せるの?
フィードバックありがとうね。良い点だね。READMEを改善するよ。
質問について答えるね。
1.今はSQLステートメントだけだけど、関数やPL/pgSQLにも対応する予定だよ。
2.その通り。PostgreSQLの方言に従ってる(Postgresのパーサーを使ってる)。
3.データベース接続を教えてもらえれば、pg_catalogテーブルから情報を取得するよ。接続情報がない場合は、それが必要な機能はバイパスするよ。
>データベース接続を教えてもらえれば、pg_catalogテーブルから情報を取得するよ。接続情報がない場合は、それが必要な機能はバイパスするよ。
手動で情報を取得して提供できるようにしてほしいな。
そうだね。でも、自分のスキーマが入った空のDBを指定すればいいだけだよ。
ブログを読まない人のために言うと、これはかなりクールだったよ。
>tree-sitterをlibpg_queryに加えて使うというアイデアは、以前のHNの投稿[0]へのフィードバックから得られたものだよ。感謝!
https://news.ycombinator.com/item?id=38570680
Language Serverって何をするもの?
Language Server Protocolは、エディタが言語ツールと通信するための標準みたいなものだよ。最近のIDEにある、リファクタリング、定義へのジャンプ、オートコンプリートなどの機能は、エディタ内でLanguage Serverへの呼び出しとして実装されてる。そしてLanguage Serverが、その機能の具体的な実装を提供するんだ。
確かMicrosoftがVS Codeを作る時に定義したんだけど、今ではVim、Emacs、Sublime Text、IntelliJとか、いろんなエディタがサポートしてるよ。LSPを通して、ほとんどのメジャーな言語で、IDEみたいな体験ができるんだ。
基本的に、どのエディタもEmacsみたいに遅くなるのがクールだと思ったんだね(愛情を込めて、Emacsユーザーとして言ってるよ)。だから今では、賢い処理はすべて、Webサーバーで実行されてて、それぞれがギガバイト単位のRAMを使ってる。
>Language Server Protocol (LSP)は、ソースコードエディタや統合開発環境 (IDE)と、「言語インテリジェンスツール」を提供するサーバー間で使用される、オープンなJSON-RPCベースのプロトコルだよ[1]: コード補完、構文ハイライト、警告とエラーのマーク、リファクタリングルーチンなどのプログラミング言語固有の機能がある。このプロトコルの目標は、プログラミング言語のサポートを、特定のエディタやIDEに依存せずに実装および配布できるようにすることだよ[2]。2020年代初頭には、LSPは言語インテリジェンスツールプロバイダーにとって「標準」になったよ[1]。
https://en.m.wikipedia.org/wiki/Language_Server_Protocol
聞いてくれてありがとね!IDEの言語に関する機能全部を支えてるんだ。オートコンプリートとか、エラー表示、シンタックスハイライトとかね。今はオートコンプリート、構文エラー表示、タイプチェック、リンティングをサポートしてるよ。
マジで楽しみ!ありがとうね。最初のテストでCTEsがあると失敗するんだけど、サポートされてないのかな?with test as (select 1 as id) select * from test;
ってクエリでエラーが出ちゃう。
報告ありがとね!見落としだったわ。修正PR出しといた。[0]
[0] https://github.com/supabase-community/postgres-language-serv…
報告ありがとう。CTEsのテストはいくつかあったんだけどね。とりあえず、そのクエリでIssueを立ててみるよ。
steinroeは仕事が早いね:
https://github.com/supabase-community/postgres-language-serv…
それはいいね!ありがとう!
>始めたのがほぼ2年前だって。
”JetBrainsがIDEにどれだけ力を入れてきたかを考えると、マジすごい。JetBrainsは人気のSQL方言をずっとサポートしてたもんね。FOSSの代替を提供してくれて感謝!今までJetBrainsに匹敵するものってなかったと思うし。
大変だったけど、Rustを学びながら2人でやったサイドプロジェクトなんだよね。フルタイムのチームならもっと早く終わってたと思うよ。
ちょっと言い過ぎじゃない?IntelliJ DB toolはまあまあだけど、特別ってほどじゃないよ。SQL Squirellだって同じくらい良いし、DB2みたいな特殊なDBの設定とかSQLの履歴管理とか、むしろ良いところもある。
Language serverってマジ最高。作ってくれてありがとう!
どういたしまして!もう一年以上、ローカルでデバッグビルドをIDEに設定してて、それが成熟していくの(クラッシュが減るって意味ね)を仕事中にゆっくり見れて、すごく良かったよ。 もしかして、将来的にフォーマット機能も入る予定ある? 間違いなく入れるよ。もちろん、ちゃんと動くって約束はできないけど、優先順位は高い方だよ。 biomeから学んだ、一番影響力があったり、目から鱗だったレッスンってどんなの? このプロジェクトでRustを学んだんだ。システムプログラミングの経験もあんまりなかったけど。普段は、動くまで色々試すのが一番だけど、language serverを作るのはかなり複雑。似たようなプロジェクトを色々読んだけど、biomeが一番理解しやすかった。アーキテクチャもまさに理想通りだったんだよね。language serverは単なるエントリーポイントの一つに過ぎない、汎用的なworkspace APIってのが。 共同開発者です。一番面白いのはSQLファイルのパースかも。Postgresのパーサーは複雑で常に変化してるから、SQLをパースする自作のパーサーは作れないんだ。しかも、そのパーサーは有効で完全なSQLステートメントしか扱えないんだけど、LSPは無効だったり不完全なものを手助けするべきだよね。簡単な解決策は、二つのパーサーを使うことなんだ。一つはPostgres自体が使ってるオリジナルのlibpg_query。もう一つはtree-sitterで不完全なステートメントを扱う。そして、パース結果をマージするんだ。 もしそれがちゃんと動くなら、これはゲームチェンジャーだね。今はSQLのlinting/autocompleteにDBeaverを使ってるんだけど、すごく良いんだ。Py/C++/Rs/Javaの文字列内のSQLステートメントのパースはどうなるんだろ?例えば、複数行の文字列を使って、VS Codeが、その行がSQLの複数行文字列の中かどうかで、別のlanguage serverを使うとか?そうすれば、コード内の文字列内のSQLステートメントを静的にチェックしたり、オートコンプリートできる。 まだちょっと粗削りだけど、コミュニティからのバグレポートに基づいて改善していきたいと思ってるよ!埋め込みSQLについては、エディター側で解決する必要があるよね。vscodeでは、リクエスト転送で可能になるはず。neovimにはotter.nvimみたいなプラグインがあるし。少なくともjsについては、workspace APIで直接サポートする予定だよ。postgrestools check file.tsで埋め込みSQLの診断を出力するようにね。これは、oxcを使ってjs/tsコードをRustで簡単にパースできるから実現可能になったんだ。他の言語で似たようなツールを知ってる? これってTypescript Language Serverのプラグインとして動く?SvelteとかVueとかは、Typescriptをテンプレートファイル内で使えるようにするために似たようなことしてるよね。もしPostgres Language Serverを自分のコードベース内で使えるようになったら、ゲームチェンジャーになると思う。 色々調べてみたんだけど、これらのツールは全部、tsserver内でTypescriptのlanguage serviceをプラグインとして実行してるみたい。つまり、隣で実行してるlanguage serverとは通信しないんだ。今のところ、考えてるのは、a. wasmビルドを動かして、tsserverプラグインを試してみる、b. oxcでコードをパースして、少なくともCLIでTypescriptの埋め込みSQLをサポートすること。 これマジすごいね!誰か、SQLXみたいなツールと連携して、Rustの中でSQL書くときに型ヒント出せるか知ってる人いる?PythonのスクリプトでSQL書くときも動くとマジで最高じゃん? Python 3.14でPEP−750のt−stringsが追加されるかもね。そうなると、こういうLSP連携がもっと現実的になるかも。https://discuss.python.org/t/pep750−template−strings−new−upd… TypeScriptで同じこと考えてるよ。最初はtsserverのプラグインでいけるかと思ったけど、他の言語サーバー呼べないみたい。VSCodeならrequest forwardingでできるかも[0]。neovimにはotter.nvimみたいなプラグインがある[1]。JS向けには、 >このプロジェクトはPostgres開発用のツールチェーンを提供してるってあるけど、この文脈での“Postgres開発”って何のこと?ストアドプロシージャ書く人向け?それとも、LSPサポートが必要な大規模で複雑なクエリ書く人向け?どういうユースケースがあるのか気になる。 いい質問だね。DBをあんまり変えないなら、そんなに役立たないかも。でも、SupabaseみたいなプラットフォームはPostgresのいろんな部分に依存してるんだ。INSERTフックでキューをトリガーしたり、Row Level Security (RLS)でデータを保護したり、SQL関数で集計クエリしたり。それに、ビジネスに合わせてスキーマも変えるし。普通はSQLのmigrationファイルに書くよね。LSPがないと、今のスキーマとか関数の状態を調べたり、エラーがないかmigrationを実行したりしないといけない。LSPがあれば、それが簡単になる。steinroeと自分は、普段の仕事(whatsappのニュースレターとfintechスタートアップ)でmigrationをたくさん使ってるよ。 いいね!週末にチェックしてみる。 これクールだけど、自分は.sqlファイルにSQL書くことあんまりないんだよね。Golangのlib/pqとか、Rustのsqlxとか使って、.goとか.rsファイルに生のSQL書くことが多い。こういうワークフローもサポートする予定ある? Jetbrainsが一番すごいと思う。クエリを解析するだけじゃなくて、ソースを与えれば実際のテーブルと照合してくれる。コードの中のSQL文字列でもできるのがクレイジー。 コードの中だけじゃなくて、コメントとかJSON Schemaを受け入れるところならどこでもできるよ。例えば、 こういうものがあるのは嬉しいね! IntelliJめっちゃ良いよ。VS Codeで色々試したけど全然かなわないって感じ。 何を探してるのかよくわかんないけど、PostgresのGUIが欲しいならMacのPosticoがマジで最高。オートコンプリートも良いし、UIも直感的で使いやすい。ネイティブアプリだからめっちゃ速いしね。Webアプリみたいな紛い物とは違うってこと。Javaみたいな静的型付け言語でPostgresサーバーとやり取りしたいなら、Jooqをチェックしてみて。前使ってたけど、Javaコードで型安全にPostgresデータベースにクエリを送れるようになるよ。 ブログにも書いたんだけど、Postgresの構文ってどんどん進化するし、めっちゃ冗長なんだよね。Postgresのコードをちゃんと解析するのってマジで無理ゲー。よくあるツールはそれをやろうとして結局諦める。僕らはlibpg_queryを使ってる。これはPostgresサーバーのコードをCライブラリにしたもの。このパーサーは実行可能なSQLを解析するように作られてるから、いくつか工夫が必要だった。 試すの楽しみ!これまでも素晴らしい出来だね! まだ検討中だよ!フォーマッターじゃなくて、プリティプリンターみたいな感じになると思う。つまり、有効なコードだけを綺麗にするってこと。でも、それにはもっと労力がかかるから、まずは安定した基盤を作ることに集中したいんだ。 PL/pgSQLのコードベースをマイグレーションファイルで管理するのに苦労してる人へ。これはマジで革命だよ。 似たようなツールで、Tuskerも役に立つよ。これは宣言的なスキーマを比較して、マイグレーションを自動生成してくれるんだ。実行中のPostgresインスタンスに接続して比較することもできるから、複数のインスタンスを同期できる。マイグレーションを実行するものは別に必要だけど、生成は完全に自動化される。 HNで自分のプロジェクトが紹介されてて嬉しい!誰かの役に立ってるみたいで良かった。 マジですごいね!宣言的なスキーマ管理もやりたいことリストの上位にあるし、このプロジェクトの一部になるかも。教えてくれてありがとう。チェックしてみるよ。 monaco-editorを使って、ブラウザ内で動作させる方法はある?もしそうなら、何か例とかおすすめはありますか? Monaco使ったことないんだけど、Language Serverをリモートで動かして、エディタからLanguage Server Protocolで接続できるはずだよ。今はまだブラウザ内でサーバーを動かせるwasmビルドは提供してないんだけど、色々試してる感じ。 開発が進んでるのを見るの嬉しいね。もっとコメントを表示(1)
そうすれば、診断用の実用的なASTと、オートコンプリート用のtree-sitterのCSTの両方が手に入る。
それについてどう思う?理想的な世界では、全てが静的にチェック可能であるべきだ。潜在的なエラーは、実行前にキャッチされるべきだ。多くの型安全な言語ではこれが可能だ。SQLでは、このlanguage serverのおかげでこれが可能になった。しかし、SQLがコードに埋め込まれている場合はどうなる?postgrestools check file.ts
で埋め込みSQLの診断が出せるようにする予定。
# 例だけど、IJはこれがSQLだってわかってるはず
spring:
datasource:
hikari:
# language=sql
connection−test−query:
SELECT count(1) FROM my_table
あと、SQLっぽくないリテラルでも。
#!/usr/bin/env python
# language=sql
MY_AWESOME_QUERY = ”””
WITH awesome AS (
−− ...
) SELECT * FROM awesome
”””
なんで今までPostgresの良いIDE体験がなかったんだろう?言い換えると、これを作る上で一番大変だったことは何?
静的型付け言語で慣れてるものに全然及ばないんだよね。Postgresみたいに厳密なら、もっと良いオートコンプリートがあってもいいと思うんだけどな。もっとコメントを表示(2)
prettierみたいなフォーマット機能も検討されてるって聞いたけど、まだ可能性ある?(ストアドプロシージャを理解できるフォーマッターが見つからないんだけど、存在するのかな?)
https://github.com/t1mmen/srtd
https://github.com/bikeshedder/tusker