mirror of
https://github.com/HypoPG/hypopg
synced 2026-05-24 09:38:21 +00:00
Better hypog() output
This commit is contained in:
parent
81b2492422
commit
5569453da5
2 changed files with 55 additions and 28 deletions
|
|
@ -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
|
||||
$_$
|
||||
|
|
|
|||
72
hypopg.c
72
hypopg.c
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue