/* * Copyright (c) 2009 Teodor Sigaev */ #include #include #include #include #include #include #include #include #include PG_MODULE_MAGIC; static int nIndexesOut = 0; static Oid *indexesOut = NULL; get_relation_info_hook_type prevHook = NULL; static char *indexesOutStr = ""; static const char * indexesOutAssign(const char * newval, bool doit, GucSource source) { char *rawname; List *namelist; ListCell *l; Oid *newOids = NULL; int nOids = 0, i = 0; rawname = pstrdup(newval); if (!SplitIdentifierString(rawname, ',', &namelist)) goto cleanup; if (doit) { nOids = list_length(namelist); newOids = malloc(sizeof(Oid) * (nOids+1)); if (!newOids) elog(ERROR,"could not allocate %d bytes", sizeof(Oid) * (nOids+1)); } foreach(l, namelist) { char *curname = (char *) lfirst(l); Oid indexOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), true); if (indexOid == InvalidOid) { elog(WARNING,"'%s' does not exist", curname); continue; } else if ( get_rel_relkind(indexOid) != RELKIND_INDEX ) { elog(WARNING,"'%s' is not an index", curname); continue; } else if (doit) { newOids[i++] = indexOid; } } if (doit) { nIndexesOut = nOids; indexesOut = newOids; } pfree(rawname); list_free(namelist); return newval; cleanup: if (newOids) free(newOids); pfree(rawname); list_free(namelist); return NULL; } static void indexFilter(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel) { int i; for(i=0;iindexlist) { IndexOptInfo *info = (IndexOptInfo*)lfirst(l); if (indexesOut[i] == info->indexoid) { rel->indexlist = list_delete_ptr(rel->indexlist, info); break; } } } /* * Call next hook if it exists */ if (prevHook) prevHook(root, relationObjectId, inhparent, rel); } static const char* IndexFilterShow(void) { char *val, *ptr; int i, len; len = 1 /* \0 */ + nIndexesOut * (2 * NAMEDATALEN + 2 /* ', ' */ + 1 /* . */); ptr = val = palloc(len); *ptr ='\0'; for(i=0; i