Switched to 0-based numbering for sparsevec on-disk format

This commit is contained in:
Andrew Kane
2024-04-24 12:51:24 -07:00
parent 4d21eea6f1
commit 78e5bcf229
4 changed files with 20 additions and 15 deletions

View File

@@ -1206,7 +1206,7 @@ sparsevec_to_halfvec(PG_FUNCTION_ARGS)
result = InitHalfVector(dim); result = InitHalfVector(dim);
for (int i = 0; i < svec->nnz; i++) for (int i = 0; i < svec->nnz; i++)
result->x[svec->indices[i] - 1] = Float4ToHalf(values[i]); result->x[svec->indices[i]] = Float4ToHalf(values[i]);
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }

View File

@@ -98,12 +98,14 @@ CheckIndex(int32 *indices, int i, int dim)
{ {
int32 index = indices[i]; int32 index = indices[i];
if (index < 1) /* TODO Better error message for binary format */
if (index < 0)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION), (errcode(ERRCODE_DATA_EXCEPTION),
errmsg("index must be greater than zero"))); errmsg("index must be greater than zero")));
if (index > dim) /* TODO Better error message for binary format */
if (index >= dim)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION), (errcode(ERRCODE_DATA_EXCEPTION),
errmsg("index must be less than or equal to dimensions"))); errmsg("index must be less than or equal to dimensions")));
@@ -273,8 +275,8 @@ sparsevec_in(PG_FUNCTION_ARGS)
/* Keep in int range for correct error message later */ /* Keep in int range for correct error message later */
if (index > INT_MAX) if (index > INT_MAX)
index = INT_MAX; index = INT_MAX;
else if (index < INT_MIN) else if (index < INT_MIN + 1)
index = INT_MIN; index = INT_MIN + 1;
pt = stringEnd; pt = stringEnd;
@@ -313,7 +315,8 @@ sparsevec_in(PG_FUNCTION_ARGS)
/* Do not store zero values */ /* Do not store zero values */
if (value != 0) if (value != 0)
{ {
elements[nnz].index = index; /* Convert 1-based numbering (SQL) to 0-based (C) */
elements[nnz].index = index - 1;
elements[nnz].value = value; elements[nnz].value = value;
nnz++; nnz++;
} }
@@ -447,7 +450,8 @@ sparsevec_out(PG_FUNCTION_ARGS)
if (i > 0) if (i > 0)
AppendChar(ptr, ','); AppendChar(ptr, ',');
AppendInt(ptr, sparsevec->indices[i]); /* Convert 0-based numbering (C) to 1-based (SQL) */
AppendInt(ptr, sparsevec->indices[i] + 1);
AppendChar(ptr, ':'); AppendChar(ptr, ':');
AppendFloat(ptr, values[i]); AppendFloat(ptr, values[i]);
} }
@@ -615,7 +619,7 @@ vector_to_sparsevec(PG_FUNCTION_ARGS)
if (j >= result->nnz) if (j >= result->nnz)
elog(ERROR, "safety check failed"); elog(ERROR, "safety check failed");
result->indices[j] = i + 1; result->indices[j] = i;
values[j] = vec->x[i]; values[j] = vec->x[i];
j++; j++;
} }
@@ -658,7 +662,7 @@ halfvec_to_sparsevec(PG_FUNCTION_ARGS)
if (j >= result->nnz) if (j >= result->nnz)
elog(ERROR, "safety check failed"); elog(ERROR, "safety check failed");
result->indices[j] = i + 1; result->indices[j] = i;
values[j] = HalfToFloat4(vec->x[i]); values[j] = HalfToFloat4(vec->x[i]);
j++; j++;
} }
@@ -1019,11 +1023,10 @@ sparsevec_cmp_internal(SparseVector * a, SparseVector * b)
return 1; return 1;
} }
/* Check <= dim since indices start at 1 */ if (a->nnz < b->nnz && b->indices[nnz] < a->dim)
if (a->nnz < b->nnz && b->indices[nnz] <= a->dim)
return bx[nnz] < 0 ? 1 : -1; return bx[nnz] < 0 ? 1 : -1;
if (a->nnz > b->nnz && a->indices[nnz] <= b->dim) if (a->nnz > b->nnz && a->indices[nnz] < b->dim)
return ax[nnz] < 0 ? -1 : 1; return ax[nnz] < 0 ? -1 : 1;
if (a->dim < b->dim) if (a->dim < b->dim)

View File

@@ -10,8 +10,10 @@
#define PG_GETARG_SPARSEVEC_P(x) DatumGetSparseVector(PG_GETARG_DATUM(x)) #define PG_GETARG_SPARSEVEC_P(x) DatumGetSparseVector(PG_GETARG_DATUM(x))
#define PG_RETURN_SPARSEVEC_P(x) PG_RETURN_POINTER(x) #define PG_RETURN_SPARSEVEC_P(x) PG_RETURN_POINTER(x)
/* Indices are always sorted */ /*
/* Values come after indices */ * Indices use 0-based numbering for the on-disk (and binary) format (consistent with C)
* and are always sorted. Values come after indices.
*/
typedef struct SparseVector typedef struct SparseVector
{ {
int32 vl_len_; /* varlena header (do not touch directly!) */ int32 vl_len_; /* varlena header (do not touch directly!) */

View File

@@ -1318,7 +1318,7 @@ sparsevec_to_vector(PG_FUNCTION_ARGS)
result = InitVector(dim); result = InitVector(dim);
for (int i = 0; i < svec->nnz; i++) for (int i = 0; i < svec->nnz; i++)
result->x[svec->indices[i] - 1] = values[i]; result->x[svec->indices[i]] = values[i];
PG_RETURN_POINTER(result); PG_RETURN_POINTER(result);
} }