make work CREATE TABLE AS/SELECT INTO in 9.2.
authorTeodor Sigaev <teodor@sigaev.ru>
Thu, 13 Sep 2012 15:42:13 +0000 (19:42 +0400)
committerTeodor Sigaev <teodor@sigaev.ru>
Thu, 13 Sep 2012 15:42:13 +0000 (19:42 +0400)
online_analyze.c

index a823216..50ee68b 100644 (file)
@@ -41,6 +41,8 @@
 #include "utils/guc.h"
 #if PG_VERSION_NUM >= 90200
 #include "catalog/pg_class.h"
+#include "nodes/primnodes.h"
+#include "tcop/utility.h"
 #include "utils/rel.h"
 #include "utils/relcache.h"
 #include "utils/timestamp.h"
@@ -56,6 +58,11 @@ static double online_analyze_scale_factor = 0.1;
 static int online_analyze_threshold = 50;
 static double online_analyze_min_interval = 10000;
 
+static ExecutorEnd_hook_type oldExecutorEndHook = NULL;
+#if PG_VERSION_NUM >= 90200
+static ProcessUtility_hook_type        oldProcessUtilityHook = NULL;
+#endif
+
 typedef enum 
 {
        OATT_ALL                = 0x03,
@@ -292,8 +299,6 @@ matchOid(TableList *tbl, Oid oid)
        return false;
 }
 
-static ExecutorEnd_hook_type oldhook = NULL;
-
 static void
 makeAnalyze(Oid relOid, CmdType operation, uint32 naffected)
 {
@@ -470,20 +475,50 @@ onlineAnalyzeHooker(QueryDesc *queryDesc)
                }
        }
 
-       if (oldhook)
-               (*oldhook)(queryDesc);
+       if (oldExecutorEndHook)
+               oldExecutorEndHook(queryDesc);
        else
                standard_ExecutorEnd(queryDesc);
 }
 
+#if PG_VERSION_NUM >= 90200
+static void
+onlineAnalyzeHookerUtility(Node *parsetree, const char *queryString, 
+                                                       ParamListInfo params, bool isTopLevel,
+                                                       DestReceiver *dest, char *completionTag) {
+       RangeVar        *tblname = NULL;
+
+       if (IsA(parsetree, CreateTableAsStmt) && ((CreateTableAsStmt*)parsetree)->into)
+               tblname = (RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel);
+
+       if (oldProcessUtilityHook)
+               oldProcessUtilityHook(parsetree, queryString, params, isTopLevel, dest, completionTag);
+       else
+               standard_ProcessUtility(parsetree, queryString, params, isTopLevel, dest, completionTag);
+
+       if (tblname) {
+               Oid     tblOid = RangeVarGetRelid(tblname, NoLock, true);
+
+               makeAnalyze(tblOid, CMD_INSERT, 0); 
+       }
+}
+#endif
+
 void _PG_init(void);
 void
 _PG_init(void)
 {
-       oldhook = ExecutorEnd_hook;
+       oldExecutorEndHook = ExecutorEnd_hook;
 
        ExecutorEnd_hook = onlineAnalyzeHooker;
 
+#if PG_VERSION_NUM >= 90200
+       oldProcessUtilityHook = ProcessUtility_hook;
+
+       ProcessUtility_hook = onlineAnalyzeHookerUtility;
+#endif
+
+
        DefineCustomBoolVariable(
                "online_analyze.enable",
                "Enable on-line analyze",
@@ -585,7 +620,7 @@ _PG_init(void)
                NULL
        );
 
-DefineCustomEnumVariable(
+       DefineCustomEnumVariable(
                "online_analyze.table_type",
                "Type(s) of table for online analyze: all(default), persistent, temporary, none",
                NULL,
@@ -648,7 +683,10 @@ void _PG_fini(void);
 void
 _PG_fini(void)
 {
-       ExecutorEnd_hook = oldhook;
+       ExecutorEnd_hook = oldExecutorEndHook;
+#if PG_VERSION_NUM >= 90200
+       ProcessUtility_hook = oldProcessUtilityHook;
+#endif
 
        if (excludeTables.tables)
                free(excludeTables.tables);