• R/O
  • HTTP
  • SSH
  • HTTPS

pg_hint_plan: Commit

firtst release


Commit MetaInfo

Revision9e2f8b6127c0f0cf9204529b2e83d967876f0ae1 (tree)
Time2022-01-18 17:40:35
AuthorDaniil Anisimov <anisimow.d@gmai...>
CommiterKyotaro Horiguchi

Log Message

Allow hints to be placed anywhere in query

Hints description is restriected to be placed before certain
characters. That is effectively at the beginning of a query, or after
EXPLAIN or PREPARE. This commit adds a new setting parameter
pg_hint_plan.hints_anywhere, which gets rid of that restriction. When
it is on, pg_hint_plan ignores SQL syntax at all while reading hints
so there's no restricion on where hint string is placed in a query
string. On the other hand it may lead to false reads from a non-hint
strings.

Change Summary

Incremental Difference

--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,9 @@
77 MODULES = pg_hint_plan
88 HINTPLANVER = 1.4
99
10-REGRESS = init base_plan pg_hint_plan ut-init ut-A ut-S ut-J ut-L ut-G ut-R ut-fdw ut-W ut-T ut-fini
10+REGRESS = init base_plan pg_hint_plan ut-init ut-A ut-S ut-J ut-L ut-G ut-R ut-fdw ut-W ut-T ut-fini hints_anywhere
1111
12-REGRESSION_EXPECTED = expected/init.out expected/base_plan.out expected/pg_hint_plan.out expected/ut-A.out expected/ut-S.out expected/ut-J.out expected/ut-L.out expected/ut-G.out
12+#REGRESSION_EXPECTED = expected/init.out expected/base_plan.out expected/pg_hint_plan.out expected/ut-A.out expected/ut-S.out expected/ut-J.out expected/ut-L.out expected/ut-G.out expected/hints_anywhere.out
1313
1414 REGRESS_OPTS = --encoding=UTF8
1515
--- a/doc/pg_hint_plan-ja.html
+++ b/doc/pg_hint_plan-ja.html
@@ -368,6 +368,8 @@ EXPLAIN SELECT * FROM a, b WHERE a.val = b.val;
368368 <td>動作状況を示すログメッセージの出力を制御します。指定可能な値は off, on, verbose, detailed です。</td><td>off</td></tr>
369369 <tr><td>pg_hint_plan.message_level</td>
370370 <td>動作ログメッセージのログレベルを指定します。有効な値は、debug5、debug4、debug3、debug2、debug1、log、info、notice、warning、またはerrorです。</td><td>LOG</td></tr>
371+<tr><td>pg_hint_plan.hints_anywhere</td>
372+ <td>On の場合、pg_hint_planはSQL構文を無視してヒント文字列の読み取りを行います。この設定ではヒントをSQL文のどこにでも記述することができますが、意図しない文字列がヒントととして読み取られる可能性がある点に注意してください。</td><td>off</td></tr>
371373
372374 </tbody>
373375 </table>
--- a/doc/pg_hint_plan.html
+++ b/doc/pg_hint_plan.html
@@ -240,6 +240,8 @@ postgres-# SELECT * FROM table1 t1 WHERE key = 'value';
240240 <td>Controls debug print and verbosity. Valid values are off, on, detailed and verbose.</td><td>off</td></tr>
241241 <tr><td>pg_hint_plan.message_level</td>
242242 <td>Specifies message level of debug print. Valid values are error, warning, notice, info, log, debug<n>.</td><td>LOG</td></tr>
243+<tr><td>pg_hint_plan.hints_anywhere</td>
244+ <td>If it is on, pg_hint_plan reads hints ignoring SQL syntax. This allows to hints to be placed anywhere in a query but be cautious of false reads.</td><td>off</td></tr>
243245 </tbody>
244246 </table>
245247 <h2 id="install">Installation</h2>
--- a/pg_hint_plan.c
+++ b/pg_hint_plan.c
@@ -530,6 +530,7 @@ static int pg_hint_plan_parse_message_level = INFO;
530530 static int pg_hint_plan_debug_message_level = LOG;
531531 /* Default is off, to keep backward compatibility. */
532532 static bool pg_hint_plan_enable_hint_table = false;
533+static bool pg_hint_plan_hints_anywhere = false;
533534
534535 static int plpgsql_recurse_level = 0; /* PLpgSQL recursion level */
535536 static int recurse_level = 0; /* recursion level incl. direct SPI calls */
@@ -701,6 +702,17 @@ _PG_init(void)
701702 assign_enable_hint_table,
702703 NULL);
703704
705+ DefineCustomBoolVariable("pg_hint_plan.hints_anywhere",
706+ "Read hints from anywhere in a query.",
707+ "This option lets pg_hint_plan ignore syntax so be cautious for false reads.",
708+ &pg_hint_plan_hints_anywhere,
709+ false,
710+ PGC_USERSET,
711+ 0,
712+ NULL,
713+ NULL,
714+ NULL);
715+
704716 EmitWarningsOnPlaceholders("pg_hint_plan");
705717
706718 /* Install hooks. */
@@ -1881,33 +1893,35 @@ get_hints_from_comment(const char *p)
18811893 hint_head = strstr(p, HINT_START);
18821894 if (hint_head == NULL)
18831895 return NULL;
1884- for (;p < hint_head; p++)
1896+ if (!pg_hint_plan_hints_anywhere)
18851897 {
1886- /*
1887- * Allow these characters precedes hint comment:
1888- * - digits
1889- * - alphabets which are in ASCII range
1890- * - space, tabs and new-lines
1891- * - underscores, for identifier
1892- * - commas, for SELECT clause, EXPLAIN and PREPARE
1893- * - parentheses, for EXPLAIN and PREPARE
1894- *
1895- * Note that we don't use isalpha() nor isalnum() in ctype.h here to
1896- * avoid behavior which depends on locale setting.
1897- */
1898- if (!(*p >= '0' && *p <= '9') &&
1899- !(*p >= 'A' && *p <= 'Z') &&
1900- !(*p >= 'a' && *p <= 'z') &&
1901- !isspace(*p) &&
1902- *p != '_' &&
1903- *p != ',' &&
1904- *p != '(' && *p != ')')
1905- return NULL;
1898+ for (;p < hint_head; p++)
1899+ {
1900+ /*
1901+ * Allow these characters precedes hint comment:
1902+ * - digits
1903+ * - alphabets which are in ASCII range
1904+ * - space, tabs and new-lines
1905+ * - underscores, for identifier
1906+ * - commas, for SELECT clause, EXPLAIN and PREPARE
1907+ * - parentheses, for EXPLAIN and PREPARE
1908+ *
1909+ * Note that we don't use isalpha() nor isalnum() in ctype.h here to
1910+ * avoid behavior which depends on locale setting.
1911+ */
1912+ if (!(*p >= '0' && *p <= '9') &&
1913+ !(*p >= 'A' && *p <= 'Z') &&
1914+ !(*p >= 'a' && *p <= 'z') &&
1915+ !isspace(*p) &&
1916+ *p != '_' &&
1917+ *p != ',' &&
1918+ *p != '(' && *p != ')')
1919+ return NULL;
1920+ }
19061921 }
19071922
1908- len = strlen(HINT_START);
1909- head = (char *) p;
1910- p += len;
1923+ head = (char *)hint_head;
1924+ p = head + strlen(HINT_START);
19111925 skip_space(p);
19121926
19131927 /* find hint end keyword. */
Show on old repository browser