😇
4/1に間に合わなかったけどSQLite3にPLEASE句を追加するパッチを書きました
はじめに
4/1 に MySQL に please 句を入れるのが流行っていた様です。
そして各 RDBMS も追従して please 句を入れる祭が開催されていた様です。
まずは PostgreSQL
そして Oracle
完全にノリ遅れてしまいました。大失態です。
気付いたのは 4/4 の昨日です。
これは乗るしかない
既に 4/5 の午前 0 時なのですが、SQLite3 に please 句を入れるパッチを書きました。
diff --git a/src/parse.y b/src/parse.y
index b748e1917..782199fb7 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -151,6 +151,12 @@ ecmd ::= explain cmdx SEMI. {NEVER-REDUCE}
explain ::= EXPLAIN. { pParse->explain = 1; }
explain ::= EXPLAIN QUERY PLAN. { pParse->explain = 2; }
%endif SQLITE_OMIT_EXPLAIN
+cmdlist ::= cmdlist pcmd.
+cmdlist ::= pcmd.
+%ifndef SQLITE_OMIT_PLEASE
+pcmd ::= please cmdx SEMI. {NEVER-REDUCE}
+please ::= PLEASE. { pParse->please = 1; }
+%endif SQLITE_OMIT_PLEASE
cmdx ::= cmd. { sqlite3FinishCoding(pParse); }
///////////////////// Begin and end transactions. ////////////////////////////
@@ -224,7 +230,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
// at the beginning.
//
%token ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST.
-%token CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL.
+%token CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL PLEASE.
%token OR AND NOT IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
%token GT LE LT GE ESCAPE.
@@ -237,7 +243,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
CONFLICT DATABASE DEFERRED DESC DETACH DO
EACH END EXCLUSIVE EXPLAIN FAIL FOR
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
- QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
+ QUERY KEY OF OFFSET PLEASE PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
NULLS FIRST LAST
%ifdef SQLITE_OMIT_COMPOUND_SELECT
diff --git a/src/select.c b/src/select.c
index 7c84bd7d6..1a1898222 100644
--- a/src/select.c
+++ b/src/select.c
@@ -6119,6 +6119,9 @@ int sqlite3Select(
}
#endif
+ if (pParse->please == 0) {
+ sqlite3OsSleep(db->pVfs, 1000*1000);
+ }
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 783950fb0..6931cb66b 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3485,6 +3485,7 @@ struct Parse {
ynVar nVar; /* Number of '?' variables seen in the SQL so far */
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
+ u8 please; /* True if the PLEASE flag is found on the query */
u8 eParseMode; /* PARSE_MODE_XXX constant */
#ifndef SQLITE_OMIT_VIRTUALTABLE
int nVtabLock; /* Number of virtual tables to lock */
diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c
index bbb0ccf29..1909f01a0 100644
--- a/tool/mkkeywordhash.c
+++ b/tool/mkkeywordhash.c
@@ -164,6 +164,11 @@ struct Keyword {
#else
# define RETURNING 0x00400000
#endif
+#ifdef SQLITE_OMIT_PLEASE
+# define PLEASE 0
+#else
+# define PLEASE 0x00800000
+#endif
/*
@@ -273,6 +278,7 @@ static Keyword aKeywordTable[] = {
{ "OVER", "TK_OVER", WINDOWFUNC, 3 },
{ "PARTITION", "TK_PARTITION", WINDOWFUNC, 3 },
{ "PLAN", "TK_PLAN", EXPLAIN, 0 },
+ { "PLEASE", "TK_PLEASE", PLEASE, 1 },
{ "PRAGMA", "TK_PRAGMA", PRAGMA, 0 },
{ "PRECEDING", "TK_PRECEDING", WINDOWFUNC, 3 },
{ "PRIMARY", "TK_PRIMARY", ALWAYS, 1 },
SQLite3 の拡張は書いた事がありましたが、SQLite3 の本体のパーサのソースを読むのはこれが初めてだったので、まぁまぁ時間を取ってしまいました。ですが適当なパッチではなく、configure のフラグ等にも対応した、ちゃんとしたパッチに仕上げる事ができました。
実際に動かしてみる
SQLite3 のシェルには .timer on
があるのでそれを付けて実行します。まずは please を付けない場合。
中二病をこじらせて1秒遅くなります。そして please を付けて実行。
ご機嫌も直って通常のパフォーマンスが得られました。
おわりに
既に 4/5 ですが、遅れて SQLite3 も仲間に入る事ができました。良かったですね。みなさんも SQLite3 を悪魔改造して楽しんで下さい。
Discussion