OSDN Git Service

Make HashJoin hint more coercive.
[pghintplan/pg_hint_plan.git] / pg_hint_plan.c
index 7b7f5b5..ef6d53f 100644 (file)
@@ -3,7 +3,7 @@
  * pg_hint_plan.c
  *               hinting on how to execute a query for PostgreSQL
  *
- * Copyright (c) 2012-2019, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ * Copyright (c) 2012-2020, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
  *
  *-------------------------------------------------------------------------
  */
@@ -2079,7 +2079,7 @@ create_hintstate(Query *parse, const char *hints)
                hstate->num_hints[HINT_TYPE_LEADING]);
        hstate->rows_hints = (RowsHint **) (hstate->set_hints +
                hstate->num_hints[HINT_TYPE_SET]);
-       hstate->parallel_hints = (ParallelHint **) (hstate->set_hints +
+       hstate->parallel_hints = (ParallelHint **) (hstate->rows_hints +
                hstate->num_hints[HINT_TYPE_ROWS]);
 
        return hstate;
@@ -2775,6 +2775,25 @@ set_join_config_options(unsigned char enforce_mask, GucContext context)
        SET_CONFIG_OPTION("enable_nestloop", ENABLE_NESTLOOP);
        SET_CONFIG_OPTION("enable_mergejoin", ENABLE_MERGEJOIN);
        SET_CONFIG_OPTION("enable_hashjoin", ENABLE_HASHJOIN);
+
+       /*
+        * Hash join may be rejected for the reason of estimated memory usage. Try
+        * getting rid of that limitation. This change on work_mem is reverted just
+        * after searching join path so no suginificant side-effects are expected.
+        */
+       if (enforce_mask == ENABLE_HASHJOIN)
+       {
+               char                    buf[32];
+
+               /* See final_cost_hashjoin(). */
+               if (work_mem < MAX_KILOBYTES)
+               {
+                       snprintf(buf, sizeof(buf), UINT64_FORMAT, (uint64)MAX_KILOBYTES);
+                       set_config_option_noerror("work_mem", buf,
+                                                                         context, PGC_S_SESSION, GUC_ACTION_SAVE,
+                                                                         true, ERROR);
+               }
+       }
 }
 
 /*