Improved performance of halfvec_in

This commit is contained in:
Andrew Kane
2024-04-13 15:04:52 -07:00
parent bb84d69e57
commit db112862a5
2 changed files with 32 additions and 46 deletions

View File

@@ -157,32 +157,32 @@ halfvec_in(PG_FUNCTION_ARGS)
int32 typmod = PG_GETARG_INT32(2); int32 typmod = PG_GETARG_INT32(2);
half x[HALFVEC_MAX_DIM]; half x[HALFVEC_MAX_DIM];
int dim = 0; int dim = 0;
char *pt; char *pt = lit;
char *stringEnd;
HalfVector *result; HalfVector *result;
char *litcopy = pstrdup(lit);
char *str = litcopy;
while (halfvec_isspace(*str)) while (halfvec_isspace(*pt))
str++; pt++;
if (*str != '[') if (*pt != '[')
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type halfvec: \"%s\"", lit), errmsg("invalid input syntax for type halfvec: \"%s\"", lit),
errdetail("Vector contents must start with \"[\"."))); errdetail("Vector contents must start with \"[\".")));
str++; pt++;
while (halfvec_isspace(*str)) while (halfvec_isspace(*pt))
str++; pt++;
pt = strtok(str, ","); if (*pt == ']')
stringEnd = pt; ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
errmsg("halfvec must have at least 1 dimension")));
while (pt != NULL && *stringEnd != ']') for (;;)
{ {
float val; float val;
char *stringEnd;
if (dim == HALFVEC_MAX_DIM) if (dim == HALFVEC_MAX_DIM)
ereport(ERROR, ereport(ERROR,
@@ -210,59 +210,49 @@ halfvec_in(PG_FUNCTION_ARGS)
x[dim] = Float4ToHalfUnchecked(val); x[dim] = Float4ToHalfUnchecked(val);
/* Check for range error like float4in */
if ((errno == ERANGE && isinf(val)) || (HalfIsInf(x[dim]) && !isinf(val))) if ((errno == ERANGE && isinf(val)) || (HalfIsInf(x[dim]) && !isinf(val)))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("\"%s\" is out of range for type halfvec", pt))); errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt))));
CheckElement(x[dim]); CheckElement(x[dim]);
dim++; dim++;
while (halfvec_isspace(*stringEnd)) pt = stringEnd;
stringEnd++;
if (*stringEnd != '\0' && *stringEnd != ']') while (halfvec_isspace(*pt))
pt++;
if (*pt == ',')
pt++;
else if (*pt == ']')
{
pt++;
break;
}
else
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); errmsg("invalid input syntax for type halfvec: \"%s\"", lit)));
pt = strtok(NULL, ",");
} }
if (stringEnd == NULL || *stringEnd != ']')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type halfvec: \"%s\"", lit),
errdetail("Unexpected end of input.")));
stringEnd++;
/* Only whitespace is allowed after the closing brace */ /* Only whitespace is allowed after the closing brace */
while (halfvec_isspace(*stringEnd)) while (halfvec_isspace(*pt))
stringEnd++; pt++;
if (*stringEnd != '\0') if (*pt != '\0')
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type halfvec: \"%s\"", lit), errmsg("invalid input syntax for type halfvec: \"%s\"", lit),
errdetail("Junk after closing right brace."))); errdetail("Junk after closing right brace.")));
/* Ensure no consecutive delimiters since strtok skips */
for (pt = lit + 1; *pt != '\0'; pt++)
{
if (pt[-1] == ',' && *pt == ',')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type halfvec: \"%s\"", lit)));
}
if (dim < 1) if (dim < 1)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION), (errcode(ERRCODE_DATA_EXCEPTION),
errmsg("halfvec must have at least 1 dimension"))); errmsg("halfvec must have at least 1 dimension")));
pfree(litcopy); CheckDim(dim);
CheckExpectedDim(typmod, dim); CheckExpectedDim(typmod, dim);
result = InitHalfVector(dim); result = InitHalfVector(dim);

View File

@@ -74,7 +74,6 @@ SELECT '[1,2,3'::halfvec;
ERROR: invalid input syntax for type halfvec: "[1,2,3" ERROR: invalid input syntax for type halfvec: "[1,2,3"
LINE 1: SELECT '[1,2,3'::halfvec; LINE 1: SELECT '[1,2,3'::halfvec;
^ ^
DETAIL: Unexpected end of input.
SELECT '[1,2,3]9'::halfvec; SELECT '[1,2,3]9'::halfvec;
ERROR: invalid input syntax for type halfvec: "[1,2,3]9" ERROR: invalid input syntax for type halfvec: "[1,2,3]9"
LINE 1: SELECT '[1,2,3]9'::halfvec; LINE 1: SELECT '[1,2,3]9'::halfvec;
@@ -94,17 +93,14 @@ SELECT '['::halfvec;
ERROR: invalid input syntax for type halfvec: "[" ERROR: invalid input syntax for type halfvec: "["
LINE 1: SELECT '['::halfvec; LINE 1: SELECT '['::halfvec;
^ ^
DETAIL: Unexpected end of input.
SELECT '[ '::halfvec; SELECT '[ '::halfvec;
ERROR: invalid input syntax for type halfvec: "[ " ERROR: invalid input syntax for type halfvec: "[ "
LINE 1: SELECT '[ '::halfvec; LINE 1: SELECT '[ '::halfvec;
^ ^
DETAIL: Unexpected end of input.
SELECT '[,'::halfvec; SELECT '[,'::halfvec;
ERROR: invalid input syntax for type halfvec: "[," ERROR: invalid input syntax for type halfvec: "[,"
LINE 1: SELECT '[,'::halfvec; LINE 1: SELECT '[,'::halfvec;
^ ^
DETAIL: Unexpected end of input.
SELECT '[]'::halfvec; SELECT '[]'::halfvec;
ERROR: halfvec must have at least 1 dimension ERROR: halfvec must have at least 1 dimension
LINE 1: SELECT '[]'::halfvec; LINE 1: SELECT '[]'::halfvec;
@@ -114,7 +110,7 @@ ERROR: halfvec must have at least 1 dimension
LINE 1: SELECT '[ ]'::halfvec; LINE 1: SELECT '[ ]'::halfvec;
^ ^
SELECT '[,]'::halfvec; SELECT '[,]'::halfvec;
ERROR: halfvec must have at least 1 dimension ERROR: invalid input syntax for type halfvec: "[,]"
LINE 1: SELECT '[,]'::halfvec; LINE 1: SELECT '[,]'::halfvec;
^ ^
SELECT '[1,]'::halfvec; SELECT '[1,]'::halfvec;