X-Git-Url: http://www.sigaev.ru/git/gitweb.cgi?p=plantuner.git;a=blobdiff_plain;f=plantuner.c;h=3c5c6c7dbe5e495ccc2ff16de12a2ebfb6695da4;hp=96d679ac60008e931f9ca7089a98605d9c123cd8;hb=3c3fe972db47384cef46dbf3f286bda95667d867;hpb=a07b2ca58b6804b8a261e674a159eb442362471a diff --git a/plantuner.c b/plantuner.c index 96d679a..3c5c6c7 100644 --- a/plantuner.c +++ b/plantuner.c @@ -6,13 +6,13 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -30,7 +30,9 @@ #include #include +#include #include +#include #include #include #include @@ -40,22 +42,33 @@ #include #include #include +#if PG_VERSION_NUM >= 100000 +#include +#include +#endif PG_MODULE_MAGIC; -static int nIndexesOut = 0; -static Oid *indexesOut = NULL; +static int nDisabledIndexes = 0; +static Oid *disabledIndexes = NULL; +static char *disableIndexesOutStr = ""; + +static int nEnabledIndexes = 0; +static Oid *enabledIndexes = NULL; +static char *enableIndexesOutStr = ""; + get_relation_info_hook_type prevHook = NULL; static bool fix_empty_table = false; -static char *indexesOutStr = ""; +static bool plantuner_enable_inited = false; +static bool plantuner_disable_inited = false; static const char * -indexesOutAssign(const char * newval, bool doit, GucSource source) +indexesAssign(const char * newval, bool doit, GucSource source, bool isDisable) { - char *rawname; - List *namelist; - ListCell *l; + char *rawname; + List *namelist; + ListCell *l; Oid *newOids = NULL; int nOids = 0, i = 0; @@ -65,18 +78,49 @@ indexesOutAssign(const char * newval, bool doit, GucSource source) if (!SplitIdentifierString(rawname, ',', &namelist)) goto cleanup; - if (doit) + /* + * follow work could be done only in normal processing because of + * accsess to system catalog + */ + if (MyBackendId == InvalidBackendId || !IsUnderPostmaster || + !IsNormalProcessingMode() || MyAuxProcType != NotAnAuxProcess || + !IsTransactionState()) + { + /* reset init state */ + if (isDisable) + plantuner_disable_inited = false; + else + plantuner_enable_inited = false; + + return newval; + } + + if (doit) { nOids = list_length(namelist); newOids = malloc(sizeof(Oid) * (nOids+1)); if (!newOids) - elog(ERROR,"could not allocate %d bytes", (int)(sizeof(Oid) * (nOids+1))); + elog(ERROR,"could not allocate %d bytes", + (int)(sizeof(Oid) * (nOids+1))); } + if (isDisable) + plantuner_disable_inited = true; + else + plantuner_enable_inited = true; + foreach(l, namelist) { - char *curname = (char *) lfirst(l); - Oid indexOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), true); + char *curname = (char *) lfirst(l); +#if PG_VERSION_NUM >= 90200 + Oid indexOid = RangeVarGetRelid( + makeRangeVarFromNameList(stringToQualifiedNameList(curname)), + NoLock, true); +#else + Oid indexOid = RangeVarGetRelid( + makeRangeVarFromNameList(stringToQualifiedNameList(curname)), + true); +#endif if (indexOid == InvalidOid) { @@ -100,10 +144,22 @@ indexesOutAssign(const char * newval, bool doit, GucSource source) } } - if (doit) + if (doit) { - nIndexesOut = nOids; - indexesOut = newOids; + if (isDisable) + { + nDisabledIndexes = i; + if (disabledIndexes) + free(disabledIndexes); + disabledIndexes = newOids; + } + else + { + nEnabledIndexes = i; + if (enabledIndexes) + free(enabledIndexes); + enabledIndexes = newOids; + } } pfree(rawname); @@ -119,14 +175,51 @@ cleanup: return NULL; } +static const char * +assignDisabledIndexes(const char * newval, bool doit, GucSource source) +{ + return indexesAssign(newval, doit, source, true); +} + +static const char * +assignEnabledIndexes(const char * newval, bool doit, GucSource source) +{ + return indexesAssign(newval, doit, source, false); +} + +static void +lateInit() +{ + if (!plantuner_enable_inited) + indexesAssign(enableIndexesOutStr, true, PGC_S_USER, false); + if (!plantuner_disable_inited) + indexesAssign(disableIndexesOutStr, true, PGC_S_USER, true); +} + #if PG_VERSION_NUM >= 90100 static bool -indexesOutCheck(char **newval, void **extra, GucSource source) +checkDisabledIndexes(char **newval, void **extra, GucSource source) +{ + char *val; + + val = (char*)indexesAssign(*newval, false, source, true); + + if (val) + { + *newval = val; + return true; + } + + return false; +} + +static bool +checkEnabledIndexes(char **newval, void **extra, GucSource source) { char *val; - val = (char*)indexesOutAssign(*newval, false, source); + val = (char*)indexesAssign(*newval, false, source, false); if (val) { @@ -136,19 +229,30 @@ indexesOutCheck(char **newval, void **extra, GucSource source) return false; } + +static void +assignDisabledIndexesNew(const char *newval, void *extra) +{ + assignDisabledIndexes(newval, true, PGC_S_USER /* doesn't matter */); +} + static void -indexesOutAssignNew(const char *newval, void *extra) +assignEnabledIndexesNew(const char *newval, void *extra) { - indexesOutAssign(newval, true, PGC_S_USER /* doesn't matter */); + assignEnabledIndexes(newval, true, PGC_S_USER /* doesn't matter */); } #endif static void -indexFilter(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel) { +indexFilter(PlannerInfo *root, Oid relationObjectId, bool inhparent, + RelOptInfo *rel) +{ int i; - for(i=0;iindexoid) + if (disabledIndexes[i] == info->indexoid) { - rel->indexlist = list_delete_ptr(rel->indexlist, info); + int j; + + for(j=0; jindexoid) + break; + + if (j >= nEnabledIndexes) + rel->indexlist = list_delete_ptr(rel->indexlist, info); + break; } } } - - if (fix_empty_table && rel) - { - - - } - } static void -execPlantuner(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel) { - Relation relation; +execPlantuner(PlannerInfo *root, Oid relationObjectId, bool inhparent, + RelOptInfo *rel) +{ + Relation relation; relation = heap_open(relationObjectId, NoLock); if (relation->rd_rel->relkind == RELKIND_RELATION) @@ -194,28 +301,30 @@ execPlantuner(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInf heap_close(relation, NoLock); /* - * Call next hook if it exists + * Call next hook if it exists */ if (prevHook) prevHook(root, relationObjectId, inhparent, rel); } static const char* -IndexFilterShow(void) +IndexFilterShow(Oid* indexes, int nIndexes) { - char *val, *ptr; - int i, + char *val, *ptr; + int i, len; - len = 1 /* \0 */ + nIndexesOut * (2 * NAMEDATALEN + 2 /* ', ' */ + 1 /* . */); + lateInit(); + + len = 1 /* \0 */ + nIndexes * (2 * NAMEDATALEN + 2 /* ', ' */ + 1 /* . */); ptr = val = palloc(len); - *ptr ='\0'; - for(i=0; i= 90100 + checkDisabledIndexes, + assignDisabledIndexesNew, +#else + assignDisabledIndexes, +#endif + disabledIndexFilterShow + ); + + DefineCustomStringVariable( + "plantuner.disable_index", + "List of disabled indexes", "Listed indexes will not be used in queries", - &indexesOutStr, + &disableIndexesOutStr, + "", + PGC_USERSET, + 0, +#if PG_VERSION_NUM >= 90100 + checkDisabledIndexes, + assignDisabledIndexesNew, +#else + assignDisabledIndexes, +#endif + disabledIndexFilterShow + ); + + DefineCustomStringVariable( + "plantuner.enable_index", + "List of enabled indexes (overload plantuner.disable_index)", + "Listed indexes which could be used in queries even they are listed in plantuner.disable_index", + &enableIndexesOutStr, "", PGC_USERSET, 0, #if PG_VERSION_NUM >= 90100 - indexesOutCheck, - indexesOutAssignNew, + checkEnabledIndexes, + assignEnabledIndexesNew, #else - indexesOutAssign, + assignEnabledIndexes, #endif - IndexFilterShow + enabledIndexFilterShow ); - DefineCustomBoolVariable( + DefineCustomBoolVariable( "plantuner.fix_empty_table", "Sets to zero estimations for empty tables", "Sets to zero estimations for empty or newly created tables",