OSDN Git Service

使用しないJoin方式が指定可能となる機能を追加した。(no_* ヒント)
authorMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Thu, 23 Feb 2012 03:28:25 +0000 (12:28 +0900)
committerMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Thu, 23 Feb 2012 03:28:25 +0000 (12:28 +0900)
expected/pg_hint_plan.out
pg_hint_plan.c

index ae9bd47..8e5b61a 100644 (file)
@@ -248,21 +248,25 @@ EXPLAIN SELECT * FROM t1, t2, t3, t4 WHERE t1.val1 = t2.val1 AND t2.val1 = t3.va
 (12 rows)
 
 SELECT pg_add_hint('no_merge(' || :t1_oid || ',' || :t2_oid || ')');
-ERROR:  Parse Error
+ pg_add_hint 
+-------------
+           1
+(1 row)
+
 EXPLAIN SELECT * FROM t1, t2, t3, t4 WHERE t1.val1 = t2.val1 AND t2.val1 = t3.val1 AND t3.val1 = t4.val1;
                                         QUERY PLAN                                        
 ------------------------------------------------------------------------------------------
- Nested Loop  (cost=1.27..1.70 rows=1 width=32)
-   ->  Merge Join  (cost=1.27..1.42 rows=1 width=24)
+ Nested Loop  (cost=1.27..1.80 rows=1 width=32)
+   ->  Merge Join  (cost=1.27..1.51 rows=1 width=24)
          Merge Cond: (t1.val1 = t4.val1)
-         ->  Merge Join  (cost=0.00..90.08 rows=1000 width=16)
-               Merge Cond: (t1.val1 = t2.val1)
+         ->  Merge Join  (cost=0.00..18.43 rows=100 width=16)
+               Merge Cond: (t1.val1 = t3.val1)
                ->  Index Scan using t1_val1 on t1  (cost=0.00..318.26 rows=10000 width=8)
-               ->  Index Scan using t2_val1 on t2  (cost=0.00..43.25 rows=1000 width=8)
+               ->  Index Scan using t3_val1 on t3  (cost=0.00..13.75 rows=100 width=8)
          ->  Sort  (cost=1.27..1.29 rows=10 width=8)
                Sort Key: t4.val1
                ->  Seq Scan on t4  (cost=0.00..1.10 rows=10 width=8)
-   ->  Index Scan using t3_val1 on t3  (cost=0.00..0.27 rows=1 width=8)
+   ->  Index Scan using t2_val1 on t2  (cost=0.00..0.27 rows=1 width=8)
          Index Cond: (val1 = t1.val1)
 (12 rows)
 
@@ -284,40 +288,50 @@ EXPLAIN SELECT * FROM t1, t2, t3, t4 WHERE t1.val1 = t2.val1 AND t2.val1 = t3.va
 (11 rows)
 
 SELECT pg_add_hint('no_hash(' || :t3_oid || ',' || :t4_oid || ')');
-ERROR:  Parse Error
+ pg_add_hint 
+-------------
+           1
+(1 row)
+
 EXPLAIN SELECT * FROM t1, t2, t3, t4 WHERE t1.val1 = t2.val1 AND t2.val1 = t3.val1 AND t3.val1 = t4.val1;
-                                  QUERY PLAN                                  
-------------------------------------------------------------------------------
- Nested Loop  (cost=1.23..11.11 rows=1 width=32)
-   ->  Nested Loop  (cost=1.23..10.52 rows=1 width=24)
-         ->  Hash Join  (cost=1.23..3.70 rows=10 width=16)
-               Hash Cond: (t3.val1 = t4.val1)
-               ->  Seq Scan on t3  (cost=0.00..2.00 rows=100 width=8)
-               ->  Hash  (cost=1.10..1.10 rows=10 width=8)
+                                      QUERY PLAN                                       
+---------------------------------------------------------------------------------------
+ Nested Loop  (cost=1.27..10.09 rows=1 width=32)
+   ->  Nested Loop  (cost=1.27..9.50 rows=1 width=24)
+         ->  Merge Join  (cost=1.27..2.68 rows=10 width=16)
+               Merge Cond: (t3.val1 = t4.val1)
+               ->  Index Scan using t3_val1 on t3  (cost=0.00..13.75 rows=100 width=8)
+               ->  Sort  (cost=1.27..1.29 rows=10 width=8)
+                     Sort Key: t4.val1
                      ->  Seq Scan on t4  (cost=0.00..1.10 rows=10 width=8)
          ->  Index Scan using t2_val1 on t2  (cost=0.00..0.67 rows=1 width=8)
                Index Cond: (val1 = t3.val1)
    ->  Index Scan using t1_val1 on t1  (cost=0.00..0.58 rows=1 width=8)
          Index Cond: (val1 = t2.val1)
-(11 rows)
+(12 rows)
 
 SELECT pg_add_hint('no_nest(' || :t2_oid || ',' || :t3_oid || ',' || :t4_oid || ')');
-ERROR:  Parse Error
+ pg_add_hint 
+-------------
+           1
+(1 row)
+
 EXPLAIN SELECT * FROM t1, t2, t3, t4 WHERE t1.val1 = t2.val1 AND t2.val1 = t3.val1 AND t3.val1 = t4.val1;
-                                  QUERY PLAN                                  
-------------------------------------------------------------------------------
- Nested Loop  (cost=1.23..11.11 rows=1 width=32)
-   ->  Nested Loop  (cost=1.23..10.52 rows=1 width=24)
-         ->  Hash Join  (cost=1.23..3.70 rows=10 width=16)
-               Hash Cond: (t3.val1 = t4.val1)
-               ->  Seq Scan on t3  (cost=0.00..2.00 rows=100 width=8)
-               ->  Hash  (cost=1.10..1.10 rows=10 width=8)
-                     ->  Seq Scan on t4  (cost=0.00..1.10 rows=10 width=8)
-         ->  Index Scan using t2_val1 on t2  (cost=0.00..0.67 rows=1 width=8)
-               Index Cond: (val1 = t3.val1)
+                                      QUERY PLAN                                       
+---------------------------------------------------------------------------------------
+ Nested Loop  (cost=1.27..2.74 rows=1 width=32)
+   ->  Merge Join  (cost=1.27..2.15 rows=1 width=24)
+         Merge Cond: (t2.val1 = t4.val1)
+         ->  Nested Loop  (cost=0.00..81.95 rows=100 width=16)
+               ->  Index Scan using t3_val1 on t3  (cost=0.00..13.75 rows=100 width=8)
+               ->  Index Scan using t2_val1 on t2  (cost=0.00..0.67 rows=1 width=8)
+                     Index Cond: (val1 = t3.val1)
+         ->  Sort  (cost=1.27..1.29 rows=10 width=8)
+               Sort Key: t4.val1
+               ->  Seq Scan on t4  (cost=0.00..1.10 rows=10 width=8)
    ->  Index Scan using t1_val1 on t1  (cost=0.00..0.58 rows=1 width=8)
          Index Cond: (val1 = t2.val1)
-(11 rows)
+(12 rows)
 
 SELECT pg_clear_hint();
  pg_clear_hint 
index c72352e..b2394fe 100644 (file)
@@ -449,13 +449,19 @@ static int parse_phrase(HashEntry **head, char **str)
        HashEntry *ent = NULL;
        char *p0;
        int len;
+       bool    not_use = false;
 
        p0 = *str;
-       while (isalpha(**str)) (*str)++;
+       while (isalpha(**str) || **str == '_') (*str)++;
        len = *str - p0;
        if (**str != '(' || len >= 12) return 0;
        strncpy(req, p0, len);
        req[len] = 0;
+       if (strncmp("no_", req, 3) == 0)
+       {
+               not_use = true;
+               memmove(req, req + 3, len - 3 + 1);
+       }
        for (cmd = 0 ; cmds[cmd] && strcmp(cmds[cmd], req) ; cmd++);
        if (cmds[cmd] == NULL) return 0;
        (*str)++;
@@ -463,7 +469,7 @@ static int parse_phrase(HashEntry **head, char **str)
        if (*(*str)++ != ')') return 0;
        if (**str != 0 && **str != ';') return 0;
        if (**str == ';') (*str)++;
-       ent->enforce_mask = masks[cmd];
+       ent->enforce_mask = not_use ? ~masks[cmd] : masks[cmd];
        ent->next = NULL;
        *head = ent;