WIP: add sql wrapper for internal index create, and use all stored informations :)

This commit is contained in:
Julien Rouhaud 2015-03-15 02:22:45 +01:00
parent 3773a6e7ba
commit 4a9827cfec
2 changed files with 113 additions and 25 deletions

View file

@ -11,9 +11,51 @@ SET client_encoding = 'UTF8';
CREATE FUNCTION pg_hypo_reset()
RETURNS void
LANGUAGE c COST 1000
AS '$libdir/pg_hypo', 'pg_hypo_reset';
AS '$libdir/pg_hypo', 'pg_hypo_reset';
CREATE FUNCTION pg_hypo_add_index_internal(IN indexid oid, relid oid, IN indexname text)
CREATE FUNCTION
pg_hypo_add_index_internal(IN indexid oid,
IN relid oid,
IN indexname text,
IN relam Oid,
IN ncolumns int,
IN indexkeys int,
IN indexcollations Oid,
IN opfamily Oid,
IN opcintype Oid)
RETURNS bool
LANGUAGE c COST 1000
AS '$libdir/pg_hypo', 'pg_hypo_add_index_internal';
AS '$libdir/pg_hypo', 'pg_hypo_add_index_internal';
CREATE FUNCTION
pg_hypo_add_index(IN _nspname name, IN _relname name, IN _attname name, IN _indtype text)
RETURNS bool
AS
$_$
SELECT pg_hypo_add_index_internal(
id,
relid,
indexname,
amoid,
ncolumns,
attnum,
indexcollations,
opfoid,
atttypid)
FROM (
SELECT DISTINCT 1 AS id, c.oid AS relid, 'index_name' AS indexname, am.oid AS amoid, 1 AS ncolumns, a.attnum, 0 AS indexcollations, opf.oid AS opfoid, a.atttypid
FROM pg_class c
JOIN pg_namespace n on n.oid = c.relnamespace
JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum > 0
JOIN pg_type t ON t.oid = a.atttypid
JOIN pg_amop amop ON amop.amoplefttype = t.oid
JOIN pg_opfamily opf ON opf.oid = amop.amopfamily
JOIN pg_am am ON am.oid = amop.amopmethod
WHERE
n.nspname = _nspname
AND c.relname = _relname
AND a.attname = _attname
AND am.amname = _indtype
) src;
$_$
LANGUAGE sql;

View file

@ -31,11 +31,11 @@
#include "utils/guc.h"
#include "utils/rel.h"
static const uint32 PGHYPO_FILE_HEADER = 0x6879706f;
PG_MODULE_MAGIC;
#define HYPOTHETICAL_INDEX_OID 123;
static const uint32 PGHYPO_FILE_HEADER = 0x6879706f;
#define HYPO_MAX_COL 1
#if PG_VERSION_NUM >= 90300
#define HYPO_DUMP_FILE "pg_stat/pg_hypo.stat"
#else
@ -54,6 +54,12 @@ typedef struct hypoEntry
Oid indexid; /* hypothetical index Oid */
Oid relid; /* related relation Oid */
char *indexname; /* hypothetical index name */
Oid relam;
int ncolumns; /* number of columns, only 1 for now */
int indexkeys; /* attnum */
Oid indexcollations;
Oid opfamily;
Oid opcintype;
slock_t mutex; /* protects fields */
} hypoEntry;
@ -83,7 +89,15 @@ PG_FUNCTION_INFO_V1(pg_hypo_add_index_internal);
static Size hypo_memsize(void);
static void entry_reset(void);
static bool entry_store(Oid indexid, Oid relid, char *indexname);
static bool entry_store(Oid indexid,
Oid relid,
char *indexname,
Oid relam,
int ncolumns,
int indexkeys,
int indexcollations,
Oid opfamily,
Oid opcintype);
static void hypo_shmem_startup(void);
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
@ -203,7 +217,6 @@ hypo_shmem_startup(void)
if (!found)
{
entry_reset();
entry_store(1, 1, "hypo_toto");
}
@ -316,12 +329,24 @@ entry_reset(void)
}
static bool
entry_store(Oid indexid, Oid relid, char *indexname)
entry_store(Oid indexid,
Oid relid,
char *indexname,
Oid relam,
int ncolumns,
int indexkeys,
int indexcollations,
Oid opfamily,
Oid opcintype)
{
int i = 0;
hypoEntry *entry;
bool found = false;
/* Make sure user didn't try to add too many columns */
if (ncolumns > HYPO_MAX_COL)
return false;
entry = hypoEntries;
LWLockAcquire(hypo->lock, LW_SHARED);
@ -333,6 +358,12 @@ entry_store(Oid indexid, Oid relid, char *indexname)
entry->indexid = indexid;
entry->relid = relid;
entry->indexname = indexname;
entry->relam = relam;
entry->ncolumns = ncolumns;
entry->indexkeys = indexkeys;
entry->indexcollations = indexcollations;
entry->opfamily = opfamily;
entry->opcintype = opcintype;
SpinLockRelease(&entry->mutex);
found = true;
break;
@ -419,19 +450,19 @@ addHypotheticalIndex(PlannerInfo *root, Oid relationObjectId, bool inhparent, Re
/* create a node */
index = makeNode(IndexOptInfo);
index->relam = BTREE_AM_OID; // more to be added
index->relam = entry.relam;
if (index->relam != BTREE_AM_OID)
{
elog(WARNING, "pg_hypo: Only btree indexes are supported for now");
elog(WARNING, "pg_hypo: Only btree indexes are supported for now!");
return;
}
// General stuff
index->indexoid = HYPOTHETICAL_INDEX_OID;
index->indexoid = entry.indexid;
index->reltablespace = rel->reltablespace; // same as relation
index->rel = rel;
index->ncolumns = ncolumns = 1; // only 1 col indexes for now
index->ncolumns = ncolumns = entry.ncolumns;
index->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
index->indexcollations = (Oid *) palloc(sizeof(int) * ncolumns);
@ -446,23 +477,23 @@ addHypotheticalIndex(PlannerInfo *root, Oid relationObjectId, bool inhparent, Re
case BTREE_AM_OID:
// hardcode int4 cols, WIP
index->indexcollations[i] = 0; //?? C_COLLATION_OID;
index->opfamily[i] = INTEGER_BTREE_FAM_OID;
index->opcintype[i] = INT4OID; // ??INT4_BTREE_OPS_OID; // btree integer opclass
index->opfamily[i] = entry.opfamily; //INTEGER_BTREE_FAM_OID;
index->opcintype[i] = entry.opcintype; //INT4OID; // ??INT4_BTREE_OPS_OID; // btree integer opclass
break;
}
}
index->canreturn = true;
index->amcanorderbyop = false;
index->amoptionalkey = true;
index->amsearcharray = true;
index->amsearchnulls = true;
index->amhasgettuple = true;
index->amhasgetbitmap = true;
index->unique = false;
index->immediate = true;
if (index->relam == BTREE_AM_OID)
{
index->canreturn = true;
index->amcanorderbyop = false;
index->amoptionalkey = true;
index->amsearcharray = true;
index->amsearchnulls = true;
index->amhasgettuple = true;
index->amhasgetbitmap = true;
index->unique = false;
index->immediate = true;
index->amcostestimate = (RegProcedure) 1268; // btcostestimate
index->sortopfamily = index->opfamily;
index->tree_height = 1; // WIP
@ -535,9 +566,17 @@ static void hypo_get_relation_info_hook(PlannerInfo *root,
break;
if (entry->relid == relationObjectId) {
SpinLockAcquire(&entry->mutex);
current.indexid = entry->indexid;
current.relid = entry->relid;
current.indexname = entry->indexname;
current.relam = entry->relam;
current.ncolumns = entry->ncolumns;
current.indexkeys = entry->indexkeys;
current.indexcollations = entry->indexcollations;
current.opfamily = entry->opfamily;
current.opcintype = entry->opcintype;
SpinLockRelease(&entry->mutex);
// Call the main function which will add hypothetical indexes if needed
addHypotheticalIndex(root, relationObjectId, inhparent, rel, relation, current);
@ -618,7 +657,14 @@ pg_hypo_add_index_internal(PG_FUNCTION_ARGS)
Oid indexid = PG_GETARG_OID(0);
Oid relid = PG_GETARG_OID(1);
char *indexname = TextDatumGetCString(PG_GETARG_TEXT_P(2));
return entry_store(indexid, relid, indexname);
Oid relam = PG_GETARG_OID(3);
int ncolumns = PG_GETARG_INT32(4);
int indexkeys = PG_GETARG_INT32(5);
Oid indexcollations = PG_GETARG_OID(6);
Oid opfamily = PG_GETARG_OID(7);
Oid opcintype = PG_GETARG_OID(8);
return entry_store(indexid, relid, indexname, relam, ncolumns, indexkeys, indexcollations, opfamily, opcintype);
}
// stolen from backend/optimisze/util/plancat.c, no export of this function :(