向量数据库支持Xstore存储

This commit is contained in:
jiwenke
2024-08-16 17:11:03 +08:00
parent 4d46d4a0f7
commit 6f63f23120
8 changed files with 70 additions and 16 deletions

View File

@ -98,6 +98,7 @@ install:
@if test -d contrib/spq_plugin; then $(MAKE) -C contrib/spq_plugin $@; fi
@if test -d contrib/dolphin; then $(MAKE) -C contrib/dolphin $@; fi
@if test -d contrib/age; then $(MAKE) -C contrib/age $@; fi
@if test -d contrib/datavec; then $(MAKE) -C contrib/datavec clean; fi
@if test -d contrib/datavec; then $(MAKE) -C contrib/datavec $@; fi
@if test -d contrib/gms_stats; then $(MAKE) -C contrib/gms_stats $@; fi
@if test -d contrib/gms_profiler; then $(MAKE) -C contrib/gms_profiler $@; fi

View File

@ -135,11 +135,15 @@ ObjectAddress CreateAccessMethod(CreateAmStmt *stmt)
FILL_ANUM_PG_AM_REGPROC_VAULE(Anum_pg_am_amcanreturn, amRoutine->amcanreturnfuncname);
FILL_ANUM_PG_AM_REGPROC_VAULE(Anum_pg_am_amcostestimate, amRoutine->amcostestimatefuncname);
FILL_ANUM_PG_AM_REGPROC_VAULE(Anum_pg_am_amoptions, amRoutine->amoptionsfuncname);
FILL_ANUM_PG_AM_REGPROC_VAULE(Anum_pg_am_amdelete, amRoutine->amdeletefuncname);
values[Anum_pg_am_amhandler - 1] = ObjectIdGetDatum(amHandler);
tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
if (strcmp(stmt->amname, "hnsw") == 0) {
HeapTupleSetOid(tup, HNSW_AM_OID);
}
amOid = simple_heap_insert(rel, tup);
CatalogUpdateIndexes(rel, tup);
heap_freetuple(tup);
@ -184,7 +188,7 @@ void RemoveAccessMethodById(Oid amOid)
ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to drop an access method.")));
if (IsSystemObjOid(amOid))
if (IsSystemObjOid(amOid) && amOid != HNSW_AM_OID)
ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("amOid %u is a builtin access method, it can not be droped", amOid)));
@ -250,6 +254,10 @@ static Oid lookup_regproc_am_handler_func(int16 procIndex, IndexAmRoutine *amRou
nargs = PG_AM_ENDSCAN_ARGS_NUM;
funcName = amRoutine->amendscanfuncname;
break;
case Anum_pg_am_amdelete:
nargs = PG_AM_DELETE_ARGS_NUM;
funcName = amRoutine->amdeletefuncname;
break;
case Anum_pg_am_ambuild:
nargs = PG_AM_BUILD_ARGS_NUM;
funcName = amRoutine->ambuildfuncname;

View File

@ -833,7 +833,7 @@ ObjectAddress DefineIndex(Oid relationId, IndexStmt* stmt, Oid indexRelationId,
if (strcmp(stmt->accessMethod, "btree") == 0) {
elog(ERROR, "btree index is not supported for ustore, please use ubtree instead");
}
if (strcmp(stmt->accessMethod, "ubtree") != 0) {
if (strcmp(stmt->accessMethod, "ubtree") != 0 && strcmp(stmt->accessMethod, "hnsw") != 0) {
elog(ERROR, "%s index is not supported for ustore", (stmt->accessMethod));
}
if (has_dedup_opt) {

View File

@ -470,7 +470,7 @@ static relopt_string stringRelOpts[] = {
},
{
{"storage_type", "Specifies the Table accessor routines",
RELOPT_KIND_HEAP | RELOPT_KIND_BTREE | RELOPT_KIND_TOAST},
RELOPT_KIND_HEAP | RELOPT_KIND_BTREE | RELOPT_KIND_TOAST | RELOPT_KIND_DATAVEC},
strlen(TABLE_ACCESS_METHOD_ASTORE),
false,
ValidateStrOptTableAccessMethod,

View File

@ -208,8 +208,46 @@ bool UBTreeDelete(Relation indexRelation, Datum* values, const bool* isnull, Ite
void index_delete(Relation index_relation, Datum* values, const bool* isnull, ItemPointer heap_t_ctid,
bool isRollbackIndex)
{
/* Assert(Ustore) Assert(B tree) */
UBTreeDelete(index_relation, values, isnull, heap_t_ctid, isRollbackIndex);
if (RelationIsUstoreIndex(index_relation)) {
/* Assert(Ustore) Assert(B tree) */
UBTreeDelete(index_relation, values, isnull, heap_t_ctid, isRollbackIndex);
} else {
HeapTuple tuple;
char* accessMethodName;
Form_pg_am accessMethodForm;
FmgrInfo flinfo;
FunctionCallInfoData fcinfo;
Datum result;
switch (index_relation->rd_rel->relam) {
case HNSW_AM_OID:
accessMethodName = DEFAULT_HNSW_INDEX_TYPE;
break;
default:
Assert(false);
break;
}
tuple = SearchSysCache1(AMNAME, PointerGetDatum(accessMethodName));
accessMethodForm = (Form_pg_am)GETSTRUCT(tuple);
fmgr_info(accessMethodForm->amdelete, &flinfo);
InitFunctionCallInfoData(fcinfo, &flinfo, 5, InvalidOid, NULL, NULL);
fcinfo.arg[0] = PointerGetDatum(index_relation);
fcinfo.arg[1] = PointerGetDatum(values);
fcinfo.arg[2] = PointerGetDatum(isnull);
fcinfo.arg[3] = PointerGetDatum(heap_t_ctid);
fcinfo.arg[4] = BoolGetDatum(isRollbackIndex);
fcinfo.argnull[0] = false;
fcinfo.argnull[1] = false;
fcinfo.argnull[2] = false;
fcinfo.argnull[3] = false;
fcinfo.argnull[4] = false;
result = FunctionCallInvoke(&fcinfo);
ReleaseSysCache(tuple);
}
}

View File

@ -29,6 +29,7 @@
#define PG_AM_VACUUMCLEANUP_ARGS_NUM 2
#define PG_AM_COSTESTIMATE_ARGS_NUM 7
#define PG_AM_OPTIONS_ARGS_NUM 2
#define PG_AM_DELETE_ARGS_NUM 5
#define PG_AM_FUNC_MAX_ARGS_NUM PG_AM_COSTESTIMATE_ARGS_NUM
struct IndexInfo;
@ -173,6 +174,7 @@ typedef struct IndexAmRoutine
char ammarkposfuncname[NAMEDATALEN];
char amrestrposfuncname[NAMEDATALEN];
char ammergefuncname[NAMEDATALEN];
char amdeletefuncname[NAMEDATALEN];
} IndexAmRoutine;
typedef IndexAmRoutine *AmRoutine;

View File

@ -51,8 +51,9 @@ typedef enum relopt_kind {
RELOPT_KIND_NPARSER = (1 << 12), /* text search configuration options defined by ngram */
RELOPT_KIND_CBTREE = (1 << 13),
RELOPT_KIND_PPARSER = (1 << 14), /* text search configuration options defined by pound */
RELOPT_KIND_DATAVEC = (1 << 15),
/* if you add a new kind, make sure you update "last_default" too */
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PPARSER,
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_DATAVEC,
/* some compilers treat enums as signed ints, so we can't use 1 << 31 */
RELOPT_KIND_MAX = (1 << 30)
} relopt_kind;

View File

@ -70,6 +70,7 @@ CATALOG(pg_am,2601) BKI_SCHEMA_MACRO
regproc amcostestimate; /* estimate cost of an indexscan */
regproc amoptions; /* parse AM-specific parameters */
regproc amhandler; /* handler function */
regproc amdelete; /* index delete function */
} FormData_pg_am;
/* ----------------
@ -83,7 +84,7 @@ typedef FormData_pg_am *Form_pg_am;
* compiler constants for pg_am
* ----------------
*/
#define Natts_pg_am 32
#define Natts_pg_am 33
#define Anum_pg_am_amname 1
#define Anum_pg_am_amstrategies 2
#define Anum_pg_am_amsupport 3
@ -116,44 +117,47 @@ typedef FormData_pg_am *Form_pg_am;
#define Anum_pg_am_amcostestimate 30
#define Anum_pg_am_amoptions 31
#define Anum_pg_am_amhandler 32
#define Anum_pg_am_amdelete 33
/* ----------------
* initial contents of pg_am
* ----------------
*/
DATA(insert OID = 403 ( btree 5 3 t f t t t t t t f t t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btmerge btbuild btbuildempty btbulkdelete btvacuumcleanup btcanreturn btcostestimate btoptions -));
DATA(insert OID = 403 ( btree 5 3 t f t t t t t t f t t 0 btinsert btbeginscan btgettuple btgetbitmap btrescan btendscan btmarkpos btrestrpos btmerge btbuild btbuildempty btbulkdelete btvacuumcleanup btcanreturn btcostestimate btoptions - -));
DESCR("b-tree index access method");
#define BTREE_AM_OID 403
DATA(insert OID = 405 ( hash 1 1 f f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashmerge hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup - hashcostestimate hashoptions -));
DATA(insert OID = 405 ( hash 1 1 f f t f f f f f f f f 23 hashinsert hashbeginscan hashgettuple hashgetbitmap hashrescan hashendscan hashmarkpos hashrestrpos hashmerge hashbuild hashbuildempty hashbulkdelete hashvacuumcleanup - hashcostestimate hashoptions - -));
DESCR("hash index access method");
#define HASH_AM_OID 405
DATA(insert OID = 783 ( gist 0 8 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistmerge gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup - gistcostestimate gistoptions -));
DATA(insert OID = 783 ( gist 0 8 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistmerge gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup - gistcostestimate gistoptions - -));
DESCR("GiST index access method");
#define GIST_AM_OID 783
DATA(insert OID = 2742 ( gin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginmerge ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions -));
DATA(insert OID = 2742 ( gin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginmerge ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions - -));
DESCR("GIN index access method");
#define GIN_AM_OID 2742
DATA(insert OID = 4000 ( spgist 0 5 f f f f f t f t f f f 0 spginsert spgbeginscan spggettuple spggetbitmap spgrescan spgendscan spgmarkpos spgrestrpos spgmerge spgbuild spgbuildempty spgbulkdelete spgvacuumcleanup spgcanreturn spgcostestimate spgoptions -));
DATA(insert OID = 4000 ( spgist 0 5 f f f f f t f t f f f 0 spginsert spgbeginscan spggettuple spggetbitmap spgrescan spgendscan spgmarkpos spgrestrpos spgmerge spgbuild spgbuildempty spgbulkdelete spgvacuumcleanup spgcanreturn spgcostestimate spgoptions - -));
DESCR("SP-GiST index access method");
#define SPGIST_AM_OID 4000
DATA(insert OID = 4039 ( psort 5 1 f f f f t t f t f f f 0 - - psortgettuple psortgetbitmap - - - - - psortbuild - - - psortcanreturn psortcostestimate psortoptions -));
DATA(insert OID = 4039 ( psort 5 1 f f f f t t f t f f f 0 - - psortgettuple psortgetbitmap - - - - - psortbuild - - - psortcanreturn psortcostestimate psortoptions - -));
DESCR("psort index access method");
#define PSORT_AM_OID 4039
DATA(insert OID = 4239 ( cbtree 5 1 f f f t t t f t f f t 0 btinsert btbeginscan cbtreegettuple cbtreegetbitmap btrescan btendscan - - - cbtreebuild btbuildempty - - cbtreecanreturn cbtreecostestimate cbtreeoptions -));
DATA(insert OID = 4239 ( cbtree 5 1 f f f t t t f t f f t 0 btinsert btbeginscan cbtreegettuple cbtreegetbitmap btrescan btendscan - - - cbtreebuild btbuildempty - - cbtreecanreturn cbtreecostestimate cbtreeoptions - -));
DESCR("cstore btree index access method");
#define CBTREE_AM_OID 4239
DATA(insert OID = 4444 ( cgin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - cgingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginmerge cginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions -));
DATA(insert OID = 4444 ( cgin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - cgingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginmerge cginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions - -));
DESCR("cstore GIN index access method");
#define CGIN_AM_OID 4444
DATA(insert OID = 4439 ( ubtree 5 3 t f t t t t t t f t t 0 ubtinsert ubtbeginscan ubtgettuple ubtgetbitmap ubtrescan ubtendscan ubtmarkpos ubtrestrpos ubtmerge ubtbuild ubtbuildempty ubtbulkdelete ubtvacuumcleanup ubtcanreturn ubtcostestimate ubtoptions -));
DATA(insert OID = 4439 ( ubtree 5 3 t f t t t t t t f t t 0 ubtinsert ubtbeginscan ubtgettuple ubtgetbitmap ubtrescan ubtendscan ubtmarkpos ubtrestrpos ubtmerge ubtbuild ubtbuildempty ubtbulkdelete ubtvacuumcleanup ubtcanreturn ubtcostestimate ubtoptions - -));
DESCR("ustore b-tree index access method");
#define UBTREE_AM_OID 4439
#define HNSW_AM_OID 4446
#define OID_IS_BTREE(oid) ((oid) == BTREE_AM_OID || (oid) == UBTREE_AM_OID)
#endif /* PG_AM_H */