Better hypog() output

This commit is contained in:
Julien Rouhaud 2015-03-22 15:42:08 +01:00
parent 81b2492422
commit 5569453da5
2 changed files with 55 additions and 28 deletions

View file

@ -18,7 +18,7 @@ hypopg_add_index_internal(IN relid oid,
IN indexname text,
IN relam Oid,
IN ncolumns int,
IN indexkeys int,
IN indexkeys smallint,
IN indexcollations Oid,
IN opfamily Oid,
IN opcintype Oid)
@ -38,7 +38,12 @@ hypopg_drop_index(IN indexid oid)
LANGUAGE c COST 100
AS '$libdir/hypopg', 'hypopg_drop_index';
CREATE FUNCTION hypopg(OUT oid Oid, OUT indexname text, OUT relid Oid, OUT amid Oid)
CREATE FUNCTION hypopg(OUT indexname text, OUT indexrelid Oid,
OUT indrelid Oid, OUT innatts integer,
OUT indisunique boolean, OUT indkey int2vector,
OUT indcollation oidvector, OUT indclass oidvector,
OUT indoption oidvector, OUT indexprs pg_node_tree,
OUT indpred pg_node_tree, OUT amid Oid)
RETURNS SETOF record
LANGUAGE c COST 100
AS '$libdir/hypopg', 'hypopg';
@ -49,7 +54,7 @@ AS
$_$
SELECT current_database(), h.indexname, n.nspname, c.relname, am.amname
FROM hypopg() h
JOIN pg_class c ON c.oid = h.relid
JOIN pg_class c ON c.oid = h.indrelid
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_am am ON am.oid = h.amid
$_$

View file

@ -16,6 +16,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_class.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "commands/explain.h"
#include "funcapi.h"
@ -35,7 +36,7 @@
PG_MODULE_MAGIC;
#define HYPO_NB_COLS 4 /* # of column hypopg() returns */
#define HYPO_NB_COLS 18 /* # of column hypopg() returns */
#define HYPO_MAX_INDEXNAME 1024 /* max length of an hypothetical index */
bool isExplain = false;
@ -53,9 +54,10 @@ typedef struct hypoEntry
/* index descriptor informations */
int ncolumns; /* number of columns, only 1 for now */
int *indexkeys; /* attnums */
short int *indexkeys; /* attnums */
Oid *indexcollations; /* OIDs of collations of index columns */
Oid *opfamily; /* OIDs of operator families for columns */
Oid *opclass; /* OIDs of opclass data types */
Oid *opcintype; /* OIDs of opclass declared input data types */
Oid *sortopfamily; /* OIDs of btree opfamilies, if orderable */
bool *reverse_sort; /* is sort order descending? */
@ -74,9 +76,21 @@ typedef struct hypoEntry
bool amsearchnulls; /* can AM search for NULL/NOT NULL entries? */
bool amhasgettuple; /* does AM have amgettuple interface? */
bool amhasgetbitmap; /* does AM have amgetbitmap interface? */
} hypoEntry;
typedef struct
{
int32 vl_len_; /* these fields must match ArrayType! */
int ndim; /* always 1 for oidvector */
int32 dataoffset; /* always 0 for oidvector */
Oid elemtype;
int dim1;
int lbound1;
int values[FLEXIBLE_ARRAY_MEMBER];
} int4vector;
#define Int4VectorSize(n) (offsetof(int4vector, values) + (n) * sizeof(int))
List *entries = NIL;
@ -106,7 +120,7 @@ static bool entry_store(Oid relid,
char *indexname,
Oid relam,
int ncolumns,
int indexkeys,
short int indexkeys,
int indexcollations,
Oid opfamily,
Oid opcintype);
@ -139,12 +153,10 @@ static void injectHypotheticalIndex(PlannerInfo *root,
hypoEntry *entry);
static bool hypo_query_walker(Node *node);
static List *
build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
Relation heapRelation);
static Oid
GetIndexOpClass(List *opclass, Oid attrType,
char *accessMethodName, Oid accessMethodId);
static List * build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
Relation heapRelation);
static Oid GetIndexOpClass(List *opclass, Oid attrType,
char *accessMethodName, Oid accessMethodId);
void
_PG_init(void)
@ -181,9 +193,10 @@ newHypoEntry(Oid relid, Oid relam, int ncolumns)
entry = palloc0(sizeof(hypoEntry));
/* palloc all arrays */
entry->indexkeys = palloc0(sizeof(int) * ncolumns);
entry->indexkeys = palloc0(sizeof(short int) * ncolumns);
entry->indexcollations = palloc0(sizeof(Oid) * ncolumns);
entry->opfamily = palloc0(sizeof(Oid) * ncolumns);
entry->opclass = palloc0(sizeof(Oid) * ncolumns);
entry->opcintype = palloc0(sizeof(Oid) * ncolumns);
entry->sortopfamily = palloc0(sizeof(Oid) * ncolumns);
entry->reverse_sort = palloc0(sizeof(bool) * ncolumns);
@ -276,7 +289,7 @@ entry_store(Oid relid,
char *indexname,
Oid relam,
int ncolumns,
int indexkeys,
short int indexkeys,
int indexcollations,
Oid opfamily,
Oid opcintype)
@ -311,7 +324,7 @@ entry_store_parsetree(IndexStmt *node)
Oid accessMethodId;
int ncolumns;
ListCell *lc;
int j = 0;
int j;
ncolumns = list_length(node->indexParams);
@ -354,6 +367,7 @@ entry_store_parsetree(IndexStmt *node)
entry->ncolumns = ncolumns;
/* iterate through columns */
j = 0;
foreach(lc, node->indexParams)
{
IndexElem *indexelem = (IndexElem *) lfirst(lc);
@ -381,6 +395,7 @@ entry_store_parsetree(IndexStmt *node)
atttype,
node->accessMethod,
accessMethodId);
entry->opclass[j] = opclass;
/* setup the opfamily */
entry->opfamily[j] = get_opclass_family(opclass);
@ -415,6 +430,7 @@ entry_remove(Oid indexid)
pfree(entry->indexkeys);
pfree(entry->indexcollations);
pfree(entry->opfamily);
pfree(entry->opclass);
pfree(entry->opcintype);
pfree(entry->sortopfamily);
pfree(entry->reverse_sort);
@ -672,20 +688,19 @@ hypopg_reset(PG_FUNCTION_ARGS)
/*
* Add an hypothetical index in the array, with all needed informations
* it supposed to be called from the provided sql function, because I'm too
* lazy to retrieve all the needed info in C !=
* it supposed to be called from the provided sql function.
*/
Datum
hypopg_add_index_internal(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
char *indexname = TextDatumGetCString(PG_GETARG_TEXT_PP(1));
Oid relam = PG_GETARG_OID(2);
int ncolumns = PG_GETARG_INT32(3);
int indexkeys = PG_GETARG_INT32(4);
Oid indexcollations = PG_GETARG_OID(5);
Oid opfamily = PG_GETARG_OID(6);
Oid opcintype = PG_GETARG_OID(7);
Oid relid = PG_GETARG_OID(0);
char *indexname = TextDatumGetCString(PG_GETARG_TEXT_PP(1));
Oid relam = PG_GETARG_OID(2);
int ncolumns = PG_GETARG_INT32(3);
short int indexkeys = PG_GETARG_INT16(4);
Oid indexcollations = PG_GETARG_OID(5);
Oid opfamily = PG_GETARG_OID(6);
Oid opcintype = PG_GETARG_OID(7);
return entry_store(relid, indexname, relam, ncolumns, indexkeys, indexcollations, opfamily, opcintype);
}
@ -739,11 +754,18 @@ hypopg(PG_FUNCTION_ARGS)
memset(values, 0, sizeof(values));
memset(nulls, 0, sizeof(nulls));
values[j++] = ObjectIdGetDatum(entry->oid);
values[j++] = CStringGetTextDatum(strdup(entry->indexname));
values[j++] = ObjectIdGetDatum(entry->oid);
values[j++] = ObjectIdGetDatum(entry->relid);
values[j++] = Int8GetDatum(entry->ncolumns);
values[j++] = BoolGetDatum(entry->unique);
values[j++] = PointerGetDatum(buildint2vector(entry->indexkeys, entry->ncolumns));
values[j++] = PointerGetDatum(buildoidvector(entry->indexcollations, entry->ncolumns));
values[j++] = PointerGetDatum(buildoidvector(entry->opclass, entry->ncolumns));
nulls[j++] = true; /* no indoption for now, TODO */
nulls[j++] = true; /* no hypothetical index on expr for now */
nulls[j++] = true; /* no hypothetical index on predicate for now */
values[j++] = ObjectIdGetDatum(entry->relam);
Assert(j == PG_STAT_PLAN_COLS);
tuplestore_putvalues(tupstore, tupdesc, values, nulls);