PostgreSQLメモ: UPDATE a SET x = x;はno-opではない。PostgreSQLの行には最後に書き換えたトランザクションのIDなどが記録されていて、x = xでも行の新しいバージョンが作られる。
とすると、UPDATE a SET x = foo;とするより、UPDATE a SET x = NOT x WHERE x <> foo;の方が速い? (NOT NULLの場合)
こういうAndroidタブレットが欲しい、というのをFreeCADとBlenderの練習を兼ねて描いてみた。アイデアスケッチはInkscape。Braunのラジオみたいな雰囲気にしたかったけどいきなりは難しかった。スピーカーグリルはPythonで作った。
https://www.tatapa.org/~takuo/speakers/speakers.svg
最初はラジカセのカセット部分にタブレットがあるようなものを考えてた。持ち手は欲しい。音ゲーとかしたいので普通のAndroidが動く。上にラジカセっぽい電源ボタンと音量ボタンがある。横にType-Cソケットがある。ただ、スピーカーグリルが圧迫感があった。
そこで、横から見たときに正方形になるようにして、横にスピーカーを付けてみる。イヤホンジャックも付ける。音ゲー用に背面を下にしても置けるようにして、そのとき少し角度が付くように背面上部に円柱を半分にしたような足を横に付けてみる。背面にはパッシブラジエータがあり、またあくまでタブレットなので背面カメラもある。
横から見たとき正方形なのは使いにくいかと思い、画面をななめにして、その代わり背面を下にはできないようにしてみる。上の持ち手に指をひっかけて手持ちでも使えるとよいと思うが、ちょっと苦しいかも。
横のスピーカーは剥き出しか、グリルを付けるか。



で、それをFreeCADで作ってBlenderでレンダリングしてみる。本体はポリカーボネートのMacっぽい質感。スケッチと比べるとだぼっとした感じ。
InkscapeとFreeCADとBlender使ってると操作方法がごちゃごちゃになる。
CADのtopological naming problem (操作により面の分割の仕方が変わると面に対する参照が壊れる)についてよく知らずに操作してたらめちゃくちゃになって、その度に手作業で修正してた。
CADやると身の周りの工業製品がブール演算とフィレット/面取りの塊に見える。
今見直してみると、ハンドルの側面のフィレットが抜けていた。
PostgreSQLバッドノウハウメモ: PostgreSQLではレコードの位置を表すctidという列が全てのテーブルにあるが、DELETE FROM foo WHERE ctid IN (複雑なクエリ)とかしても最適化してくれない。ctidでソートしてマージジョインとかになる。素直にプライマリキーを使う必要がある。
PostgreSQLメモ: PostgreSQLでは、`statement_timestamp()`はロックを取得する前の時刻が返ってくる。正確にはクライアントからのコマンドメッセージの到着時刻と定められている。
https://www.postgresql.org/docs/16/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
`clock_timestamp()`は、`INSERT INTO test (t) VALUES (clock_timestamp());`などとした場合はロックを取得した後の時刻が返ってくるけど、保障はされていないっぽい。
やりたいのは前回のバッチ処理より後に作成されたレコードを取得して処理することで、`LOCK foo IN SHARE MODE`とすれば「現在書き込み途中のトランザクション」が終わるまで待って処理を開始できる。しかし、それだと「トランザクションは開始したがまだ書き込み始めていない」トランザクションは漏れてしまう。
バッチごとに増えるカウンタを用意して、その値を各行に入れてもらう: バッチのために余分な列と処理が増える。
レコード書き込み側も協力して事前に別のロックを別のステートメントで明示的あるいは暗黙のうちに取るようにする: バッチのために余計な処理が必要になる。忘れられがち。
一定時間より前のレコードだけ処理対象にする: 現実的だけどきれいじゃないし、バッチに反映されるまで時間がかかる。
PostgreSQLにはトランザクションのコミット時刻をとる関数があり、また、テーブルの各行には書き込んだトランザクションのIDが記録されている。しかしトランザクションのコミット時刻は一時的に保存されているものなので、インデックスに使えないはず。
https://www.postgresql.org/docs/16/functions-info.html#FUNCTIONS-COMMIT-TIMESTAMP
https://www.postgresql.org/docs/16/ddl-system-columns.html
https://www.postgresql.org/docs/16/runtime-config-replication.html#GUC-TRACK-COMMIT-TIMESTAMP
PostgreSQLメモ: PostgreSQLでは、`statement_timestamp()`はロックを取得する前の時刻が返ってくる。正確にはクライアントからのコマンドメッセージの到着時刻と定められている。
https://www.postgresql.org/docs/16/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
`clock_timestamp()`は、`INSERT INTO test (t) VALUES (clock_timestamp());`などとした場合はロックを取得した後の時刻が返ってくるけど、保障はされていないっぽい。
やりたいのは前回のバッチ処理より後に作成されたレコードを取得して処理することで、`LOCK foo IN SHARE MODE`とすれば「現在書き込み途中のトランザクション」が終わるまで待って処理を開始できる。しかし、それだと「トランザクションは開始したがまだ書き込み始めていない」トランザクションは漏れてしまう。
バッチごとに増えるカウンタを用意して、その値を各行に入れてもらう: バッチのために余分な列と処理が増える。
レコード書き込み側も協力して事前に別のロックを別のステートメントで明示的あるいは暗黙のうちに取るようにする: バッチのために余計な処理が必要になる。忘れられがち。
一定時間より前のレコードだけ処理対象にする: 現実的だけどきれいじゃないし、バッチに反映されるまで時間がかかる。
PostgreSQLではプライマリキーで一部の列だけ降順にするのはできないらしい。普通のインデックスならできる。
今回はクエリ側のORDER BYですべての列を降順に指定してIndex Scan Backwardにできたけど、常にできるわけじゃないので不便。
普通のLinuxコマンドでファイル中の文字列を置換したいとき、置換後の文字列が不定(任意の文字を含み得る)のときってどうするのがいいんだろう。
jqありなら以下で行ける。
jq --raw-input --raw-output --arg x "$STR" 'gsub("foo", $x)' foo.txt > result.txt
短く書くと以下のようになる。
jq -Rr --arg x "$STR" 'gsub("foo", $x)' foo.txt > result.txt
AWKでawk -v FS=foo -v OFS="$STR" '{$1 = $1; print}'だとOFS内のバックスラッシュが解釈されてしまう。
cutのデリミタは1文字である必要がある。
Majestouch Xacro M10SP気になったけど、左右スペースキーにAltなどを割り当てるとかはできないっぽい。
Issue立ててみた。日本語で良かったんだろうか。
Tsurugi (劔)よくわからない。LTXの仕様がドキュメント化されていなくて(解説本には書いてあるかも)、それっぽいコードを実行したら普通にwrite skewが起きた。使い方が悪いのかもしれない。
次のSQLを実行した場合、serializableでないのでどちらかはCOMMITできないはずだけど、なぜかコミットできる。
```sql
-- 準備
CREATE TABLE test (
id int PRIMARY KEY,
value int NOT NULL
);
INSERT INTO test (id, value) VALUES (1, 1);
COMMIT;
-- transaction 1
BEGIN LONG TRANSACTION WRITE PRESERVE test;
-- 本来は
-- INSERT INTO test (id, value) VALUES (2, SELECT SUM(VALUE) + 1 FROM test);
-- と書きたいが、まだサポートされていないので、クライアント側でSELECT結果をINSERTに渡しているものとする。
SELECT SUM(value) + 1 FROM test;
INSERT INTO test (id, value) VALUES (2, 2);
-- transaction 2 (別の接続で実行する)
BEGIN LONG TRANSACTION WRITE PRESERVE test;
SELECT SUM(value) + 1 FROM test;
INSERT INTO test (id, value) VALUES (3, 2);
-- transaction 1に戻る
COMMIT;
-- transaction 2に戻る
COMMIT;
```
バッドノウハウメモ:
GPT-4のGPTの後はU+002D HYPHEN-MINUS。
DALL·E 3のDALLの後はU+00B7 MIDDLE DOT。
今日のミス: curlで--cookie-jarは付けたけど--cookieはつけ忘れた。
今日のミス:
for f in *.json ; do ./hoge.rb "$f" > tmp.json && mv -f tmp.json "$f" ; done
ってやってhoge.rbにバグがあって止まったので、直してもう一回やったらtmp.jsonも処理対象になってエラーになった。
Bing Chat、SVG出力とかはなさそう? と思って「このページのデータをグラフにしてください」的なことを言ったらDALL-Eで棒グラフっぽい絵を出してきた。なるほどー。
ディストピアなSNSに欲しい機能
・過去のポストも勝手に書き換わる。
・プレミアムユーザは他ユーザの生ポストを見られる。
・プレミアムユーザは他ユーザのポストを書き換えられる。
・エンド・トゥ・エンド暗号化を謳うDM機能がある(検閲されている)。
・運営者とされる人物の実在が怪しい。
・運営者がある日突然理由になっていない理由で変わる。
・一般ユーザは機能が制限されているが、あるアカウントに暗号通貨を送ると格安で一部機能が使えるようになる。
・相手がボットかどうか判定するプログラムも買えるが、精度は低い。
・突然皆がコカコーラを褒めるポストをするし、1ヶ月後にはそのポストは全てペプシコーラに書き換わっている。
・ある日突然長時間のサービス停止があるが、なんのアナウンスもなく再開する。ポストが何割か失われている。
・サービス停止中に犯行声明を見たという噂が流れる。あわせて「生ポストを見る方法」とされる情報が出回るが、使っても何も起きない。
Codeium Chatで特定の関数を見て欲しいときは、関数名 (ファイル名)とすると良いっぽい。
『詳説データベース』で紹介されていたページ: https://lwn.net/Articles/752063/
Linuxのfsyncはページのフラッシュに失敗してもダーティ状態をクリアしてしまう(USBドライブが抜けた場合などにダーティなページが溜まっていくのを防ぐため)。
また、ファイルを開いていないときにカーネルがページをフラッシュしたときのエラーはfsync等で取れない。
これはPostgreSQLなど、データ書き込みプロセスとは別のfsync用プロセスがまとめてfsyncするようなアプリケーションで問題となる。
この対策として現在のPostgreSQLではカーネルのページキャッシュを使わずにdirect I/Oを使って自前でキャッシュを管理している。
コーディングAIはPythonとかJavaScript/TypeScriptのサポートが厚いけど、本当に求められているのはCOBOLの読み書きなんじゃないだろうか。Excelで書かれた仕様書と連携してCOBOLを読み書きしたりJavaに変換したりして、Excel資料を更新してくれたら嬉しい人はいそう。