OSDN Git Service

Merge branch 'separate_func'
authorRyohei OKADA <okada.ryohei@metrosystems.co.jp>
Fri, 7 Jun 2013 08:09:51 +0000 (17:09 +0900)
committerRyohei OKADA <okada.ryohei@metrosystems.co.jp>
Fri, 7 Jun 2013 08:09:51 +0000 (17:09 +0900)
Conflicts:
pg_hint_plan.c

1  2 
pg_hint_plan.c

diff --cc pg_hint_plan.c
@@@ -1323,78 -1320,14 +1323,71 @@@ parse_hints(HintState *hstate, Query *p
        pfree(buf.data);
  }
  
 +
 +/* search hint. */
 +static const char *
 +search_hints(const char *client_query,
 +                       const char *client_application)
 +{
 +      const char *search_query =
 +              "SELECT hints "
 +              "  FROM hint_plan.hints "
 +              " WHERE norm_query_string = $1 "
 +              "   AND ( application_name = $2 "
 +              "    OR application_name = '' ) "
 +              " ORDER BY application_name DESC";
 +      static SPIPlanPtr plan = NULL;
 +      int             ret;
 +      char   *hints = NULL;
 +      Oid             argtypes[2] = { TEXTOID, TEXTOID };
 +      Datum   values[2];
 +      bool    nulls[2] = { false, false };
 +      text   *qry;
 +      text   *app;
 +
 +      ret = SPI_connect();
 +      if (ret != SPI_OK_CONNECT)
 +              elog(ERROR, "pg_hint_plan: SPI_connect => %d", ret);
 +
 +      if (plan == NULL)
 +      {
 +              SPIPlanPtr      p;
 +              p = SPI_prepare(search_query, 2, argtypes);
 +              if (p == NULL)
 +                      elog(ERROR, "pg_hint_plan: SPI_prepare => %d", SPI_result);
 +              plan = SPI_saveplan(p);
 +              SPI_freeplan(p);
 +      }
 +
 +      qry = cstring_to_text(client_query);
 +      app = cstring_to_text(client_application);
 +      values[0] = PointerGetDatum(qry);
 +      values[1] = PointerGetDatum(app);
 +
 +      pg_hint_plan_enable_hint = false;
 +      ret = SPI_execute_plan(plan, values, nulls, true, 1);
 +      pg_hint_plan_enable_hint = true;
 +      if (ret != SPI_OK_SELECT)
 +              elog(ERROR, "pg_hint_plan: SPI_execute_plan => %d", ret);
 +
 +      if (SPI_processed > 0)
 +      {
 +              hints = pstrdup(SPI_getvalue(SPI_tuptable->vals[0],
 +                                                                         SPI_tuptable->tupdesc, 1));
 +      }
 +      SPI_finish();
 +
 +      return hints;
 +}
 +
  /*
-  * Do basic parsing of the query head comment.
+  * Get client-supplied query string.
   */
- static HintState *
parse_head_comment(Query *parse)
+ static const char *
get_query_string(void)
  {
        const char *p;
-       const char *hint_head;
-       char       *head;
-       char       *tail;
-       int                     len;
-       int                     i;
-       HintState   *hstate;
  
-       /* get client-supplied query string. */
        if (stmt_name)
        {
                PreparedStatement  *entry;
@@@ -2089,29 -2054,12 +2114,24 @@@ pg_hint_plan_planner(Query *parse, int 
         * try to change plan with current_hint if any, so set it to NULL.
         */
        if (!pg_hint_plan_enable_hint)
-       {
-               current_hint = NULL;
-               if (prev_planner)
-                       return (*prev_planner) (parse, cursorOptions, boundParams);
-               else
-                       return standard_planner(parse, cursorOptions, boundParams);
-       }
+               goto standard_planner_proc;
  
-       /* Create hint struct from parse tree. */
-       hstate = parse_head_comment(parse);
 +      /*
 +       *search hint.
 +       * TODO: replace "app1" with current application_name setting of the
 +       * session.
 +       * XXX: use something instead of debug_query_string?
 +       */
 +      hints = search_hints(debug_query_string, application_name);
 +      elog(LOG,
 +               "pg_hint_plan: search_hints [%s][%s]=>[%s]",
 +               debug_query_string, application_name,
 +               hints ? hints : "(none)");
 +
+       /* Create hint struct from client-supplied query string. */
+       query = get_query_string();
+       hints = get_hints_from_comment(query);
+       hstate = create_hintstate(parse, hints);
  
        /*
         * Use standard planner if the statement has not valid hint.  Other hook