• R/O
  • HTTP
  • SSH
  • HTTPS

提交

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

firtst release


Commit MetaInfo

修訂52d9acd38b91e8fe6b1b76bde5f1d591780fe279 (tree)
時間2020-02-17 14:55:03
作者Kyotaro Horiguchi <horikyota.ntt@gmai...>
CommiterKyotaro Horiguchi

Log Message

Fix Rows hint parsing

This is a long standing bug that Rows hint with no parameter causees a
crash. Fixed the Rows hint parser.

Change Summary

差異

--- a/expected/pg_hint_plan.out
+++ b/expected/pg_hint_plan.out
@@ -275,6 +275,21 @@ Set(work_mem TO 1MB)
275275 -> Index Scan using t2_pkey on t2
276276 (4 rows)
277277
278+/*+SeqScan() */ SELECT 1;
279+INFO: pg_hint_plan: hint syntax error at or near " "
280+DETAIL: SeqScan hint requires a relation.
281+LOG: pg_hint_plan:
282+used hint:
283+not used hint:
284+duplication hint:
285+error hint:
286+SeqScan()
287+
288+ ?column?
289+----------
290+ 1
291+(1 row)
292+
278293 /*+SeqScan(t1 t2)*/
279294 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id;
280295 INFO: pg_hint_plan: hint syntax error at or near ""
@@ -444,6 +459,36 @@ error hint:
444459 Index Cond: (id = t1.id)
445460 (5 rows)
446461
462+/*+ NestLoop() */ SELECT 1;
463+INFO: pg_hint_plan: hint syntax error at or near " "
464+DETAIL: NestLoop hint requires at least two relations.
465+LOG: pg_hint_plan:
466+used hint:
467+not used hint:
468+duplication hint:
469+error hint:
470+NestLoop()
471+
472+ ?column?
473+----------
474+ 1
475+(1 row)
476+
477+/*+ NestLoop(x) */ SELECT 1;
478+INFO: pg_hint_plan: hint syntax error at or near " "
479+DETAIL: NestLoop hint requires at least two relations.
480+LOG: pg_hint_plan:
481+used hint:
482+not used hint:
483+duplication hint:
484+error hint:
485+NestLoop(x)
486+
487+ ?column?
488+----------
489+ 1
490+(1 row)
491+
447492 /*+HashJoin(t1 t2)*/
448493 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id;
449494 LOG: pg_hint_plan:
@@ -8751,6 +8796,37 @@ error hint:
87518796 -- Explain result includes "Planning time" if COSTS is enabled, but
87528797 -- this test needs it enabled for get rows count. So do tests via psql
87538798 -- and grep -v the mutable line.
8799+-- Parse error check
8800+/*+ Rows() */ SELECT 1;
8801+INFO: pg_hint_plan: hint syntax error at or near " "
8802+DETAIL: Rows hint needs at least one relation followed by one correction term.
8803+LOG: pg_hint_plan:
8804+used hint:
8805+not used hint:
8806+duplication hint:
8807+error hint:
8808+Rows()
8809+
8810+ ?column?
8811+----------
8812+ 1
8813+(1 row)
8814+
8815+/*+ Rows(x) */ SELECT 1;
8816+INFO: pg_hint_plan: hint syntax error at or near " "
8817+DETAIL: Rows hint needs at least one relation followed by one correction term.
8818+LOG: pg_hint_plan:
8819+used hint:
8820+not used hint:
8821+duplication hint:
8822+error hint:
8823+Rows()
8824+
8825+ ?column?
8826+----------
8827+ 1
8828+(1 row)
8829+
87548830 -- value types
87558831 \o results/pg_hint_plan.tmpout
87568832 EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id);
--- a/pg_hint_plan.c
+++ b/pg_hint_plan.c
@@ -1067,7 +1067,8 @@ RowsHintDesc(RowsHint *hint, StringInfo buf, bool nolf)
10671067 quote_value(buf, hint->relnames[i]);
10681068 }
10691069 }
1070- appendStringInfo(buf, " %s", hint->rows_str);
1070+ if (hint->rows_str != NULL)
1071+ appendStringInfo(buf, " %s", hint->rows_str);
10711072 appendStringInfoString(buf, ")");
10721073 if (!nolf)
10731074 appendStringInfoChar(buf, '\n');
@@ -2241,6 +2242,8 @@ RowsHintParse(RowsHint *hint, HintState *hstate, Query *parse,
22412242 List *name_list = NIL;
22422243 char *rows_str;
22432244 char *end_ptr;
2245+ ListCell *l;
2246+ int i = 0;
22442247
22452248 if ((str = parse_parentheses(str, &name_list, hint_keyword)) == NULL)
22462249 return NULL;
@@ -2248,23 +2251,28 @@ RowsHintParse(RowsHint *hint, HintState *hstate, Query *parse,
22482251 /* Last element must be rows specification */
22492252 hint->nrels = list_length(name_list) - 1;
22502253
2251- if (hint->nrels > 0)
2254+ if (hint->nrels < 1)
22522255 {
2253- ListCell *l;
2254- int i = 0;
2256+ hint_ereport(str,
2257+ ("%s hint needs at least one relation followed by one correction term.",
2258+ hint->base.keyword));
2259+ hint->base.state = HINT_STATE_ERROR;
22552260
2256- /*
2257- * Transform relation names from list to array to sort them with qsort
2258- * after.
2259- */
2260- hint->relnames = palloc(sizeof(char *) * hint->nrels);
2261- foreach (l, name_list)
2262- {
2263- if (hint->nrels <= i)
2264- break;
2265- hint->relnames[i] = lfirst(l);
2266- i++;
2267- }
2261+ return str;
2262+ }
2263+
2264+
2265+ /*
2266+ * Transform relation names from list to array to sort them with qsort
2267+ * after.
2268+ */
2269+ hint->relnames = palloc(sizeof(char *) * hint->nrels);
2270+ foreach (l, name_list)
2271+ {
2272+ if (hint->nrels <= i)
2273+ break;
2274+ hint->relnames[i] = lfirst(l);
2275+ i++;
22682276 }
22692277
22702278 /* Retieve rows estimation */
--- a/sql/pg_hint_plan.sql
+++ b/sql/pg_hint_plan.sql
@@ -51,6 +51,7 @@ EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id;
5151 /*+Set(work_mem TO "1MB")*/
5252 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id;
5353
54+/*+SeqScan() */ SELECT 1;
5455 /*+SeqScan(t1 t2)*/
5556 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id;
5657 /*+SeqScan(t1)*/
@@ -71,6 +72,8 @@ EXPLAIN (COSTS false) SELECT * FROM t3, t4 WHERE t3.id = t4.id AND t4.ctid = '(1
7172 /*+NoTidScan(t1)*/
7273 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)';
7374
75+/*+ NestLoop() */ SELECT 1;
76+/*+ NestLoop(x) */ SELECT 1;
7477 /*+HashJoin(t1 t2)*/
7578 EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id;
7679 /*+NestLoop(t1 t2)*/
@@ -1044,6 +1047,10 @@ SELECT val::int FROM p2 WHERE id < 1000;
10441047 -- this test needs it enabled for get rows count. So do tests via psql
10451048 -- and grep -v the mutable line.
10461049
1050+-- Parse error check
1051+/*+ Rows() */ SELECT 1;
1052+/*+ Rows(x) */ SELECT 1;
1053+
10471054 -- value types
10481055 \o results/pg_hint_plan.tmpout
10491056 EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id);