From cd5f60b1fffa9161d9b2360546a94fa67c164d72 Mon Sep 17 00:00:00 2001 From: Shigeru Hanada Date: Wed, 18 Apr 2012 14:54:18 +0900 Subject: [PATCH] =?utf8?q?=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC=E4=B8=AD?= =?utf8?q?=E3=81=AB=E6=B0=97=E3=81=A5=E3=81=84=E3=81=9F=E7=82=B9=E3=81=AE?= =?utf8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= =?utf8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- pg_hint_plan.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pg_hint_plan.c b/pg_hint_plan.c index 1975648..005cb06 100644 --- a/pg_hint_plan.c +++ b/pg_hint_plan.c @@ -766,12 +766,20 @@ skip_closed_parenthesis(const char *str) return str; } +/* + * 二重引用符で囲まれているかもしれないトークンを読み取り word 引数に palloc + * で確保したバッファに格納してそのポインタを返す。 + * + * 正常にパースできた場合は残りの文字列の先頭位置を、異常があった場合は NULL を + * 返す。 + */ static const char * parse_quote_value(const char *str, char **word, char *value_type) { StringInfoData buf; bool in_quote; + /* 先頭のスペースは読み飛ばす。 */ skip_space(str); initStringInfo(&buf); @@ -783,7 +791,8 @@ parse_quote_value(const char *str, char **word, char *value_type) else { /* - * 1文字目以降の制限の適用 + * 二重引用符で囲まれていない場合は、1文字目に出現してよいのは + * アルファベットまたはアンダースコアのみ。 */ if (!isalpha(*str) && *str != '_') { @@ -800,6 +809,7 @@ parse_quote_value(const char *str, char **word, char *value_type) { if (in_quote) { + /* 二重引用符が閉じられていない場合はパース中断 */ if (*str == '\0') { pfree(buf.data); @@ -822,6 +832,8 @@ parse_quote_value(const char *str, char **word, char *value_type) { /* * 2文字目以降の制限の適用 + * 二重引用符で囲まれていない場合、二文字目以降に出現してよいのは + * 英数字、アンダースコア、ドル記号のみ。 */ if (!isalnum(*str) && *str != '_' && *str != '$') break; @@ -1014,6 +1026,9 @@ parse_head_comment(Query *parse) return plan; } +/* + * スキャン方式ヒントのパースでの共通処理 + */ static const char * parse_scan_method(PlanHint *plan, Query *parse, char *keyword, const char *str) { @@ -1022,12 +1037,18 @@ parse_scan_method(PlanHint *plan, Query *parse, char *keyword, const char *str) hint = ScanHintCreate(); hint->opt_str = str; + /* + * スキャン方式のヒントでリレーション名が読み取れない場合はヒント無効 + */ if ((str = parse_quote_value(str, &hint->relname, "ralation name")) == NULL) { ScanHintDelete(hint); return NULL; } + /* + * ヒントごとに決まっている許容スキャン方式をビットマスクとして設定 + */ if (strcasecmp(keyword, HINT_SEQSCAN) == 0) hint->enforce_mask = ENABLE_SEQSCAN; else if (strcasecmp(keyword, HINT_INDEXSCAN) == 0) @@ -1050,6 +1071,9 @@ parse_scan_method(PlanHint *plan, Query *parse, char *keyword, const char *str) return NULL; } + /* + * 出来上がったヒント情報を追加。スロットが足りない場合は二倍に拡張する。 + */ if (plan->nscan_hints == 0) { plan->max_scan_hints = HINT_ARRAY_DEFAULT_INITSIZE; -- 2.11.0