From 7cf4a323043c6ee10cb934149ddf74e4a605e0c1 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Wed, 30 Oct 2024 20:05:18 +0800 Subject: [PATCH 01/67] =?UTF-8?q?datavec=E8=BF=81=E7=A7=BBopenGauss?= =?UTF-8?q?=E5=86=85=E6=A0=B8=EF=BC=9A=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/utils/adt/bitvec.cpp | 81 + src/common/backend/utils/adt/f2s.cpp | 803 +++++++++ src/common/backend/utils/adt/halfutils.cpp | 294 ++++ src/common/backend/utils/adt/halfvec.cpp | 1211 ++++++++++++++ src/common/backend/utils/adt/sparsevec.cpp | 1137 +++++++++++++ src/common/backend/utils/adt/vector.cpp | 1472 +++++++++++++++++ .../storage/access/datavec/CMakeLists.txt | 16 + .../storage/access/datavec/bitutils.cpp | 215 +++ .../storage/access/datavec/hnsw.cpp | 362 ++++ .../storage/access/datavec/hnswbuild.cpp | 1089 ++++++++++++ .../storage/access/datavec/hnswdelete.cpp | 199 +++ .../storage/access/datavec/hnswinsert.cpp | 682 ++++++++ .../storage/access/datavec/hnswscan.cpp | 214 +++ .../storage/access/datavec/hnswutils.cpp | 1472 +++++++++++++++++ .../storage/access/datavec/hnswvacuum.cpp | 646 ++++++++ .../storage/access/datavec/ivfbuild.cpp | 906 ++++++++++ .../storage/access/datavec/ivfflat.cpp | 365 ++++ .../storage/access/datavec/ivfinsert.cpp | 208 +++ .../storage/access/datavec/ivfkmeans.cpp | 583 +++++++ .../storage/access/datavec/ivfscan.cpp | 363 ++++ .../storage/access/datavec/ivfutils.cpp | 369 +++++ .../storage/access/datavec/ivfvacuum.cpp | 157 ++ .../storage/access/datavec/vecindex.cpp | 293 ++++ src/include/access/datavec/bitvec.h | 17 + src/include/access/datavec/halfutils.h | 263 +++ src/include/access/datavec/halfvec.h | 112 ++ src/include/access/datavec/hnsw.h | 642 +++++++ src/include/access/datavec/ivfflat.h | 330 ++++ src/include/access/datavec/pg_prng.h | 61 + src/include/access/datavec/ryu_common.h | 150 ++ src/include/access/datavec/sampling.h | 45 + src/include/access/datavec/shortest_dec.h | 9 + src/include/access/datavec/sparsevec.h | 67 + src/include/access/datavec/vecindex.h | 23 + src/include/access/datavec/vector.h | 72 + 35 files changed, 14928 insertions(+) create mode 100644 src/common/backend/utils/adt/bitvec.cpp create mode 100644 src/common/backend/utils/adt/f2s.cpp create mode 100644 src/common/backend/utils/adt/halfutils.cpp create mode 100644 src/common/backend/utils/adt/halfvec.cpp create mode 100644 src/common/backend/utils/adt/sparsevec.cpp create mode 100644 src/common/backend/utils/adt/vector.cpp create mode 100644 src/gausskernel/storage/access/datavec/CMakeLists.txt create mode 100644 src/gausskernel/storage/access/datavec/bitutils.cpp create mode 100644 src/gausskernel/storage/access/datavec/hnsw.cpp create mode 100644 src/gausskernel/storage/access/datavec/hnswbuild.cpp create mode 100644 src/gausskernel/storage/access/datavec/hnswdelete.cpp create mode 100644 src/gausskernel/storage/access/datavec/hnswinsert.cpp create mode 100644 src/gausskernel/storage/access/datavec/hnswscan.cpp create mode 100644 src/gausskernel/storage/access/datavec/hnswutils.cpp create mode 100644 src/gausskernel/storage/access/datavec/hnswvacuum.cpp create mode 100644 src/gausskernel/storage/access/datavec/ivfbuild.cpp create mode 100644 src/gausskernel/storage/access/datavec/ivfflat.cpp create mode 100644 src/gausskernel/storage/access/datavec/ivfinsert.cpp create mode 100644 src/gausskernel/storage/access/datavec/ivfkmeans.cpp create mode 100644 src/gausskernel/storage/access/datavec/ivfscan.cpp create mode 100644 src/gausskernel/storage/access/datavec/ivfutils.cpp create mode 100644 src/gausskernel/storage/access/datavec/ivfvacuum.cpp create mode 100644 src/gausskernel/storage/access/datavec/vecindex.cpp create mode 100644 src/include/access/datavec/bitvec.h create mode 100644 src/include/access/datavec/halfutils.h create mode 100644 src/include/access/datavec/halfvec.h create mode 100644 src/include/access/datavec/hnsw.h create mode 100644 src/include/access/datavec/ivfflat.h create mode 100644 src/include/access/datavec/pg_prng.h create mode 100644 src/include/access/datavec/ryu_common.h create mode 100644 src/include/access/datavec/sampling.h create mode 100644 src/include/access/datavec/shortest_dec.h create mode 100644 src/include/access/datavec/sparsevec.h create mode 100644 src/include/access/datavec/vecindex.h create mode 100644 src/include/access/datavec/vector.h diff --git a/src/common/backend/utils/adt/bitvec.cpp b/src/common/backend/utils/adt/bitvec.cpp new file mode 100644 index 0000000000..bbaeb4e9f7 --- /dev/null +++ b/src/common/backend/utils/adt/bitvec.cpp @@ -0,0 +1,81 @@ +#include "postgres.h" + +#include "access/datavec/bitvec.h" +#include "utils/varbit.h" + +#if PG_VERSION_NUM >= 160000 +#include "varatt.h" +#endif + +uint64 (*BitHammingDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance); +double (*BitJaccardDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb); +static THR_LOCAL bool BitvecNeedInitialization = true; + +/* + * Allocate and initialize a new bit vector + */ +VarBit * +InitBitVector(int dim) +{ + VarBit *result; + int size; + + size = VARBITTOTALLEN(dim); + result = (VarBit *) palloc0(size); + SET_VARSIZE(result, size); + VARBITLEN(result) = dim; + + return result; +} + +/* + * Ensure same dimensions + */ +static inline void +CheckDims(VarBit *a, VarBit *b) +{ + if (VARBITLEN(a) != VARBITLEN(b)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different bit lengths %u and %u", VARBITLEN(a), VARBITLEN(b)))); +} + +/* + * Get the Hamming distance between two bit vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(hamming_distance); +Datum +hamming_distance(PG_FUNCTION_ARGS) +{ + VarBit *a = PG_GETARG_VARBIT_P(0); + VarBit *b = PG_GETARG_VARBIT_P(1); + + if (BitvecNeedInitialization) { + BitvecInit(); + BitvecNeedInitialization = false; + } + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) BitHammingDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0)); +} + +/* + * Get the Jaccard distance between two bit vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(jaccard_distance); +Datum +jaccard_distance(PG_FUNCTION_ARGS) +{ + VarBit *a = PG_GETARG_VARBIT_P(0); + VarBit *b = PG_GETARG_VARBIT_P(1); + + if (BitvecNeedInitialization) { + BitvecInit(); + BitvecNeedInitialization = false; + } + + CheckDims(a, b); + + PG_RETURN_FLOAT8(BitJaccardDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0, 0, 0)); +} diff --git a/src/common/backend/utils/adt/f2s.cpp b/src/common/backend/utils/adt/f2s.cpp new file mode 100644 index 0000000000..56432680b2 --- /dev/null +++ b/src/common/backend/utils/adt/f2s.cpp @@ -0,0 +1,803 @@ +/*--------------------------------------------------------------------------- + * + * Ryu floating-point output for single precision. + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/f2s.c + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ + +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif + +#include "access/datavec/shortest_dec.h" + +#include "access/datavec/ryu_common.h" + +#define FLOAT_MANTISSA_BITS 23 +#define FLOAT_EXPONENT_BITS 8 +#define FLOAT_BIAS 127 + +/* + * This table is generated (by the upstream) by PrintFloatLookupTable, + * and modified (by us) to add UINT64CONST. + */ +#define FLOAT_POW5_INV_BITCOUNT 59 +static const uint64 FLOAT_POW5_INV_SPLIT[31] = { + UINT64CONST(576460752303423489), UINT64CONST(461168601842738791), UINT64CONST(368934881474191033), UINT64CONST(295147905179352826), + UINT64CONST(472236648286964522), UINT64CONST(377789318629571618), UINT64CONST(302231454903657294), UINT64CONST(483570327845851670), + UINT64CONST(386856262276681336), UINT64CONST(309485009821345069), UINT64CONST(495176015714152110), UINT64CONST(396140812571321688), + UINT64CONST(316912650057057351), UINT64CONST(507060240091291761), UINT64CONST(405648192073033409), UINT64CONST(324518553658426727), + UINT64CONST(519229685853482763), UINT64CONST(415383748682786211), UINT64CONST(332306998946228969), UINT64CONST(531691198313966350), + UINT64CONST(425352958651173080), UINT64CONST(340282366920938464), UINT64CONST(544451787073501542), UINT64CONST(435561429658801234), + UINT64CONST(348449143727040987), UINT64CONST(557518629963265579), UINT64CONST(446014903970612463), UINT64CONST(356811923176489971), + UINT64CONST(570899077082383953), UINT64CONST(456719261665907162), UINT64CONST(365375409332725730) +}; +#define FLOAT_POW5_BITCOUNT 61 +static const uint64 FLOAT_POW5_SPLIT[47] = { + UINT64CONST(1152921504606846976), UINT64CONST(1441151880758558720), UINT64CONST(1801439850948198400), UINT64CONST(2251799813685248000), + UINT64CONST(1407374883553280000), UINT64CONST(1759218604441600000), UINT64CONST(2199023255552000000), UINT64CONST(1374389534720000000), + UINT64CONST(1717986918400000000), UINT64CONST(2147483648000000000), UINT64CONST(1342177280000000000), UINT64CONST(1677721600000000000), + UINT64CONST(2097152000000000000), UINT64CONST(1310720000000000000), UINT64CONST(1638400000000000000), UINT64CONST(2048000000000000000), + UINT64CONST(1280000000000000000), UINT64CONST(1600000000000000000), UINT64CONST(2000000000000000000), UINT64CONST(1250000000000000000), + UINT64CONST(1562500000000000000), UINT64CONST(1953125000000000000), UINT64CONST(1220703125000000000), UINT64CONST(1525878906250000000), + UINT64CONST(1907348632812500000), UINT64CONST(1192092895507812500), UINT64CONST(1490116119384765625), UINT64CONST(1862645149230957031), + UINT64CONST(1164153218269348144), UINT64CONST(1455191522836685180), UINT64CONST(1818989403545856475), UINT64CONST(2273736754432320594), + UINT64CONST(1421085471520200371), UINT64CONST(1776356839400250464), UINT64CONST(2220446049250313080), UINT64CONST(1387778780781445675), + UINT64CONST(1734723475976807094), UINT64CONST(2168404344971008868), UINT64CONST(1355252715606880542), UINT64CONST(1694065894508600678), + UINT64CONST(2117582368135750847), UINT64CONST(1323488980084844279), UINT64CONST(1654361225106055349), UINT64CONST(2067951531382569187), + UINT64CONST(1292469707114105741), UINT64CONST(1615587133892632177), UINT64CONST(2019483917365790221) +}; + +static inline uint32 +pow5Factor(uint32 value) +{ + uint32 count = 0; + + for (;;) + { + Assert(value != 0); + const uint32 q = value / 5; + const uint32 r = value % 5; + + if (r != 0) + break; + + value = q; + ++count; + } + return count; +} + +/* Returns true if value is divisible by 5^p. */ +static inline bool +multipleOfPowerOf5(const uint32 value, const uint32 p) +{ + return pow5Factor(value) >= p; +} + +/* Returns true if value is divisible by 2^p. */ +static inline bool +multipleOfPowerOf2(const uint32 value, const uint32 p) +{ + /* return __builtin_ctz(value) >= p; */ + return (value & ((1u << p) - 1)) == 0; +} + +/* + * It seems to be slightly faster to avoid uint128_t here, although the + * generated code for uint128_t looks slightly nicer. + */ +static inline uint32 +mulShift(const uint32 m, const uint64 factor, const int32 shift) +{ + /* + * The casts here help MSVC to avoid calls to the __allmul library + * function. + */ + const uint32 factorLo = (uint32) (factor); + const uint32 factorHi = (uint32) (factor >> 32); + const uint64 bits0 = (uint64) m * factorLo; + const uint64 bits1 = (uint64) m * factorHi; + + Assert(shift > 32); + +#ifdef RYU_32_BIT_PLATFORM + + /* + * On 32-bit platforms we can avoid a 64-bit shift-right since we only + * need the upper 32 bits of the result and the shift value is > 32. + */ + const uint32 bits0Hi = (uint32) (bits0 >> 32); + uint32 bits1Lo = (uint32) (bits1); + uint32 bits1Hi = (uint32) (bits1 >> 32); + + bits1Lo += bits0Hi; + bits1Hi += (bits1Lo < bits0Hi); + + const int32 s = shift - 32; + + return (bits1Hi << (32 - s)) | (bits1Lo >> s); + +#else /* RYU_32_BIT_PLATFORM */ + + const uint64 sum = (bits0 >> 32) + bits1; + const uint64 shiftedSum = sum >> (shift - 32); + + Assert(shiftedSum <= UINT32_MAX); + return (uint32) shiftedSum; + +#endif /* RYU_32_BIT_PLATFORM */ +} + +static inline uint32 +mulPow5InvDivPow2(const uint32 m, const uint32 q, const int32 j) +{ + return mulShift(m, FLOAT_POW5_INV_SPLIT[q], j); +} + +static inline uint32 +mulPow5divPow2(const uint32 m, const uint32 i, const int32 j) +{ + return mulShift(m, FLOAT_POW5_SPLIT[i], j); +} + +static inline uint32 +decimalLength(const uint32 v) +{ + /* Function precondition: v is not a 10-digit number. */ + /* (9 digits are sufficient for round-tripping.) */ + Assert(v < 1000000000); + if (v >= 100000000) + { + return 9; + } + if (v >= 10000000) + { + return 8; + } + if (v >= 1000000) + { + return 7; + } + if (v >= 100000) + { + return 6; + } + if (v >= 10000) + { + return 5; + } + if (v >= 1000) + { + return 4; + } + if (v >= 100) + { + return 3; + } + if (v >= 10) + { + return 2; + } + return 1; +} + +/* A floating decimal representing m * 10^e. */ +typedef struct floating_decimal_32 +{ + uint32 mantissa; + int32 exponent; +} floating_decimal_32; + +static inline floating_decimal_32 +f2d(const uint32 ieeeMantissa, const uint32 ieeeExponent) +{ + int32 e2; + uint32 m2; + + if (ieeeExponent == 0) + { + /* We subtract 2 so that the bounds computation has 2 additional bits. */ + e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; + m2 = ieeeMantissa; + } + else + { + e2 = ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; + m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa; + } + +#if STRICTLY_SHORTEST + const bool even = (m2 & 1) == 0; + const bool acceptBounds = even; +#else + const bool acceptBounds = false; +#endif + + /* Step 2: Determine the interval of legal decimal representations. */ + const uint32 mv = 4 * m2; + const uint32 mp = 4 * m2 + 2; + + /* Implicit bool -> int conversion. True is 1, false is 0. */ + const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; + const uint32 mm = 4 * m2 - 1 - mmShift; + + /* Step 3: Convert to a decimal power base using 64-bit arithmetic. */ + uint32 vr, + vp, + vm; + int32 e10; + bool vmIsTrailingZeros = false; + bool vrIsTrailingZeros = false; + uint8 lastRemovedDigit = 0; + + if (e2 >= 0) + { + const uint32 q = log10Pow2(e2); + + e10 = q; + + const int32 k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1; + const int32 i = -e2 + q + k; + + vr = mulPow5InvDivPow2(mv, q, i); + vp = mulPow5InvDivPow2(mp, q, i); + vm = mulPow5InvDivPow2(mm, q, i); + + if (q != 0 && (vp - 1) / 10 <= vm / 10) + { + /* + * We need to know one removed digit even if we are not going to + * loop below. We could use q = X - 1 above, except that would + * require 33 bits for the result, and we've found that 32-bit + * arithmetic is faster even on 64-bit machines. + */ + const int32 l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q - 1) - 1; + + lastRemovedDigit = (uint8) (mulPow5InvDivPow2(mv, q - 1, -e2 + q - 1 + l) % 10); + } + if (q <= 9) + { + /* + * The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 + * seems to be safe as well. + * + * Only one of mp, mv, and mm can be a multiple of 5, if any. + */ + if (mv % 5 == 0) + { + vrIsTrailingZeros = multipleOfPowerOf5(mv, q); + } + else if (acceptBounds) + { + vmIsTrailingZeros = multipleOfPowerOf5(mm, q); + } + else + { + vp -= multipleOfPowerOf5(mp, q); + } + } + } + else + { + const uint32 q = log10Pow5(-e2); + + e10 = q + e2; + + const int32 i = -e2 - q; + const int32 k = pow5bits(i) - FLOAT_POW5_BITCOUNT; + int32 j = q - k; + + vr = mulPow5divPow2(mv, i, j); + vp = mulPow5divPow2(mp, i, j); + vm = mulPow5divPow2(mm, i, j); + + if (q != 0 && (vp - 1) / 10 <= vm / 10) + { + j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); + lastRemovedDigit = (uint8) (mulPow5divPow2(mv, i + 1, j) % 10); + } + if (q <= 1) + { + /* + * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q + * trailing 0 bits. + */ + /* mv = 4 * m2, so it always has at least two trailing 0 bits. */ + vrIsTrailingZeros = true; + if (acceptBounds) + { + /* + * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff + * mmShift == 1. + */ + vmIsTrailingZeros = mmShift == 1; + } + else + { + /* + * mp = mv + 2, so it always has at least one trailing 0 bit. + */ + --vp; + } + } + else if (q < 31) + { + /* TODO(ulfjack):Use a tighter bound here. */ + vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); + } + } + + /* + * Step 4: Find the shortest decimal representation in the interval of + * legal representations. + */ + uint32 removed = 0; + uint32 output; + + if (vmIsTrailingZeros || vrIsTrailingZeros) + { + /* General case, which happens rarely (~4.0%). */ + while (vp / 10 > vm / 10) + { + vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0; + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8) (vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + if (vmIsTrailingZeros) + { + while (vm % 10 == 0) + { + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8) (vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + } + + if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) + { + /* Round even if the exact number is .....50..0. */ + lastRemovedDigit = 4; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); + } + else + { + /* + * Specialized for the common case (~96.0%). Percentages below are + * relative to this. + * + * Loop iterations below (approximately): 0: 13.6%, 1: 70.7%, 2: + * 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% + */ + while (vp / 10 > vm / 10) + { + lastRemovedDigit = (uint8) (vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + (vr == vm || lastRemovedDigit >= 5); + } + + const int32 exp = e10 + removed; + + floating_decimal_32 fd; + + fd.exponent = exp; + fd.mantissa = output; + return fd; +} + +static inline int +to_chars_f(const floating_decimal_32 v, const uint32 olength, char *const result) +{ + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint32 output = v.mantissa; + int32 exp = v.exponent; + + /*---- + * On entry, mantissa * 10^exp is the result to be output. + * Caller has already done the - sign if needed. + * + * We want to insert the point somewhere depending on the output length + * and exponent, which might mean adding zeros: + * + * exp | format + * 1+ | ddddddddd000000 + * 0 | ddddddddd + * -1 .. -len+1 | dddddddd.d to d.ddddddddd + * -len ... | 0.ddddddddd to 0.000dddddd + */ + uint32 i = 0; + int32 nexp = exp + olength; + + if (nexp <= 0) + { + /* -nexp is number of 0s to add after '.' */ + Assert(nexp >= -3); + /* 0.000ddddd */ + index = 2 - nexp; + /* copy 8 bytes rather than 5 to let compiler optimize */ + memcpy(result, "0.000000", 8); + } + else if (exp < 0) + { + /* + * dddd.dddd; leave space at the start and move the '.' in after + */ + index = 1; + } + else + { + /* + * We can save some code later by pre-filling with zeros. We know + * that there can be no more than 6 output digits in this form, + * otherwise we would not choose fixed-point output. memset 8 + * rather than 6 bytes to let the compiler optimize it. + */ + Assert(exp < 6 && exp + olength <= 6); + memset(result, '0', 8); + } + + while (output >= 10000) + { + const uint32 c = output - 10000 * (output / 10000); + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + output /= 10000; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output >= 100) + { + const uint32 c = (output % 100) << 1; + + output /= 100; + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + i += 2; + } + if (output >= 10) + { + const uint32 c = output << 1; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + } + else + { + result[index] = (char) ('0' + output); + } + + if (index == 1) + { + /* + * nexp is 1..6 here, representing the number of digits before the + * point. A value of 7+ is not possible because we switch to + * scientific notation when the display exponent reaches 6. + */ + Assert(nexp < 7); + /* gcc only seems to want to optimize memmove for small 2^n */ + if (nexp & 4) + { + memmove(result + index - 1, result + index, 4); + index += 4; + } + if (nexp & 2) + { + memmove(result + index - 1, result + index, 2); + index += 2; + } + if (nexp & 1) + { + result[index - 1] = result[index]; + } + result[nexp] = '.'; + index = olength + 1; + } + else if (exp >= 0) + { + /* we supplied the trailing zeros earlier, now just set the length. */ + index = olength + exp; + } + else + { + index = olength + (2 - nexp); + } + + return index; +} + +static inline int +to_chars(const floating_decimal_32 v, const bool sign, char *const result) +{ + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint32 output = v.mantissa; + uint32 olength = decimalLength(output); + int32 exp = v.exponent + olength - 1; + + if (sign) + result[index++] = '-'; + + /* + * The thresholds for fixed-point output are chosen to match printf + * defaults. Beware that both the code of to_chars_f and the value + * of FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. + */ + if (exp >= -4 && exp < 6) + return to_chars_f(v, olength, result + index) + sign; + + /* + * If v.exponent is exactly 0, we might have reached here via the small + * integer fast path, in which case v.mantissa might contain trailing + * (decimal) zeros. For scientific notation we need to move these zeros + * into the exponent. (For fixed point this doesn't matter, which is why + * we do this here rather than above.) + * + * Since we already calculated the display exponent (exp) above based on + * the old decimal length, that value does not change here. Instead, we + * just reduce the display length for each digit removed. + * + * If we didn't get here via the fast path, the raw exponent will not + * usually be 0, and there will be no trailing zeros, so we pay no more + * than one div10/multiply extra cost. We claw back half of that by + * checking for divisibility by 2 before dividing by 10. + */ + if (v.exponent == 0) + { + while ((output & 1) == 0) + { + const uint32 q = output / 10; + const uint32 r = output - 10 * q; + + if (r != 0) + break; + output = q; + --olength; + } + } + + /*---- + * Print the decimal digits. + * The following code is equivalent to: + * + * for (uint32 i = 0; i < olength - 1; ++i) { + * const uint32 c = output % 10; output /= 10; + * result[index + olength - i] = (char) ('0' + c); + * } + * result[index] = '0' + output % 10; + */ + uint32 i = 0; + + while (output >= 10000) + { + const uint32 c = output - 10000 * (output / 10000); + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + output /= 10000; + + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output >= 100) + { + const uint32 c = (output % 100) << 1; + + output /= 100; + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); + i += 2; + } + if (output >= 10) + { + const uint32 c = output << 1; + + /* + * We can't use memcpy here: the decimal dot goes between these two + * digits. + */ + result[index + olength - i] = DIGIT_TABLE[c + 1]; + result[index] = DIGIT_TABLE[c]; + } + else + { + result[index] = (char) ('0' + output); + } + + /* Print decimal point if needed. */ + if (olength > 1) + { + result[index + 1] = '.'; + index += olength + 1; + } + else + { + ++index; + } + + /* Print the exponent. */ + result[index++] = 'e'; + if (exp < 0) + { + result[index++] = '-'; + exp = -exp; + } + else + result[index++] = '+'; + + memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); + index += 2; + + return index; +} + +static inline bool +f2d_small_int(const uint32 ieeeMantissa, + const uint32 ieeeExponent, + floating_decimal_32 *v) +{ + const int32 e2 = (int32) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS; + + /* + * Avoid using multiple "return false;" here since it tends to provoke the + * compiler into inlining multiple copies of f2d, which is undesirable. + */ + + if (e2 >= -FLOAT_MANTISSA_BITS && e2 <= 0) + { + /*---- + * Since 2^23 <= m2 < 2^24 and 0 <= -e2 <= 23: + * 1 <= f = m2 / 2^-e2 < 2^24. + * + * Test if the lower -e2 bits of the significand are 0, i.e. whether + * the fraction is 0. We can use ieeeMantissa here, since the implied + * 1 bit can never be tested by this; the implied 1 can only be part + * of a fraction if e2 < -FLOAT_MANTISSA_BITS which we already + * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -24) + */ + const uint32 mask = (1U << -e2) - 1; + const uint32 fraction = ieeeMantissa & mask; + + if (fraction == 0) + { + /*---- + * f is an integer in the range [1, 2^24). + * Note: mantissa might contain trailing (decimal) 0's. + * Note: since 2^24 < 10^9, there is no need to adjust + * decimalLength(). + */ + const uint32 m2 = (1U << FLOAT_MANTISSA_BITS) | ieeeMantissa; + + v->mantissa = m2 >> -e2; + v->exponent = 0; + return true; + } + } + + return false; +} + +/* + * Store the shortest decimal representation of the given float as an + * UNTERMINATED string in the caller's supplied buffer (which must be at least + * FLOAT_SHORTEST_DECIMAL_LEN-1 bytes long). + * + * Returns the number of bytes stored. + */ +int +float_to_shortest_decimal_bufn(float f, char *result) +{ + /* + * Step 1: Decode the floating-point number, and unify normalized and + * subnormal cases. + */ + const uint32 bits = float_to_bits(f); + + /* Decode bits into sign, mantissa, and exponent. */ + const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; + const uint32 ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1); + const uint32 ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1); + + /* Case distinction; exit early for the easy cases. */ + if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) + { + return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa); + } + + floating_decimal_32 v; + const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v); + + if (!isSmallInt) + { + v = f2d(ieeeMantissa, ieeeExponent); + } + + return to_chars(v, ieeeSign, result); +} + +/* + * Store the shortest decimal representation of the given float as a + * null-terminated string in the caller's supplied buffer (which must be at + * least FLOAT_SHORTEST_DECIMAL_LEN bytes long). + * + * Returns the string length. + */ +int +float_to_shortest_decimal_buf(float f, char *result) +{ + const int index = float_to_shortest_decimal_bufn(f, result); + + /* Terminate the string. */ + Assert(index < FLOAT_SHORTEST_DECIMAL_LEN); + result[index] = '\0'; + return index; +} + +/* + * Return the shortest decimal representation as a null-terminated palloc'd + * string (outside the backend, uses malloc() instead). + * + * Caller is responsible for freeing the result. + */ +char * +float_to_shortest_decimal(float f) +{ + char *const result = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN); + + float_to_shortest_decimal_buf(f, result); + return result; +} diff --git a/src/common/backend/utils/adt/halfutils.cpp b/src/common/backend/utils/adt/halfutils.cpp new file mode 100644 index 0000000000..6269af642c --- /dev/null +++ b/src/common/backend/utils/adt/halfutils.cpp @@ -0,0 +1,294 @@ +#include "postgres.h" + +#include "access/datavec/halfutils.h" +#include "access/datavec/halfvec.h" + +#ifdef HALFVEC_DISPATCH +#include + +#if defined(USE__GET_CPUID) +#include +#else +#include +#endif + +#define TARGET_F16C +#endif + +float (*HalfvecL2SquaredDistance) (int dim, half * ax, half * bx); +float (*HalfvecInnerProduct) (int dim, half * ax, half * bx); +double (*HalfvecCosineSimilarity) (int dim, half * ax, half * bx); +float (*HalfvecL1Distance) (int dim, half * ax, half * bx); + +static float +HalfvecL2SquaredDistanceDefault(int dim, half * ax, half * bx) +{ + float distance = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); + + distance += diff * diff; + } + + return distance; +} + +#ifdef HALFVEC_DISPATCH +TARGET_F16C static float +HalfvecL2SquaredDistanceF16c(int dim, half * ax, half * bx) +{ + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); + + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); + __m256 diff = _mm256_sub_ps(axs, bxs); + + dist = _mm256_fmadd_ps(diff, diff, dist); + } + + _mm256_storeu_ps(s, dist); + + distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + for (; i < dim; i++) + { + float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); + + distance += diff * diff; + } + + return distance; +} +#endif + +static float +HalfvecInnerProductDefault(int dim, half * ax, half * bx) +{ + float distance = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += HalfToFloat4(ax[i]) * HalfToFloat4(bx[i]); + + return distance; +} + +#ifdef HALFVEC_DISPATCH +TARGET_F16C static float +HalfvecInnerProductF16c(int dim, half * ax, half * bx) +{ + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); + + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); + + dist = _mm256_fmadd_ps(axs, bxs, dist); + } + + _mm256_storeu_ps(s, dist); + + distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + for (; i < dim; i++) + distance += HalfToFloat4(ax[i]) * HalfToFloat4(bx[i]); + + return distance; +} +#endif + +static double +HalfvecCosineSimilarityDefault(int dim, half * ax, half * bx) +{ + float similarity = 0.0; + float norma = 0.0; + float normb = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + float axi = HalfToFloat4(ax[i]); + float bxi = HalfToFloat4(bx[i]); + + similarity += axi * bxi; + norma += axi * axi; + normb += bxi * bxi; + } + + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + return (double) similarity / sqrt((double) norma * (double) normb); +} + +#ifdef HALFVEC_DISPATCH +TARGET_F16C static double +HalfvecCosineSimilarityF16c(int dim, half * ax, half * bx) +{ + float similarity; + float norma; + float normb; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 sim = _mm256_setzero_ps(); + __m256 na = _mm256_setzero_ps(); + __m256 nb = _mm256_setzero_ps(); + + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); + + sim = _mm256_fmadd_ps(axs, bxs, sim); + na = _mm256_fmadd_ps(axs, axs, na); + nb = _mm256_fmadd_ps(bxs, bxs, nb); + } + + _mm256_storeu_ps(s, sim); + similarity = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + _mm256_storeu_ps(s, na); + norma = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + _mm256_storeu_ps(s, nb); + normb = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + /* Auto-vectorized */ + for (; i < dim; i++) + { + float axi = HalfToFloat4(ax[i]); + float bxi = HalfToFloat4(bx[i]); + + similarity += axi * bxi; + norma += axi * axi; + normb += bxi * bxi; + } + + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + return (double) similarity / sqrt((double) norma * (double) normb); +} +#endif + +static float +HalfvecL1DistanceDefault(int dim, half * ax, half * bx) +{ + float distance = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += fabsf(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); + + return distance; +} + +#ifdef HALFVEC_DISPATCH +/* Does not require FMA, but keep logic simple */ +TARGET_F16C static float +HalfvecL1DistanceF16c(int dim, half * ax, half * bx) +{ + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); + __m256 sign = _mm256_set1_ps(-0.0); + + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); + + dist = _mm256_add_ps(dist, _mm256_andnot_ps(sign, _mm256_sub_ps(axs, bxs))); + } + + _mm256_storeu_ps(s, dist); + + distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + for (; i < dim; i++) + distance += fabsf(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); + + return distance; +} +#endif + +#ifdef HALFVEC_DISPATCH +#define CPU_FEATURE_FMA (1 << 12) +#define CPU_FEATURE_OSXSAVE (1 << 27) +#define CPU_FEATURE_AVX (1 << 28) +#define CPU_FEATURE_F16C (1 << 29) + +#ifdef _MSC_VER +#define TARGET_XSAVE +#else +#define TARGET_XSAVE __attribute__((target("xsave"))) +#endif + +TARGET_XSAVE static bool +SupportsCpuFeature(unsigned int feature) +{ + unsigned int exx[4] = {0, 0, 0, 0}; + +#if defined(USE__GET_CPUID) + __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); +#else + __cpuid(exx, 1); +#endif + + /* Check OS supports XSAVE */ + if ((exx[2] & CPU_FEATURE_OSXSAVE) != CPU_FEATURE_OSXSAVE) + return false; + + /* Check XMM and YMM registers are enabled */ + if ((_xgetbv(0) & 6) != 6) + return false; + + /* Now check features */ + return (exx[2] & feature) == feature; +} +#endif + +void +HalfvecInit(void) +{ + /* + * Could skip pointer when single function, but no difference in + * performance + */ + HalfvecL2SquaredDistance = HalfvecL2SquaredDistanceDefault; + HalfvecInnerProduct = HalfvecInnerProductDefault; + HalfvecCosineSimilarity = HalfvecCosineSimilarityDefault; + HalfvecL1Distance = HalfvecL1DistanceDefault; + +#ifdef HALFVEC_DISPATCH + if (SupportsCpuFeature(CPU_FEATURE_AVX | CPU_FEATURE_F16C | CPU_FEATURE_FMA)) + { + HalfvecL2SquaredDistance = HalfvecL2SquaredDistanceF16c; + HalfvecInnerProduct = HalfvecInnerProductF16c; + HalfvecCosineSimilarity = HalfvecCosineSimilarityF16c; + /* Does not require FMA, but keep logic simple */ + HalfvecL1Distance = HalfvecL1DistanceF16c; + } +#endif +} diff --git a/src/common/backend/utils/adt/halfvec.cpp b/src/common/backend/utils/adt/halfvec.cpp new file mode 100644 index 0000000000..4fab3462f4 --- /dev/null +++ b/src/common/backend/utils/adt/halfvec.cpp @@ -0,0 +1,1211 @@ +#include "postgres.h" + +#include + +#include "access/datavec/bitvec.h" +#include "catalog/pg_type.h" +#include "fmgr.h" +#include "access/datavec/halfutils.h" +#include "access/datavec/halfvec.h" +#include "lib/stringinfo.h" +#include "libpq/pqformat.h" +#include "port.h" /* for strtof() */ +#include "access/datavec/shortest_dec.h" +#include "access/datavec/sparsevec.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "utils/lsyscache.h" +#include "utils/numeric.h" +#include "access/datavec/vector.h" + +#if PG_VERSION_NUM < 130000 +#define TYPALIGN_DOUBLE 'd' +#define TYPALIGN_INT 'i' +#endif + +#define STATE_DIMS(x) (ARR_DIMS(x)[0] - 1) +#define CreateStateDatums(dim) palloc(sizeof(Datum) * (dim + 1)) + +/* + * Get a half from a message buffer + */ +static half +pq_getmsghalf(StringInfo msg) +{ + union + { + half h; + uint16 i; + } swap; + + swap.i = pq_getmsgint(msg, 2); + return swap.h; +} + +/* + * Append a half to a StringInfo buffer + */ +static void +pq_sendhalf(StringInfo buf, half h) +{ + union + { + half h; + uint16 i; + } swap; + + swap.h = h; + pq_sendint16(buf, swap.i); +} + +/* + * Ensure same dimensions + */ +static inline void +CheckDims(HalfVector * a, HalfVector * b) +{ + if (a->dim != b->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different halfvec dimensions %d and %d", a->dim, b->dim))); +} + +/* + * Ensure expected dimensions + */ +static inline void +CheckExpectedDim(int32 typmod, int dim) +{ + if (typmod != -1 && typmod != dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected %d dimensions, not %d", typmod, dim))); +} + +/* + * Ensure valid dimensions + */ +static inline void +CheckDim(int dim) +{ + if (dim < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + if (dim > HALFVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); +} + +/* + * Ensure finite element + */ +static inline void +CheckElement(half value) +{ + if (HalfIsNan(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("NaN not allowed in halfvec"))); + + if (HalfIsInf(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("infinite value not allowed in halfvec"))); +} + +/* + * Allocate and initialize a new half vector + */ +HalfVector * +InitHalfVector(int dim) +{ + HalfVector *result; + int size; + + size = HALFVEC_SIZE(dim); + result = (HalfVector *) palloc0(size); + SET_VARSIZE(result, size); + result->dim = dim; + + return result; +} + +/* + * Check for whitespace, since array_isspace() is static + */ +static inline bool +halfvec_isspace(char ch) +{ + if (ch == ' ' || + ch == '\t' || + ch == '\n' || + ch == '\r' || + ch == '\v' || + ch == '\f') + return true; + return false; +} + +/* + * Check state array + */ +static float8 * +CheckStateArray(ArrayType *statearray, const char *caller) +{ + if (ARR_NDIM(statearray) != 1 || + ARR_DIMS(statearray)[0] < 1 || + ARR_HASNULL(statearray) || + ARR_ELEMTYPE(statearray) != FLOAT8OID) + elog(ERROR, "%s: expected state array", caller); + return (float8 *) ARR_DATA_PTR(statearray); +} + +#if PG_VERSION_NUM < 120003 +static pg_noinline void +float_overflow_error(void) +{ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); +} + +static pg_noinline void +float_underflow_error(void) +{ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: underflow"))); +} +#endif + +/* + * Convert textual representation to internal representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_in); +Datum +halfvec_in(PG_FUNCTION_ARGS) +{ + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + half x[HALFVEC_MAX_DIM]; + int dim = 0; + char *pt = lit; + HalfVector *result; + + while (halfvec_isspace(*pt)) + pt++; + + if (*pt != '[') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit), + errdetail("Vector contents must start with \"[\"."))); + + pt++; + + while (halfvec_isspace(*pt)) + pt++; + + if (*pt == ']') + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + for (;;) + { + float val; + char *stringEnd; + + if (dim == HALFVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); + + while (halfvec_isspace(*pt)) + pt++; + + /* Check for empty string like float4in */ + if (*pt == '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + + errno = 0; + + /* Postgres sets LC_NUMERIC to C on startup */ + val = strtof(pt, &stringEnd); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + + x[dim] = Float4ToHalfUnchecked(val); + + /* Check for range error like float4in */ + if ((errno == ERANGE && isinf(val)) || (HalfIsInf(x[dim]) && !isinf(val))) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt)))); + + CheckElement(x[dim]); + dim++; + + pt = stringEnd; + + while (halfvec_isspace(*pt)) + pt++; + + if (*pt == ',') + pt++; + else if (*pt == ']') + { + pt++; + break; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + } + + /* Only whitespace is allowed after the closing brace */ + while (halfvec_isspace(*pt)) + pt++; + + if (*pt != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit), + errdetail("Junk after closing right brace."))); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + result = InitHalfVector(dim); + for (int i = 0; i < dim; i++) + result->x[i] = x[i]; + + PG_RETURN_POINTER(result); +} + +#define AppendChar(ptr, c) (*(ptr)++ = (c)) +#define AppendFloat(ptr, f) ((ptr) += float_to_shortest_decimal_bufn((f), (ptr))) + +/* + * Convert internal representation to textual representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_out); +Datum +halfvec_out(PG_FUNCTION_ARGS) +{ + HalfVector *vector = PG_GETARG_HALFVEC_P(0); + int dim = vector->dim; + char *buf; + char *ptr; + + /* + * Need: + * + * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for + * float_to_shortest_decimal_bufn + * + * dim - 1 bytes for separator + * + * 3 bytes for [, ], and \0 + */ + buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); + ptr = buf; + + AppendChar(ptr, '['); + + for (int i = 0; i < dim; i++) + { + if (i > 0) + AppendChar(ptr, ','); + + /* + * Use shortest decimal representation of single-precision float for + * simplicity + */ + AppendFloat(ptr, HalfToFloat4(vector->x[i])); + } + + AppendChar(ptr, ']'); + *ptr = '\0'; + + PG_FREE_IF_COPY(vector, 0); + PG_RETURN_CSTRING(buf); +} + +/* + * Convert type modifier + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_typmod_in); +Datum +halfvec_typmod_in(PG_FUNCTION_ARGS) +{ + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; + + tl = ArrayGetIntegerTypmods(ta, &n); + + if (n != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid type modifier"))); + + if (*tl < 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type halfvec must be at least 1"))); + + if (*tl > HALFVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type halfvec cannot exceed %d", HALFVEC_MAX_DIM))); + + PG_RETURN_INT32(*tl); +} + +/* + * Convert external binary representation to internal representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_recv); +Datum +halfvec_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); + HalfVector *result; + int16 dim; + int16 unused; + + dim = pq_getmsgint(buf, sizeof(int16)); + unused = pq_getmsgint(buf, sizeof(int16)); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + if (unused != 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected unused to be 0, not %d", unused))); + + result = InitHalfVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = pq_getmsghalf(buf); + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); +} + +/* + * Convert internal representation to the external binary representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_send); +Datum +halfvec_send(PG_FUNCTION_ARGS) +{ + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + StringInfoData buf; + + pq_begintypsend(&buf); + pq_sendint(&buf, vec->dim, sizeof(int16)); + pq_sendint(&buf, vec->unused, sizeof(int16)); + for (int i = 0; i < vec->dim; i++) + pq_sendhalf(&buf, vec->x[i]); + + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} + +/* + * Convert half vector to half vector + * This is needed to check the type modifier + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec); +Datum +halfvec(PG_FUNCTION_ARGS) +{ + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + + CheckExpectedDim(typmod, vec->dim); + + PG_RETURN_POINTER(vec); +} + +/* + * Convert array to half vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(array_to_halfvec); +Datum +array_to_halfvec(PG_FUNCTION_ARGS) +{ + ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); + int32 typmod = PG_GETARG_INT32(1); + HalfVector *result; + int16 typlen; + bool typbyval; + char typalign; + Datum *elemsp; + int nelemsp; + + if (ARR_NDIM(array) > 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("array must be 1-D"))); + + if (ARR_HASNULL(array) && array_contains_nulls(array)) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("array must not contain nulls"))); + + get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); + deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); + + CheckDim(nelemsp); + CheckExpectedDim(typmod, nelemsp); + + result = InitHalfVector(nelemsp); + + if (ARR_ELEMTYPE(array) == INT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetInt32(elemsp[i])); + } + else if (ARR_ELEMTYPE(array) == FLOAT8OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetFloat8(elemsp[i])); + } + else if (ARR_ELEMTYPE(array) == FLOAT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetFloat4(elemsp[i])); + } + else if (ARR_ELEMTYPE(array) == NUMERICOID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i]))); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("unsupported array type"))); + } + + /* + * Free allocation from deconstruct_array. Do not free individual elements + * when pass-by-reference since they point to original array. + */ + pfree(elemsp); + + /* Check elements */ + for (int i = 0; i < result->dim; i++) + CheckElement(result->x[i]); + + PG_RETURN_POINTER(result); +} + +/* + * Convert half vector to float4[] + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_float4); +Datum +halfvec_to_float4(PG_FUNCTION_ARGS) +{ + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + Datum *datums; + ArrayType *result; + + datums = (Datum *) palloc(sizeof(Datum) * vec->dim); + + for (int i = 0; i < vec->dim; i++) + datums[i] = Float4GetDatum(HalfToFloat4(vec->x[i])); + + /* Use TYPALIGN_INT for float4 */ + result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); + + pfree(datums); + + PG_RETURN_POINTER(result); +} + +/* + * Convert vector to half vec + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_halfvec); +Datum +vector_to_halfvec(PG_FUNCTION_ARGS) +{ + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); + HalfVector *result; + + CheckDim(vec->dim); + CheckExpectedDim(typmod, vec->dim); + + result = InitHalfVector(vec->dim); + + for (int i = 0; i < vec->dim; i++) + result->x[i] = Float4ToHalf(vec->x[i]); + + PG_RETURN_POINTER(result); +} + +/* + * Get the L2 distance between half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_distance); +Datum +halfvec_l2_distance(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8(sqrt((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x))); +} + +/* + * Get the L2 squared distance between half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_squared_distance); +Datum +halfvec_l2_squared_distance(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x)); +} + +/* + * Get the inner product of two half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_inner_product); +Datum +halfvec_inner_product(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) HalfvecInnerProduct(a->dim, a->x, b->x)); +} + +/* + * Get the negative inner product of two half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_negative_inner_product); +Datum +halfvec_negative_inner_product(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) -HalfvecInnerProduct(a->dim, a->x, b->x)); +} + +/* + * Get the cosine distance between two half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_cosine_distance); +Datum +halfvec_cosine_distance(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + double similarity; + + CheckDims(a, b); + + similarity = HalfvecCosineSimilarity(a->dim, a->x, b->x); + +#ifdef _MSC_VER + /* /fp:fast may not propagate NaN */ + if (isnan(similarity)) + PG_RETURN_FLOAT8(NAN); +#endif + + /* Keep in range */ + if (similarity > 1) + similarity = 1; + else if (similarity < -1) + similarity = -1; + + PG_RETURN_FLOAT8(1 - similarity); +} + +/* + * Get the distance for spherical k-means + * Currently uses angular distance since needs to satisfy triangle inequality + * Assumes inputs are unit vectors (skips norm) + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_spherical_distance); +Datum +halfvec_spherical_distance(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + double distance; + + CheckDims(a, b); + + distance = (double) HalfvecInnerProduct(a->dim, a->x, b->x); + + /* Prevent NaN with acos with loss of precision */ + if (distance > 1) + distance = 1; + else if (distance < -1) + distance = -1; + + PG_RETURN_FLOAT8(acos(distance) / M_PI); +} + +/* + * Get the L1 distance between two half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l1_distance); +Datum +halfvec_l1_distance(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) HalfvecL1Distance(a->dim, a->x, b->x)); +} + +/* + * Get the dimensions of a half vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_vector_dims); +Datum +halfvec_vector_dims(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + + PG_RETURN_INT32(a->dim); +} + +/* + * Get the L2 norm of a half vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_norm); +Datum +halfvec_l2_norm(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + half *ax = a->x; + double norm = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + { + double axi = (double) HalfToFloat4(ax[i]); + + norm += axi * axi; + } + + PG_RETURN_FLOAT8(sqrt(norm)); +} + +/* + * Normalize a half vector with the L2 norm + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_normalize); +Datum +halfvec_l2_normalize(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + half *ax = a->x; + double norm = 0; + HalfVector *result; + half *rx; + + result = InitHalfVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + norm += (double) HalfToFloat4(ax[i]) * (double) HalfToFloat4(ax[i]); + + norm = sqrt(norm); + + /* Return zero vector for zero norm */ + if (norm > 0) + { + for (int i = 0; i < a->dim; i++) + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) / norm); + + /* Check for overflow */ + for (int i = 0; i < a->dim; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); + } + } + + PG_RETURN_POINTER(result); +} + +/* + * Add half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_add); +Datum +halfvec_add(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + half *ax = a->x; + half *bx = b->x; + HalfVector *result; + half *rx; + + CheckDims(a, b); + + result = InitHalfVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + { +#ifdef FLT16_SUPPORT + rx[i] = ax[i] + bx[i]; +#else + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) + HalfToFloat4(bx[i])); +#endif + } + + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); + } + + PG_RETURN_POINTER(result); +} + +/* + * Subtract half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_sub); +Datum +halfvec_sub(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + half *ax = a->x; + half *bx = b->x; + HalfVector *result; + half *rx; + + CheckDims(a, b); + + result = InitHalfVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + { +#ifdef FLT16_SUPPORT + rx[i] = ax[i] - bx[i]; +#else + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); +#endif + } + + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); + } + + PG_RETURN_POINTER(result); +} + +/* + * Multiply half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_mul); +Datum +halfvec_mul(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + half *ax = a->x; + half *bx = b->x; + HalfVector *result; + half *rx; + + CheckDims(a, b); + + result = InitHalfVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + { +#ifdef FLT16_SUPPORT + rx[i] = ax[i] * bx[i]; +#else + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) * HalfToFloat4(bx[i])); +#endif + } + + /* Check for overflow and underflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); + + if (HalfIsZero(rx[i]) && !(HalfIsZero(ax[i]) || HalfIsZero(bx[i]))) + float_underflow_error(); + } + + PG_RETURN_POINTER(result); +} + +/* + * Concatenate half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_concat); +Datum +halfvec_concat(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *result; + int dim = a->dim + b->dim; + + CheckDim(dim); + result = InitHalfVector(dim); + + for (int i = 0; i < a->dim; i++) + result->x[i] = a->x[i]; + + for (int i = 0; i < b->dim; i++) + result->x[i + a->dim] = b->x[i]; + + PG_RETURN_POINTER(result); +} + +/* + * Quantize a half vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_binary_quantize); +Datum +halfvec_binary_quantize(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + half *ax = a->x; + VarBit *result = InitBitVector(a->dim); + unsigned char *rx = VARBITS(result); + + for (int i = 0; i < a->dim; i++) + rx[i / 8] |= (HalfToFloat4(ax[i]) > 0) << (7 - (i % 8)); + + PG_RETURN_VARBIT_P(result); +} + +/* + * Get a subvector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_subvector); +Datum +halfvec_subvector(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + int32 start = PG_GETARG_INT32(1); + int32 count = PG_GETARG_INT32(2); + int32 end; + half *ax = a->x; + HalfVector *result; + int32 dim; + + if (count < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + /* + * Check if (start + count > a->dim), avoiding integer overflow. a->dim + * and count are both positive, so a->dim - count won't overflow. + */ + if (start > a->dim - count) + end = a->dim + 1; + else + end = start + count; + + /* Indexing starts at 1, like substring */ + if (start < 1) + start = 1; + else if (start > a->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + dim = end - start; + CheckDim(dim); + result = InitHalfVector(dim); + + for (int i = 0; i < dim; i++) + result->x[i] = ax[start - 1 + i]; + + PG_RETURN_POINTER(result); +} + +/* + * Internal helper to compare half vectors + */ +static int +halfvec_cmp_internal(HalfVector * a, HalfVector * b) +{ + int dim = Min(a->dim, b->dim); + + /* Check values before dimensions to be consistent with Postgres arrays */ + for (int i = 0; i < dim; i++) + { + if (HalfToFloat4(a->x[i]) < HalfToFloat4(b->x[i])) + return -1; + + if (HalfToFloat4(a->x[i]) > HalfToFloat4(b->x[i])) + return 1; + } + + if (a->dim < b->dim) + return -1; + + if (a->dim > b->dim) + return 1; + + return 0; +} + +/* + * Less than + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_lt); +Datum +halfvec_lt(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) < 0); +} + +/* + * Less than or equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_le); +Datum +halfvec_le(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) <= 0); +} + +/* + * Equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_eq); +Datum +halfvec_eq(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) == 0); +} + +/* + * Not equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ne); +Datum +halfvec_ne(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) != 0); +} + +/* + * Greater than or equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ge); +Datum +halfvec_ge(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) >= 0); +} + +/* + * Greater than + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_gt); +Datum +halfvec_gt(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) > 0); +} + +/* + * Compare half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_cmp); +Datum +halfvec_cmp(PG_FUNCTION_ARGS) +{ + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + + PG_RETURN_INT32(halfvec_cmp_internal(a, b)); +} + +/* + * Accumulate half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_accum); +Datum +halfvec_accum(PG_FUNCTION_ARGS) +{ + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + HalfVector *newval = PG_GETARG_HALFVEC_P(1); + float8 *statevalues; + int16 dim; + bool newarr; + float8 n; + Datum *statedatums; + half *x = newval->x; + ArrayType *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "halfvec_accum"); + dim = STATE_DIMS(statearray); + newarr = dim == 0; + + if (newarr) + dim = newval->dim; + else + CheckExpectedDim(dim, newval->dim); + + n = statevalues[0] + 1.0; + + statedatums = (Datum *)CreateStateDatums(dim); + statedatums[0] = Float8GetDatum(n); + + if (newarr) + { + for (int i = 0; i < dim; i++) + statedatums[i + 1] = Float8GetDatum((double) HalfToFloat4(x[i])); + } + else + { + for (int i = 0; i < dim; i++) + { + double v = statevalues[i + 1] + (double) HalfToFloat4(x[i]); + + /* Check for overflow */ + if (isinf(v)) + float_overflow_error(); + + statedatums[i + 1] = Float8GetDatum(v); + } + } + + /* Use float8 array like float4_accum */ + result = construct_array(statedatums, dim + 1, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + + pfree(statedatums); + + PG_RETURN_ARRAYTYPE_P(result); +} + +/* + * Average half vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_avg); +Datum +halfvec_avg(PG_FUNCTION_ARGS) +{ + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + float8 *statevalues; + float8 n; + uint16 dim; + HalfVector *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "halfvec_avg"); + n = statevalues[0]; + + /* SQL defines AVG of no values to be NULL */ + if (n == 0.0) + PG_RETURN_NULL(); + + /* Create half vector */ + dim = STATE_DIMS(statearray); + CheckDim(dim); + result = InitHalfVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = Float4ToHalf(statevalues[i + 1] / n); + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); +} + +/* + * Convert sparse vector to half vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_to_halfvec); +Datum +sparsevec_to_halfvec(PG_FUNCTION_ARGS) +{ + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + HalfVector *result; + int dim = svec->dim; + float *values = SPARSEVEC_VALUES(svec); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + result = InitHalfVector(dim); + for (int i = 0; i < svec->nnz; i++) + result->x[svec->indices[i]] = Float4ToHalf(values[i]); + + PG_RETURN_POINTER(result); +} diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp new file mode 100644 index 0000000000..0a3262bb72 --- /dev/null +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -0,0 +1,1137 @@ +#include "postgres.h" + +#include +#include + +#include "fmgr.h" +#include "access/datavec/halfutils.h" +#include "access/datavec/halfvec.h" +#include "libpq/pqformat.h" +#include "access/datavec/shortest_dec.h" +#include "access/datavec/sparsevec.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "access/datavec/vector.h" + +#if PG_VERSION_NUM >= 120000 +#include "common/shortest_dec.h" +#include "utils/float.h" +#else +#include +#include "utils/builtins.h" +#endif + +typedef struct SparseInputElement +{ + int32 index; + float value; +} SparseInputElement; + +/* + * Ensure same dimensions + */ +static inline void +CheckDims(SparseVector * a, SparseVector * b) +{ + if (a->dim != b->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different sparsevec dimensions %d and %d", a->dim, b->dim))); +} + +/* + * Ensure expected dimensions + */ +static inline void +CheckExpectedDim(int32 typmod, int dim) +{ + if (typmod != -1 && typmod != dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected %d dimensions, not %d", typmod, dim))); +} + +/* + * Ensure valid dimensions + */ +static inline void +CheckDim(int dim) +{ + if (dim < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec must have at least 1 dimension"))); + + if (dim > SPARSEVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d dimensions", SPARSEVEC_MAX_DIM))); +} + +/* + * Ensure valid nnz + */ +static inline void +CheckNnz(int nnz, int dim) +{ + if (nnz < 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec cannot have negative number of elements"))); + + if (nnz > SPARSEVEC_MAX_NNZ) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); + + if (nnz > dim) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more elements than dimensions"))); +} + +/* + * Ensure valid index + */ +static inline void +CheckIndex(int32 *indices, int i, int dim) +{ + int32 index = indices[i]; + + if (index < 0 || index >= dim) + { + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec index out of bounds"))); + } + + if (i > 0) + { + if (index < indices[i - 1]) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec indices must be in ascending order"))); + + if (index == indices[i - 1]) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec indices must not contain duplicates"))); + } +} + +/* + * Ensure finite element + */ +static inline void +CheckElement(float value) +{ + if (isnan(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("NaN not allowed in sparsevec"))); + + if (isinf(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("infinite value not allowed in sparsevec"))); +} + +/* + * Allocate and initialize a new sparse vector + */ +SparseVector * +InitSparseVector(int dim, int nnz) +{ + SparseVector *result; + int size; + + size = SPARSEVEC_SIZE(nnz); + result = (SparseVector *) palloc0(size); + SET_VARSIZE(result, size); + result->dim = dim; + result->nnz = nnz; + + return result; +} + +/* + * Check for whitespace, since array_isspace() is static + */ +static inline bool +sparsevec_isspace(char ch) +{ + if (ch == ' ' || + ch == '\t' || + ch == '\n' || + ch == '\r' || + ch == '\v' || + ch == '\f') + return true; + return false; +} + +/* + * Compare indices + */ +static int +CompareIndices(const void *a, const void *b) +{ + if (((SparseInputElement *) a)->index < ((SparseInputElement *) b)->index) + return -1; + + if (((SparseInputElement *) a)->index > ((SparseInputElement *) b)->index) + return 1; + + return 0; +} + +/* + * Convert textual representation to internal representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_in); +Datum +sparsevec_in(PG_FUNCTION_ARGS) +{ + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + long dim; + char *pt = lit; + char *stringEnd; + SparseVector *result; + float *rvalues; + SparseInputElement *elements; + int maxNnz; + int nnz = 0; + + maxNnz = 1; + while (*pt != '\0') + { + if (*pt == ',') + maxNnz++; + + pt++; + } + + if (maxNnz > SPARSEVEC_MAX_NNZ) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); + + elements = (SparseInputElement *)palloc(maxNnz * sizeof(SparseInputElement)); + + pt = lit; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != '{') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Vector contents must start with \"{\"."))); + + pt++; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt == '}') + pt++; + else + { + for (;;) + { + long index; + float value; + + if (nnz == maxNnz) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("ran out of buffer: \"%s\"", lit))); + + while (sparsevec_isspace(*pt)) + pt++; + + /* Check for empty string like float4in */ + if (*pt == '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Use similar logic as int2vectorin */ + index = strtol(pt, &stringEnd, 10); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Keep in int range for correct error message later */ + if (index > INT_MAX) + index = INT_MAX; + else if (index < INT_MIN + 1) + index = INT_MIN + 1; + + pt = stringEnd; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != ':') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + pt++; + + while (sparsevec_isspace(*pt)) + pt++; + + errno = 0; + + /* Use strtof like float4in to avoid a double-rounding problem */ + /* Postgres sets LC_NUMERIC to C on startup */ + value = strtof(pt, &stringEnd); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Check for range error like float4in */ + if (errno == ERANGE && (value == 0 || isinf(value))) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type sparsevec", pnstrdup(pt, stringEnd - pt)))); + + CheckElement(value); + + /* Do not store zero values */ + if (value != 0) + { + /* Convert 1-based numbering (SQL) to 0-based (C) */ + elements[nnz].index = index - 1; + elements[nnz].value = value; + nnz++; + } + + pt = stringEnd; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt == ',') + pt++; + else if (*pt == '}') + { + pt++; + break; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + } + } + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != '/') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Unexpected end of input."))); + + pt++; + + while (sparsevec_isspace(*pt)) + pt++; + + /* Use similar logic as int2vectorin */ + dim = strtol(pt, &stringEnd, 10); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Keep in int range for correct error message later */ + if (dim > INT_MAX) + dim = INT_MAX; + else if (dim < INT_MIN) + dim = INT_MIN; + + pt = stringEnd; + + /* Only whitespace is allowed after the closing brace */ + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Junk after closing."))); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + qsort(elements, nnz, sizeof(SparseInputElement), CompareIndices); + + result = InitSparseVector(dim, nnz); + rvalues = SPARSEVEC_VALUES(result); + for (int i = 0; i < nnz; i++) + { + result->indices[i] = elements[i].index; + rvalues[i] = elements[i].value; + + CheckIndex(result->indices, i, dim); + } + + PG_RETURN_POINTER(result); +} + +#define AppendChar(ptr, c) (*(ptr)++ = (c)) +#define AppendFloat(ptr, f) ((ptr) += float_to_shortest_decimal_bufn((f), (ptr))) + +#if PG_VERSION_NUM >= 140000 +#define AppendInt(ptr, i) ((ptr) += pg_ltoa((i), (ptr))) +#else +#define AppendInt(ptr, i) \ + do { \ + pg_ltoa(i, ptr); \ + while (*ptr != '\0') \ + ptr++; \ + } while (0) +#endif + +/* + * Convert internal representation to textual representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_out); +Datum +sparsevec_out(PG_FUNCTION_ARGS) +{ + SparseVector *sparsevec = PG_GETARG_SPARSEVEC_P(0); + float *values = SPARSEVEC_VALUES(sparsevec); + char *buf; + char *ptr; + + /* + * Need: + * + * nnz * 10 bytes for index (positive integer) + * + * nnz bytes for : + * + * nnz * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for + * float_to_shortest_decimal_bufn + * + * nnz - 1 bytes for , + * + * 10 bytes for dimensions + * + * 4 bytes for {, }, /, and \0 + */ + buf = (char *) palloc((11 + FLOAT_SHORTEST_DECIMAL_LEN) * sparsevec->nnz + 13); + ptr = buf; + + AppendChar(ptr, '{'); + + for (int i = 0; i < sparsevec->nnz; i++) + { + if (i > 0) + AppendChar(ptr, ','); + + /* Convert 0-based numbering (C) to 1-based (SQL) */ + AppendInt(ptr, sparsevec->indices[i] + 1); + AppendChar(ptr, ':'); + AppendFloat(ptr, values[i]); + } + + AppendChar(ptr, '}'); + AppendChar(ptr, '/'); + AppendInt(ptr, sparsevec->dim); + *ptr = '\0'; + + PG_FREE_IF_COPY(sparsevec, 0); + PG_RETURN_CSTRING(buf); +} + +/* + * Convert type modifier + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_typmod_in); +Datum +sparsevec_typmod_in(PG_FUNCTION_ARGS) +{ + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; + + tl = ArrayGetIntegerTypmods(ta, &n); + + if (n != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid type modifier"))); + + if (*tl < 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type sparsevec must be at least 1"))); + + if (*tl > SPARSEVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type sparsevec cannot exceed %d", SPARSEVEC_MAX_DIM))); + + PG_RETURN_INT32(*tl); +} + +/* + * Convert external binary representation to internal representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_recv); +Datum +sparsevec_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); + SparseVector *result; + int32 dim; + int32 nnz; + int32 unused; + float *values; + + dim = pq_getmsgint(buf, sizeof(int32)); + nnz = pq_getmsgint(buf, sizeof(int32)); + unused = pq_getmsgint(buf, sizeof(int32)); + + CheckDim(dim); + CheckNnz(nnz, dim); + CheckExpectedDim(typmod, dim); + + if (unused != 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected unused to be 0, not %d", unused))); + + result = InitSparseVector(dim, nnz); + values = SPARSEVEC_VALUES(result); + + /* Binary representation uses zero-based numbering for indices */ + for (int i = 0; i < nnz; i++) + { + result->indices[i] = pq_getmsgint(buf, sizeof(int32)); + CheckIndex(result->indices, i, dim); + } + + for (int i = 0; i < nnz; i++) + { + values[i] = pq_getmsgfloat4(buf); + CheckElement(values[i]); + + if (values[i] == 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("binary representation of sparsevec cannot contain zero values"))); + } + + PG_RETURN_POINTER(result); +} + +/* + * Convert internal representation to the external binary representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_send); +Datum +sparsevec_send(PG_FUNCTION_ARGS) +{ + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + float *values = SPARSEVEC_VALUES(svec); + StringInfoData buf; + + pq_begintypsend(&buf); + pq_sendint(&buf, svec->dim, sizeof(int32)); + pq_sendint(&buf, svec->nnz, sizeof(int32)); + pq_sendint(&buf, svec->unused, sizeof(int32)); + + /* Binary representation uses zero-based numbering for indices */ + for (int i = 0; i < svec->nnz; i++) + pq_sendint(&buf, svec->indices[i], sizeof(int32)); + + for (int i = 0; i < svec->nnz; i++) + pq_sendfloat4(&buf, values[i]); + + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} + +/* + * Convert sparse vector to sparse vector + * This is needed to check the type modifier + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec); +Datum +sparsevec(PG_FUNCTION_ARGS) +{ + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + + CheckExpectedDim(typmod, svec->dim); + + PG_RETURN_POINTER(svec); +} + +/* + * Convert dense vector to sparse vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_sparsevec); +Datum +vector_to_sparsevec(PG_FUNCTION_ARGS) +{ + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); + SparseVector *result; + int dim = vec->dim; + int nnz = 0; + float *values; + int j = 0; + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + for (int i = 0; i < dim; i++) + { + if (vec->x[i] != 0) + nnz++; + } + + result = InitSparseVector(dim, nnz); + values = SPARSEVEC_VALUES(result); + for (int i = 0; i < dim; i++) + { + if (vec->x[i] != 0) + { + /* Safety check */ + if (j >= result->nnz) + elog(ERROR, "safety check failed"); + + result->indices[j] = i; + values[j] = vec->x[i]; + j++; + } + } + + PG_RETURN_POINTER(result); +} + +/* + * Convert half vector to sparse vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_sparsevec); +Datum +halfvec_to_sparsevec(PG_FUNCTION_ARGS) +{ + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + SparseVector *result; + int dim = vec->dim; + int nnz = 0; + float *values; + int j = 0; + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + for (int i = 0; i < dim; i++) + { + if (!HalfIsZero(vec->x[i])) + nnz++; + } + + result = InitSparseVector(dim, nnz); + values = SPARSEVEC_VALUES(result); + for (int i = 0; i < dim; i++) + { + if (!HalfIsZero(vec->x[i])) + { + /* Safety check */ + if (j >= result->nnz) + elog(ERROR, "safety check failed"); + + result->indices[j] = i; + values[j] = HalfToFloat4(vec->x[i]); + j++; + } + } + + PG_RETURN_POINTER(result); +} + +/* + * Get the L2 squared distance between sparse vectors + */ +static float +SparsevecL2SquaredDistance(SparseVector * a, SparseVector * b) +{ + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; + + for (int i = 0; i < a->nnz; i++) + { + int ai = a->indices[i]; + int bi = -1; + + for (int j = bpos; j < b->nnz; j++) + { + bi = b->indices[j]; + + if (ai == bi) + { + float diff = ax[i] - bx[j]; + + distance += diff * diff; + } + else if (ai > bi) + distance += bx[j] * bx[j]; + + /* Update start for next iteration */ + if (ai >= bi) + bpos = j + 1; + + /* Found or passed it */ + if (bi >= ai) + break; + } + + if (ai != bi) + distance += ax[i] * ax[i]; + } + + for (int j = bpos; j < b->nnz; j++) + distance += bx[j] * bx[j]; + + return distance; +} + +/* + * Get the L2 distance between sparse vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_distance); +Datum +sparsevec_l2_distance(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8(sqrt((double) SparsevecL2SquaredDistance(a, b))); +} + +/* + * Get the L2 squared distance between sparse vectors + * This saves a sqrt calculation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_squared_distance); +Datum +sparsevec_l2_squared_distance(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) SparsevecL2SquaredDistance(a, b)); +} + +/* + * Get the inner product of two sparse vectors + */ +static float +SparsevecInnerProduct(SparseVector * a, SparseVector * b) +{ + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; + + for (int i = 0; i < a->nnz; i++) + { + int ai = a->indices[i]; + + for (int j = bpos; j < b->nnz; j++) + { + int bi = b->indices[j]; + + /* Only update when the same index */ + if (ai == bi) + distance += ax[i] * bx[j]; + + /* Update start for next iteration */ + if (ai >= bi) + bpos = j + 1; + + /* Found or passed it */ + if (bi >= ai) + break; + } + } + + return distance; +} + +/* + * Get the inner product of two sparse vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_inner_product); +Datum +sparsevec_inner_product(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) SparsevecInnerProduct(a, b)); +} + +/* + * Get the negative inner product of two sparse vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_negative_inner_product); +Datum +sparsevec_negative_inner_product(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) -SparsevecInnerProduct(a, b)); +} + +/* + * Get the cosine distance between two sparse vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_cosine_distance); +Datum +sparsevec_cosine_distance(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float norma = 0.0; + float normb = 0.0; + double similarity; + + CheckDims(a, b); + + similarity = SparsevecInnerProduct(a, b); + + /* Auto-vectorized */ + for (int i = 0; i < a->nnz; i++) + norma += ax[i] * ax[i]; + + /* Auto-vectorized */ + for (int i = 0; i < b->nnz; i++) + normb += bx[i] * bx[i]; + + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + similarity /= sqrt((double) norma * (double) normb); + +#ifdef _MSC_VER + /* /fp:fast may not propagate NaN */ + if (isnan(similarity)) + PG_RETURN_FLOAT8(NAN); +#endif + + /* Keep in range */ + if (similarity > 1) + similarity = 1.0; + else if (similarity < -1) + similarity = -1.0; + + PG_RETURN_FLOAT8(1.0 - similarity); +} + +/* + * Get the L1 distance between two sparse vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l1_distance); +Datum +sparsevec_l1_distance(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; + + CheckDims(a, b); + + for (int i = 0; i < a->nnz; i++) + { + int ai = a->indices[i]; + int bi = -1; + + for (int j = bpos; j < b->nnz; j++) + { + bi = b->indices[j]; + + if (ai == bi) + distance += fabsf(ax[i] - bx[j]); + else if (ai > bi) + distance += fabsf(bx[j]); + + /* Update start for next iteration */ + if (ai >= bi) + bpos = j + 1; + + /* Found or passed it */ + if (bi >= ai) + break; + } + + if (ai != bi) + distance += fabsf(ax[i]); + } + + for (int j = bpos; j < b->nnz; j++) + distance += fabsf(bx[j]); + + PG_RETURN_FLOAT8((double) distance); +} + +/* + * Get the L2 norm of a sparse vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_norm); +Datum +sparsevec_l2_norm(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + float *ax = SPARSEVEC_VALUES(a); + double norm = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < a->nnz; i++) + norm += (double) ax[i] * (double) ax[i]; + + PG_RETURN_FLOAT8(sqrt(norm)); +} + +static pg_noinline void +float_overflow_error(void) +{ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); +} + +/* + * Normalize a sparse vector with the L2 norm + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_normalize); +Datum +sparsevec_l2_normalize(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + float *ax = SPARSEVEC_VALUES(a); + double norm = 0; + SparseVector *result; + float *rx; + + result = InitSparseVector(a->dim, a->nnz); + rx = SPARSEVEC_VALUES(result); + + /* Auto-vectorized */ + for (int i = 0; i < a->nnz; i++) + norm += (double) ax[i] * (double) ax[i]; + + norm = sqrt(norm); + + /* Return zero vector for zero norm */ + if (norm > 0) + { + int zeros = 0; + + for (int i = 0; i < a->nnz; i++) + { + result->indices[i] = a->indices[i]; + rx[i] = ax[i] / norm; + + if (isinf(rx[i])) + float_overflow_error(); + + if (rx[i] == 0) + zeros++; + } + + /* Allocate a new vector in the unlikely event there are zeros */ + if (zeros > 0) + { + SparseVector *newResult = InitSparseVector(result->dim, result->nnz - zeros); + float *nx = SPARSEVEC_VALUES(newResult); + int j = 0; + + for (int i = 0; i < result->nnz; i++) + { + if (rx[i] == 0) + continue; + + /* Safety check */ + if (j >= newResult->nnz) + elog(ERROR, "safety check failed"); + + newResult->indices[j] = result->indices[i]; + nx[j] = rx[i]; + j++; + } + + pfree(result); + + PG_RETURN_POINTER(newResult); + } + } + + PG_RETURN_POINTER(result); +} + +/* + * Internal helper to compare sparse vectors + */ +static int +sparsevec_cmp_internal(SparseVector * a, SparseVector * b) +{ + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + int nnz = Min(a->nnz, b->nnz); + + /* Check values before dimensions to be consistent with Postgres arrays */ + for (int i = 0; i < nnz; i++) + { + if (a->indices[i] < b->indices[i]) + return ax[i] < 0 ? -1 : 1; + + if (a->indices[i] > b->indices[i]) + return bx[i] < 0 ? 1 : -1; + + if (ax[i] < bx[i]) + return -1; + + if (ax[i] > bx[i]) + return 1; + } + + if (a->nnz < b->nnz && b->indices[nnz] < a->dim) + return bx[nnz] < 0 ? 1 : -1; + + if (a->nnz > b->nnz && a->indices[nnz] < b->dim) + return ax[nnz] < 0 ? -1 : 1; + + if (a->dim < b->dim) + return -1; + + if (a->dim > b->dim) + return 1; + + return 0; +} + +/* + * Less than + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_lt); +Datum +sparsevec_lt(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) < 0); +} + +/* + * Less than or equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_le); +Datum +sparsevec_le(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) <= 0); +} + +/* + * Equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_eq); +Datum +sparsevec_eq(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) == 0); +} + +/* + * Not equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_ne); +Datum +sparsevec_ne(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) != 0); +} + +/* + * Greater than or equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_ge); +Datum +sparsevec_ge(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) >= 0); +} + +/* + * Greater than + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_gt); +Datum +sparsevec_gt(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) > 0); +} + +/* + * Compare sparse vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_cmp); +Datum +sparsevec_cmp(PG_FUNCTION_ARGS) +{ + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + + PG_RETURN_INT32(sparsevec_cmp_internal(a, b)); +} diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp new file mode 100644 index 0000000000..549b1f9ba6 --- /dev/null +++ b/src/common/backend/utils/adt/vector.cpp @@ -0,0 +1,1472 @@ +#include "postgres.h" + +#include + +#include "access/datavec/bitvec.h" +#include "catalog/pg_type.h" +#include "fmgr.h" +#include "access/datavec/halfutils.h" +#include "access/datavec/halfvec.h" +#include "access/datavec/hnsw.h" +#include "access/datavec/ivfflat.h" +#include "lib/stringinfo.h" +#include "libpq/pqformat.h" +#include "port.h" /* for strtof() */ +#include "access/datavec/shortest_dec.h" +#include "access/datavec/sparsevec.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "utils/lsyscache.h" +#include "utils/numeric.h" +#include "commands/extension.h" +#include "knl/knl_session.h" +#include "access/datavec/vector.h" + +#if PG_VERSION_NUM >= 160000 +#include "varatt.h" +#endif + +#if PG_VERSION_NUM < 130000 +#define TYPALIGN_DOUBLE 'd' +#define TYPALIGN_INT 'i' +#endif + +#define STATE_DIMS(x) (ARR_DIMS(x)[0] - 1) +#define CreateStateDatums(dim) palloc(sizeof(Datum) * (dim + 1)) + +#if defined(USE_TARGET_CLONES) && !defined(__FMA__) +#define VECTOR_TARGET_CLONES __attribute__((target_clones("default", "fma"))) +#else +#define VECTOR_TARGET_CLONES +#endif + +#if PG_VERSION_NUM < 150000 +#define MarkGUCPrefixReserved(x) EmitWarningsOnPlaceholders(x) +#endif + +uint32 datavec_index; + +void set_extension_index(uint32 index) +{ + datavec_index = index; +} + +datavec_session_context* get_session_context() +{ + if (u_sess->attr.attr_common.extension_session_vars_array[datavec_index] == NULL) { + init_session_vars(); + } + return (datavec_session_context*)u_sess->attr.attr_common.extension_session_vars_array[datavec_index]; +} + +void init_session_vars(void) +{ + RepallocSessionVarsArrayIfNecessary(); + datavec_session_context* ctx = (datavec_session_context*)MemoryContextAllocZero(u_sess->self_mem_cxt, + sizeof(datavec_session_context)); + u_sess->attr.attr_common.extension_session_vars_array[datavec_index] = ctx; + + ctx->hnsw_ef_search = 0; + ctx->ivfflat_probes = 0; + + DefineCustomIntVariable("hnsw.ef_search", "Sets the size of the dynamic candidate list for search", + "Valid range is 1..1000.", &(get_session_context()->hnsw_ef_search), + HNSW_DEFAULT_EF_SEARCH, HNSW_MIN_EF_SEARCH, HNSW_MAX_EF_SEARCH, + PGC_USERSET, 0, NULL, NULL, NULL); + + MarkGUCPrefixReserved("hnsw"); + + DefineCustomIntVariable("ivfflat.probes", "Sets the number of probes", + "Valid range is 1..lists.", &(get_session_context()->ivfflat_probes), + IVFFLAT_DEFAULT_PROBES, IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS, + PGC_USERSET, 0, NULL, NULL, NULL); + + MarkGUCPrefixReserved("ivfflat"); +} + +/* + * Ensure same dimensions + */ +static inline void +CheckDims(Vector * a, Vector * b) +{ + if (a->dim != b->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different vector dimensions %d and %d", a->dim, b->dim))); +} + +/* + * Ensure expected dimensions + */ +static inline void +CheckExpectedDim(int32 typmod, int dim) +{ + if (typmod != -1 && typmod != dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected %d dimensions, not %d", typmod, dim))); +} + +/* + * Ensure valid dimensions + */ +static inline void +CheckDim(int dim) +{ + if (dim < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + if (dim > VECTOR_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); +} + +/* + * Ensure finite element + */ +static inline void +CheckElement(float value) +{ + if (isnan(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("NaN not allowed in vector"))); + + if (isinf(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("infinite value not allowed in vector"))); +} + +/* + * Allocate and initialize a new vector + */ +Vector * +InitVector(int dim) +{ + Vector *result; + int size; + + size = VECTOR_SIZE(dim); + result = (Vector *) palloc0(size); + SET_VARSIZE(result, size); + result->dim = dim; + + return result; +} + +/* + * Check for whitespace, since array_isspace() is static + */ +static inline bool +vector_isspace(char ch) +{ + if (ch == ' ' || + ch == '\t' || + ch == '\n' || + ch == '\r' || + ch == '\v' || + ch == '\f') + return true; + return false; +} + +/* + * Check state array + */ +static float8 * +CheckStateArray(ArrayType *statearray, const char *caller) +{ + if (ARR_NDIM(statearray) != 1 || + ARR_DIMS(statearray)[0] < 1 || + ARR_HASNULL(statearray) || + ARR_ELEMTYPE(statearray) != FLOAT8OID) + elog(ERROR, "%s: expected state array", caller); + return (float8 *) ARR_DATA_PTR(statearray); +} + +#if PG_VERSION_NUM < 120003 +static pg_noinline void +float_overflow_error(void) +{ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); +} + +static pg_noinline void +float_underflow_error(void) +{ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: underflow"))); +} +#endif + +/* + * Convert textual representation to internal representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_in); +Datum +vector_in(PG_FUNCTION_ARGS) +{ + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + float x[VECTOR_MAX_DIM]; + int dim = 0; + char *pt = lit; + Vector *result; + + while (vector_isspace(*pt)) + pt++; + + if (*pt != '[') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit), + errdetail("Vector contents must start with \"[\"."))); + + pt++; + + while (vector_isspace(*pt)) + pt++; + + if (*pt == ']') + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + for (;;) + { + float val; + char *stringEnd; + + if (dim == VECTOR_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); + + while (vector_isspace(*pt)) + pt++; + + /* Check for empty string like float4in */ + if (*pt == '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); + + errno = 0; + + /* Use strtof like float4in to avoid a double-rounding problem */ + /* Postgres sets LC_NUMERIC to C on startup */ + val = strtof(pt, &stringEnd); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); + + /* Check for range error like float4in */ + if (errno == ERANGE && isinf(val)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type vector", pnstrdup(pt, stringEnd - pt)))); + + CheckElement(val); + x[dim++] = val; + + pt = stringEnd; + + while (vector_isspace(*pt)) + pt++; + + if (*pt == ',') + pt++; + else if (*pt == ']') + { + pt++; + break; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); + } + + /* Only whitespace is allowed after the closing brace */ + while (vector_isspace(*pt)) + pt++; + + if (*pt != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit), + errdetail("Junk after closing right brace."))); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + result = InitVector(dim); + for (int i = 0; i < dim; i++) + result->x[i] = x[i]; + + PG_RETURN_POINTER(result); +} + +#define AppendChar(ptr, c) (*(ptr)++ = (c)) +#define AppendFloat(ptr, f) ((ptr) += float_to_shortest_decimal_bufn((f), (ptr))) + +/* + * Convert internal representation to textual representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_out); +Datum +vector_out(PG_FUNCTION_ARGS) +{ + Vector *vector = PG_GETARG_VECTOR_P(0); + int dim = vector->dim; + char *buf; + char *ptr; + + /* + * Need: + * + * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for + * float_to_shortest_decimal_bufn + * + * dim - 1 bytes for separator + * + * 3 bytes for [, ], and \0 + */ + buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); + ptr = buf; + + AppendChar(ptr, '['); + + for (int i = 0; i < dim; i++) + { + if (i > 0) + AppendChar(ptr, ','); + + AppendFloat(ptr, vector->x[i]); + } + + AppendChar(ptr, ']'); + *ptr = '\0'; + + PG_FREE_IF_COPY(vector, 0); + PG_RETURN_CSTRING(buf); +} + +/* + * Print vector - useful for debugging + */ +void +PrintVector(char *msg, Vector * vector) +{ + char *out = DatumGetPointer(DirectFunctionCall1(vector_out, PointerGetDatum(vector))); + + elog(INFO, "%s = %s", msg, out); + pfree(out); +} + +/* + * Convert type modifier + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_typmod_in); +Datum +vector_typmod_in(PG_FUNCTION_ARGS) +{ + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; + + tl = ArrayGetIntegerTypmods(ta, &n); + + if (n != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid type modifier"))); + + if (*tl < 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type vector must be at least 1"))); + + if (*tl > VECTOR_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type vector cannot exceed %d", VECTOR_MAX_DIM))); + + PG_RETURN_INT32(*tl); +} + +/* + * Convert external binary representation to internal representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_recv); +Datum +vector_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); + Vector *result; + int16 dim; + int16 unused; + + dim = pq_getmsgint(buf, sizeof(int16)); + unused = pq_getmsgint(buf, sizeof(int16)); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + if (unused != 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected unused to be 0, not %d", unused))); + + result = InitVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = pq_getmsgfloat4(buf); + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); +} + +/* + * Convert internal representation to the external binary representation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_send); +Datum +vector_send(PG_FUNCTION_ARGS) +{ + Vector *vec = PG_GETARG_VECTOR_P(0); + StringInfoData buf; + + pq_begintypsend(&buf); + pq_sendint(&buf, vec->dim, sizeof(int16)); + pq_sendint(&buf, vec->unused, sizeof(int16)); + for (int i = 0; i < vec->dim; i++) + pq_sendfloat4(&buf, vec->x[i]); + + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} + +/* + * Convert vector to vector + * This is needed to check the type modifier + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector); +Datum +vector(PG_FUNCTION_ARGS) +{ + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); + + CheckExpectedDim(typmod, vec->dim); + + PG_RETURN_POINTER(vec); +} + +/* + * Convert array to vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(array_to_vector); +Datum +array_to_vector(PG_FUNCTION_ARGS) +{ + ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; + int16 typlen; + bool typbyval; + char typalign; + Datum *elemsp; + int nelemsp; + + if (ARR_NDIM(array) > 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("array must be 1-D"))); + + if (ARR_HASNULL(array) && array_contains_nulls(array)) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("array must not contain nulls"))); + + get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); + deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); + + CheckDim(nelemsp); + CheckExpectedDim(typmod, nelemsp); + + result = InitVector(nelemsp); + + if (ARR_ELEMTYPE(array) == INT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetInt32(elemsp[i]); + } + else if (ARR_ELEMTYPE(array) == FLOAT8OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetFloat8(elemsp[i]); + } + else if (ARR_ELEMTYPE(array) == FLOAT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetFloat4(elemsp[i]); + } + else if (ARR_ELEMTYPE(array) == NUMERICOID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i])); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("unsupported array type"))); + } + + /* + * Free allocation from deconstruct_array. Do not free individual elements + * when pass-by-reference since they point to original array. + */ + pfree(elemsp); + + /* Check elements */ + for (int i = 0; i < result->dim; i++) + CheckElement(result->x[i]); + + PG_RETURN_POINTER(result); +} + +/* + * Convert vector to float4[] + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_float4); +Datum +vector_to_float4(PG_FUNCTION_ARGS) +{ + Vector *vec = PG_GETARG_VECTOR_P(0); + Datum *datums; + ArrayType *result; + + datums = (Datum *) palloc(sizeof(Datum) * vec->dim); + + for (int i = 0; i < vec->dim; i++) + datums[i] = Float4GetDatum(vec->x[i]); + + /* Use TYPALIGN_INT for float4 */ + result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); + + pfree(datums); + + PG_RETURN_POINTER(result); +} + +/* + * Convert half vector to vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_vector); +Datum +halfvec_to_vector(PG_FUNCTION_ARGS) +{ + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; + + CheckDim(vec->dim); + CheckExpectedDim(typmod, vec->dim); + + result = InitVector(vec->dim); + + for (int i = 0; i < vec->dim; i++) + result->x[i] = HalfToFloat4(vec->x[i]); + + PG_RETURN_POINTER(result); +} + +VECTOR_TARGET_CLONES static float +VectorL2SquaredDistance(int dim, float *ax, float *bx) +{ + float distance = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + float diff = ax[i] - bx[i]; + + distance += diff * diff; + } + + return distance; +} + +/* + * Get the L2 distance between vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(l2_distance); +Datum +l2_distance(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8(sqrt((double) VectorL2SquaredDistance(a->dim, a->x, b->x))); +} + +/* + * Get the L2 squared distance between vectors + * This saves a sqrt calculation + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_l2_squared_distance); +Datum +vector_l2_squared_distance(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) VectorL2SquaredDistance(a->dim, a->x, b->x)); +} + +VECTOR_TARGET_CLONES static float +VectorInnerProduct(int dim, float *ax, float *bx) +{ + float distance = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += ax[i] * bx[i]; + + return distance; +} + +/* + * Get the inner product of two vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(inner_product); +Datum +inner_product(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) VectorInnerProduct(a->dim, a->x, b->x)); +} + +/* + * Get the negative inner product of two vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_negative_inner_product); +Datum +vector_negative_inner_product(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) -VectorInnerProduct(a->dim, a->x, b->x)); +} + +VECTOR_TARGET_CLONES static double +VectorCosineSimilarity(int dim, float *ax, float *bx) +{ + float similarity = 0.0; + float norma = 0.0; + float normb = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + similarity += ax[i] * bx[i]; + norma += ax[i] * ax[i]; + normb += bx[i] * bx[i]; + } + + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + return (double) similarity / sqrt((double) norma * (double) normb); +} + +/* + * Get the cosine distance between two vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(cosine_distance); +Datum +cosine_distance(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + double similarity; + + CheckDims(a, b); + + similarity = VectorCosineSimilarity(a->dim, a->x, b->x); + +#ifdef _MSC_VER + /* /fp:fast may not propagate NaN */ + if (isnan(similarity)) + PG_RETURN_FLOAT8(NAN); +#endif + + /* Keep in range */ + if (similarity > 1) + similarity = 1.0; + else if (similarity < -1) + similarity = -1.0; + + PG_RETURN_FLOAT8(1.0 - similarity); +} + +/* + * Get the distance for spherical k-means + * Currently uses angular distance since needs to satisfy triangle inequality + * Assumes inputs are unit vectors (skips norm) + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_spherical_distance); +Datum +vector_spherical_distance(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + double distance; + + CheckDims(a, b); + + distance = (double) VectorInnerProduct(a->dim, a->x, b->x); + + /* Prevent NaN with acos with loss of precision */ + if (distance > 1) + distance = 1; + else if (distance < -1) + distance = -1; + + PG_RETURN_FLOAT8(acos(distance) / M_PI); +} + +/* Does not require FMA, but keep logic simple */ +VECTOR_TARGET_CLONES static float +VectorL1Distance(int dim, float *ax, float *bx) +{ + float distance = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += fabsf(ax[i] - bx[i]); + + return distance; +} + +/* + * Get the L1 distance between two vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(l1_distance); +Datum +l1_distance(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + CheckDims(a, b); + + PG_RETURN_FLOAT8((double) VectorL1Distance(a->dim, a->x, b->x)); +} + +/* + * Get the dimensions of a vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_dims); +Datum +vector_dims(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + + PG_RETURN_INT32(a->dim); +} + +/* + * Get the L2 norm of a vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_norm); +Datum +vector_norm(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + double norm = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + norm += (double) ax[i] * (double) ax[i]; + + PG_RETURN_FLOAT8(sqrt(norm)); +} + +/* + * Normalize a vector with the L2 norm + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(l2_normalize); +Datum +l2_normalize(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + double norm = 0; + Vector *result; + float *rx; + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + norm += (double) ax[i] * (double) ax[i]; + + norm = sqrt(norm); + + /* Return zero vector for zero norm */ + if (norm > 0) + { + for (int i = 0; i < a->dim; i++) + rx[i] = ax[i] / norm; + + /* Check for overflow */ + for (int i = 0; i < a->dim; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + } + } + + PG_RETURN_POINTER(result); +} + +/* + * Add vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_add); +Datum +vector_add(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; + + CheckDims(a, b); + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + rx[i] = ax[i] + bx[i]; + + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + } + + PG_RETURN_POINTER(result); +} + +/* + * Subtract vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_sub); +Datum +vector_sub(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; + + CheckDims(a, b); + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + rx[i] = ax[i] - bx[i]; + + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + } + + PG_RETURN_POINTER(result); +} + +/* + * Multiply vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_mul); +Datum +vector_mul(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; + + CheckDims(a, b); + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + rx[i] = ax[i] * bx[i]; + + /* Check for overflow and underflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + + if (rx[i] == 0 && !(ax[i] == 0 || bx[i] == 0)) + float_underflow_error(); + } + + PG_RETURN_POINTER(result); +} + +/* + * Concatenate vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_concat); +Datum +vector_concat(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + Vector *result; + int dim = a->dim + b->dim; + + CheckDim(dim); + result = InitVector(dim); + + for (int i = 0; i < a->dim; i++) + result->x[i] = a->x[i]; + + for (int i = 0; i < b->dim; i++) + result->x[i + a->dim] = b->x[i]; + + PG_RETURN_POINTER(result); +} + +/* + * Quantize a vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(binary_quantize); +Datum +binary_quantize(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + VarBit *result = InitBitVector(a->dim); + unsigned char *rx = VARBITS(result); + + for (int i = 0; i < a->dim; i++) + rx[i / 8] |= (ax[i] > 0) << (7 - (i % 8)); + + PG_RETURN_VARBIT_P(result); +} + +/* + * Get a subvector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(subvector); +Datum +subvector(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + int32 start = PG_GETARG_INT32(1); + int32 count = PG_GETARG_INT32(2); + int32 end; + float *ax = a->x; + Vector *result; + int dim; + + if (count < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + /* + * Check if (start + count > a->dim), avoiding integer overflow. a->dim + * and count are both positive, so a->dim - count won't overflow. + */ + if (start > a->dim - count) + end = a->dim + 1; + else + end = start + count; + + /* Indexing starts at 1, like substring */ + if (start < 1) + start = 1; + else if (start > a->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + dim = end - start; + CheckDim(dim); + result = InitVector(dim); + + for (int i = 0; i < dim; i++) + result->x[i] = ax[start - 1 + i]; + + PG_RETURN_POINTER(result); +} + +/* + * Internal helper to compare vectors + */ +int +vector_cmp_internal(Vector * a, Vector * b) +{ + int dim = Min(a->dim, b->dim); + + /* Check values before dimensions to be consistent with Postgres arrays */ + for (int i = 0; i < dim; i++) + { + if (a->x[i] < b->x[i]) + return -1; + + if (a->x[i] > b->x[i]) + return 1; + } + + if (a->dim < b->dim) + return -1; + + if (a->dim > b->dim) + return 1; + + return 0; +} + +/* + * Less than + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_lt); +Datum +vector_lt(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + PG_RETURN_BOOL(vector_cmp_internal(a, b) < 0); +} + +/* + * Less than or equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_le); +Datum +vector_le(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + PG_RETURN_BOOL(vector_cmp_internal(a, b) <= 0); +} + +/* + * Equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_eq); +Datum +vector_eq(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + PG_RETURN_BOOL(vector_cmp_internal(a, b) == 0); +} + +/* + * Not equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ne); +Datum +vector_ne(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + PG_RETURN_BOOL(vector_cmp_internal(a, b) != 0); +} + +/* + * Greater than or equal + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ge); +Datum +vector_ge(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + PG_RETURN_BOOL(vector_cmp_internal(a, b) >= 0); +} + +/* + * Greater than + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_gt); +Datum +vector_gt(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + PG_RETURN_BOOL(vector_cmp_internal(a, b) > 0); +} + +/* + * Compare vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_cmp); +Datum +vector_cmp(PG_FUNCTION_ARGS) +{ + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + + PG_RETURN_INT32(vector_cmp_internal(a, b)); +} + +/* + * Accumulate vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_accum); +Datum +vector_accum(PG_FUNCTION_ARGS) +{ + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + Vector *newval = PG_GETARG_VECTOR_P(1); + float8 *statevalues; + int16 dim; + bool newarr; + float8 n; + Datum *statedatums; + float *x = newval->x; + ArrayType *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "vector_accum"); + dim = STATE_DIMS(statearray); + newarr = dim == 0; + + if (newarr) + dim = newval->dim; + else + CheckExpectedDim(dim, newval->dim); + + n = statevalues[0] + 1.0; + + statedatums = (Datum *)CreateStateDatums(dim); + statedatums[0] = Float8GetDatum(n); + + if (newarr) + { + for (int i = 0; i < dim; i++) + statedatums[i + 1] = Float8GetDatum((double) x[i]); + } + else + { + for (int i = 0; i < dim; i++) + { + double v = statevalues[i + 1] + x[i]; + + /* Check for overflow */ + if (isinf(v)) + float_overflow_error(); + + statedatums[i + 1] = Float8GetDatum(v); + } + } + + /* Use float8 array like float4_accum */ + result = construct_array(statedatums, dim + 1, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + + pfree(statedatums); + + PG_RETURN_ARRAYTYPE_P(result); +} + +/* + * Combine vectors or half vectors (also used for halfvec_combine) + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_combine); +Datum +vector_combine(PG_FUNCTION_ARGS) +{ + /* Must also update parameters of halfvec_combine if modifying */ + ArrayType *statearray1 = PG_GETARG_ARRAYTYPE_P(0); + ArrayType *statearray2 = PG_GETARG_ARRAYTYPE_P(1); + float8 *statevalues1; + float8 *statevalues2; + float8 n; + float8 n1; + float8 n2; + int16 dim; + Datum *statedatums; + ArrayType *result; + + /* Check arrays before using */ + statevalues1 = CheckStateArray(statearray1, "vector_combine"); + statevalues2 = CheckStateArray(statearray2, "vector_combine"); + + n1 = statevalues1[0]; + n2 = statevalues2[0]; + + if (n1 == 0.0) + { + n = n2; + dim = STATE_DIMS(statearray2); + statedatums = (Datum *)CreateStateDatums(dim); + for (int i = 1; i <= dim; i++) + statedatums[i] = Float8GetDatum(statevalues2[i]); + } + else if (n2 == 0.0) + { + n = n1; + dim = STATE_DIMS(statearray1); + statedatums = (Datum *)CreateStateDatums(dim); + for (int i = 1; i <= dim; i++) + statedatums[i] = Float8GetDatum(statevalues1[i]); + } + else + { + n = n1 + n2; + dim = STATE_DIMS(statearray1); + CheckExpectedDim(dim, STATE_DIMS(statearray2)); + statedatums = (Datum *)CreateStateDatums(dim); + for (int i = 1; i <= dim; i++) + { + double v = statevalues1[i] + statevalues2[i]; + + /* Check for overflow */ + if (isinf(v)) + float_overflow_error(); + + statedatums[i] = Float8GetDatum(v); + } + } + + statedatums[0] = Float8GetDatum(n); + + result = construct_array(statedatums, dim + 1, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + + pfree(statedatums); + + PG_RETURN_ARRAYTYPE_P(result); +} + +/* + * Average vectors + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_avg); +Datum +vector_avg(PG_FUNCTION_ARGS) +{ + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + float8 *statevalues; + float8 n; + uint16 dim; + Vector *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "vector_avg"); + n = statevalues[0]; + + /* SQL defines AVG of no values to be NULL */ + if (n == 0.0) + PG_RETURN_NULL(); + + /* Create vector */ + dim = STATE_DIMS(statearray); + CheckDim(dim); + result = InitVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = statevalues[i + 1] / n; + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); +} + +/* + * Convert sparse vector to dense vector + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_to_vector); +Datum +sparsevec_to_vector(PG_FUNCTION_ARGS) +{ + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; + int dim = svec->dim; + float *values = SPARSEVEC_VALUES(svec); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + result = InitVector(dim); + for (int i = 0; i < svec->nnz; i++) + result->x[svec->indices[i]] = values[i]; + + PG_RETURN_POINTER(result); +} + +/* + * WAL-log a range of blocks in a relation. + * + * An image of all pages with block numbers 'startblk' <= X < 'endblk' is + * written to the WAL. If the range is large, this is done in multiple WAL + * records. + * + * If all page follows the standard page layout, with a PageHeader and unused + * space between pd_lower and pd_upper, set 'page_std' to true. That allows + * the unused space to be left out from the WAL records, making them smaller. + * + * NOTE: This function acquires exclusive-locks on the pages. Typically, this + * is used on a newly-built relation, and the caller is holding a + * AccessExclusiveLock on it, so no other backend can be accessing it at the + * same time. If that's not the case, you must ensure that this does not + * cause a deadlock through some other means. + */ +void +log_newpage_range(Relation rel, ForkNumber forknum, + BlockNumber startblk, BlockNumber endblk, + bool page_std) +{ + int flags; + BlockNumber blkno; + + flags = REGBUF_FORCE_IMAGE; + if (page_std) + flags |= REGBUF_STANDARD; + + /* + * Iterate over all the pages in the range. They are collected into + * batches of XLR_MAX_BLOCK_ID pages, and a single WAL-record is written + * for each batch. + */ + XLogEnsureRecordSpace(XLR_MAX_BLOCK_ID - 1, 0); + + blkno = startblk; + while (blkno < endblk) + { + Buffer bufpack[XLR_MAX_BLOCK_ID]; + XLogRecPtr recptr; + int nbufs; + int i; + + CHECK_FOR_INTERRUPTS(); + + /* Collect a batch of blocks. */ + nbufs = 0; + while (nbufs < XLR_MAX_BLOCK_ID && blkno < endblk) + { + Buffer buf = ReadBufferExtended(rel, forknum, blkno, + RBM_NORMAL, NULL); + + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + + /* + * Completely empty pages are not WAL-logged. Writing a WAL record + * would change the LSN, and we don't want that. We want the page + * to stay empty. + */ + if (!PageIsNew(BufferGetPage(buf))) + bufpack[nbufs++] = buf; + else + UnlockReleaseBuffer(buf); + blkno++; + } + + /* Nothing more to do if all remaining blocks were empty. */ + if (nbufs == 0) + break; + + /* Write WAL record for this batch. */ + XLogBeginInsert(); + + START_CRIT_SECTION(); + for (i = 0; i < nbufs; i++) + { + MarkBufferDirty(bufpack[i]); + XLogRegisterBuffer(i, bufpack[i], flags); + } + + recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI); + + for (i = 0; i < nbufs; i++) + { + PageSetLSN(BufferGetPage(bufpack[i]), recptr); + UnlockReleaseBuffer(bufpack[i]); + } + END_CRIT_SECTION(); + } +} + +int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo) +{ + int parallelWorkers = RelationGetParallelWorkers(heapRelation, 0); + int max_hashbucket_index_worker = 32; + + if (parallelWorkers != 0) { + parallelWorkers = Min(max_hashbucket_index_worker, parallelWorkers); + } + + if (indexInfo->ii_Concurrent && indexInfo->ii_ParallelWorkers > 0) { + ereport(NOTICE, (errmsg("switch off parallel mode when concurrently flag is set"))); + parallelWorkers = 0; + } + + if (heapRelation->rd_rel->relpersistence == RELPERSISTENCE_GLOBAL_TEMP && indexInfo->ii_ParallelWorkers > 0) { + ereport(NOTICE, (errmsg("switch off parallel mode for global temp table"))); + parallelWorkers = 0; + } + + /* disable parallel building index for system table*/ + if (IsCatalogRelation(heapRelation)) { + parallelWorkers = 0; + } + return parallelWorkers; +} diff --git a/src/gausskernel/storage/access/datavec/CMakeLists.txt b/src/gausskernel/storage/access/datavec/CMakeLists.txt new file mode 100644 index 0000000000..1b2a4b6c90 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/CMakeLists.txt @@ -0,0 +1,16 @@ +#This is the main CMAKE for build all components. +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TGT_datavec_SRC) + +set(TGT_datavec_INC + ${PROJECT_SRC_DIR}/include + ${LZ4_INCLUDE_PATH} + ${LIBCGROUP_INCLUDE_PATH} + ${EVENT_INCLUDE_PATH} + ${ZLIB_INCLUDE_PATH} +) + +set(datavec_DEF_OPTIONS ${MACRO_OPTIONS}) +set(datavec_COMPILE_OPTIONS ${OPTIMIZE_OPTIONS} ${OS_OPTIONS} ${PROTECT_OPTIONS} ${WARNING_OPTIONS} ${BIN_SECURE_OPTIONS} ${CHECK_OPTIONS}) +set(datavec_LINK_OPTIONS ${BIN_LINK_OPTIONS}) +add_static_objtarget(gausskernel_storage_access_datavec TGT_datavec_SRC TGT_datavec_INC "${datavec_DEF_OPTIONS}" "${datavec_COMPILE_OPTIONS}" "${datavec_LINK_OPTIONS}") + diff --git a/src/gausskernel/storage/access/datavec/bitutils.cpp b/src/gausskernel/storage/access/datavec/bitutils.cpp new file mode 100644 index 0000000000..fcbf97c893 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/bitutils.cpp @@ -0,0 +1,215 @@ +#include "postgres.h" + +#include "access/datavec/bitvec.h" +#include "access/datavec/halfvec.h" /* for USE_DISPATCH and USE_TARGET_CLONES */ +#include "port/pg_bitutils.h" + +#if defined(USE_DISPATCH) +#define BIT_DISPATCH +#endif + +#ifdef BIT_DISPATCH +#include + +#if defined(USE__GET_CPUID) +#include +#else +#include +#endif + +#define TARGET_AVX512_POPCOUNT +#endif + +/* Disable for LLVM due to crash with bitcode generation */ +#if defined(USE_TARGET_CLONES) && !defined(__POPCNT__) && !defined(__llvm__) +#define BIT_TARGET_CLONES __attribute__((target_clones("default", "popcnt"))) +#else +#define BIT_TARGET_CLONES +#endif + +/* Use built-ins when possible for inlining */ +#if defined(HAVE__BUILTIN_POPCOUNT) && defined(HAVE_LONG_INT_64) +#define popcount64(x) __builtin_popcountl(x) +#elif defined(HAVE__BUILTIN_POPCOUNT) && defined(HAVE_LONG_LONG_INT_64) +#define popcount64(x) __builtin_popcountll(x) +#elif !defined(_MSC_VER) +/* Fails to resolve with MSVC */ +#define popcount64(x) pg_popcount64(x) +#endif + +BIT_TARGET_CLONES static uint64 +BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance) +{ +#ifdef popcount64 + for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) + { + uint64 axs; + uint64 bxs; + + /* Ensure aligned */ + memcpy(&axs, ax, sizeof(uint64)); + memcpy(&bxs, bx, sizeof(uint64)); + + distance += popcount64(axs ^ bxs); + + ax += sizeof(uint64); + bx += sizeof(uint64); + } +#endif + + for (uint32 i = 0; i < bytes; i++) + distance += pg_number_of_ones[ax[i] ^ bx[i]]; + + return distance; +} + +#ifdef BIT_DISPATCH +TARGET_AVX512_POPCOUNT static uint64 +BitHammingDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance) +{ + __m512i dist = _mm512_setzero_si512(); + + for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) + { + __m512i axs = _mm512_loadu_si512((const __m512i *) ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + + dist = _mm512_add_epi64(dist, _mm512_popcnt_epi64(_mm512_xor_si512(axs, bxs))); + + ax += sizeof(__m512i); + bx += sizeof(__m512i); + } + + distance += _mm512_reduce_add_epi64(dist); + + return BitHammingDistanceDefault(bytes, ax, bx, distance); +} +#endif + +BIT_TARGET_CLONES static double +BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) +{ +#ifdef popcount64 + for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) + { + uint64 axs; + uint64 bxs; + + /* Ensure aligned */ + memcpy(&axs, ax, sizeof(uint64)); + memcpy(&bxs, bx, sizeof(uint64)); + + ab += popcount64(axs & bxs); + aa += popcount64(axs); + bb += popcount64(bxs); + + ax += sizeof(uint64); + bx += sizeof(uint64); + } +#endif + + for (uint32 i = 0; i < bytes; i++) + { + ab += pg_number_of_ones[ax[i] & bx[i]]; + aa += pg_number_of_ones[ax[i]]; + bb += pg_number_of_ones[bx[i]]; + } + + if (ab == 0) + return 1; + else + return 1 - (ab / ((double) (aa + bb - ab))); +} + +#ifdef BIT_DISPATCH +TARGET_AVX512_POPCOUNT static double +BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) +{ + __m512i abx = _mm512_setzero_si512(); + __m512i aax = _mm512_setzero_si512(); + __m512i bbx = _mm512_setzero_si512(); + + for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) + { + __m512i axs = _mm512_loadu_si512((const __m512i *) ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + + abx = _mm512_add_epi64(abx, _mm512_popcnt_epi64(_mm512_and_si512(axs, bxs))); + aax = _mm512_add_epi64(aax, _mm512_popcnt_epi64(axs)); + bbx = _mm512_add_epi64(bbx, _mm512_popcnt_epi64(bxs)); + + ax += sizeof(__m512i); + bx += sizeof(__m512i); + } + + ab += _mm512_reduce_add_epi64(abx); + aa += _mm512_reduce_add_epi64(aax); + bb += _mm512_reduce_add_epi64(bbx); + + return BitJaccardDistanceDefault(bytes, ax, bx, ab, aa, bb); +} +#endif + +#ifdef BIT_DISPATCH +#define CPU_FEATURE_OSXSAVE (1 << 27) /* F1 ECX */ +#define CPU_FEATURE_AVX512F (1 << 16) /* F7,0 EBX */ +#define CPU_FEATURE_AVX512VPOPCNTDQ (1 << 14) /* F7,0 ECX */ + +#ifdef _MSC_VER +#define TARGET_XSAVE +#else +#define TARGET_XSAVE __attribute__((target("xsave"))) +#endif + +TARGET_XSAVE static bool +SupportsAvx512Popcount() +{ + unsigned int exx[4] = {0, 0, 0, 0}; + +#if defined(USE__GET_CPUID) + __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); +#else + __cpuid(exx, 1); +#endif + + /* Check OS supports XSAVE */ + if ((exx[2] & CPU_FEATURE_OSXSAVE) != CPU_FEATURE_OSXSAVE) + return false; + + /* Check XMM, YMM, and ZMM registers are enabled */ + if ((_xgetbv(0) & 0xe6) != 0xe6) + return false; + +#if defined(USE__GET_CPUID) + __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]); +#else + __cpuidex(exx, 7, 0); +#endif + + /* Check AVX512F */ + if ((exx[1] & CPU_FEATURE_AVX512F) != CPU_FEATURE_AVX512F) + return false; + + /* Check AVX512VPOPCNTDQ */ + return (exx[2] & CPU_FEATURE_AVX512VPOPCNTDQ) == CPU_FEATURE_AVX512VPOPCNTDQ; +} +#endif + +void +BitvecInit(void) +{ + /* + * Could skip pointer when single function, but no difference in + * performance + */ + BitHammingDistance = BitHammingDistanceDefault; + BitJaccardDistance = BitJaccardDistanceDefault; + +#ifdef BIT_DISPATCH + if (SupportsAvx512Popcount()) + { + BitHammingDistance = BitHammingDistanceAvx512Popcount; + BitJaccardDistance = BitJaccardDistanceAvx512Popcount; + } +#endif +} diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp new file mode 100644 index 0000000000..18aa9e33df --- /dev/null +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -0,0 +1,362 @@ +#include "postgres.h" + +#include +#include + +#include "access/amapi.h" +#include "access/reloptions.h" +#include "commands/vacuum.h" +#include "access/datavec/hnsw.h" +#include "miscadmin.h" +#include "utils/guc.h" +#include "utils/selfuncs.h" + +int hnsw_lock_tranche_id; +static relopt_kind hnsw_relopt_kind; +static THR_LOCAL bool HnswNeedInitialization = true; + +/* + * Initialize index options and variables + */ +void +HnswInit(void) +{ + hnsw_relopt_kind = RELOPT_KIND_DATAVEC; + add_int_reloption(hnsw_relopt_kind, "m", "Max number of connections", + HNSW_DEFAULT_M, HNSW_MIN_M, HNSW_MAX_M); + add_int_reloption(hnsw_relopt_kind, "ef_construction", "Size of the dynamic candidate list for construction", + HNSW_DEFAULT_EF_CONSTRUCTION, HNSW_MIN_EF_CONSTRUCTION, HNSW_MAX_EF_CONSTRUCTION); + add_int_reloption(hnsw_relopt_kind, "pq_m", "Number of PQ subquantizer", + HNSW_DEFAULT_PQ_M, HNSW_MIN_PQ_M, HNSW_MAX_PQ_M); + add_int_reloption(hnsw_relopt_kind, "pq_ksub", "Number of centroids for each PQ subquantizer", + HNSW_DEFAULT_PQ_KSUB, HNSW_MIN_PQ_KSUB, HNSW_MAX_PQ_KSUB); + add_bool_reloption(hnsw_relopt_kind, "enable_pq", "Whether to enable PQ", HNSW_DEFAULT_ENABLE_PQ); +} + +/* + * Estimate the cost of an index scan + */ +static void +hnswcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) +{ + GenericCosts costs; + int m; + int entryLevel; + Relation index; + + /* Never use index without order */ + if (path->indexorderbys == NULL) + { + *indexStartupCost = DBL_MAX; + *indexTotalCost = DBL_MAX; + *indexSelectivity = 0; + *indexCorrelation = 0; + return; + } + + MemSet(&costs, 0, sizeof(costs)); + + index = index_open(path->indexinfo->indexoid, NoLock); + HnswGetMetaPageInfo(index, &m, NULL); + index_close(index, NoLock); + + /* Approximate entry level */ + entryLevel = (int) -log(1.0 / path->indexinfo->tuples) * HnswGetMl(m); + + /* TODO Improve estimate of visited tuples (currently underestimates) */ + /* Account for number of tuples (or entry level), m, and ef_search */ + costs.numIndexTuples = (entryLevel + 2) * m; + + genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, + &costs.indexTotalCost, &costs.indexSelectivity, &costs.indexCorrelation); + + /* Use total cost since most work happens before first tuple is returned */ + *indexStartupCost = costs.indexTotalCost; + *indexTotalCost = costs.indexTotalCost; + *indexSelectivity = costs.indexSelectivity; + *indexCorrelation = costs.indexCorrelation; +} + +/* + * Parse and validate the reloptions + */ +static bytea * +hnswoptions_internal(Datum reloptions, bool validate) +{ + static const relopt_parse_elt tab[] = { + {"m", RELOPT_TYPE_INT, offsetof(HnswOptions, m)}, + {"ef_construction", RELOPT_TYPE_INT, offsetof(HnswOptions, efConstruction)}, + {"enable_pq", RELOPT_TYPE_BOOL, offsetof(HnswOptions, enablePQ)}, + {"pq_m", RELOPT_TYPE_INT, offsetof(HnswOptions, pqM)}, + {"pq_ksub", RELOPT_TYPE_INT, offsetof(HnswOptions, pqKsub)}, + {"parallel_workers", RELOPT_TYPE_INT, offsetof(StdRdOptions, parallel_workers)}, + {"storage_type", RELOPT_TYPE_STRING, offsetof(HnswOptions, storage_type)} + }; + +#if PG_VERSION_NUM >= 130000 + return (bytea *) build_reloptions(reloptions, validate, + hnsw_relopt_kind, + sizeof(HnswOptions), + tab, lengthof(tab)); +#else + relopt_value *options; + int numoptions; + HnswOptions *rdopts; + + if (HnswNeedInitialization) { + HnswInit(); + HnswNeedInitialization = false; + } + options = parseRelOptions(reloptions, validate, hnsw_relopt_kind, &numoptions); + rdopts = (HnswOptions *)allocateReloptStruct(sizeof(HnswOptions), options, numoptions); + fillRelOptions((void *) rdopts, sizeof(HnswOptions), options, numoptions, + validate, tab, lengthof(tab)); + + return (bytea *) rdopts; +#endif +} + +/* + * Validate catalog entries for the specified operator class + */ +static bool +hnswvalidate_internal(Oid opclassoid) +{ + return true; +} + +/* + * Define index handler + * + * See https://www.postgresql.org/docs/current/index-api.html + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswhandler); +Datum +hnswhandler(PG_FUNCTION_ARGS) +{ + IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); + + amroutine->amstrategies = 0; + amroutine->amsupport = 3; +#if PG_VERSION_NUM >= 130000 + amroutine->amoptsprocnum = 0; +#endif + amroutine->amcanorder = false; + amroutine->amcanorderbyop = true; + amroutine->amcanbackward = false; /* can change direction mid-scan */ + amroutine->amcanunique = false; + amroutine->amcanmulticol = false; + amroutine->amoptionalkey = true; + amroutine->amsearcharray = false; + amroutine->amsearchnulls = false; + amroutine->amstorage = false; + amroutine->amclusterable = false; + amroutine->ampredlocks = false; + amroutine->amcanparallel = false; + amroutine->amcaninclude = false; +#if PG_VERSION_NUM >= 130000 + amroutine->amusemaintenanceworkmem = false; /* not used during VACUUM */ + amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL; +#endif + amroutine->amkeytype = InvalidOid; + + /* Interface functions */ + errno_t rc = 0; + rc = strcpy_s(amroutine->ambuildfuncname, NAMEDATALEN, "hnswbuild"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambuildemptyfuncname, NAMEDATALEN, "hnswbuildempty"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->aminsertfuncname, NAMEDATALEN, "hnswinsert"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambulkdeletefuncname, NAMEDATALEN, "hnswbulkdelete"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amvacuumcleanupfuncname, NAMEDATALEN, "hnswvacuumcleanup"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amcostestimatefuncname, NAMEDATALEN, "hnswcostestimate"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amoptionsfuncname, NAMEDATALEN, "hnswoptions"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amvalidatefuncname, NAMEDATALEN, "hnswvalidate"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambeginscanfuncname, NAMEDATALEN, "hnswbeginscan"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amrescanfuncname, NAMEDATALEN, "hnswrescan"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amgettuplefuncname, NAMEDATALEN, "hnswgettuple"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amendscanfuncname, NAMEDATALEN, "hnswendscan"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amdeletefuncname, NAMEDATALEN, "hnswdelete"); + securec_check(rc, "\0", "\0"); + + PG_RETURN_POINTER(amroutine); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbuild); +Datum +hnswbuild(PG_FUNCTION_ARGS) +{ + Relation heap = (Relation)PG_GETARG_POINTER(0); + Relation index = (Relation)PG_GETARG_POINTER(1); + IndexInfo *indexinfo = (IndexInfo *)PG_GETARG_POINTER(2); + IndexBuildResult *result = hnswbuild_internal(heap, index, indexinfo); + + PG_RETURN_POINTER(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbuildempty); +Datum +hnswbuildempty(PG_FUNCTION_ARGS) +{ + Relation index = (Relation)PG_GETARG_POINTER(0); + hnswbuildempty_internal(index); + + PG_RETURN_VOID(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswinsert); +Datum +hnswinsert(PG_FUNCTION_ARGS) +{ + Relation rel = (Relation)PG_GETARG_POINTER(0); + Datum * values = (Datum *)PG_GETARG_POINTER(1); + bool *isnull = (bool *)PG_GETARG_POINTER(2); + ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); + Relation heaprel = (Relation)PG_GETARG_POINTER(4); + IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); + bool result = hnswinsert_internal(rel, values, isnull, ht_ctid, heaprel, checkunique); + + PG_RETURN_BOOL(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbulkdelete); +Datum +hnswbulkdelete(PG_FUNCTION_ARGS) +{ + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); + void *callback_state = (void *)PG_GETARG_POINTER(3); + stats = hnswbulkdelete_internal(info, stats, callback, callback_state); + + PG_RETURN_POINTER(stats); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswvacuumcleanup); +Datum +hnswvacuumcleanup(PG_FUNCTION_ARGS) +{ + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + stats = hnswvacuumcleanup_internal(info, stats); + + PG_RETURN_POINTER(stats); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswcostestimate); +Datum +hnswcostestimate(PG_FUNCTION_ARGS) +{ + PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); + IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); + double loopcount = (double)PG_GETARG_FLOAT8(2); + Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); + Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); + Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); + double *correlation = (double *)PG_GETARG_POINTER(6); + hnswcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); + + PG_RETURN_VOID(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswoptions); +Datum +hnswoptions(PG_FUNCTION_ARGS) +{ + Datum reloptions = PG_GETARG_DATUM(0); + bool validate = PG_GETARG_BOOL(1); + bytea *result = hnswoptions_internal(reloptions, validate); + + if (NULL != result) + PG_RETURN_BYTEA_P(result); + + PG_RETURN_NULL(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswvalidate); +Datum +hnswvalidate(PG_FUNCTION_ARGS) +{ + Oid opclassoid = PG_GETARG_OID(0); + bool result = hnswvalidate_internal(opclassoid); + + PG_RETURN_BOOL(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbeginscan); +Datum +hnswbeginscan(PG_FUNCTION_ARGS) +{ + Relation rel = (Relation)PG_GETARG_POINTER(0); + int nkeys = PG_GETARG_INT32(1); + int norderbys = PG_GETARG_INT32(2); + IndexScanDesc scan = hnswbeginscan_internal(rel, nkeys, norderbys); + + PG_RETURN_POINTER(scan); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswrescan); +Datum +hnswrescan(PG_FUNCTION_ARGS) +{ + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); + int nkeys = PG_GETARG_INT32(2); + ScanKey orderbys = (ScanKey)PG_GETARG_POINTER(3); + int norderbys = PG_GETARG_INT32(4); + hnswrescan_internal(scan, scankey, nkeys, orderbys, norderbys); + + PG_RETURN_VOID(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswgettuple); +Datum +hnswgettuple(PG_FUNCTION_ARGS) +{ + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); + + if (NULL == scan) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function hnswgettuple"))); + + bool result = hnswgettuple_internal(scan, direction); + + PG_RETURN_BOOL(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswendscan); +Datum +hnswendscan(PG_FUNCTION_ARGS) +{ + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + hnswendscan_internal(scan); + + PG_RETURN_VOID(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswdelete); +Datum +hnswdelete(PG_FUNCTION_ARGS) +{ + Relation rel = (Relation)PG_GETARG_POINTER(0); + Datum *values = (Datum *)PG_GETARG_POINTER(1); + const bool* isnull = (const bool*)PG_GETARG_POINTER(2); + ItemPointer heapTCtid = (ItemPointer)PG_GETARG_POINTER(3); + bool isRollbackIndex = (bool)PG_GETARG_POINTER(4); + + bool result = hnswdelete_internal(rel, values, isnull, heapTCtid, isRollbackIndex); + + PG_RETURN_BOOL(result); +} \ No newline at end of file diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp new file mode 100644 index 0000000000..234dd23840 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -0,0 +1,1089 @@ +/* + * The HNSW build happens in two phases: + * + * 1. In-memory phase + * + * In this first phase, the graph is held completely in memory. When the graph + * is fully built, or we run out of memory reserved for the build (determined + * by maintenance_work_mem), we materialize the graph to disk (see + * FlushPages()), and switch to the on-disk phase. + * + * In a parallel build, a large contiguous chunk of shared memory is allocated + * to hold the graph. Each worker process has its own HnswBuildState struct in + * private memory, which contains information that doesn't change throughout + * the build, and pointers to the shared structs in shared memory. The shared + * memory area is mapped to a different address in each worker process, and + * 'HnswBuildState.hnswarea' points to the beginning of the shared area in the + * worker process's address space. All pointers used in the graph are + * "relative pointers", stored as an offset from 'hnswarea'. + * + * Each element is protected by an LWLock. It must be held when reading or + * modifying the element's neighbors or 'heaptids'. + * + * In a non-parallel build, the graph is held in backend-private memory. All + * the elements are allocated in a dedicated memory context, 'graphCtx', and + * the pointers used in the graph are regular pointers. + * + * 2. On-disk phase + * + * In the on-disk phase, the index is built by inserting each vector to the + * index one by one, just like on INSERT. The only difference is that we don't + * WAL-log the individual inserts. If the graph fit completely in memory and + * was fully built in the in-memory phase, the on-disk phase is skipped. + * + * After we have finished building the graph, we perform one more scan through + * the index and write all the pages to the WAL. + */ +#include "postgres.h" + +#include + +#include "access/tableam.h" +#include "access/xact.h" +#include "access/xloginsert.h" +#include "postmaster/bgworker.h" +#include "catalog/index.h" +#include "access/datavec/hnsw.h" +#include "miscadmin.h" +#include "storage/buf/bufmgr.h" +#include "tcop/tcopprot.h" +#include "utils/datum.h" +#include "utils/memutils.h" + +#if PG_VERSION_NUM >= 140000 +#include "utils/backend_progress.h" +#else +#include "pgstat.h" +#endif + +#if PG_VERSION_NUM >= 130000 +#define CALLBACK_ITEM_POINTER ItemPointer tid +#else +#define CALLBACK_ITEM_POINTER HeapTuple hup +#endif + +#if PG_VERSION_NUM >= 140000 +#include "utils/backend_status.h" +#include "utils/wait_event.h" +#endif + +#define PARALLEL_KEY_HNSW_SHARED UINT64CONST(0xA000000000000001) +#define PARALLEL_KEY_HNSW_AREA UINT64CONST(0xA000000000000002) +#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000003) +#define PROGRESS_CREATEIDX_TUPLES_DONE 0 + +#if PG_VERSION_NUM < 130000 +#define GENERATIONCHUNK_RAWSIZE (SIZEOF_SIZE_T + SIZEOF_VOID_P * 2) +#endif + +/* + * Create the metapage + */ +static void +CreateMetaPage(HnswBuildState * buildstate) +{ + Relation index = buildstate->index; + ForkNumber forkNum = buildstate->forkNum; + Buffer buf; + Page page; + HnswMetaPage metap; + + buf = HnswNewBuffer(index, forkNum); + page = BufferGetPage(buf); + HnswInitPage(buf, page); + + if (buildstate->isUStore) { + HnswPageGetOpaque(page)->pageType = HNSW_USTORE_PAGE_TYPE; + } + + /* Set metapage data */ + metap = HnswPageGetMeta(page); + metap->magicNumber = HNSW_MAGIC_NUMBER; + metap->version = HNSW_VERSION; + metap->dimensions = buildstate->dimensions; + metap->m = buildstate->m; + metap->efConstruction = buildstate->efConstruction; + metap->entryBlkno = InvalidBlockNumber; + metap->entryOffno = InvalidOffsetNumber; + metap->entryLevel = -1; + metap->insertPage = InvalidBlockNumber; + ((PageHeader) page)->pd_lower = + ((char *) metap + sizeof(HnswMetaPageData)) - (char *) page; + + MarkBufferDirty(buf); + UnlockReleaseBuffer(buf); +} + +/* + * Create the append metapage + */ +static void +CreateAppendMetaPage(HnswBuildState *buildstate) +{ + Relation index = buildstate->index; + ForkNumber forkNum = buildstate->forkNum; + Buffer buf; + Page page; + HnswAppendMetaPage appMetap; + int slotTypeNum = 2; + + buf = HnswNewBuffer(index, forkNum); + page = BufferGetPage(buf); + HnswInitPage(buf, page); + + /* Set append metapage data */ + appMetap = HnswPageGetAppendMeta(page); + appMetap->magicNumber = HNSW_MAGIC_NUMBER; + appMetap->version = HNSW_VERSION; + appMetap->dimensions = buildstate->dimensions; + appMetap->m = buildstate->m; + appMetap->efConstruction = buildstate->efConstruction; + appMetap->entryBlkno = InvalidBlockNumber; + appMetap->entryOffno = InvalidOffsetNumber; + appMetap->entryLevel = -1; + + /* set PQ info */ + appMetap->enablePQ = buildstate->enablePQ; + appMetap->pqM = buildstate->pqM; + appMetap->pqKsub = buildstate->pqKsub; + appMetap->pqcodeSize = buildstate->pqcodeSize; + if (buildstate->enablePQ) { + appMetap->centerTableSize = (uint32)buildstate->dimensions * sizeof(float); + appMetap->pqTableSize = (uint32)buildstate->dimensions * buildstate->pqKsub * sizeof(float); + appMetap->pqTableNblk = (uint16)((appMetap->pqTableSize + HNSW_PQTABLE_STORAGE_SIZE - 1) / + HNSW_PQTABLE_STORAGE_SIZE); + } else { + appMetap->centerTableSize = 0; + appMetap->pqTableSize = 0; + appMetap->pqTableNblk = 0; + } + + /* set slot info */ + appMetap->npages = (HNSW_DEFAULT_NPAGES_PER_SLOT * slotTypeNum) < + (g_instance.attr.attr_storage.NBuffers / HNSW_BUFFER_THRESHOLD) ? HNSW_DEFAULT_NPAGES_PER_SLOT : + (g_instance.attr.attr_storage.NBuffers / (slotTypeNum * HNSW_BUFFER_THRESHOLD)); + appMetap->slotStartBlkno = HNSW_PQTABLE_START_BLKNO + appMetap->pqTableNblk; + appMetap->elementInsertSlot = InvalidBlockNumber; + appMetap->neighborInsertSlot = InvalidBlockNumber; + + ((PageHeader) page)->pd_lower = + ((char *) appMetap + sizeof(HnswAppendMetaPageData)) - (char *) page; + + MarkBufferDirty(buf); + UnlockReleaseBuffer(buf); +} + +/* + * Add a new page + */ +static void +HnswBuildAppendPage(Relation index, Buffer *buf, Page *page, ForkNumber forkNum) +{ + /* Add a new page */ + Buffer newbuf = HnswNewBuffer(index, forkNum); + + /* Update previous page */ + HnswPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); + + /* Commit */ + MarkBufferDirty(*buf); + UnlockReleaseBuffer(*buf); + + /* Can take a while, so ensure we can interrupt */ + /* Needs to be called when no buffer locks are held */ + LockBuffer(newbuf, BUFFER_LOCK_UNLOCK); + CHECK_FOR_INTERRUPTS(); + LockBuffer(newbuf, BUFFER_LOCK_EXCLUSIVE); + + /* Prepare new page */ + *buf = newbuf; + *page = BufferGetPage(*buf); + HnswInitPage(*buf, *page); +} + +/* + * Create graph pages + */ +static void +CreateGraphPages(HnswBuildState * buildstate) +{ + Relation index = buildstate->index; + ForkNumber forkNum = buildstate->forkNum; + Size maxSize; + HnswElementTuple etup; + HnswNeighborTuple ntup; + BlockNumber insertPage; + HnswElement entryPoint; + Buffer buf; + Page page; + HnswElementPtr iter = buildstate->graph->head; + char *base = buildstate->hnswarea; + IndexTransInfo* idxXid; + + /* Calculate sizes */ + maxSize = HNSW_MAX_SIZE; + + /* Allocate once */ + etup = (HnswElementTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); + ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); + + /* Prepare first page */ + buf = HnswNewBuffer(index, forkNum); + page = BufferGetPage(buf); + HnswInitPage(buf, page); + + if (buildstate->isUStore) { + HnswPageGetOpaque(page)->pageType = HNSW_USTORE_PAGE_TYPE; + } + + while (!HnswPtrIsNull(base, iter)) { + HnswElement element = (HnswElement)HnswPtrAccess(base, iter); + Size etupSize; + Size ntupSize; + Size combinedSize; + Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); + + /* Update iterator */ + iter = element->next; + + /* Zero memory for each element */ + MemSet(etup, 0, HNSW_TUPLE_ALLOC_SIZE); + + /* Calculate sizes */ + etupSize = HNSW_ELEMENT_TUPLE_SIZE(VARSIZE_ANY(valuePtr)); + ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, buildstate->m); + combinedSize = etupSize + ntupSize + sizeof(ItemIdData); + + if (buildstate->isUStore) { + combinedSize += sizeof(IndexTransInfo); + } + + /* Initial size check */ + if (etupSize > HNSW_TUPLE_ALLOC_SIZE) { + elog(ERROR, "index tuple too large"); + } + + HnswSetElementTuple(base, etup, element); + + /* Keep element and neighbors on the same page if possible */ + if (PageGetFreeSpace(page) < etupSize || (combinedSize <= maxSize && PageGetFreeSpace(page) < combinedSize)) { + HnswBuildAppendPage(index, &buf, &page, forkNum); + if (buildstate->isUStore) { + HnswPageGetOpaque(page)->pageType = HNSW_USTORE_PAGE_TYPE; + } + } + + /* Calculate offsets */ + element->blkno = BufferGetBlockNumber(buf); + element->offno = OffsetNumberNext(PageGetMaxOffsetNumber(page)); + if (combinedSize <= maxSize) { + element->neighborPage = element->blkno; + element->neighborOffno = OffsetNumberNext(element->offno); + } else { + element->neighborPage = element->blkno + 1; + element->neighborOffno = FirstOffsetNumber; + } + + ItemPointerSet(&etup->neighbortid, element->neighborPage, element->neighborOffno); + + if (buildstate->isUStore) { + ((PageHeader)page)->pd_upper -= sizeof(IndexTransInfo); + idxXid = (IndexTransInfo*)(((char*)page) + ((PageHeader)page)->pd_upper); + idxXid->xmin = FrozenTransactionId; + idxXid->xmax = InvalidTransactionId; + } + + /* Add element */ + if (PageAddItem(page, (Item) etup, etupSize, InvalidOffsetNumber, false, false) != element->offno) { + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + } + + /* Add new page if needed */ + if (PageGetFreeSpace(page) < ntupSize) { + HnswBuildAppendPage(index, &buf, &page, forkNum); + if (buildstate->isUStore) { + HnswPageGetOpaque(page)->pageType = HNSW_USTORE_PAGE_TYPE; + } + } + /* Add placeholder for neighbors */ + if (PageAddItem(page, (Item) ntup, ntupSize, InvalidOffsetNumber, false, false) != element->neighborOffno) { + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + } + } + + insertPage = BufferGetBlockNumber(buf); + + /* Commit */ + MarkBufferDirty(buf); + UnlockReleaseBuffer(buf); + + entryPoint = (HnswElement)HnswPtrAccess(base, buildstate->graph->entryPoint); + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_ALWAYS, entryPoint, insertPage, forkNum, true); + + pfree(etup); + pfree(ntup); +} + +/* + * Write neighbor tuples + */ +static void +WriteNeighborTuples(HnswBuildState * buildstate) +{ + Relation index = buildstate->index; + ForkNumber forkNum = buildstate->forkNum; + int m = buildstate->m; + HnswElementPtr iter = buildstate->graph->head; + char *base = buildstate->hnswarea; + HnswNeighborTuple ntup; + + /* Allocate once */ + ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); + + while (!HnswPtrIsNull(base, iter)) + { + HnswElement element = (HnswElement)HnswPtrAccess(base, iter); + Buffer buf; + Page page; + Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); + + /* Update iterator */ + iter = element->next; + + /* Zero memory for each element */ + MemSet(ntup, 0, HNSW_TUPLE_ALLOC_SIZE); + + /* Can take a while, so ensure we can interrupt */ + /* Needs to be called when no buffer locks are held */ + CHECK_FOR_INTERRUPTS(); + + buf = ReadBufferExtended(index, forkNum, element->neighborPage, RBM_NORMAL, NULL); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + page = BufferGetPage(buf); + + HnswSetNeighborTuple(base, ntup, element, m); + + if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + /* Commit */ + MarkBufferDirty(buf); + UnlockReleaseBuffer(buf); + } + + pfree(ntup); +} + +/* + * Flush pages + */ +static void +FlushPages(HnswBuildState * buildstate) +{ +#ifdef HNSW_MEMORY + elog(INFO, "memory: %zu MB", buildstate->graph->memoryUsed / (1024 * 1024)); +#endif + + CreateMetaPage(buildstate); + CreateGraphPages(buildstate); + WriteNeighborTuples(buildstate); + + buildstate->graph->flushed = true; + MemoryContextReset(buildstate->graphCtx); +} + +/* + * Add a heap TID to an existing element + */ +static bool +AddDuplicateInMemory(HnswElement element, HnswElement dup) +{ + LWLockAcquire(&dup->lock, LW_EXCLUSIVE); + + if (dup->heaptidsLength == HNSW_HEAPTIDS) + { + LWLockRelease(&dup->lock); + return false; + } + + HnswAddHeapTid(dup, &element->heaptids[0]); + + LWLockRelease(&dup->lock); + + return true; +} + +/* + * Find duplicate element + */ +static bool +FindDuplicateInMemory(char *base, HnswElement element) +{ + HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); + Datum value = HnswGetValue(base, element); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *neighbor = &neighbors->items[i]; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); + Datum neighborValue = HnswGetValue(base, neighborElement); + + /* Exit early since ordered by distance */ + if (!datumIsEqual(value, neighborValue, false, -1)) + return false; + + /* Check for space */ + if (AddDuplicateInMemory(element, neighborElement)) + return true; + } + + return false; +} + +/* + * Add to element list + */ +static void +AddElementInMemory(char *base, HnswGraph * graph, HnswElement element) +{ + SpinLockAcquire(&graph->lock); + element->next = graph->head; + HnswPtrStore(base, graph->head, element); + SpinLockRelease(&graph->lock); +} + +/* + * Update neighbors + */ +static void +UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswElement e, int m) +{ + for (int lc = e->level; lc >= 0; lc--) + { + int lm = HnswGetLayerM(m, lc); + HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *hc = &neighbors->items[i]; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); + + /* Keep scan-build happy on Mac x86-64 */ + Assert(neighborElement); + + /* Use element for lock instead of hc since hc can be replaced */ + LWLockAcquire(&neighborElement->lock, LW_EXCLUSIVE); + HnswUpdateConnection(base, e, hc, lm, lc, NULL, NULL, procinfo, collation); + LWLockRelease(&neighborElement->lock); + } + } +} + +/* + * Update graph in memory + */ +static void +UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, HnswBuildState * buildstate) +{ + HnswGraph *graph = buildstate->graph; + char *base = buildstate->hnswarea; + + /* Look for duplicate */ + if (FindDuplicateInMemory(base, element)) + return; + + /* Add element */ + AddElementInMemory(base, graph, element); + + /* Update neighbors */ + UpdateNeighborsInMemory(base, procinfo, collation, element, m); + + /* Update entry point if needed (already have lock) */ + if (entryPoint == NULL || element->level > entryPoint->level) + HnswPtrStore(base, graph->entryPoint, element); +} + +/* + * Insert tuple in memory + */ +static void +InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) +{ + FmgrInfo *procinfo = buildstate->procinfo; + Oid collation = buildstate->collation; + HnswGraph *graph = buildstate->graph; + HnswElement entryPoint; + LWLock *entryLock = &graph->entryLock; + LWLock *entryWaitLock = &graph->entryWaitLock; + int efConstruction = buildstate->efConstruction; + int m = buildstate->m; + char *base = buildstate->hnswarea; + + /* Wait if another process needs exclusive lock on entry lock */ + LWLockAcquire(entryWaitLock, LW_EXCLUSIVE); + LWLockRelease(entryWaitLock); + + /* Get entry point */ + LWLockAcquire(entryLock, LW_SHARED); + entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); + + /* Prevent concurrent inserts when likely updating entry point */ + if (entryPoint == NULL || element->level > entryPoint->level) + { + /* Release shared lock */ + LWLockRelease(entryLock); + + /* Tell other processes to wait and get exclusive lock */ + LWLockAcquire(entryWaitLock, LW_EXCLUSIVE); + LWLockAcquire(entryLock, LW_EXCLUSIVE); + LWLockRelease(entryWaitLock); + + /* Get latest entry point after lock is acquired */ + entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); + } + + /* Find neighbors for element */ + HnswFindElementNeighbors(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false); + + /* Update graph in memory */ + UpdateGraphInMemory(procinfo, collation, element, m, efConstruction, entryPoint, buildstate); + + /* Release entry lock */ + LWLockRelease(entryLock); +} + +/* + * Insert tuple + */ +static bool +InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heaptid, HnswBuildState * buildstate) +{ + const HnswTypeInfo *typeInfo = buildstate->typeInfo; + HnswGraph *graph = buildstate->graph; + HnswElement element; + HnswAllocator *allocator = &buildstate->allocator; + Size valueSize; + Pointer valuePtr; + LWLock *flushLock = &graph->flushLock; + char *base = buildstate->hnswarea; + + /* Detoast once for all calls */ + Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Check value */ + if (typeInfo->checkValue != NULL) + typeInfo->checkValue(DatumGetPointer(value)); + + /* Normalize if needed */ + if (buildstate->normprocinfo != NULL) + { + if (!HnswCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) + return false; + + value = HnswNormValue(typeInfo, buildstate->collation, value); + } + + /* Get datum size */ + valueSize = VARSIZE_ANY(DatumGetPointer(value)); + + /* Ensure graph not flushed when inserting */ + LWLockAcquire(flushLock, LW_SHARED); + + /* Are we in the on-disk phase? */ + if (graph->flushed) + { + LWLockRelease(flushLock); + + return HnswInsertTupleOnDisk(index, value, values, isnull, heaptid, true); + } + + /* + * In a parallel build, the HnswElement is allocated from the shared + * memory area, so we need to coordinate with other processes. + */ + LWLockAcquire(&graph->allocatorLock, LW_EXCLUSIVE); + + /* + * Check that we have enough memory available for the new element now that + * we have the allocator lock, and flush pages if needed. + */ + if (graph->memoryUsed >= graph->memoryTotal) + { + LWLockRelease(&graph->allocatorLock); + + LWLockRelease(flushLock); + LWLockAcquire(flushLock, LW_EXCLUSIVE); + + if (!graph->flushed) + { + ereport(NOTICE, + (errmsg("hnsw graph no longer fits into maintenance_work_mem after " INT64_FORMAT " tuples", (int64) graph->indtuples), + errdetail("Building will take significantly more time."), + errhint("Increase maintenance_work_mem to speed up builds."))); + + FlushPages(buildstate); + } + + LWLockRelease(flushLock); + + return HnswInsertTupleOnDisk(index, value, values, isnull, heaptid, true); + } + + /* Ok, we can proceed to allocate the element */ + element = HnswInitElement(base, heaptid, buildstate->m, buildstate->ml, buildstate->maxLevel, allocator); + valuePtr = (Pointer)HnswAlloc(allocator, valueSize); + + /* + * We have now allocated the space needed for the element, so we don't + * need the allocator lock anymore. Release it and initialize the rest of + * the element. + */ + LWLockRelease(&graph->allocatorLock); + + /* Copy the datum */ + memcpy(valuePtr, DatumGetPointer(value), valueSize); + HnswPtrStore(base, element->value, valuePtr); + + /* Create a lock for the element */ + LWLockInitialize(&element->lock, hnsw_lock_tranche_id); + + /* Insert tuple */ + InsertTupleInMemory(buildstate, element); + + /* Release flush lock */ + LWLockRelease(flushLock); + + return true; +} + +/* + * Callback for table_index_build_scan + */ +static void +BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, + const bool *isnull, bool tupleIsAlive, void *state) +{ + HnswBuildState *buildstate = (HnswBuildState *) state; + HnswGraph *graph = buildstate->graph; + MemoryContext oldCtx; + +#if PG_VERSION_NUM < 130000 + ItemPointer tid = &hup->t_self; +#endif + + /* Skip nulls */ + if (isnull[0]) + return; + + /* Use memory context */ + oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); + + /* Insert tuple */ + if (InsertTuple(index, values, isnull, tid, buildstate)) + { + /* Update progress */ + SpinLockAcquire(&graph->lock); + UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++graph->indtuples); + SpinLockRelease(&graph->lock); + } + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(buildstate->tmpCtx); +} + +/* + * Initialize the graph + */ +static void +InitGraph(HnswGraph * graph, char *base, long memoryTotal) +{ + HnswPtrStore(base, graph->head, (HnswElement) NULL); + HnswPtrStore(base, graph->entryPoint, (HnswElement) NULL); + graph->memoryUsed = 0; + graph->memoryTotal = memoryTotal; + graph->flushed = false; + graph->indtuples = 0; + SpinLockInit(&graph->lock); + LWLockInitialize(&graph->entryLock, hnsw_lock_tranche_id); + LWLockInitialize(&graph->entryWaitLock, hnsw_lock_tranche_id); + LWLockInitialize(&graph->allocatorLock, hnsw_lock_tranche_id); + LWLockInitialize(&graph->flushLock, hnsw_lock_tranche_id); +} + +/* + * Initialize an allocator + */ +static void +InitAllocator(HnswAllocator * allocator, void *(*alloc) (Size size, void *state), void *state) +{ + allocator->alloc = alloc; + allocator->state = state; +} + +/* + * Memory context allocator + */ +static void * +HnswMemoryContextAlloc(Size size, void *state) +{ + HnswBuildState *buildstate = (HnswBuildState *) state; + void *chunk = MemoryContextAlloc(buildstate->graphCtx, size); + +#if PG_VERSION_NUM >= 130000 + buildstate->graphData.memoryUsed = MemoryContextMemAllocated(buildstate->graphCtx, false); +#else + buildstate->graphData.memoryUsed += MAXALIGN(size); +#endif + + return chunk; +} + +/* + * Shared memory allocator + */ +static void * +HnswSharedMemoryAlloc(Size size, void *state) +{ + HnswBuildState *buildstate = (HnswBuildState *) state; + void *chunk = buildstate->hnswarea + buildstate->graph->memoryUsed; + + buildstate->graph->memoryUsed += MAXALIGN(size); + return chunk; +} + +/* + * Initialize the build state + */ +static void +InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, IndexInfo *indexInfo, ForkNumber forkNum) +{ + buildstate->heap = heap; + buildstate->index = index; + buildstate->indexInfo = indexInfo; + buildstate->forkNum = forkNum; + buildstate->typeInfo = HnswGetTypeInfo(index); + + buildstate->m = HnswGetM(index); + buildstate->efConstruction = HnswGetEfConstruction(index); + buildstate->dimensions = TupleDescAttr(index->rd_att, 0)->atttypmod; + + /* Disallow varbit since require fixed dimensions */ + if (TupleDescAttr(index->rd_att, 0)->atttypid == VARBITOID) { + elog(ERROR, "type not supported for hnsw index"); + } + + /* Require column to have dimensions to be indexed */ + if (buildstate->dimensions < 0) { + elog(ERROR, "column does not have dimensions"); + } + + if (buildstate->dimensions > buildstate->typeInfo->maxDimensions) { + elog(ERROR, "column cannot have more than %d dimensions for hnsw index", buildstate->typeInfo->maxDimensions); + } + + if (buildstate->efConstruction < 2 * buildstate->m) { + elog(ERROR, "ef_construction must be greater than or equal to 2 * m"); + } + + buildstate->reltuples = 0; + buildstate->indtuples = 0; + + /* Get support functions */ + buildstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); + buildstate->normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); + buildstate->collation = index->rd_indcollation[0]; + + InitGraph(&buildstate->graphData, NULL, u_sess->attr.attr_memory.maintenance_work_mem * 1024L); + buildstate->graph = &buildstate->graphData; + buildstate->ml = HnswGetMl(buildstate->m); + buildstate->maxLevel = HnswGetMaxLevel(buildstate->m); + + buildstate->graphCtx = AllocSetContextCreate(CurrentMemoryContext, + "Hnsw build graph context", + ALLOCSET_DEFAULT_SIZES); + buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, + "Hnsw build temporary context", + ALLOCSET_DEFAULT_SIZES); + + InitAllocator(&buildstate->allocator, &HnswMemoryContextAlloc, buildstate); + + buildstate->hnswleader = NULL; + buildstate->hnswshared = NULL; + buildstate->hnswarea = NULL; + + buildstate->enablePQ = HnswGetEnablePQ(index); + buildstate->pqM = HnswGetPqM(index); + buildstate->pqKsub = HnswGetPqKsub(index); + buildstate->pqTable = NULL; + buildstate->centerTable = NULL; + buildstate->pqcodeSize = 0; + + buildstate->isUStore = buildstate->heap ? RelationIsUstoreFormat(buildstate->heap) : false; +} + +/* + * Free resources + */ +static void +FreeBuildState(HnswBuildState * buildstate) +{ + MemoryContextDelete(buildstate->graphCtx); + MemoryContextDelete(buildstate->tmpCtx); +} + +static double +ParallelHeapScan(HnswBuildState * buildstate, int* nparticipanttuplesorts) +{ + HnswShared *hnswshared = buildstate->hnswleader->hnswshared; + double reltuples; + + BgworkerListWaitFinish(&buildstate->hnswleader->nparticipanttuplesorts); + pg_memory_barrier(); + + *nparticipanttuplesorts = buildstate->hnswleader->nparticipanttuplesorts; + buildstate->graph = &hnswshared->graphData; + buildstate->hnswarea = hnswshared->hnswarea; + reltuples = hnswshared->reltuples; + + return reltuples; +} + +/* + * Perform a worker's portion of a parallel insert + */ +static void +HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared * hnswshared, char *hnswarea) +{ + HnswBuildState buildstate; + TableScanDesc scan; + double reltuples; + IndexInfo *indexInfo; + + /* Join parallel scan */ + indexInfo = BuildIndexInfo(indexRel); + InitBuildState(&buildstate, heapRel, indexRel, indexInfo, MAIN_FORKNUM); + buildstate.graph = &hnswshared->graphData; + buildstate.hnswarea = hnswarea; + InitAllocator(&buildstate.allocator, &HnswSharedMemoryAlloc, &buildstate); + scan = tableam_scan_begin_parallel(heapRel, &hnswshared->heapdesc); + reltuples = tableam_index_build_scan(heapRel, indexRel, indexInfo, + true, BuildCallback, (void *) &buildstate, scan); + + /* Record statistics */ + SpinLockAcquire(&hnswshared->mutex); + hnswshared->nparticipantsdone++; + hnswshared->reltuples += reltuples; + SpinLockRelease(&hnswshared->mutex); + + FreeBuildState(&buildstate); +} + +/* + * Perform work within a launched parallel process + */ +void +HnswParallelBuildMain(const BgWorkerContext *bwc) +{ + HnswShared *hnswshared; + char *hnswarea; + Relation heapRel; + Relation indexRel; + + /* Look up shared state */ + hnswshared = (HnswShared*)bwc->bgshared; + + /* Open relations within worker */ + heapRel = heap_open(hnswshared->heaprelid, NoLock); + indexRel = index_open(hnswshared->indexrelid, NoLock); + + hnswarea = hnswshared->hnswarea; + + /* Perform inserts */ + HnswParallelScanAndInsert(heapRel, indexRel, hnswshared, hnswarea); + + /* Close relations within worker */ + index_close(indexRel, NoLock); + heap_close(heapRel, NoLock); +} + +/* + * End parallel build + */ +static void +HnswEndParallel() +{ + BgworkerListSyncQuit(); +} + +static HnswShared* +HnswParallelInitshared(HnswBuildState * buildstate) +{ + HnswShared *hnswshared; + char *hnswarea; + Size esthnswarea; + Size estother; + + /* Store shared build state, for which we reserved space */ + hnswshared = (HnswShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(HnswShared)); + + /* Initialize immutable state */ + hnswshared->heaprelid = RelationGetRelid(buildstate->heap); + hnswshared->indexrelid = RelationGetRelid(buildstate->index); + SpinLockInit(&hnswshared->mutex); + /* Initialize mutable state */ + hnswshared->nparticipantsdone = 0; + hnswshared->reltuples = 0; + HeapParallelscanInitialize(&hnswshared->heapdesc, buildstate->heap); + + /* Leave space for other objects in shared memory */ + /* Docker has a default limit of 64 MB for shm_size */ + /* which happens to be the default value of maintenance_work_mem */ + esthnswarea = u_sess->attr.attr_memory.maintenance_work_mem * 1024L; + estother = 3 * 1024 * 1024; + if (esthnswarea > estother) + esthnswarea -= estother; + + hnswarea = (char *) palloc0_huge(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), esthnswarea); + /* Report less than allocated so never fails */ + InitGraph(&hnswshared->graphData, hnswarea, esthnswarea - 1024 * 1024); + + /* + * Avoid base address for relptr for Postgres < 14.5 + * https://github.com/postgres/postgres/commit/7201cd18627afc64850537806da7f22150d1a83b + */ +#if PG_VERSION_NUM < 140005 + hnswshared->graphData.memoryUsed += MAXALIGN(1); +#endif + + hnswshared->hnswarea = hnswarea; + return hnswshared; +} + +/* + * Begin parallel build + */ +static void +HnswBeginParallel(HnswBuildState * buildstate, int request) +{ + HnswShared *hnswshared; + HnswLeader *hnswleader = (HnswLeader *) palloc0(sizeof(HnswLeader)); + + Assert(request > 0); + + hnswshared = HnswParallelInitshared(buildstate); + /* Launch workers, saving status for leader/caller */ + hnswleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, hnswshared, HnswParallelBuildMain, NULL); + hnswleader->hnswshared = hnswshared; + + /* If no workers were successfully launched, back out (do serial build) */ + if (hnswleader->nparticipanttuplesorts == 0) + { + HnswEndParallel(); + return; + } + + /* Log participants */ + ereport(DEBUG1, (errmsg("using %d parallel workers", hnswleader->nparticipanttuplesorts))); + + /* Save leader state now that it's clear build will be parallel */ + buildstate->hnswleader = hnswleader; +} + +/* + * Build graph + */ +static void +BuildGraph(HnswBuildState * buildstate, ForkNumber forkNum) +{ + int parallel_workers = 0; + + /* Calculate parallel workers */ + if (buildstate->heap != NULL) { + parallel_workers = PlanCreateIndexWorkers(buildstate->heap, buildstate->indexInfo); + } + + /* Attempt to launch parallel worker scan when required */ + if (parallel_workers > 0) { + HnswBeginParallel(buildstate, parallel_workers); + } + + /* Add tuples to graph */ + if (buildstate->heap != NULL) { + if (!buildstate->hnswleader) { +serial_build: + buildstate->reltuples = tableam_index_build_scan(buildstate->heap, buildstate->index, buildstate->indexInfo, + true, BuildCallback, (void *) buildstate, NULL); + } else { + int nruns; + buildstate->reltuples = ParallelHeapScan(buildstate, &nruns); + if (nruns == 0) { + /* failed to startup any bgworker, retry to do serial build */ + goto serial_build; + } + } + + buildstate->indtuples = buildstate->graph->indtuples; + } + + /* Flush pages */ + if (!buildstate->graph->flushed) { + FlushPages(buildstate); + } + + /* End parallel build */ + if (buildstate->hnswleader) { + HnswEndParallel(); + } +} + +/* + * Build the index + */ +static void +BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, + HnswBuildState * buildstate, ForkNumber forkNum) +{ +#ifdef HNSW_MEMORY + SeedRandom(42); +#endif + + InitBuildState(buildstate, heap, index, indexInfo, forkNum); + + BuildGraph(buildstate, forkNum); + + if (RelationNeedsWAL(index) || forkNum == INIT_FORKNUM) + log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); + + FreeBuildState(buildstate); +} + +/* + * Build the index for a logged table + */ +IndexBuildResult * +hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) +{ + IndexBuildResult *result; + HnswBuildState buildstate; + + BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); + + result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + result->heap_tuples = buildstate.reltuples; + result->index_tuples = buildstate.indtuples; + + return result; +} + +/* + * Build the index for an unlogged table + */ +void +hnswbuildempty_internal(Relation index) +{ + IndexInfo *indexInfo = BuildIndexInfo(index); + HnswBuildState buildstate; + + BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); +} diff --git a/src/gausskernel/storage/access/datavec/hnswdelete.cpp b/src/gausskernel/storage/access/datavec/hnswdelete.cpp new file mode 100644 index 0000000000..408d0f0025 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/hnswdelete.cpp @@ -0,0 +1,199 @@ +#include "access/ubtree.h" +#include "access/datavec/hnsw.h" +#include "access/datavec/vecindex.h" + +bool HnswIsTIDEquals(ItemPointer p1, ItemPointer p2) +{ + int id; + bool equal = true; + for (id = 0; id < HNSW_HEAPTIDS; id++) { + if (ItemPointerIsValid(&p1[id]) && ItemPointerIsValid(&p2[id])) { + equal = ItemPointerEquals(&p1[id], &p2[id]); + } else if (!ItemPointerIsValid(&p1[id]) && !ItemPointerIsValid(&p2[id])) { + continue; + } else { + equal = false; + } + + if (!equal) { + break; + } + } + + return equal; +} + +bool HnswIsETUPEqual(HnswElementTuple etup1, HnswElementTuple etup2) +{ + if (etup1 == NULL || etup2 == NULL) { + return false; + } + Size len1 = MAXALIGN(VARSIZE_ANY(&etup1->data)); + Size len2 = MAXALIGN(VARSIZE_ANY(&etup2->data)); + if (len1 == 0 || len2 == 0 || len1 != len2) { + return false; + } + return memcmp(&etup1->data, &etup2->data, len1) == 0; +} + +OffsetNumber HnswFindDeleteLocation(Relation index, Buffer buf, HnswElementTuple etup) +{ + OffsetNumber off; + OffsetNumber maxOff; + Page page; + TransactionId xmin; + TransactionId xmax; + + page = BufferGetPage(buf); + maxOff = PageGetMaxOffsetNumber(page); + + if (RelationIsGlobalIndex(index)) { + elog(ERROR, "the GLOBAL partitioned index is not supported.\n"); + } + + for (off = FirstOffsetNumber; off < maxOff; off++) { + ItemId iid; + HnswElementTuple tup; + + iid = PageGetItemId(page, off); + if (!ItemIdIsDead(iid)) { + tup = (HnswElementTuple)PageGetItem(page, iid); + if (!HnswIsTIDEquals(etup->heaptids, tup->heaptids)) { + continue; + } + + if (!HnswIsETUPEqual(etup, tup)) { + continue; + } + + bool xminCommitted = false; + bool xmaxCommitted = false; + bool isDead = VecItupGetXminXmax(page, off, InvalidTransactionId, &xmin, &xmax, &xminCommitted, + &xmaxCommitted, RelationGetNamespace(index) == PG_TOAST_NAMESPACE); + if (!isDead && !TransactionIdIsValid(xmax)) { + return off; + } + } + } + return InvalidOffsetNumber; +} + +void HnswDeleteOnPage(Relation index, Buffer buf, OffsetNumber offset) +{ + ItemId iid; + IndexTransInfo* idxXid; + Page page; + HnswElementTuple etup; + + page = BufferGetPage(buf); + iid = PageGetItemId(page, offset); + etup = (HnswElementTuple)PageGetItem(page, iid); + idxXid = (IndexTransInfo*)VecIndexTupleGetXid(etup); + + idxXid->xmax = GetCurrentTransactionId(); + + MarkBufferDirty(buf); +} + +bool IsHnswEntryPoint(Relation index, BlockNumber blkno, OffsetNumber offno) +{ + Buffer buf; + Page page; + HnswMetaPage metap; + bool res = false; + + buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + metap = HnswPageGetMeta(page); + if (blkno == metap->entryBlkno && offno == metap->entryOffno) { + res = true; + } + UnlockReleaseBuffer(buf); + return res; +} + +bool HnswDeleteIndex(Relation index, HnswElementTuple etup) +{ + bool found = false; + BlockNumber blkno; + Buffer buf; + char *base = NULL; + Datum q; + List *ep; + List *w; + ListCell *cell; + int m; + HnswElement entryPoint; + FmgrInfo *procinfo; + Oid collation; + OffsetNumber offset; + Page page; + + blkno = InvalidBlockNumber; + procinfo = index_getprocinfo(index, 1, 1); + collation = index->rd_indcollation[0]; + q = (Datum)(&etup->data); + HnswGetMetaPageInfo(index, &m, &entryPoint); + ep = list_make1(HnswEntryCandidate(base, entryPoint, q, index, procinfo, collation, false, NULL)); + + for (int lc = entryPoint->level; lc >= 0; lc--) { + w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, false, NULL); + ep = w; + } + + foreach(cell, ep) { + HnswCandidate *hc = (HnswCandidate *) lfirst(cell); + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + blkno = element->blkno; + } + + while (BlockNumberIsValid(blkno)) { + buf = ReadBuffer(index, blkno); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + offset = HnswFindDeleteLocation(index, buf, etup); + if (offset != InvalidOffsetNumber && ! IsHnswEntryPoint(index, blkno, offset)) { + HnswDeleteOnPage(index, buf, offset); + UnlockReleaseBuffer(buf); + found = true; + break; + } + + page = BufferGetPage(buf); + blkno = HnswPageGetOpaque(page)->nextblkno; + UnlockReleaseBuffer(buf); + } + return found; +} + +HnswElementTuple IndexFormHnswElementTuple(TupleDesc tupleDesc, Datum* values, const bool* isnull, + ItemPointer heapTCtid) +{ + Datum value; + HnswElementTuple etup; + Size etupSize; + + value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + etup = (HnswElementTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); + etupSize = HNSW_ELEMENT_TUPLE_SIZE(VARSIZE_ANY(DatumGetPointer(value))); + + etup->heaptids[0] = *heapTCtid; + for (int i = 1; i < HNSW_HEAPTIDS; i++) { + ItemPointerSetInvalid(&etup->heaptids[i]); + } + + memcpy(&etup->data, DatumGetPointer(value), VARSIZE_ANY(DatumGetPointer(value))); + return etup; +} + +bool hnswdelete_internal(Relation index, Datum* values, const bool* isnull, ItemPointer heapTCtid, bool isRollbackIndex) +{ + bool found; + HnswElementTuple etup; + + etup = IndexFormHnswElementTuple(RelationGetDescr(index), values, isnull, heapTCtid); + found = HnswDeleteIndex(index, etup); + + return found; +} diff --git a/src/gausskernel/storage/access/datavec/hnswinsert.cpp b/src/gausskernel/storage/access/datavec/hnswinsert.cpp new file mode 100644 index 0000000000..90720293f2 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/hnswinsert.cpp @@ -0,0 +1,682 @@ +#include "postgres.h" + +#include + +#include "access/generic_xlog.h" +#include "access/xact.h" +#include "access/datavec/hnsw.h" +#include "storage/buf/bufmgr.h" +#include "storage/lmgr.h" +#include "utils/datum.h" +#include "utils/memutils.h" + +/* + * Get the insert page + */ +static BlockNumber +GetInsertPage(Relation index) +{ + Buffer buf; + Page page; + HnswMetaPage metap; + BlockNumber insertPage; + + buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + metap = HnswPageGetMeta(page); + + insertPage = metap->insertPage; + + UnlockReleaseBuffer(buf); + + return insertPage; +} + +/* + * Check for a free offset + */ +static bool +HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size ntupSize, Buffer *nbuf, Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, BlockNumber *newInsertPage) +{ + OffsetNumber offno; + OffsetNumber maxoffno = PageGetMaxOffsetNumber(page); + + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + if (etup->deleted) + { + BlockNumber elementPage = BufferGetBlockNumber(buf); + BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); + OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); + ItemId itemid; + + if (!BlockNumberIsValid(*newInsertPage)) + *newInsertPage = elementPage; + + if (neighborPage == elementPage) + { + *nbuf = buf; + *npage = page; + } + else + { + *nbuf = ReadBuffer(index, neighborPage); + LockBuffer(*nbuf, BUFFER_LOCK_EXCLUSIVE); + + /* Skip WAL for now */ + *npage = BufferGetPage(*nbuf); + } + + itemid = PageGetItemId(*npage, neighborOffno); + + /* Check for space on neighbor tuple page */ + if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize) + { + *freeOffno = offno; + *freeNeighborOffno = neighborOffno; + return true; + } + else if (*nbuf != buf) + UnlockReleaseBuffer(*nbuf); + } + } + + return false; +} + +/* + * Add a new page + */ +static void +HnswInsertAppendPage(Relation index, Buffer *nbuf, Page *npage, GenericXLogState *state, Page page, bool building) +{ + /* Add a new page */ + LockRelationForExtension(index, ExclusiveLock); + *nbuf = HnswNewBuffer(index, MAIN_FORKNUM); + UnlockRelationForExtension(index, ExclusiveLock); + + /* Init new page */ + if (building) + *npage = BufferGetPage(*nbuf); + else + *npage = GenericXLogRegisterBuffer(state, *nbuf, GENERIC_XLOG_FULL_IMAGE); + + HnswInitPage(*nbuf, *npage); + + /* Update previous buffer */ + HnswPageGetOpaque(page)->nextblkno = BufferGetBlockNumber(*nbuf); +} + +/* + * Add to element and neighbor pages + */ +static void +AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, BlockNumber *updatedInsertPage, bool building) +{ + Buffer buf; + Page page; + GenericXLogState *state; + Size etupSize; + Size ntupSize; + Size combinedSize; + Size maxSize; + Size minCombinedSize; + HnswElementTuple etup; + BlockNumber currentPage = insertPage; + HnswNeighborTuple ntup; + Buffer nbuf; + Page npage; + OffsetNumber freeOffno = InvalidOffsetNumber; + OffsetNumber freeNeighborOffno = InvalidOffsetNumber; + BlockNumber newInsertPage = InvalidBlockNumber; + char *base = NULL; + bool isUStore; + IndexTransInfo* idxXid; + + /* Calculate sizes */ + etupSize = HNSW_ELEMENT_TUPLE_SIZE(VARSIZE_ANY(HnswPtrAccess(base, e->value))); + ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(e->level, m); + combinedSize = etupSize + ntupSize + sizeof(ItemIdData); + maxSize = HNSW_MAX_SIZE; + minCombinedSize = etupSize + HNSW_NEIGHBOR_TUPLE_SIZE(0, m) + sizeof(ItemIdData); + + /* Prepare element tuple */ + etup = (HnswElementTuple)palloc0(etupSize); + HnswSetElementTuple(base, etup, e); + + /* Prepare neighbor tuple */ + ntup = (HnswNeighborTuple)palloc0(ntupSize); + HnswSetNeighborTuple(base, ntup, e, m); + + /* Find a page (or two if needed) to insert the tuples */ + for (;;) { + buf = ReadBuffer(index, currentPage); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + + if (building) { + state = NULL; + page = BufferGetPage(buf); + } else { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + isUStore = HnswPageGetOpaque(page)->pageType == HNSW_USTORE_PAGE_TYPE; + /* Keep track of first page where element at level 0 can fit */ + if (!BlockNumberIsValid(newInsertPage) && PageGetFreeSpace(page) >= minCombinedSize) { + newInsertPage = currentPage; + } + + /* First, try the fastest path */ + /* Space for both tuples on the current page */ + /* This can split existing tuples in rare cases */ + if (PageGetFreeSpace(page) >= combinedSize) { + nbuf = buf; + npage = page; + break; + } + + /* Next, try space from a deleted element */ + if (HnswFreeOffset(index, buf, page, e, ntupSize, &nbuf, &npage, &freeOffno, + &freeNeighborOffno, &newInsertPage)) { + if (nbuf != buf) { + if (building) { + npage = BufferGetPage(nbuf); + } else { + npage = GenericXLogRegisterBuffer(state, nbuf, 0); + } + } + + break; + } + + /* Finally, try space for element only if last page */ + /* Skip if both tuples can fit on the same page */ + if (combinedSize > maxSize && PageGetFreeSpace(page) >= etupSize && + !BlockNumberIsValid(HnswPageGetOpaque(page)->nextblkno)) { + HnswInsertAppendPage(index, &nbuf, &npage, state, page, building); + if (isUStore) { + HnswPageGetOpaque(npage)->pageType = HNSW_USTORE_PAGE_TYPE; + } + break; + } + + currentPage = HnswPageGetOpaque(page)->nextblkno; + + if (BlockNumberIsValid(currentPage)) { + /* Move to next page */ + if (!building) + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + } else { + Buffer newbuf; + Page newpage; + + HnswInsertAppendPage(index, &newbuf, &newpage, state, page, building); + if (isUStore) { + HnswPageGetOpaque(npage)->pageType = HNSW_USTORE_PAGE_TYPE; + } + /* Commit */ + if (building) { + MarkBufferDirty(buf); + } else { + GenericXLogFinish(state); + } + + /* Unlock previous buffer */ + UnlockReleaseBuffer(buf); + + /* Prepare new buffer */ + buf = newbuf; + if (building) { + state = NULL; + page = BufferGetPage(buf); + } else { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + /* Create new page for neighbors if needed */ + if (PageGetFreeSpace(page) < combinedSize) { + HnswInsertAppendPage(index, &nbuf, &npage, state, page, building); + if (isUStore) { + HnswPageGetOpaque(npage)->pageType = HNSW_USTORE_PAGE_TYPE; + } + } else { + nbuf = buf; + npage = page; + } + + break; + } + } + + e->blkno = BufferGetBlockNumber(buf); + e->neighborPage = BufferGetBlockNumber(nbuf); + + /* Added tuple to new page if newInsertPage is not set */ + /* So can set to neighbor page instead of element page */ + if (!BlockNumberIsValid(newInsertPage)) { + newInsertPage = e->neighborPage; + } + + if (OffsetNumberIsValid(freeOffno)) { + e->offno = freeOffno; + e->neighborOffno = freeNeighborOffno; + } else { + e->offno = OffsetNumberNext(PageGetMaxOffsetNumber(page)); + if (nbuf == buf) { + e->neighborOffno = OffsetNumberNext(e->offno); + } else { + e->neighborOffno = FirstOffsetNumber; + } + } + + ItemPointerSet(&etup->neighbortid, e->neighborPage, e->neighborOffno); + + /* Add element and neighbors */ + if (OffsetNumberIsValid(freeOffno)) { + if (isUStore) { + ItemId item_id = PageGetItemId(page, e->offno); + Size aligned_size = MAXALIGN(ItemIdGetLength(item_id)); + unsigned offset = ItemIdGetOffset(item_id); + idxXid = (IndexTransInfo*)((char*)page + offset + aligned_size); + idxXid->xmin = GetCurrentTransactionId(); + idxXid->xmax = InvalidTransactionId; + } + if (!page_index_tuple_overwrite(page, e->offno, (Item) etup, etupSize)) { + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + } + + if (!page_index_tuple_overwrite(npage, e->neighborOffno, (Item) ntup, ntupSize)) { + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + } + } else { + if (isUStore) { + ((PageHeader)page)->pd_upper -= sizeof(IndexTransInfo); + idxXid = (IndexTransInfo*)(((char*)page) + ((PageHeader)page)->pd_upper); + idxXid->xmin = GetCurrentTransactionId(); + idxXid->xmax = InvalidTransactionId; + } + if (PageAddItem(page, (Item) etup, etupSize, InvalidOffsetNumber, false, false) != e->offno) { + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + } + + if (PageAddItem(npage, (Item) ntup, ntupSize, InvalidOffsetNumber, false, false) != e->neighborOffno) { + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + } + } + + /* Commit */ + if (building) { + MarkBufferDirty(buf); + if (nbuf != buf) + MarkBufferDirty(nbuf); + } else { + GenericXLogFinish(state); + } + UnlockReleaseBuffer(buf); + if (nbuf != buf) + UnlockReleaseBuffer(nbuf); + + /* Update the insert page */ + if (BlockNumberIsValid(newInsertPage) && newInsertPage != insertPage) + *updatedInsertPage = newInsertPage; +} + +/* + * Check if connection already exists + */ +static bool +ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) +{ + for (int i = 0; i < lm; i++) + { + ItemPointer indextid = &ntup->indextids[startIdx + i]; + + if (!ItemPointerIsValid(indextid)) + break; + + if (ItemPointerGetBlockNumber(indextid) == e->blkno && ItemPointerGetOffsetNumber(indextid) == e->offno) + return true; + } + + return false; +} + +/* + * Update neighbors + */ +void +HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting, bool building) +{ + char *base = NULL; + + for (int lc = e->level; lc >= 0; lc--) + { + int lm = HnswGetLayerM(m, lc); + HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *hc = &neighbors->items[i]; + Buffer buf; + Page page; + GenericXLogState *state; + HnswNeighborTuple ntup; + int idx = -1; + int startIdx; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); + OffsetNumber offno = neighborElement->neighborOffno; + + /* Get latest neighbors since they may have changed */ + /* Do not lock yet since selecting neighbors can take time */ + HnswLoadNeighbors(neighborElement, index, m); + + /* + * Could improve performance for vacuuming by checking neighbors + * against list of elements being deleted to find index. It's + * important to exclude already deleted elements for this since + * they can be replaced at any time. + */ + + /* Select neighbors */ + HnswUpdateConnection(NULL, e, hc, lm, lc, &idx, index, procinfo, collation); + + /* New element was not selected as a neighbor */ + if (idx == -1) + continue; + + /* Register page */ + buf = ReadBuffer(index, neighborElement->neighborPage); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (building) + { + state = NULL; + page = BufferGetPage(buf); + } + else + { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + /* Get tuple */ + ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, offno)); + + /* Calculate index for update */ + startIdx = (neighborElement->level - lc) * m; + + /* Check for existing connection */ + if (checkExisting && ConnectionExists(e, ntup, startIdx, lm)) + idx = -1; + else if (idx == -2) + { + /* Find free offset if still exists */ + /* TODO Retry updating connections if not */ + for (int j = 0; j < lm; j++) + { + if (!ItemPointerIsValid(&ntup->indextids[startIdx + j])) + { + idx = startIdx + j; + break; + } + } + } + else + idx += startIdx; + + /* Make robust to issues */ + if (idx >= 0 && idx < ntup->count) + { + ItemPointer indextid = &ntup->indextids[idx]; + + /* Update neighbor on the buffer */ + ItemPointerSet(indextid, e->blkno, e->offno); + + /* Commit */ + if (building) + MarkBufferDirty(buf); + else + GenericXLogFinish(state); + } + else if (!building) + GenericXLogAbort(state); + + UnlockReleaseBuffer(buf); + } + } +} + +/* + * Add a heap TID to an existing element + */ +static bool +AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool building) +{ + Buffer buf; + Page page; + GenericXLogState *state; + HnswElementTuple etup; + int i; + + /* Read page */ + buf = ReadBuffer(index, dup->blkno); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (building) + { + state = NULL; + page = BufferGetPage(buf); + } + else + { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + /* Find space */ + etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, dup->offno)); + for (i = 0; i < HNSW_HEAPTIDS; i++) + { + if (!ItemPointerIsValid(&etup->heaptids[i])) + break; + } + + /* Either being deleted or we lost our chance to another backend */ + if (i == 0 || i == HNSW_HEAPTIDS) + { + if (!building) + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + return false; + } + + /* Add heap TID, modifying the tuple on the page directly */ + etup->heaptids[i] = element->heaptids[0]; + + /* Commit */ + if (building) + MarkBufferDirty(buf); + else + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); + + return true; +} + +/* + * Find duplicate element + */ +static bool +FindDuplicateOnDisk(Relation index, HnswElement element, bool building) +{ + char *base = NULL; + HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); + Datum value = HnswGetValue(base, element); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *neighbor = &neighbors->items[i]; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); + Datum neighborValue = HnswGetValue(base, neighborElement); + + /* Exit early since ordered by distance */ + if (!datumIsEqual(value, neighborValue, false, -1)) + return false; + + if (AddDuplicateOnDisk(index, element, neighborElement, building)) + return true; + } + + return false; +} + +/* + * Update graph on disk + */ +static void +UpdateGraphOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, bool building) +{ + BlockNumber newInsertPage = InvalidBlockNumber; + + /* Look for duplicate */ + if (FindDuplicateOnDisk(index, element, building)) + return; + + /* Add element */ + AddElementOnDisk(index, element, m, GetInsertPage(index), &newInsertPage, building); + + /* Update insert page if needed */ + if (BlockNumberIsValid(newInsertPage)) + HnswUpdateMetaPage(index, 0, NULL, newInsertPage, MAIN_FORKNUM, building); + + /* Update neighbors */ + HnswUpdateNeighborsOnDisk(index, procinfo, collation, element, m, false, building); + + /* Update entry point if needed */ + if (entryPoint == NULL || element->level > entryPoint->level) + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM, building); +} + +/* + * Insert a tuple into the index + */ +bool +HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *isnull, ItemPointer heap_tid, bool building) +{ + HnswElement entryPoint; + HnswElement element; + int m; + int efConstruction = HnswGetEfConstruction(index); + FmgrInfo *procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); + Oid collation = index->rd_indcollation[0]; + LOCKMODE lockmode = ShareLock; + char *base = NULL; + + /* + * Get a shared lock. This allows vacuum to ensure no in-flight inserts + * before repairing graph. Use a page lock so it does not interfere with + * buffer lock (or reads when vacuuming). + */ + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get m and entry point */ + HnswGetMetaPageInfo(index, &m, &entryPoint); + + /* Create an element */ + element = HnswInitElement(base, heap_tid, m, HnswGetMl(m), HnswGetMaxLevel(m), NULL); + HnswPtrStore(base, element->value, DatumGetPointer(value)); + + /* Prevent concurrent inserts when likely updating entry point */ + if (entryPoint == NULL || element->level > entryPoint->level) + { + /* Release shared lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get exclusive lock */ + lockmode = ExclusiveLock; + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get latest entry point after lock is acquired */ + entryPoint = HnswGetEntryPoint(index); + } + + /* Find neighbors for element */ + HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, false); + + /* Update graph on disk */ + UpdateGraphOnDisk(index, procinfo, collation, element, m, efConstruction, entryPoint, building); + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + + return true; +} + +/* + * Insert a tuple into the index + */ +static void +HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid) +{ + Datum value; + const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index); + FmgrInfo *normprocinfo; + Oid collation = index->rd_indcollation[0]; + + /* Detoast once for all calls */ + value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Check value */ + if (typeInfo->checkValue != NULL) + typeInfo->checkValue(DatumGetPointer(value)); + + /* Normalize if needed */ + normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); + if (normprocinfo != NULL) + { + if (!HnswCheckNorm(normprocinfo, collation, value)) + return; + + value = HnswNormValue(typeInfo, collation, value); + } + + HnswInsertTupleOnDisk(index, value, values, isnull, heap_tid, false); +} + +/* + * Insert a tuple into the index + */ +bool +hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, + Relation heap, IndexUniqueCheck checkUnique) +{ + MemoryContext oldCtx; + MemoryContext insertCtx; + + /* Skip nulls */ + if (isnull[0]) + return false; + + /* Create memory context */ + insertCtx = AllocSetContextCreate(CurrentMemoryContext, + "Hnsw insert temporary context", + ALLOCSET_DEFAULT_SIZES); + oldCtx = MemoryContextSwitchTo(insertCtx); + + /* Insert tuple */ + HnswInsertTuple(index, values, isnull, heap_tid); + + /* Delete memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(insertCtx); + + return false; +} diff --git a/src/gausskernel/storage/access/datavec/hnswscan.cpp b/src/gausskernel/storage/access/datavec/hnswscan.cpp new file mode 100644 index 0000000000..a9c68a3628 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/hnswscan.cpp @@ -0,0 +1,214 @@ +#include "postgres.h" + +#include "access/relscan.h" +#include "access/datavec/hnsw.h" +#include "pgstat.h" +#include "storage/buf/bufmgr.h" +#include "storage/lmgr.h" +#include "utils/memutils.h" + +/* + * Algorithm 5 from paper + */ +static List * +GetScanItems(IndexScanDesc scan, Datum q) +{ + HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + Relation index = scan->indexRelation; + FmgrInfo *procinfo = so->procinfo; + Oid collation = so->collation; + List *ep; + List *w; + int m; + HnswElement entryPoint; + char *base = NULL; + + /* Get m and entry point */ + HnswGetMetaPageInfo(index, &m, &entryPoint); + + if (entryPoint == NULL) + return NIL; + + ep = list_make1(HnswEntryCandidate(base, entryPoint, q, index, procinfo, collation, false, scan)); + + for (int lc = entryPoint->level; lc >= 1; lc--) { + w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, false, NULL, scan); + ep = w; + } + + int hnsw_ef_search = get_session_context()->hnsw_ef_search; + return HnswSearchLayer(base, q, ep, hnsw_ef_search, 0, index, procinfo, collation, m, false, NULL, scan); +} + +/* + * Get scan value + */ +static Datum +GetScanValue(IndexScanDesc scan) +{ + HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + Datum value; + + if (scan->orderByData->sk_flags & SK_ISNULL) + value = PointerGetDatum(NULL); + else + { + value = scan->orderByData->sk_argument; + + /* Value should not be compressed or toasted */ + Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); + Assert(!VARATT_IS_EXTENDED(DatumGetPointer(value))); + + /* Normalize if needed */ + if (so->normprocinfo != NULL) + value = HnswNormValue(so->typeInfo, so->collation, value); + } + + return value; +} + +/* + * Prepare for an index scan + */ +IndexScanDesc +hnswbeginscan_internal(Relation index, int nkeys, int norderbys) +{ + IndexScanDesc scan; + HnswScanOpaque so; + + scan = RelationGetIndexScan(index, nkeys, norderbys); + + so = (HnswScanOpaque) palloc(sizeof(HnswScanOpaqueData)); + so->typeInfo = HnswGetTypeInfo(index); + so->first = true; + so->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, + "Hnsw scan temporary context", + ALLOCSET_DEFAULT_SIZES); + + so->vs.buf = InvalidBuffer; + so->vs.lastSelfModifiedItup = NULL; + so->vs.lastSelfModifiedItupBufferSize = 0; + + /* Set support functions */ + so->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); + so->normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); + so->collation = index->rd_indcollation[0]; + + scan->opaque = so; + + return scan; +} + +/* + * Start or restart an index scan + */ +void +hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) +{ + HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + + if (so->vs.lastSelfModifiedItup) { + IndexTupleSetSize(((IndexTuple)(so->vs.lastSelfModifiedItup)), 0); /* clear */ + } + + so->first = true; + MemoryContextReset(so->tmpCtx); + + if (keys && scan->numberOfKeys > 0) + memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData)); + + if (orderbys && scan->numberOfOrderBys > 0) + memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); +} + +/* + * Fetch the next tuple in the given scan + */ +bool +hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir) +{ + HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + MemoryContext oldCtx = MemoryContextSwitchTo(so->tmpCtx); + + /* + * Index can be used to scan backward, but Postgres doesn't support + * backward scan on operators + */ + Assert(ScanDirectionIsForward(dir)); + + if (so->first) { + Datum value; + + /* Count index scan for stats */ + pgstat_count_index_scan(scan->indexRelation); + + /* Safety check */ + if (scan->orderByData == NULL) + elog(ERROR, "cannot scan hnsw index without order"); + + /* Requires MVCC-compliant snapshot as not able to maintain a pin */ + /* https://www.postgresql.org/docs/current/index-locking.html */ + if (!IsMVCCSnapshot(scan->xs_snapshot)) + elog(ERROR, "non-MVCC snapshots are not supported with hnsw"); + + /* Get scan value */ + value = GetScanValue(scan); + + /* + * Get a shared lock. This allows vacuum to ensure no in-flight scans + * before marking tuples as deleted. + */ + LockPage(scan->indexRelation, HNSW_SCAN_LOCK, ShareLock); + + so->w = GetScanItems(scan, value); + + /* Release shared lock */ + UnlockPage(scan->indexRelation, HNSW_SCAN_LOCK, ShareLock); + + so->first = false; + +#if defined(HNSW_MEMORY) && PG_VERSION_NUM >= 130000 + elog(INFO, "memory: %zu MB", MemoryContextMemAllocated(so->tmpCtx, false) / MEM_INFO_NUM); +#endif + } + + while (list_length(so->w) > 0) { + char *base = NULL; + HnswCandidate *hc = (HnswCandidate *)linitial(so->w); + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + ItemPointer heaptid; + + /* Move to next element if no valid heap TIDs */ + if (element->heaptidsLength == 0) { + so->w = list_delete_first(so->w); + continue; + } + + heaptid = &element->heaptids[--element->heaptidsLength]; + + MemoryContextSwitchTo(oldCtx); + + scan->xs_ctup.t_self = *heaptid; + scan->xs_recheck = false; + return true; + } + + MemoryContextSwitchTo(oldCtx); + return false; +} + +/* + * End a scan and release resources + */ +void +hnswendscan_internal(IndexScanDesc scan) +{ + HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + + FREE_POINTER(so->vs.lastSelfModifiedItup); + + MemoryContextDelete(so->tmpCtx); + + pfree(so); + scan->opaque = NULL; +} diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp new file mode 100644 index 0000000000..a198d9713c --- /dev/null +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -0,0 +1,1472 @@ +#include "postgres.h" + +#include + +#include "access/generic_xlog.h" +#include "catalog/pg_type.h" +#include "fmgr.h" +#include "access/datavec/hnsw.h" +#include "lib/pairingheap.h" +#include "access/datavec/halfvec.h" +#include "access/datavec/sparsevec.h" +#include "storage/buf/bufmgr.h" +#include "utils/datum.h" +#include "utils/rel.h" + +#if PG_VERSION_NUM >= 130000 +#include "common/hashfn.h" +#else +#include "utils/hashutils.h" +#endif + +#if PG_VERSION_NUM < 170000 +static inline uint64 +murmurhash64(uint64 data) +{ + uint64 h = data; + + h ^= h >> 33; + h *= 0xff51afd7ed558ccd; + h ^= h >> 33; + h *= 0xc4ceb9fe1a85ec53; + h ^= h >> 33; + + return h; +} +#endif + +/* TID hash table */ +static uint32 +hash_tid(ItemPointerData tid) +{ + union + { + uint64 i; + ItemPointerData tid; + } x; + + /* Initialize unused bytes */ + x.i = 0; + x.tid = tid; + + return murmurhash64(x.i); +} + +#define VALGRIND_MAKE_MEM_DEFINED(addr, size) do {} while (0) + +#define SH_PREFIX tidhash +#define SH_ELEMENT_TYPE TidHashEntry +#define SH_KEY_TYPE ItemPointerData +#define SH_KEY tid +#define SH_HASH_KEY(tb, key) hash_tid(key) +#define SH_EQUAL(tb, a, b) ItemPointerEquals(&a, &b) +#define SH_SCOPE extern +#define SH_DEFINE +#include "lib/simplehash.h" + +/* Pointer hash table */ +static uint32 +hash_pointer(uintptr_t ptr) +{ +#if SIZEOF_VOID_P == 8 + return murmurhash64((uint64) ptr); +#else + return murmurhash32((uint32) ptr); +#endif +} + +#define SH_PREFIX pointerhash +#define SH_ELEMENT_TYPE PointerHashEntry +#define SH_KEY_TYPE uintptr_t +#define SH_KEY ptr +#define SH_HASH_KEY(tb, key) hash_pointer(key) +#define SH_EQUAL(tb, a, b) (a == b) +#define SH_SCOPE extern +#define SH_DEFINE +#include "lib/simplehash.h" + +/* Offset hash table */ +static uint32 +hash_offset(Size offset) +{ +#if SIZEOF_SIZE_T == 8 + return murmurhash64((uint64) offset); +#else + return murmurhash32((uint32) offset); +#endif +} + +#define SH_PREFIX offsethash +#define SH_ELEMENT_TYPE OffsetHashEntry +#define SH_KEY_TYPE Size +#define SH_KEY offset +#define SH_HASH_KEY(tb, key) hash_offset(key) +#define SH_EQUAL(tb, a, b) (a == b) +#define SH_SCOPE extern +#define SH_DEFINE +#include "lib/simplehash.h" + +typedef union +{ + pointerhash_hash *pointers; + offsethash_hash *offsets; + tidhash_hash *tids; +} visited_hash; + +/* + * Get the max number of connections in an upper layer for each element in the index + */ +int +HnswGetM(Relation index) +{ + HnswOptions *opts = (HnswOptions *) index->rd_options; + + if (opts) + return opts->m; + + return HNSW_DEFAULT_M; +} + +/* + * Get the size of the dynamic candidate list in the index + */ +int +HnswGetEfConstruction(Relation index) +{ + HnswOptions *opts = (HnswOptions *) index->rd_options; + + if (opts) + return opts->efConstruction; + + return HNSW_DEFAULT_EF_CONSTRUCTION; +} + +/* + * Get whether to enable PQ + */ +bool +HnswGetEnablePQ(Relation index) +{ + HnswOptions *opts = (HnswOptions *) index->rd_options; + + if (opts) { + return opts->enablePQ; + } + + return HNSW_DEFAULT_ENABLE_PQ; +} + +/* + * Get the number of subquantizer + */ +int +HnswGetPqM(Relation index) +{ + HnswOptions *opts = (HnswOptions *) index->rd_options; + + if (opts) { + return opts->pqM; + } + + return HNSW_DEFAULT_PQ_M; +} + +/* + * Get the number of centroids for each subquantizer + */ +int +HnswGetPqKsub(Relation index) +{ + HnswOptions *opts = (HnswOptions *) index->rd_options; + + if (opts) { + return opts->pqKsub; + } + + return HNSW_DEFAULT_PQ_KSUB; +} + + +/* + * Get proc + */ +FmgrInfo * +HnswOptionalProcInfo(Relation index, uint16 procnum) +{ + if (!OidIsValid(index_getprocid(index, 1, procnum))) + return NULL; + + return index_getprocinfo(index, 1, procnum); +} + +/* + * Normalize value + */ +Datum +HnswNormValue(const HnswTypeInfo * typeInfo, Oid collation, Datum value) +{ + return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); +} + +/* + * Check if non-zero norm + */ +bool +HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) +{ + return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; +} + +/* + * New buffer + */ +Buffer +HnswNewBuffer(Relation index, ForkNumber forkNum) +{ + Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); + + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + return buf; +} + +/* + * Init page + */ +void +HnswInitPage(Buffer buf, Page page) +{ + PageInit(page, BufferGetPageSize(buf), sizeof(HnswPageOpaqueData)); + HnswPageGetOpaque(page)->nextblkno = InvalidBlockNumber; + HnswPageGetOpaque(page)->pageType = HNSW_DEFAULT_PAGE_TYPE; + HnswPageGetOpaque(page)->page_id = HNSW_PAGE_ID; +} + +/* + * Allocate a neighbor array + */ +static HnswNeighborArray * +HnswInitNeighborArray(int lm, HnswAllocator * allocator) +{ + HnswNeighborArray *a = (HnswNeighborArray *)HnswAlloc(allocator, HNSW_NEIGHBOR_ARRAY_SIZE(lm)); + + a->length = 0; + a->closerSet = false; + return a; +} + +/* + * Allocate neighbors + */ +void +HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * allocator) +{ + int level = element->level; + HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *) HnswAlloc(allocator, sizeof(HnswNeighborArrayPtr) * (level + 1)); + + HnswPtrStore(base, element->neighbors, neighborList); + + for (int lc = 0; lc <= level; lc++) + HnswPtrStore(base, neighborList[lc], HnswInitNeighborArray(HnswGetLayerM(m, lc), allocator)); +} + +/* + * Allocate memory from the allocator + */ +void * +HnswAlloc(HnswAllocator * allocator, Size size) +{ + if (allocator) + return (*(allocator)->alloc) (size, (allocator)->state); + + return palloc(size); +} + +/* + * Allocate an element + */ +HnswElement +HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, HnswAllocator * allocator) +{ + HnswElement element = (HnswElement)HnswAlloc(allocator, sizeof(HnswElementData)); + + int level = (int) (-log(RandomDouble()) * ml); + + /* Cap level */ + if (level > maxLevel) + level = maxLevel; + + element->heaptidsLength = 0; + HnswAddHeapTid(element, heaptid); + + element->level = level; + element->deleted = 0; + + HnswInitNeighbors(base, element, m, allocator); + + HnswPtrStore(base, element->value, (Pointer) NULL); + + return element; +} + +/* + * Add a heap TID to an element + */ +void +HnswAddHeapTid(HnswElement element, ItemPointer heaptid) +{ + element->heaptids[element->heaptidsLength++] = *heaptid; +} + +/* + * Allocate an element from block and offset numbers + */ +HnswElement +HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno) +{ + HnswElement element = (HnswElement)palloc(sizeof(HnswElementData)); + char *base = NULL; + + element->blkno = blkno; + element->offno = offno; + HnswPtrStore(base, element->neighbors, (HnswNeighborArrayPtr *) NULL); + HnswPtrStore(base, element->value, (Pointer) NULL); + return element; +} + +/* + * Get the metapage info + */ +void +HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint) +{ + Buffer buf; + Page page; + HnswMetaPage metap; + + buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + metap = HnswPageGetMeta(page); + + if (unlikely(metap->magicNumber != HNSW_MAGIC_NUMBER)) + elog(ERROR, "hnsw index is not valid"); + + if (m != NULL) + *m = metap->m; + + if (entryPoint != NULL) + { + if (BlockNumberIsValid(metap->entryBlkno)) + { + *entryPoint = HnswInitElementFromBlock(metap->entryBlkno, metap->entryOffno); + (*entryPoint)->level = metap->entryLevel; + } + else + *entryPoint = NULL; + } + + UnlockReleaseBuffer(buf); +} + +/* + * Get the entry point + */ +HnswElement +HnswGetEntryPoint(Relation index) +{ + HnswElement entryPoint; + + HnswGetMetaPageInfo(index, NULL, &entryPoint); + + return entryPoint; +} + +/* + * Update the metapage info + */ +static void +HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, BlockNumber insertPage) +{ + HnswMetaPage metap = HnswPageGetMeta(page); + + if (updateEntry) + { + if (entryPoint == NULL) + { + metap->entryBlkno = InvalidBlockNumber; + metap->entryOffno = InvalidOffsetNumber; + metap->entryLevel = -1; + } + else if (entryPoint->level > metap->entryLevel || updateEntry == HNSW_UPDATE_ENTRY_ALWAYS) + { + metap->entryBlkno = entryPoint->blkno; + metap->entryOffno = entryPoint->offno; + metap->entryLevel = entryPoint->level; + } + } + + if (BlockNumberIsValid(insertPage)) + metap->insertPage = insertPage; +} + +/* + * Update the append metapage info + */ +static void +HnswUpdateAppendMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, + BlockNumber eleInsertSlotStartPage, BlockNumber neiInsertSlotStartPage) +{ + HnswAppendMetaPage metap = HnswPageGetAppendMeta(page); + + if (updateEntry) { + if (entryPoint == NULL) { + metap->entryBlkno = InvalidBlockNumber; + metap->entryOffno = InvalidOffsetNumber; + metap->entryLevel = -1; + } else if (entryPoint->level > metap->entryLevel || updateEntry == HNSW_UPDATE_ENTRY_ALWAYS) { + metap->entryBlkno = entryPoint->blkno; + metap->entryOffno = entryPoint->offno; + metap->entryLevel = entryPoint->level; + } + } + + if (BlockNumberIsValid(eleInsertSlotStartPage)) { + metap->elementInsertSlot = eleInsertSlotStartPage; + } + + if (BlockNumberIsValid(neiInsertSlotStartPage)) { + metap->neighborInsertSlot = neiInsertSlotStartPage; + } +} + +/* + * Update the metapage + */ +void +HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum, bool building) +{ + Buffer buf; + Page page; + GenericXLogState *state; + + buf = ReadBufferExtended(index, forkNum, HNSW_METAPAGE_BLKNO, RBM_NORMAL, NULL); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (building) + { + state = NULL; + page = BufferGetPage(buf); + } + else + { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + HnswUpdateMetaPageInfo(page, updateEntry, entryPoint, insertPage); + + if (building) + MarkBufferDirty(buf); + else + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); +} + +/* + * Update the append metapage + */ +void +HnswUpdateAppendMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber eleInsertPage, + BlockNumber neiInsertPage, ForkNumber forkNum, bool building) +{ + Buffer buf; + Page page; + GenericXLogState *state; + + buf = ReadBufferExtended(index, forkNum, HNSW_METAPAGE_BLKNO, RBM_NORMAL, NULL); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (building) { + state = NULL; + page = BufferGetPage(buf); + } else { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + HnswUpdateAppendMetaPageInfo(page, updateEntry, entryPoint, eleInsertPage, neiInsertPage); + + if (building) { + MarkBufferDirty(buf); + } else { + GenericXLogFinish(state); + } + UnlockReleaseBuffer(buf); +} + +/* + * Set element tuple, except for neighbor info + */ +void +HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) +{ + Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); + + etup->type = HNSW_ELEMENT_TUPLE_TYPE; + etup->level = element->level; + etup->deleted = 0; + for (int i = 0; i < HNSW_HEAPTIDS; i++) + { + if (i < element->heaptidsLength) + etup->heaptids[i] = element->heaptids[i]; + else + ItemPointerSetInvalid(&etup->heaptids[i]); + } + memcpy(&etup->data, valuePtr, VARSIZE_ANY(valuePtr)); +} + +/* + * Set neighbor tuple + */ +void +HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) +{ + int idx = 0; + + ntup->type = HNSW_NEIGHBOR_TUPLE_TYPE; + + for (int lc = e->level; lc >= 0; lc--) + { + HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); + int lm = HnswGetLayerM(m, lc); + + for (int i = 0; i < lm; i++) + { + ItemPointer indextid = &ntup->indextids[idx++]; + + if (i < neighbors->length) + { + HnswCandidate *hc = &neighbors->items[i]; + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + + ItemPointerSet(indextid, hce->blkno, hce->offno); + } + else + ItemPointerSetInvalid(indextid); + } + } + + ntup->count = idx; +} + +/* + * Load neighbors from page + */ +static void +LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) +{ + char *base = NULL; + + HnswNeighborTuple ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); + int neighborCount = (element->level + 2) * m; + + Assert(HnswIsNeighborTuple(ntup)); + + HnswInitNeighbors(base, element, m, NULL); + + /* Ensure expected neighbors */ + if (ntup->count != neighborCount) + return; + + for (int i = 0; i < neighborCount; i++) + { + HnswElement e; + int level; + HnswCandidate *hc; + ItemPointer indextid; + HnswNeighborArray *neighbors; + + indextid = &ntup->indextids[i]; + + if (!ItemPointerIsValid(indextid)) + continue; + + e = HnswInitElementFromBlock(ItemPointerGetBlockNumber(indextid), ItemPointerGetOffsetNumber(indextid)); + + /* Calculate level based on offset */ + level = element->level - i / m; + if (level < 0) + level = 0; + + neighbors = HnswGetNeighbors(base, element, level); + hc = &neighbors->items[neighbors->length++]; + HnswPtrStore(base, hc->element, e); + } +} + +/* + * Load neighbors + */ +void +HnswLoadNeighbors(HnswElement element, Relation index, int m) +{ + Buffer buf; + Page page; + + buf = ReadBuffer(index, element->neighborPage); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + + LoadNeighborsFromPage(element, index, page, m); + + UnlockReleaseBuffer(buf); +} + +/* + * Load an element from a tuple + */ +void +HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec) +{ + element->level = etup->level; + element->deleted = etup->deleted; + element->neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); + element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); + element->heaptidsLength = 0; + + if (loadHeaptids) + { + for (int i = 0; i < HNSW_HEAPTIDS; i++) + { + /* Can stop at first invalid */ + if (!ItemPointerIsValid(&etup->heaptids[i])) + break; + + HnswAddHeapTid(element, &etup->heaptids[i]); + } + } + + if (loadVec) + { + char *base = NULL; + Datum value = datumCopy(PointerGetDatum(&etup->data), false, -1); + + HnswPtrStore(base, element->value, DatumGetPointer(value)); + } +} + +/* + * Load an element and optionally get its distance from q + */ +bool +HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, + Oid collation, bool loadVec, float *maxDistance, IndexScanDesc scan) +{ + Buffer buf; + Page page; + HnswElementTuple etup; + bool needRecheck = false; + bool isVisible = true; + + /* Read vector */ + buf = ReadBuffer(index, element->blkno); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + if (scan != NULL && HnswPageGetOpaque(page)->pageType == HNSW_USTORE_PAGE_TYPE) { + HnswScanOpaque so = (HnswScanOpaque)scan->opaque; + so->vs.buf = buf; + isVisible = VecVisibilityCheck(scan, page, element->offno, &needRecheck); + } + + etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, element->offno)); + + Assert(HnswIsElementTuple(etup)); + + /* Calculate distance */ + if (distance != NULL) { + if (DatumGetPointer(*q) == NULL) { + *distance = 0; + } else { + *distance = (float) DatumGetFloat8(FunctionCall2Coll(procinfo, collation, *q, + PointerGetDatum(&etup->data))); + } + } + + /* Load element */ + if (distance == NULL || maxDistance == NULL || *distance < *maxDistance) { + HnswLoadElementFromTuple(element, etup, true, loadVec); + } + + UnlockReleaseBuffer(buf); + return isVisible; +} + +/* + * Get the distance for a candidate + */ +static float +GetCandidateDistance(char *base, HnswCandidate * hc, Datum q, FmgrInfo *procinfo, Oid collation) +{ + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + Datum value = HnswGetValue(base, hce); + + return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, q, value)); +} + +/* + * Create a candidate for the entry point + */ +HnswCandidate * +HnswEntryCandidate(char *base, HnswElement entryPoint, Datum q, Relation index, FmgrInfo *procinfo, + Oid collation, bool loadVec, IndexScanDesc scan) +{ + HnswCandidate *hc = (HnswCandidate *)palloc(sizeof(HnswCandidate)); + + HnswPtrStore(base, hc->element, entryPoint); + if (index == NULL) { + hc->distance = GetCandidateDistance(base, hc, q, procinfo, collation); + } else { + bool isVisible = HnswLoadElement(entryPoint, &hc->distance, &q, index, procinfo, + collation, loadVec, NULL, scan); + if (!isVisible) { + elog(ERROR, "hnsw entryPoint is invisible\n"); + } + } + return hc; +} + +/* + * Compare candidate distances + */ +static int +CompareNearestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) +{ + if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) + return 1; + + if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) + return -1; + + return 0; +} + +/* + * Compare candidate distances + */ +static int +CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) +{ + if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) + return -1; + + if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) + return 1; + + return 0; +} + +/* + * Create a pairing heap node for a candidate + */ +static HnswPairingHeapNode * +CreatePairingHeapNode(HnswCandidate * c) +{ + HnswPairingHeapNode *node = (HnswPairingHeapNode *)palloc(sizeof(HnswPairingHeapNode)); + + node->inner = c; + return node; +} + +/* + * Init visited + */ +static inline void +InitVisited(char *base, visited_hash * v, Relation index, int ef, int m) +{ + if (index != NULL) + v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL); + else if (base != NULL) + v->offsets = offsethash_create(CurrentMemoryContext, ef * m * 2, NULL); + else + v->pointers = pointerhash_create(CurrentMemoryContext, ef * m * 2, NULL); +} + +/* + * Add to visited + */ +static inline void +AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, bool *found) +{ + if (index != NULL) + { + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + ItemPointerData indextid; + + ItemPointerSet(&indextid, element->blkno, element->offno); + tidhash_insert(v->tids, indextid, found); + } + else if (base != NULL) + { +#if PG_VERSION_NUM >= 130000 + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + + offsethash_insert_hash(v->offsets, HnswPtrOffset(hc->element), element->hash, found); +#else + offsethash_insert(v->offsets, HnswPtrOffset(hc->element), found); +#endif + } + else + { +#if PG_VERSION_NUM >= 130000 + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + + pointerhash_insert_hash(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), element->hash, found); +#else + pointerhash_insert(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), found); +#endif + } +} + +/* + * Count element towards ef + */ +static inline bool +CountElement(char *base, HnswElement skipElement, HnswCandidate * hc) +{ + HnswElement e; + + if (skipElement == NULL) + return true; + + /* Ensure does not access heaptidsLength during in-memory build */ + pg_memory_barrier(); + + e = (HnswElement)HnswPtrAccess(base, hc->element); + return e->heaptidsLength != 0; +} + +/* + * Algorithm 2 from paper + */ +List * +HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *procinfo, + Oid collation, int m, bool inserting, HnswElement skipElement, IndexScanDesc scan) +{ + List *w = NIL; + pairingheap *C = pairingheap_allocate(CompareNearestCandidates, NULL); + pairingheap *W = pairingheap_allocate(CompareFurthestCandidates, NULL); + int wlen = 0; + visited_hash v; + ListCell *lc2; + HnswNeighborArray *neighborhoodData = NULL; + Size neighborhoodSize; + bool isVisible = true; + + InitVisited(base, &v, index, ef, m); + + /* Create local memory for neighborhood if needed */ + if (index == NULL) { + neighborhoodSize = HNSW_NEIGHBOR_ARRAY_SIZE(HnswGetLayerM(m, lc)); + neighborhoodData = (HnswNeighborArray *)palloc(neighborhoodSize); + } + + /* Add entry points to v, C, and W */ + foreach(lc2, ep) { + HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); + bool found; + + AddToVisited(base, &v, hc, index, &found); + + pairingheap_add(C, &(CreatePairingHeapNode(hc)->ph_node)); + pairingheap_add(W, &(CreatePairingHeapNode(hc)->ph_node)); + + /* + * Do not count elements being deleted towards ef when vacuuming. It + * would be ideal to do this for inserts as well, but this could + * affect insert performance. + */ + if (CountElement(base, skipElement, hc)) + wlen++; + } + + while (!pairingheap_is_empty(C)) { + HnswNeighborArray *neighborhood; + HnswCandidate *c = ((HnswPairingHeapNode *) pairingheap_remove_first(C))->inner; + HnswCandidate *f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner; + HnswElement cElement; + + if (c->distance > f->distance) + break; + + cElement = (HnswElement)HnswPtrAccess(base, c->element); + + if (HnswPtrIsNull(base, cElement->neighbors)) + HnswLoadNeighbors(cElement, index, m); + + /* Get the neighborhood at layer lc */ + neighborhood = HnswGetNeighbors(base, cElement, lc); + + /* Copy neighborhood to local memory if needed */ + if (index == NULL) { + LWLockAcquire(&cElement->lock, LW_SHARED); + memcpy(neighborhoodData, neighborhood, neighborhoodSize); + LWLockRelease(&cElement->lock); + neighborhood = neighborhoodData; + } + + for (int i = 0; i < neighborhood->length; i++) { + HnswCandidate *e = &neighborhood->items[i]; + bool visited; + + AddToVisited(base, &v, e, index, &visited); + + if (!visited) { + float eDistance; + HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); + bool alwaysAdd = wlen < ef; + + f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner; + + if (index == NULL) { + eDistance = GetCandidateDistance(base, e, q, procinfo, collation); + } else { + isVisible = HnswLoadElement(eElement, &eDistance, &q, index, procinfo, collation, inserting, + alwaysAdd ? NULL : &f->distance, scan); + } + if (!isVisible) { + continue; + } + + if (eDistance < f->distance || alwaysAdd) { + HnswCandidate *ec; + + Assert(!eElement->deleted); + + /* Make robust to issues */ + if (eElement->level < lc) + continue; + + /* Copy e */ + ec = (HnswCandidate *)palloc(sizeof(HnswCandidate)); + HnswPtrStore(base, ec->element, eElement); + ec->distance = eDistance; + + pairingheap_add(C, &(CreatePairingHeapNode(ec)->ph_node)); + pairingheap_add(W, &(CreatePairingHeapNode(ec)->ph_node)); + + /* + * Do not count elements being deleted towards ef when + * vacuuming. It would be ideal to do this for inserts as + * well, but this could affect insert performance. + */ + if (CountElement(base, skipElement, e)) { + wlen++; + + /* No need to decrement wlen */ + if (wlen > ef) + pairingheap_remove_first(W); + } + } + } + } + } + + /* Add each element of W to w */ + while (!pairingheap_is_empty(W)) { + HnswCandidate *hc = ((HnswPairingHeapNode *) pairingheap_remove_first(W))->inner; + + w = lcons(hc, w); + } + + return w; +} + +/* + * Compare candidate distances with pointer tie-breaker + */ +static int +#if PG_VERSION_NUM >= 130000 +CompareCandidateDistances(const ListCell *a, const ListCell *b) +{ + HnswCandidate *hca = (HnswCandidate *)lfirst(a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(b); +#else +CompareCandidateDistances(const void *a, const void *b) +{ + HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); +#endif + + if (hca->distance < hcb->distance) + return 1; + + if (hca->distance > hcb->distance) + return -1; + + if (HnswPtrPointer(hca->element) < HnswPtrPointer(hcb->element)) + return 1; + + if (HnswPtrPointer(hca->element) > HnswPtrPointer(hcb->element)) + return -1; + + return 0; +} + +/* + * Compare candidate distances with offset tie-breaker + */ +static int +#if PG_VERSION_NUM >= 130000 +CompareCandidateDistancesOffset(const ListCell *a, const ListCell *b) +{ + HnswCandidate *hca = (HnswCandidate *)lfirst(a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(b); +#else +CompareCandidateDistancesOffset(const void *a, const void *b) +{ + HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); +#endif + + if (hca->distance < hcb->distance) + return 1; + + if (hca->distance > hcb->distance) + return -1; + + if (HnswPtrOffset(hca->element) < HnswPtrOffset(hcb->element)) + return 1; + + if (HnswPtrOffset(hca->element) > HnswPtrOffset(hcb->element)) + return -1; + + return 0; +} + +/* + * Calculate the distance between elements + */ +static float +HnswGetDistance(char *base, HnswElement a, HnswElement b, FmgrInfo *procinfo, Oid collation) +{ + Datum aValue = HnswGetValue(base, a); + Datum bValue = HnswGetValue(base, b); + + return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, aValue, bValue)); +} + +/* + * Check if an element is closer to q than any element from R + */ +static bool +CheckElementCloser(char *base, HnswCandidate * e, List *r, FmgrInfo *procinfo, Oid collation) +{ + HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); + ListCell *lc2; + + foreach(lc2, r) + { + HnswCandidate *ri = (HnswCandidate *)lfirst(lc2); + HnswElement riElement = (HnswElement)HnswPtrAccess(base, ri->element); + float distance = HnswGetDistance(base, eElement, riElement, procinfo, collation); + + if (distance <= e->distance) + return false; + } + + return true; +} + +/* + * Algorithm 4 from paper + */ +static List * +SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid collation, HnswElement e2, HnswCandidate * newCandidate, HnswCandidate * *pruned, bool sortCandidates) +{ + List *r = NIL; + List *w = list_copy(c); + HnswCandidate **wd; + int wdlen = 0; + int wdoff = 0; + HnswNeighborArray *neighbors = HnswGetNeighbors(base, e2, lc); + bool mustCalculate = !neighbors->closerSet; + List *added = NIL; + bool removedAny = false; + + if (list_length(w) <= lm) + return w; + + wd = (HnswCandidate **)palloc(sizeof(HnswCandidate *) * list_length(w)); + + /* Ensure order of candidates is deterministic for closer caching */ + if (sortCandidates) + { + if (base == NULL) { + list_sort(w, CompareCandidateDistances); + } + else { + list_sort(w, CompareCandidateDistancesOffset); + } + } + + while (list_length(w) > 0 && list_length(r) < lm) { + /* Assumes w is already ordered desc */ + HnswCandidate *e = (HnswCandidate *)linitial(w); + + w = list_delete_first(w); + + /* Use previous state of r and wd to skip work when possible */ + if (mustCalculate) { + e->closer = CheckElementCloser(base, e, r, procinfo, collation); + } + else if (list_length(added) > 0) { + /* Keep Valgrind happy for in-memory, parallel builds */ + if (base != NULL) { + VALGRIND_MAKE_MEM_DEFINED(&e->closer, 1); + } + + /* + * If the current candidate was closer, we only need to compare it + * with the other candidates that we have added. + */ + if (e->closer) { + e->closer = CheckElementCloser(base, e, added, procinfo, collation); + + if (!e->closer) { + removedAny = true; + } + } + else { + /* + * If we have removed any candidates from closer, a candidate + * that was not closer earlier might now be. + */ + if (removedAny) { + e->closer = CheckElementCloser(base, e, r, procinfo, collation); + if (e->closer) { + added = lappend(added, e); + } + } + } + } + else if (e == newCandidate) + { + e->closer = CheckElementCloser(base, e, r, procinfo, collation); + if (e->closer) { + added = lappend(added, e); + } + } + + /* Keep Valgrind happy for in-memory, parallel builds */ + if (base != NULL) { + VALGRIND_MAKE_MEM_DEFINED(&e->closer, 1); + } + + if (e->closer) { + r = lappend(r, e); + } + else { + wd[wdlen++] = e; + } + } + + /* Cached value can only be used in future if sorted deterministically */ + neighbors->closerSet = sortCandidates; + + /* Keep pruned connections */ + while (wdoff < wdlen && list_length(r) < lm) { + r = lappend(r, wd[wdoff++]); + } + + /* Return pruned for update connections */ + if (pruned != NULL) { + if (wdoff < wdlen) { + *pruned = wd[wdoff]; + } + else { + *pruned = (HnswCandidate *)linitial(w); + } + } + + return r; +} + +/* + * Add connections + */ +static void +AddConnections(char *base, HnswElement element, List *neighbors, int lc) +{ + ListCell *lc2; + HnswNeighborArray *a = HnswGetNeighbors(base, element, lc); + + foreach(lc2, neighbors) + a->items[a->length++] = *((HnswCandidate *) lfirst(lc2)); +} + +/* + * Update connections + */ +void +HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation) +{ + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + HnswNeighborArray *currentNeighbors = HnswGetNeighbors(base, hce, lc); + HnswCandidate hc2; + + HnswPtrStore(base, hc2.element, element); + hc2.distance = hc->distance; + + if (currentNeighbors->length < lm) + { + currentNeighbors->items[currentNeighbors->length++] = hc2; + + /* Track update */ + if (updateIdx != NULL) + *updateIdx = -2; + } + else + { + /* Shrink connections */ + HnswCandidate *pruned = NULL; + + /* Load elements on insert */ + if (index != NULL) + { + Datum q = HnswGetValue(base, hce); + + for (int i = 0; i < currentNeighbors->length; i++) + { + HnswCandidate *hc3 = ¤tNeighbors->items[i]; + HnswElement hc3Element = (HnswElement)HnswPtrAccess(base, hc3->element); + + if (HnswPtrIsNull(base, hc3Element->value)) + HnswLoadElement(hc3Element, &hc3->distance, &q, index, procinfo, collation, true, NULL); + else + hc3->distance = GetCandidateDistance(base, hc3, q, procinfo, collation); + + /* Prune element if being deleted */ + if (hc3Element->heaptidsLength == 0) + { + pruned = ¤tNeighbors->items[i]; + break; + } + } + } + + if (pruned == NULL) + { + List *c = NIL; + + /* Add candidates */ + for (int i = 0; i < currentNeighbors->length; i++) + c = lappend(c, ¤tNeighbors->items[i]); + c = lappend(c, &hc2); + + SelectNeighbors(base, c, lm, lc, procinfo, collation, hce, &hc2, &pruned, true); + + /* Should not happen */ + if (pruned == NULL) + return; + } + + /* Find and replace the pruned element */ + for (int i = 0; i < currentNeighbors->length; i++) + { + if (HnswPtrEqual(base, currentNeighbors->items[i].element, pruned->element)) + { + currentNeighbors->items[i] = hc2; + + /* Track update */ + if (updateIdx != NULL) + *updateIdx = i; + + break; + } + } + } +} + +/* + * Remove elements being deleted or skipped + */ +static List * +RemoveElements(char *base, List *w, HnswElement skipElement) +{ + ListCell *lc2; + List *w2 = NIL; + + /* Ensure does not access heaptidsLength during in-memory build */ + pg_memory_barrier(); + + foreach(lc2, w) + { + HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + + /* Skip self for vacuuming update */ + if (skipElement != NULL && hce->blkno == skipElement->blkno && hce->offno == skipElement->offno) + continue; + + if (hce->heaptidsLength != 0) + w2 = lappend(w2, hc); + } + + return w2; +} + +#if PG_VERSION_NUM >= 130000 +/* + * Precompute hash + */ +static void +PrecomputeHash(char *base, HnswElement element) +{ + HnswElementPtr ptr; + + HnswPtrStore(base, ptr, element); + + if (base == NULL) + element->hash = hash_pointer((uintptr_t) HnswPtrPointer(ptr)); + else + element->hash = hash_offset(HnswPtrOffset(ptr)); +} +#endif + +/* + * Algorithm 1 from paper + */ +void +HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing) +{ + List *ep; + List *w; + int level = element->level; + int entryLevel; + Datum q = HnswGetValue(base, element); + HnswElement skipElement = existing ? element : NULL; + +#if PG_VERSION_NUM >= 130000 + /* Precompute hash */ + if (index == NULL) + PrecomputeHash(base, element); +#endif + + /* No neighbors if no entry point */ + if (entryPoint == NULL) + return; + + /* Get entry point and level */ + ep = list_make1(HnswEntryCandidate(base, entryPoint, q, index, procinfo, collation, true)); + entryLevel = entryPoint->level; + + /* 1st phase: greedy search to insert level */ + for (int lc = entryLevel; lc >= level + 1; lc--) + { + w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, true, skipElement); + ep = w; + } + + if (level > entryLevel) + level = entryLevel; + + /* Add one for existing element */ + if (existing) + efConstruction++; + + /* 2nd phase */ + for (int lc = level; lc >= 0; lc--) + { + int lm = HnswGetLayerM(m, lc); + List *neighbors; + List *lw; + + w = HnswSearchLayer(base, q, ep, efConstruction, lc, index, procinfo, collation, m, true, skipElement); + + /* Elements being deleted or skipped can help with search */ + /* but should be removed before selecting neighbors */ + if (index != NULL) + lw = RemoveElements(base, w, skipElement); + else + lw = w; + + /* + * Candidates are sorted, but not deterministically. Could set + * sortCandidates to true for in-memory builds to enable closer + * caching, but there does not seem to be a difference in performance. + */ + neighbors = SelectNeighbors(base, lw, lm, lc, procinfo, collation, element, NULL, NULL, false); + + AddConnections(base, element, neighbors, lc); + + ep = w; + } +} + +static void +SparsevecCheckValue(Pointer v) +{ + SparseVector *vec = (SparseVector *) v; + + if (vec->nnz > HNSW_MAX_NNZ) + elog(ERROR, "sparsevec cannot have more than %d non-zero elements for hnsw index", HNSW_MAX_NNZ); +} + +/* + * Get type info + */ +const HnswTypeInfo * +HnswGetTypeInfo(Relation index) +{ + FmgrInfo *procinfo = HnswOptionalProcInfo(index, HNSW_TYPE_INFO_PROC); + + if (procinfo == NULL) + { + static const HnswTypeInfo typeInfo = { + .maxDimensions = HNSW_MAX_DIM, + .normalize = l2_normalize, + .checkValue = NULL + }; + + return (&typeInfo); + } + else + return (const HnswTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_halfvec_support); +Datum +hnsw_halfvec_support(PG_FUNCTION_ARGS) +{ + static const HnswTypeInfo typeInfo = { + .maxDimensions = HNSW_MAX_DIM * 2, + .normalize = halfvec_l2_normalize, + .checkValue = NULL + }; + + PG_RETURN_POINTER(&typeInfo); +}; + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_bit_support); +Datum +hnsw_bit_support(PG_FUNCTION_ARGS) +{ + static const HnswTypeInfo typeInfo = { + .maxDimensions = HNSW_MAX_DIM * 32, + .normalize = NULL, + .checkValue = NULL + }; + + PG_RETURN_POINTER(&typeInfo); +}; + +PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_sparsevec_support); +Datum +hnsw_sparsevec_support(PG_FUNCTION_ARGS) +{ + static const HnswTypeInfo typeInfo = { + .maxDimensions = SPARSEVEC_MAX_DIM, + .normalize = sparsevec_l2_normalize, + .checkValue = SparsevecCheckValue + }; + + PG_RETURN_POINTER(&typeInfo); +}; diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp new file mode 100644 index 0000000000..d9e5f0574f --- /dev/null +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -0,0 +1,646 @@ +#include "postgres.h" + +#include + +#include "access/generic_xlog.h" +#include "commands/vacuum.h" +#include "access/datavec/hnsw.h" +#include "storage/buf/bufmgr.h" +#include "storage/lmgr.h" +#include "utils/memutils.h" + +/* + * Check if deleted list contains an index TID + */ +static bool +DeletedContains(tidhash_hash * deleted, ItemPointer indextid) +{ + return tidhash_lookup(deleted, *indextid) != NULL; +} + +/* + * Remove deleted heap TIDs + * + * OK to remove for entry point, since always considered for searches and inserts + */ +static void +RemoveHeapTids(HnswVacuumState * vacuumstate) +{ + BlockNumber blkno = HNSW_HEAD_BLKNO; + HnswElement highestPoint = &vacuumstate->highestPoint; + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + HnswElement entryPoint = HnswGetEntryPoint(vacuumstate->index); + IndexBulkDeleteResult *stats = vacuumstate->stats; + + /* Store separately since highestPoint.level is uint8 */ + int highestLevel = -1; + + /* Initialize highest point */ + highestPoint->blkno = InvalidBlockNumber; + highestPoint->offno = InvalidOffsetNumber; + + while (BlockNumberIsValid(blkno)) + { + Buffer buf; + Page page; + GenericXLogState *state; + OffsetNumber offno; + OffsetNumber maxoffno; + bool updated = false; + + vacuum_delay_point(); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + maxoffno = PageGetMaxOffsetNumber(page); + + /* Iterate over nodes */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + int idx = 0; + bool itemUpdated = false; + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + if (ItemPointerIsValid(&etup->heaptids[0])) + { + for (int i = 0; i < HNSW_HEAPTIDS; i++) + { + /* Stop at first unused */ + if (!ItemPointerIsValid(&etup->heaptids[i])) + break; + + if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, InvalidBktId)) + { + itemUpdated = true; + stats->tuples_removed++; + } + else + { + /* Move to front of list */ + etup->heaptids[idx++] = etup->heaptids[i]; + stats->num_index_tuples++; + } + } + + if (itemUpdated) + { + /* Mark rest as invalid */ + for (int i = idx; i < HNSW_HEAPTIDS; i++) + ItemPointerSetInvalid(&etup->heaptids[i]); + + updated = true; + } + } + + if (!ItemPointerIsValid(&etup->heaptids[0])) + { + ItemPointerData ip; + bool found; + + /* Add to deleted list */ + ItemPointerSet(&ip, blkno, offno); + + tidhash_insert(vacuumstate->deleted, ip, &found); + Assert(!found); + } + else if (etup->level > highestLevel && !(entryPoint != NULL && blkno == entryPoint->blkno && offno == entryPoint->offno)) + { + /* Keep track of highest non-entry point */ + highestPoint->blkno = blkno; + highestPoint->offno = offno; + highestPoint->level = etup->level; + highestLevel = etup->level; + } + } + + blkno = HnswPageGetOpaque(page)->nextblkno; + + if (updated) + GenericXLogFinish(state); + else + GenericXLogAbort(state); + + UnlockReleaseBuffer(buf); + } +} + +/* + * Check for deleted neighbors + */ +static bool +NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) +{ + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + Buffer buf; + Page page; + HnswNeighborTuple ntup; + bool needsUpdated = false; + + buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); + + Assert(HnswIsNeighborTuple(ntup)); + + /* Check neighbors */ + for (int i = 0; i < ntup->count; i++) + { + ItemPointer indextid = &ntup->indextids[i]; + + if (!ItemPointerIsValid(indextid)) + continue; + + /* Check if in deleted list */ + if (DeletedContains(vacuumstate->deleted, indextid)) + { + needsUpdated = true; + break; + } + } + + /* Also update if layer 0 is not full */ + /* This could indicate too many candidates being deleted during insert */ + if (!needsUpdated) + needsUpdated = !ItemPointerIsValid(&ntup->indextids[ntup->count - 1]); + + UnlockReleaseBuffer(buf); + + return needsUpdated; +} + +/* + * Repair graph for a single element + */ +static void +RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswElement entryPoint) +{ + Relation index = vacuumstate->index; + Buffer buf; + Page page; + GenericXLogState *state; + int m = vacuumstate->m; + int efConstruction = vacuumstate->efConstruction; + FmgrInfo *procinfo = vacuumstate->procinfo; + Oid collation = vacuumstate->collation; + BufferAccessStrategy bas = vacuumstate->bas; + HnswNeighborTuple ntup = vacuumstate->ntup; + Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); + char *base = NULL; + + /* Skip if element is entry point */ + if (entryPoint != NULL && element->blkno == entryPoint->blkno && element->offno == entryPoint->offno) + return; + + /* Init fields */ + HnswInitNeighbors(base, element, m, NULL); + element->heaptidsLength = 0; + + /* Find neighbors for element, skipping itself */ + HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, true); + + /* Zero memory for each element */ + MemSet(ntup, 0, HNSW_TUPLE_ALLOC_SIZE); + + /* Update neighbor tuple */ + /* Do this before getting page to minimize locking */ + HnswSetNeighborTuple(base, ntup, element, m); + + /* Get neighbor page */ + buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + + /* Overwrite tuple */ + if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + /* Commit */ + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); + + /* Update neighbors */ + HnswUpdateNeighborsOnDisk(index, procinfo, collation, element, m, true, false); +} + +/* + * Repair graph entry point + */ +static void +RepairGraphEntryPoint(HnswVacuumState * vacuumstate) +{ + Relation index = vacuumstate->index; + HnswElement highestPoint = &vacuumstate->highestPoint; + HnswElement entryPoint; + MemoryContext oldCtx = MemoryContextSwitchTo(vacuumstate->tmpCtx); + + if (!BlockNumberIsValid(highestPoint->blkno)) + highestPoint = NULL; + + /* + * Repair graph for highest non-entry point. Highest point may be outdated + * due to inserts that happen during and after RemoveHeapTids. + */ + if (highestPoint != NULL) + { + /* Get a shared lock */ + LockPage(index, HNSW_UPDATE_LOCK, ShareLock); + + /* Load element */ + HnswLoadElement(highestPoint, NULL, NULL, index, vacuumstate->procinfo, vacuumstate->collation, true, NULL); + + /* Repair if needed */ + if (NeedsUpdated(vacuumstate, highestPoint)) + RepairGraphElement(vacuumstate, highestPoint, HnswGetEntryPoint(index)); + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, ShareLock); + } + + /* Prevent concurrent inserts when possibly updating entry point */ + LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + + /* Get latest entry point */ + entryPoint = HnswGetEntryPoint(index); + + if (entryPoint != NULL) + { + ItemPointerData epData; + + ItemPointerSet(&epData, entryPoint->blkno, entryPoint->offno); + + if (DeletedContains(vacuumstate->deleted, &epData)) + { + /* + * Replace the entry point with the highest point. If highest + * point is outdated and empty, the entry point will be empty + * until an element is repaired. + */ + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_ALWAYS, highestPoint, InvalidBlockNumber, MAIN_FORKNUM, false); + } + else + { + /* + * Repair the entry point with the highest point. If highest point + * is outdated, this can remove connections at higher levels in + * the graph until they are repaired, but this should be fine. + */ + HnswLoadElement(entryPoint, NULL, NULL, index, vacuumstate->procinfo, vacuumstate->collation, true, NULL); + + if (NeedsUpdated(vacuumstate, entryPoint)) + { + /* Reset neighbors from previous update */ + if (highestPoint != NULL) + HnswPtrStore((char *) NULL, highestPoint->neighbors, (HnswNeighborArrayPtr *) NULL); + + RepairGraphElement(vacuumstate, entryPoint, highestPoint); + } + } + } + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(vacuumstate->tmpCtx); +} + +/* + * Repair graph for all elements + */ +static void +RepairGraph(HnswVacuumState * vacuumstate) +{ + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + BlockNumber blkno = HNSW_HEAD_BLKNO; + + /* + * Wait for inserts to complete. Inserts before this point may have + * neighbors about to be deleted. Inserts after this point will not. + */ + LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + + /* Repair entry point first */ + RepairGraphEntryPoint(vacuumstate); + + while (BlockNumberIsValid(blkno)) + { + Buffer buf; + Page page; + OffsetNumber offno; + OffsetNumber maxoffno; + List *elements = NIL; + ListCell *lc2; + MemoryContext oldCtx; + + vacuum_delay_point(); + + oldCtx = MemoryContextSwitchTo(vacuumstate->tmpCtx); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + maxoffno = PageGetMaxOffsetNumber(page); + + /* Load items into memory to minimize locking */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswElement element; + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + /* Skip updating neighbors if being deleted */ + if (!ItemPointerIsValid(&etup->heaptids[0])) + continue; + + /* Create an element */ + element = HnswInitElementFromBlock(blkno, offno); + HnswLoadElementFromTuple(element, etup, false, true); + + elements = lappend(elements, element); + } + + blkno = HnswPageGetOpaque(page)->nextblkno; + + UnlockReleaseBuffer(buf); + + /* Update neighbor pages */ + foreach(lc2, elements) + { + HnswElement element = (HnswElement) lfirst(lc2); + HnswElement entryPoint; + LOCKMODE lockmode = ShareLock; + + /* Check if any neighbors point to deleted values */ + if (!NeedsUpdated(vacuumstate, element)) + continue; + + /* Get a shared lock */ + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Refresh entry point for each element */ + entryPoint = HnswGetEntryPoint(index); + + /* Prevent concurrent inserts when likely updating entry point */ + if (entryPoint == NULL || element->level > entryPoint->level) + { + /* Release shared lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get exclusive lock */ + lockmode = ExclusiveLock; + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get latest entry point after lock is acquired */ + entryPoint = HnswGetEntryPoint(index); + } + + /* Repair connections */ + RepairGraphElement(vacuumstate, element, entryPoint); + + /* + * Update metapage if needed. Should only happen if entry point + * was replaced and highest point was outdated. + */ + if (entryPoint == NULL || element->level > entryPoint->level) + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM, false); + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + } + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(vacuumstate->tmpCtx); + } +} + +/* + * Mark items as deleted + */ +static void +MarkDeleted(HnswVacuumState * vacuumstate) +{ + BlockNumber blkno = HNSW_HEAD_BLKNO; + BlockNumber insertPage = InvalidBlockNumber; + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + + /* + * Wait for index scans to complete. Scans before this point may contain + * tuples about to be deleted. Scans after this point will not, since the + * graph has been repaired. + */ + LockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); + UnlockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); + + while (BlockNumberIsValid(blkno)) + { + Buffer buf; + Page page; + GenericXLogState *state; + OffsetNumber offno; + OffsetNumber maxoffno; + + vacuum_delay_point(); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); + + /* + * ambulkdelete cannot delete entries from pages that are pinned by + * other backends + * + * https://www.postgresql.org/docs/current/index-locking.html + */ + LockBufferForCleanup(buf); + + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + maxoffno = PageGetMaxOffsetNumber(page); + + /* Update element and neighbors together */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswNeighborTuple ntup; + Buffer nbuf; + Page npage; + BlockNumber neighborPage; + OffsetNumber neighborOffno; + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + /* Skip deleted tuples */ + if (etup->deleted) + { + /* Set to first free page */ + if (!BlockNumberIsValid(insertPage)) + insertPage = blkno; + + continue; + } + + /* Skip live tuples */ + if (ItemPointerIsValid(&etup->heaptids[0])) + continue; + + /* Get neighbor page */ + neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); + neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); + + if (neighborPage == blkno) + { + nbuf = buf; + npage = page; + } + else + { + nbuf = ReadBufferExtended(index, MAIN_FORKNUM, neighborPage, RBM_NORMAL, bas); + LockBuffer(nbuf, BUFFER_LOCK_EXCLUSIVE); + npage = GenericXLogRegisterBuffer(state, nbuf, 0); + } + + ntup = (HnswNeighborTuple) PageGetItem(npage, PageGetItemId(npage, neighborOffno)); + + /* Overwrite element */ + etup->deleted = 1; + MemSet(&etup->data, 0, VARSIZE_ANY(&etup->data)); + + /* Overwrite neighbors */ + for (int i = 0; i < ntup->count; i++) + ItemPointerSetInvalid(&ntup->indextids[i]); + + /* + * We modified the tuples in place, no need to call + * page_index_tuple_overwrite + */ + + /* Commit */ + GenericXLogFinish(state); + if (nbuf != buf) + UnlockReleaseBuffer(nbuf); + + /* Set to first free page */ + if (!BlockNumberIsValid(insertPage)) + insertPage = blkno; + + /* Prepare new xlog */ + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + blkno = HnswPageGetOpaque(page)->nextblkno; + + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + } + + /* Update insert page last, after everything has been marked as deleted */ + HnswUpdateMetaPage(index, 0, NULL, insertPage, MAIN_FORKNUM, false); +} + +/* + * Initialize the vacuum state + */ +static void +InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) +{ + Relation index = info->index; + + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + + vacuumstate->index = index; + vacuumstate->stats = stats; + vacuumstate->callback = callback; + vacuumstate->callback_state = callback_state; + vacuumstate->efConstruction = HnswGetEfConstruction(index); + vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD); + vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); + vacuumstate->collation = index->rd_indcollation[0]; + vacuumstate->ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); + vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, + "Hnsw vacuum temporary context", + ALLOCSET_DEFAULT_SIZES); + + /* Get m from metapage */ + HnswGetMetaPageInfo(index, &vacuumstate->m, NULL); + + /* Create hash table */ + vacuumstate->deleted = tidhash_create(CurrentMemoryContext, 256, NULL); +} + +/* + * Free resources + */ +static void +FreeVacuumState(HnswVacuumState * vacuumstate) +{ + tidhash_destroy(vacuumstate->deleted); + FreeAccessStrategy(vacuumstate->bas); + pfree(vacuumstate->ntup); + MemoryContextDelete(vacuumstate->tmpCtx); +} + +/* + * Bulk delete tuples from the index + */ +IndexBulkDeleteResult * +hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) +{ + HnswVacuumState vacuumstate; + + InitVacuumState(&vacuumstate, info, stats, callback, callback_state); + + /* Pass 1: Remove heap TIDs */ + RemoveHeapTids(&vacuumstate); + + /* Pass 2: Repair graph */ + RepairGraph(&vacuumstate); + + /* Pass 3: Mark as deleted */ + MarkDeleted(&vacuumstate); + + FreeVacuumState(&vacuumstate); + + return vacuumstate.stats; +} + +/* + * Clean up after a VACUUM operation + */ +IndexBulkDeleteResult * +hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) +{ + Relation rel = info->index; + + if (info->analyze_only) + return stats; + + /* stats is NULL if ambulkdelete not called */ + /* OK to return NULL if index not changed */ + if (stats == NULL) + return NULL; + + stats->num_pages = RelationGetNumberOfBlocks(rel); + + return stats; +} diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp new file mode 100644 index 0000000000..b28bd73f33 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -0,0 +1,906 @@ +#include "postgres.h" + +#include + +#include "access/tableam.h" +#include "access/xact.h" +#include "access/datavec/bitvec.h" +#include "catalog/index.h" +#include "access/datavec/halfvec.h" +#include "access/datavec/ivfflat.h" +#include "miscadmin.h" +#include "storage/buf/bufmgr.h" +#include "tcop/tcopprot.h" +#include "utils/memutils.h" +#include "access/datavec/vector.h" +#include "postmaster/bgworker.h" +#include "commands/vacuum.h" + +#if PG_VERSION_NUM >= 140000 +#include "utils/backend_progress.h" +#else +#include "pgstat.h" +#endif + +#if PG_VERSION_NUM >= 130000 +#define CALLBACK_ITEM_POINTER ItemPointer tid +#else +#define CALLBACK_ITEM_POINTER HeapTuple hup +#endif + +#if PG_VERSION_NUM >= 140000 +#include "utils/backend_status.h" +#include "utils/wait_event.h" +#endif + +#define PARALLEL_KEY_IVFFLAT_SHARED UINT64CONST(0xA000000000000001) +#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xA000000000000002) +#define PARALLEL_KEY_IVFFLAT_CENTERS UINT64CONST(0xA000000000000003) +#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000004) + +/* + * Add sample + */ +static void +AddSample(Datum *values, IvfflatBuildState *buildstate) +{ + VectorArray samples = buildstate->samples; + int targsamples = samples->maxlen; + + /* Detoast once for all calls */ + Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* + * Normalize with KMEANS_NORM_PROC since spherical distance function + * expects unit vectors + */ + if (buildstate->kmeansnormprocinfo != NULL) { + if (!IvfflatCheckNorm(buildstate->kmeansnormprocinfo, buildstate->collation, value)) { + return; + } + + value = IvfflatNormValue(buildstate->typeInfo, buildstate->collation, value); + } + + if (samples->length < targsamples) { + VectorArraySet(samples, samples->length, DatumGetPointer(value)); + samples->length++; + } else { + if (buildstate->rowstoskip < 0) { + buildstate->rowstoskip = anl_get_next_S(samples->length, targsamples, &buildstate->rstate); + } + + if (buildstate->rowstoskip <= 0) { + int k = (int) (targsamples * anl_random_fract()); + Assert(k >= 0 && k < targsamples); + VectorArraySet(samples, k, DatumGetPointer(value)); + } + + buildstate->rowstoskip -= 1; + } +} + +/* + * Callback for sampling + */ +static void +SampleCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, + const bool *isnull, bool tupleIsAlive, void *state) +{ + IvfflatBuildState *buildstate = (IvfflatBuildState *) state; + MemoryContext oldCtx; + + /* Skip nulls */ + if (isnull[0]) { + return; + } + + /* Use memory context since detoast can allocate */ + oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); + + /* Add sample */ + AddSample(values, buildstate); + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(buildstate->tmpCtx); +} + +/* + * Sample rows with same logic as ANALYZE + */ +static void +SampleRows(IvfflatBuildState *buildstate) +{ + int targsamples = buildstate->samples->maxlen; + BlockNumber totalblocks = RelationGetNumberOfBlocks(buildstate->heap); + + buildstate->rowstoskip = -1; + + BlockSampler_Init(&buildstate->bs, totalblocks, targsamples); + + buildstate->rstate = anl_init_selection_state(targsamples); + while (BlockSampler_HasMore(&buildstate->bs)) { + BlockNumber targblock = BlockSampler_Next(&buildstate->bs); + + tableam_index_build_scan(buildstate->heap, buildstate->index, buildstate->indexInfo, + false, SampleCallback, (void *) buildstate, NULL, targblock, 1); + } +} + +/* + * Add tuple to sort + */ +static void +AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState * buildstate) +{ + double distance; + double minDistance = DBL_MAX; + int closestCenter = 0; + VectorArray centers = buildstate->centers; + TupleTableSlot *slot = buildstate->slot; + + /* Detoast once for all calls */ + Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Normalize if needed */ + if (buildstate->normprocinfo != NULL) + { + if (!IvfflatCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) + return; + + value = IvfflatNormValue(buildstate->typeInfo, buildstate->collation, value); + } + + /* Find the list that minimizes the distance */ + for (int i = 0; i < centers->length; i++) + { + distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, value, PointerGetDatum(VectorArrayGet(centers, i)))); + + if (distance < minDistance) + { + minDistance = distance; + closestCenter = i; + } + } + +#ifdef IVFFLAT_KMEANS_DEBUG + buildstate->inertia += minDistance; + buildstate->listSums[closestCenter] += minDistance; + buildstate->listCounts[closestCenter]++; +#endif + + /* Create a virtual tuple */ + ExecClearTuple(slot); + slot->tts_values[0] = Int32GetDatum(closestCenter); + slot->tts_isnull[0] = false; + slot->tts_values[1] = PointerGetDatum(tid); + slot->tts_isnull[1] = false; + slot->tts_values[2] = value; + slot->tts_isnull[2] = false; + ExecStoreVirtualTuple(slot); + + /* + * Add tuple to sort + * + * tuplesort_puttupleslot comment: Input data is always copied; the caller + * need not save it. + */ + tuplesort_puttupleslot(buildstate->sortstate, slot); + + buildstate->indtuples++; +} + +/* + * Callback for table_index_build_scan + */ +static void +BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, + const bool *isnull, bool tupleIsAlive, void *state) +{ + IvfflatBuildState *buildstate = (IvfflatBuildState *) state; + MemoryContext oldCtx; + +#if PG_VERSION_NUM < 130000 + ItemPointer tid = &hup->t_self; +#endif + + /* Skip nulls */ + if (isnull[0]) + return; + + /* Use memory context since detoast can allocate */ + oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); + + /* Add tuple to sort */ + AddTupleToSort(index, tid, values, buildstate); + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(buildstate->tmpCtx); +} + +/* + * Get index tuple from sort state + */ +static inline void +GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, IndexTuple *itup, int *list) +{ + Datum value; + bool isnull; + + if (tuplesort_gettupleslot(sortstate, true, slot, NULL)) + { + *list = DatumGetInt32(heap_slot_getattr(slot, 1, &isnull)); + value = heap_slot_getattr(slot, 3, &isnull); + + /* Form the index tuple */ + *itup = index_form_tuple(tupdesc, &value, &isnull); + (*itup)->t_tid = *((ItemPointer) DatumGetPointer(heap_slot_getattr(slot, 2, &isnull))); + } + else + *list = -1; +} + +/* + * Create initial entry pages + */ +static void +InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) +{ + int list; + IndexTuple itup = NULL; /* silence compiler warning */ + int64 inserted = 0; + + TupleTableSlot *slot = MakeSingleTupleTableSlot(buildstate->tupdesc); + TupleDesc tupdesc = RelationGetDescr(index); + + GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); + + for (int i = 0; i < buildstate->centers->length; i++) + { + Buffer buf; + Page page; + GenericXLogState *state; + BlockNumber startPage; + BlockNumber insertPage; + + /* Can take a while, so ensure we can interrupt */ + /* Needs to be called when no buffer locks are held */ + CHECK_FOR_INTERRUPTS(); + + buf = IvfflatNewBuffer(index, forkNum); + IvfflatInitRegisterPage(index, &buf, &page, &state); + + startPage = BufferGetBlockNumber(buf); + + /* Get all tuples for list */ + while (list == i) + { + /* Check for free space */ + Size itemsz = MAXALIGN(IndexTupleSize(itup)); + + if (PageGetFreeSpace(page) < itemsz) + IvfflatAppendPage(index, &buf, &page, &state, forkNum); + + /* Add the item */ + if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + pfree(itup); + + UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++inserted); + + GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); + } + + insertPage = BufferGetBlockNumber(buf); + + IvfflatCommitBuffer(buf, state); + + /* Set the start and insert pages */ + IvfflatUpdateList(index, buildstate->listInfo[i], insertPage, InvalidBlockNumber, startPage, forkNum); + } +} + +/* + * Initialize the build state + */ +static void +InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, IndexInfo *indexInfo) +{ + buildstate->heap = heap; + buildstate->index = index; + buildstate->indexInfo = indexInfo; + buildstate->typeInfo = IvfflatGetTypeInfo(index); + + buildstate->lists = IvfflatGetLists(index); + buildstate->dimensions = TupleDescAttr(index->rd_att, 0)->atttypmod; + + /* Disallow varbit since require fixed dimensions */ + if (TupleDescAttr(index->rd_att, 0)->atttypid == VARBITOID) + elog(ERROR, "type not supported for ivfflat index"); + + /* Require column to have dimensions to be indexed */ + if (buildstate->dimensions < 0) + elog(ERROR, "column does not have dimensions"); + + if (buildstate->dimensions > buildstate->typeInfo->maxDimensions) + elog(ERROR, "column cannot have more than %d dimensions for ivfflat index", buildstate->typeInfo->maxDimensions); + + buildstate->reltuples = 0; + buildstate->indtuples = 0; + + /* Get support functions */ + buildstate->procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC); + buildstate->normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + buildstate->kmeansnormprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); + buildstate->collation = index->rd_indcollation[0]; + + /* Require more than one dimension for spherical k-means */ + if (buildstate->kmeansnormprocinfo != NULL && buildstate->dimensions == 1) + elog(ERROR, "dimensions must be greater than one for this opclass"); + + /* Create tuple description for sorting */ + buildstate->tupdesc = CreateTemplateTupleDesc(3, false); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 1, "list", INT4OID, -1, 0); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 2, "tid", TIDOID, -1, 0); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 3, "vector", RelationGetDescr(index)->attrs[0].atttypid, -1, 0); + + buildstate->slot = MakeSingleTupleTableSlot(buildstate->tupdesc); + + buildstate->centers = VectorArrayInit(buildstate->lists, buildstate->dimensions, buildstate->typeInfo->itemSize(buildstate->dimensions)); + buildstate->listInfo = (ListInfo *)palloc(sizeof(ListInfo) * buildstate->lists); + + buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat build temporary context", + ALLOCSET_DEFAULT_SIZES); + +#ifdef IVFFLAT_KMEANS_DEBUG + buildstate->inertia = 0; + buildstate->listSums = palloc0(sizeof(double) * buildstate->lists); + buildstate->listCounts = palloc0(sizeof(int) * buildstate->lists); +#endif + buildstate->ivfleader = NULL; +} + +/* + * Free resources + */ +static void +FreeBuildState(IvfflatBuildState * buildstate) +{ + VectorArrayFree(buildstate->centers); + pfree(buildstate->listInfo); + +#ifdef IVFFLAT_KMEANS_DEBUG + pfree(buildstate->listSums); + pfree(buildstate->listCounts); +#endif + + MemoryContextDelete(buildstate->tmpCtx); +} + +/* + * Compute centers + */ +static void +ComputeCenters(IvfflatBuildState *buildstate) +{ + int numSamples; + + /* Target 50 samples per list, with at least 10000 samples */ + /* The number of samples has a large effect on index build time */ + numSamples = buildstate->lists * 50; + if (numSamples < 10000) { + numSamples = 10000; + } + + /* Skip samples for unlogged table */ + if (buildstate->heap == NULL) { + numSamples = 1; + } + + /* Sample rows */ + /* TODO Ensure within maintenance_work_mem */ + buildstate->samples = VectorArrayInit(numSamples, buildstate->dimensions, buildstate->centers->itemsize); + if (buildstate->heap != NULL) { + SampleRows(buildstate); + if (buildstate->samples->length < buildstate->lists) { + ereport(NOTICE, + (errmsg("ivfflat index created with little data"), + errdetail("This will cause low recall."), + errhint("Drop the index until the table has more data."))); + } + } + + /* Calculate centers */ + IvfflatBench("k-means", IvfflatKmeans(buildstate->index, buildstate->samples, + buildstate->centers, buildstate->typeInfo)); + + /* Free samples before we allocate more memory */ + VectorArrayFree(buildstate->samples); +} + +/* + * Create the metapage + */ +static void +CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) +{ + Buffer buf; + Page page; + GenericXLogState *state; + IvfflatMetaPage metap; + + buf = IvfflatNewBuffer(index, forkNum); + IvfflatInitRegisterPage(index, &buf, &page, &state); + + /* Set metapage data */ + metap = IvfflatPageGetMeta(page); + metap->magicNumber = IVFFLAT_MAGIC_NUMBER; + metap->version = IVFFLAT_VERSION; + metap->dimensions = dimensions; + metap->lists = lists; + ((PageHeader) page)->pd_lower = + ((char *) metap + sizeof(IvfflatMetaPageData)) - (char *) page; + + IvfflatCommitBuffer(buf, state); +} + +/* + * Create list pages + */ +static void +CreateListPages(Relation index, VectorArray centers, int dimensions, + int lists, ForkNumber forkNum, ListInfo * *listInfo) +{ + Buffer buf; + Page page; + GenericXLogState *state; + Size listSize; + IvfflatList list; + + listSize = MAXALIGN(IVFFLAT_LIST_SIZE(centers->itemsize)); + list = (IvfflatList)palloc0(listSize); + + buf = IvfflatNewBuffer(index, forkNum); + IvfflatInitRegisterPage(index, &buf, &page, &state); + + for (int i = 0; i < lists; i++) + { + OffsetNumber offno; + + /* Zero memory for each list */ + MemSet(list, 0, listSize); + + /* Load list */ + list->startPage = InvalidBlockNumber; + list->insertPage = InvalidBlockNumber; + memcpy(&list->center, VectorArrayGet(centers, i), VARSIZE_ANY(VectorArrayGet(centers, i))); + + /* Ensure free space */ + if (PageGetFreeSpace(page) < listSize) + IvfflatAppendPage(index, &buf, &page, &state, forkNum); + + /* Add the item */ + offno = PageAddItem(page, (Item) list, listSize, InvalidOffsetNumber, false, false); + if (offno == InvalidOffsetNumber) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + /* Save location info */ + (*listInfo)[i].blkno = BufferGetBlockNumber(buf); + (*listInfo)[i].offno = offno; + } + + IvfflatCommitBuffer(buf, state); + + pfree(list); +} + +#ifdef IVFFLAT_KMEANS_DEBUG +/* + * Print k-means metrics + */ +static void +PrintKmeansMetrics(IvfflatBuildState * buildstate) +{ + elog(INFO, "inertia: %.3e", buildstate->inertia); + + /* Calculate Davies-Bouldin index */ + if (buildstate->lists > 1) + { + double db = 0.0; + + /* Calculate average distance */ + for (int i = 0; i < buildstate->lists; i++) + { + if (buildstate->listCounts[i] > 0) + buildstate->listSums[i] /= buildstate->listCounts[i]; + } + + for (int i = 0; i < buildstate->lists; i++) + { + double max = 0.0; + double distance; + + for (int j = 0; j < buildstate->lists; j++) + { + if (j == i) + continue; + + distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, PointerGetDatum(VectorArrayGet(buildstate->centers, i)), PointerGetDatum(VectorArrayGet(buildstate->centers, j)))); + distance = (buildstate->listSums[i] + buildstate->listSums[j]) / distance; + + if (distance > max) + max = distance; + } + db += max; + } + db /= buildstate->lists; + elog(INFO, "davies-bouldin: %.3f", db); + } +} +#endif + +/* + * Within leader, wait for end of heap scan + */ +static double +ParallelHeapScan(IvfflatBuildState * buildstate) +{ + IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; + double reltuples; + + BgworkerListWaitFinish(&buildstate->ivfleader->nparticipanttuplesorts); + pg_memory_barrier(); + + /*all done, update to the actual number of participants*/ + if (ivfshared->sharedsort != NULL) { + ivfshared->sharedsort->actualParticipants = buildstate->ivfleader->nparticipanttuplesorts; + } + + buildstate->indtuples = ivfshared->indtuples; + reltuples = ivfshared->reltuples; +#ifdef IVFFLAT_KMEANS_DEBUG + buildstate->inertia = ivfshared->inertia; +#endif + + return reltuples; +} + +/* + * Perform a worker's portion of a parallel sort + */ +static void +IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, Vector *ivfcenters) +{ + SortCoordinate coordinate; + IvfflatBuildState buildstate; + TableScanDesc scan; + double reltuples; + IndexInfo *indexInfo; + + /* Sort options, which must match AssignTuples */ + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {INT4LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; + + /* Initialize local tuplesort coordination state */ + coordinate = (SortCoordinate)palloc0(sizeof(SortCoordinateData)); + coordinate->isWorker = true; + coordinate->nParticipants = -1; + coordinate->sharedsort = ivfshared->sharedsort; + + int sortmem = ivfshared->workmem / ivfshared->scantuplesortstates; + + /* Join parallel scan */ + indexInfo = BuildIndexInfo(ivfspool->index); + indexInfo->ii_Concurrent = false; + InitBuildState(&buildstate, ivfspool->heap, ivfspool->index, indexInfo); + memcpy(buildstate.centers->items, ivfcenters, VECTOR_SIZE(buildstate.centers->dim) * buildstate.centers->maxlen); + buildstate.centers->length = buildstate.centers->maxlen; + ivfspool->sortstate = tuplesort_begin_heap(buildstate.tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, sortmem, false, 0, 0, 1, coordinate); + buildstate.sortstate = ivfspool->sortstate; + + scan = tableam_scan_begin_parallel(ivfspool->heap, &ivfshared->heapdesc); + reltuples = tableam_index_build_scan(ivfspool->heap, ivfspool->index, indexInfo, + true, BuildCallback, (void *) &buildstate, scan); + + /* Execute this worker's part of the sort */ + tuplesort_performsort(ivfspool->sortstate); + + /* Record statistics */ + SpinLockAcquire(&ivfshared->mutex); + ivfshared->nparticipantsdone++; + ivfshared->reltuples += reltuples; + ivfshared->indtuples += buildstate.indtuples; +#ifdef IVFFLAT_KMEANS_DEBUG + ivfshared->inertia += buildstate.inertia; +#endif + SpinLockRelease(&ivfshared->mutex); + + /* We can end tuplesorts immediately */ + tuplesort_end(ivfspool->sortstate); + + FreeBuildState(&buildstate); +} + +/* + * Perform work within a launched parallel process + */ +void +IvfflatParallelBuildMain(const BgWorkerContext *bwc) +{ + IvfflatSpool *ivfspool; + IvfflatShared *ivfshared; + Relation heapRel; + Relation indexRel; + + ivfshared = (IvfflatShared*)bwc->bgshared; + + /* Open relations within worker */ + heapRel = heap_open(ivfshared->heaprelid, NoLock); + indexRel = index_open(ivfshared->indexrelid, NoLock); + + /* Initialize worker's own spool */ + ivfspool = (IvfflatSpool *) palloc0(sizeof(IvfflatSpool)); + ivfspool->heap = heapRel; + ivfspool->index = indexRel; + + IvfflatParallelScanAndSort(ivfspool, ivfshared, ivfshared->ivfcenters); + + /* Close relations within worker */ + index_close(indexRel, NoLock); + heap_close(heapRel, NoLock); +} + +/* + * End parallel build + */ +static void +IvfflatParallelCleanup(const BgWorkerContext *bwc) +{ + IvfflatShared *ivfshared = (IvfflatShared*)bwc->bgshared; + + /* delete shared fileset */ + Assert(ivfshared->sharedsort); + SharedFileSetDeleteAll(&ivfshared->sharedsort->fileset); + pfree_ext(ivfshared->sharedsort); +} + +static IvfflatShared* +IvfflatParallelInitshared(IvfflatBuildState * buildstate, int workmem, int scantuplesortstates) +{ + IvfflatShared *ivfshared; + Sharedsort *sharedsort; + Size estsort; + Size estcenters; + char *ivfcenters; + + /* Store shared build state, for which we reserved space */ + ivfshared = (IvfflatShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(IvfflatShared)); + + /* Initialize immutable state */ + ivfshared->heaprelid = RelationGetRelid(buildstate->heap); + ivfshared->indexrelid = RelationGetRelid(buildstate->index); + ivfshared->scantuplesortstates = scantuplesortstates; + SpinLockInit(&ivfshared->mutex); + + /* Initialize mutable state */ + ivfshared->nparticipantsdone = 0; + ivfshared->reltuples = 0; + ivfshared->indtuples = 0; + ivfshared->workmem = workmem; +#ifdef IVFFLAT_KMEANS_DEBUG + ivfshared->inertia = 0; +#endif + HeapParallelscanInitialize(&ivfshared->heapdesc, buildstate->heap); + + /* Store shared tuplesort-private state, for which we reserved space */ + estsort = tuplesort_estimate_shared(scantuplesortstates); + sharedsort = (Sharedsort *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estsort); + tuplesort_initialize_shared(sharedsort, scantuplesortstates); + ivfshared->sharedsort = sharedsort; + + estcenters = VECTOR_SIZE(buildstate->dimensions) * buildstate->lists; + ivfcenters = (char *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estcenters); + memcpy(ivfcenters, buildstate->centers->items, estcenters); + ivfshared->ivfcenters = (Vector*)ivfcenters; + + return ivfshared; +} + +/* + * Begin parallel build + */ +static void +IvfflatBeginParallel(IvfflatBuildState * buildstate, int request, int workmem) +{ + IvfflatShared *ivfshared; + IvfflatLeader *ivfleader = (IvfflatLeader *) palloc0(sizeof(IvfflatLeader)); + + Assert(request > 0); + ivfshared = IvfflatParallelInitshared(buildstate, workmem, request); + + /* Launch workers, saving status for leader/caller */ + ivfleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, ivfshared, IvfflatParallelBuildMain, IvfflatParallelCleanup); + + /* If no workers were successfully launched, back out (do serial build) */ + if (ivfleader->nparticipanttuplesorts == 0) + { + pfree_ext(ivfshared); + pfree_ext(ivfleader); + return; + } + + /* Log participants */ + ereport(DEBUG1, (errmsg("using %d parallel workers", ivfleader->nparticipanttuplesorts))); + + ivfleader->ivfshared = ivfshared; + /* Save leader state now that it's clear build will be parallel */ + buildstate->ivfleader = ivfleader; +} + +static double AssignTupleUtility(IvfflatBuildState * buildstate) +{ + Relation heap = buildstate->heap; + Relation index = buildstate->index; + IndexInfo *indexInfo = buildstate->indexInfo; + double reltuples = 0; + + /* Fill spool using either serial or parallel heap scan */ + if (!buildstate->ivfleader) { +serial_build: + reltuples = tableam_index_build_scan(heap, index, indexInfo, true, BuildCallback, (void*)buildstate, NULL); + } else { + reltuples = ParallelHeapScan(buildstate); + IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; + int nruns = ivfshared->sharedsort->actualParticipants; + if (nruns == 0) { + /* failed to startup any bgworker, retry to do serial build */ + goto serial_build; + } + } + return reltuples; +} + +/* + * Shut down workers, destory parallel context, and end parallel mode. + */ +void IvfflatEndParallel() +{ + BgworkerListSyncQuit(); +} + +/* + * Scan table for tuples to index + */ +static void +AssignTuples(IvfflatBuildState * buildstate) +{ + SortCoordinate coordinate = NULL; + int parallel_workers = 0; + IndexInfo *indexInfo = buildstate->indexInfo; + UtilityDesc *desc = &indexInfo->ii_desc; + int workmem; + + /* Sort options, which must match IvfflatParallelScanAndSort */ + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {INT4LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; + + workmem = (desc->query_mem[0] > 0) ? (desc->query_mem[0] - SIMPLE_THRESHOLD) : + u_sess->attr.attr_memory.maintenance_work_mem; + + /* Calculate parallel workers */ + if (buildstate->heap != NULL) + parallel_workers = PlanCreateIndexWorkers(buildstate->heap, indexInfo); + + /* Attempt to launch parallel worker scan when required */ + if (parallel_workers > 0) { + Assert(!indexInfo->ii_Concurrent); + IvfflatBeginParallel(buildstate, parallel_workers,workmem); + } + + /* Set up coordination state if at least one worker launched */ + if (buildstate->ivfleader) + { + coordinate = (SortCoordinate) palloc0(sizeof(SortCoordinateData)); + coordinate->isWorker = false; + coordinate->nParticipants = buildstate->ivfleader->nparticipanttuplesorts; + coordinate->sharedsort = buildstate->ivfleader->ivfshared->sharedsort; + } + + /* Begin serial/leader tuplesort */ + buildstate->sortstate = tuplesort_begin_heap(buildstate->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, + u_sess->attr.attr_memory.maintenance_work_mem, false, 0, 0, 1, coordinate); + + /* Add tuples to sort */ + if (buildstate->heap != NULL) + { + buildstate->reltuples = AssignTupleUtility(buildstate); + +#ifdef IVFFLAT_KMEANS_DEBUG + PrintKmeansMetrics(buildstate); +#endif + } +} + +/* + * Create entry pages + */ +static void +CreateEntryPages(IvfflatBuildState * buildstate, ForkNumber forkNum) +{ + /* Assign */ + IvfflatBench("assign tuples", AssignTuples(buildstate)); + + /* Sort */ + IvfflatBench("sort tuples", tuplesort_performsort(buildstate->sortstate)); + + /* Load */ + IvfflatBench("load tuples", InsertTuples(buildstate->index, buildstate, forkNum)); + + /* End sort */ + tuplesort_end(buildstate->sortstate); + + /* End parallel build */ + if (buildstate->ivfleader) + IvfflatEndParallel(); +} + +/* + * Build the index + */ +static void +BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, + IvfflatBuildState * buildstate, ForkNumber forkNum) +{ + InitBuildState(buildstate, heap, index, indexInfo); + + ComputeCenters(buildstate); + + /* Create pages */ + CreateMetaPage(index, buildstate->dimensions, buildstate->lists, forkNum); + CreateListPages(index, buildstate->centers, buildstate->dimensions, buildstate->lists, forkNum, &buildstate->listInfo); + CreateEntryPages(buildstate, forkNum); + + /* Write WAL for initialization fork since GenericXLog functions do not */ + if (forkNum == INIT_FORKNUM) + log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); + + FreeBuildState(buildstate); +} + +/* + * Build the index for a logged table + */ +IndexBuildResult * +ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) +{ + IndexBuildResult *result; + IvfflatBuildState buildstate; + + BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); + + result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + result->heap_tuples = buildstate.reltuples; + result->index_tuples = buildstate.indtuples; + + return result; +} + +/* + * Build the index for an unlogged table + */ +void +ivfflatbuildempty_internal(Relation index) +{ + IndexInfo *indexInfo = BuildIndexInfo(index); + IvfflatBuildState buildstate; + + BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); +} diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp new file mode 100644 index 0000000000..41c2e8f59b --- /dev/null +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -0,0 +1,365 @@ +#include "postgres.h" + +#include + +#include "access/amapi.h" +#include "access/reloptions.h" +#include "commands/vacuum.h" +#include "access/datavec/ivfflat.h" +#include "utils/guc.h" +#include "utils/selfuncs.h" +#include "utils/spccache.h" + +static relopt_kind ivfflat_relopt_kind; +static THR_LOCAL bool IvfflatNeedInitialization = true; + +/* + * Initialize index options and variables + */ +void +IvfflatInit(void) +{ + ivfflat_relopt_kind = add_reloption_kind(); + add_int_reloption(ivfflat_relopt_kind, "lists", "Number of inverted lists", + IVFFLAT_DEFAULT_LISTS, IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS +#if PG_VERSION_NUM >= 130000 + ,AccessExclusiveLock +#endif + ); +} + +/* + * Estimate the cost of an index scan + */ +static void +ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) +{ + GenericCosts costs; + int lists; + double ratio; + double spc_seq_page_cost; + Relation index; + double half = 0.5; + + /* Never use index without order */ + if (path->indexorderbys == NULL) { + *indexStartupCost = DBL_MAX; + *indexTotalCost = DBL_MAX; + *indexSelectivity = 0; + *indexCorrelation = 0; + return; + } + + MemSet(&costs, 0, sizeof(costs)); + + index = index_open(path->indexinfo->indexoid, NoLock); + IvfflatGetMetaPageInfo(index, &lists, NULL); + index_close(index, NoLock); + + /* Get the ratio of lists that we need to visit */ + ratio = ((double) get_session_context()->ivfflat_probes) / lists; + if (ratio > 1.0) { + ratio = 1.0; + } + + /* + * This gives us the subset of tuples to visit. This value is passed into + * the generic cost estimator to determine the number of pages to visit + * during the index scan. + */ + costs.numIndexTuples = path->indexinfo->tuples * ratio; + + genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, + &costs.indexTotalCost, &costs.indexSelectivity, &costs.indexCorrelation); + + get_tablespace_page_costs(path->indexinfo->reltablespace, NULL, &spc_seq_page_cost); + + /* Adjust cost if needed since TOAST not included in seq scan cost */ + if (costs.numIndexPages > path->indexinfo->rel->pages && ratio < half) { + /* Change all page cost from random to sequential */ + costs.indexTotalCost -= costs.numIndexPages * (costs.spc_random_page_cost - spc_seq_page_cost); + + /* Remove cost of extra pages */ + costs.indexTotalCost -= (costs.numIndexPages - path->indexinfo->rel->pages) * spc_seq_page_cost; + } else { + /* Change some page cost from random to sequential */ + costs.indexTotalCost -= half * costs.numIndexPages * (costs.spc_random_page_cost - spc_seq_page_cost); + } + + /* + * If the list selectivity is lower than what is returned from the generic + * cost estimator, use that. + */ + if (ratio < costs.indexSelectivity) { + costs.indexSelectivity = ratio; + } + + /* Use total cost since most work happens before first tuple is returned */ + *indexStartupCost = costs.indexTotalCost; + *indexTotalCost = costs.indexTotalCost; + *indexSelectivity = costs.indexSelectivity; + *indexCorrelation = costs.indexCorrelation; +} + +/* + * Parse and validate the reloptions + */ +static bytea * +ivfflatoptions_internal(Datum reloptions, bool validate) +{ + static const relopt_parse_elt tab[] = { + {"lists", RELOPT_TYPE_INT, offsetof(IvfflatOptions, lists)}, + {"parallel_workers", RELOPT_TYPE_INT, offsetof(StdRdOptions, parallel_workers)} + }; + +#if PG_VERSION_NUM >= 130000 + return (bytea *) build_reloptions(reloptions, validate, + ivfflat_relopt_kind, + sizeof(IvfflatOptions), + tab, lengthof(tab)); +#else + relopt_value *options; + int numoptions; + IvfflatOptions *rdopts; + + if (IvfflatNeedInitialization) { + IvfflatInit(); + IvfflatNeedInitialization = false; + } + + options = parseRelOptions(reloptions, validate, ivfflat_relopt_kind, &numoptions); + rdopts = (IvfflatOptions *)allocateReloptStruct(sizeof(IvfflatOptions), options, numoptions); + fillRelOptions((void *) rdopts, sizeof(IvfflatOptions), options, numoptions, + validate, tab, lengthof(tab)); + + return (bytea *) rdopts; +#endif +} + +/* + * Validate catalog entries for the specified operator class + */ +static bool +ivfflatvalidate_internal(Oid opclassoid) +{ + return true; +} + +/* + * Define index handler + * + * See https://www.postgresql.org/docs/current/index-api.html + */ +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflathandler); +Datum +ivfflathandler(PG_FUNCTION_ARGS) +{ + IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); + + amroutine->amstrategies = 0; + amroutine->amsupport = 5; +#if PG_VERSION_NUM >= 130000 + amroutine->amoptsprocnum = 0; +#endif + amroutine->amcanorder = false; + amroutine->amcanorderbyop = true; + amroutine->amcanbackward = false; /* can change direction mid-scan */ + amroutine->amcanunique = false; + amroutine->amcanmulticol = false; + amroutine->amoptionalkey = true; + amroutine->amsearcharray = false; + amroutine->amsearchnulls = false; + amroutine->amstorage = false; + amroutine->amclusterable = false; + amroutine->ampredlocks = false; + amroutine->amcanparallel = false; + amroutine->amcaninclude = false; +#if PG_VERSION_NUM >= 130000 + amroutine->amusemaintenanceworkmem = false; /* not used during VACUUM */ + amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL; +#endif + amroutine->amkeytype = InvalidOid; + + /* Interface functions */ + errno_t rc; + rc = strcpy_s(amroutine->ambuildfuncname, NAMEDATALEN, "ivfflatbuild"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambuildemptyfuncname, NAMEDATALEN, "ivfflatbuildempty"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->aminsertfuncname, NAMEDATALEN, "ivfflatinsert"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambulkdeletefuncname, NAMEDATALEN, "ivfflatbulkdelete"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amvacuumcleanupfuncname, NAMEDATALEN, "ivfflatvacuumcleanup"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amcostestimatefuncname, NAMEDATALEN, "ivfflatcostestimate"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amoptionsfuncname, NAMEDATALEN, "ivfflatoptions"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amvalidatefuncname, NAMEDATALEN, "ivfflatvalidate"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambeginscanfuncname, NAMEDATALEN, "ivfflatbeginscan"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amrescanfuncname, NAMEDATALEN, "ivfflatrescan"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amgettuplefuncname, NAMEDATALEN, "ivfflatgettuple"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amendscanfuncname, NAMEDATALEN, "ivfflatendscan"); + securec_check(rc, "\0", "\0"); + + PG_RETURN_POINTER(amroutine); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbuild); +Datum +ivfflatbuild(PG_FUNCTION_ARGS) +{ + Relation heap = (Relation)PG_GETARG_POINTER(0); + Relation index = (Relation)PG_GETARG_POINTER(1); + IndexInfo *indexinfo = (IndexInfo *)PG_GETARG_POINTER(2); + IndexBuildResult *result = ivfflatbuild_internal(heap, index, indexinfo); + + PG_RETURN_POINTER(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbuildempty); +Datum +ivfflatbuildempty(PG_FUNCTION_ARGS) +{ + Relation index = (Relation)PG_GETARG_POINTER(0); + ivfflatbuildempty_internal(index); + + PG_RETURN_VOID(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatinsert); +Datum +ivfflatinsert(PG_FUNCTION_ARGS) +{ + Relation rel = (Relation)PG_GETARG_POINTER(0); + Datum * values = (Datum *)PG_GETARG_POINTER(1); + bool *isnull = (bool *)PG_GETARG_POINTER(2); + ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); + Relation heaprel = (Relation)PG_GETARG_POINTER(4); + IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); + bool result = ivfflatinsert_internal(rel, values, isnull, ht_ctid, heaprel, checkunique); + + PG_RETURN_BOOL(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbulkdelete); +Datum +ivfflatbulkdelete(PG_FUNCTION_ARGS) +{ + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); + void *callback_state = (void *)PG_GETARG_POINTER(3); + stats = ivfflatbulkdelete_internal(info, stats, callback, callback_state); + + PG_RETURN_POINTER(stats); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatvacuumcleanup); +Datum +ivfflatvacuumcleanup(PG_FUNCTION_ARGS) +{ + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + stats = ivfflatvacuumcleanup_internal(info, stats); + + PG_RETURN_POINTER(stats); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatcostestimate); +Datum +ivfflatcostestimate(PG_FUNCTION_ARGS) +{ + PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); + IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); + double loopcount = (double)PG_GETARG_FLOAT8(2); + Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); + Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); + Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); + double *correlation = (double *)PG_GETARG_POINTER(6); + ivfflatcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); + + PG_RETURN_VOID(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatoptions); +Datum +ivfflatoptions(PG_FUNCTION_ARGS) +{ + Datum reloptions = PG_GETARG_DATUM(0); + bool validate = PG_GETARG_BOOL(1); + bytea *result = ivfflatoptions_internal(reloptions, validate); + + if (NULL != result) + PG_RETURN_BYTEA_P(result); + + PG_RETURN_NULL(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatvalidate); +Datum +ivfflatvalidate(PG_FUNCTION_ARGS) +{ + Oid opclassoid = PG_GETARG_OID(0); + bool result = ivfflatvalidate_internal(opclassoid); + + PG_RETURN_BOOL(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbeginscan); +Datum +ivfflatbeginscan(PG_FUNCTION_ARGS) +{ + Relation rel = (Relation)PG_GETARG_POINTER(0); + int nkeys = PG_GETARG_INT32(1); + int norderbys = PG_GETARG_INT32(2); + IndexScanDesc scan = ivfflatbeginscan_internal(rel, nkeys, norderbys); + + PG_RETURN_POINTER(scan); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatrescan); +Datum +ivfflatrescan(PG_FUNCTION_ARGS) +{ + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); + int nkeys = PG_GETARG_INT32(2); + ScanKey orderbys = (ScanKey)PG_GETARG_POINTER(3); + int norderbys = PG_GETARG_INT32(4); + ivfflatrescan_internal(scan, scankey, nkeys, orderbys, norderbys); + + PG_RETURN_VOID(); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatgettuple); +Datum +ivfflatgettuple(PG_FUNCTION_ARGS) +{ + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); + + if (NULL == scan) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function ivfflatgettuple"))); + + bool result = ivfflatgettuple_internal(scan, direction); + + PG_RETURN_BOOL(result); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatendscan); +Datum +ivfflatendscan(PG_FUNCTION_ARGS) +{ + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ivfflatendscan_internal(scan); + + PG_RETURN_VOID(); +} diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp new file mode 100644 index 0000000000..aa53fc013d --- /dev/null +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -0,0 +1,208 @@ +#include "postgres.h" + +#include + +#include "access/generic_xlog.h" +#include "access/datavec/ivfflat.h" +#include "storage/buf/bufmgr.h" +#include "storage/lmgr.h" +#include "utils/memutils.h" + +/* + * Find the list that minimizes the distance function + */ +static void +FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo * listInfo) +{ + double minDistance = DBL_MAX; + BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; + FmgrInfo *procinfo; + Oid collation; + + /* Avoid compiler warning */ + listInfo->blkno = nextblkno; + listInfo->offno = FirstOffsetNumber; + + procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC); + collation = index->rd_indcollation[0]; + + /* Search all list pages */ + while (BlockNumberIsValid(nextblkno)) + { + Buffer cbuf; + Page cpage; + OffsetNumber maxoffno; + + cbuf = ReadBuffer(index, nextblkno); + LockBuffer(cbuf, BUFFER_LOCK_SHARE); + cpage = BufferGetPage(cbuf); + maxoffno = PageGetMaxOffsetNumber(cpage); + + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IvfflatList list; + double distance; + + list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); + distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, values[0], PointerGetDatum(&list->center))); + + if (distance < minDistance || !BlockNumberIsValid(*insertPage)) + { + *insertPage = list->insertPage; + listInfo->blkno = nextblkno; + listInfo->offno = offno; + minDistance = distance; + } + } + + nextblkno = IvfflatPageGetOpaque(cpage)->nextblkno; + + UnlockReleaseBuffer(cbuf); + } +} + +/* + * Insert a tuple into the index + */ +static void +InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heapRel) +{ + const IvfflatTypeInfo *typeInfo = IvfflatGetTypeInfo(index); + IndexTuple itup; + Datum value; + FmgrInfo *normprocinfo; + Buffer buf; + Page page; + GenericXLogState *state; + Size itemsz; + BlockNumber insertPage = InvalidBlockNumber; + ListInfo listInfo; + BlockNumber originalInsertPage; + + /* Detoast once for all calls */ + value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Normalize if needed */ + normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + if (normprocinfo != NULL) + { + Oid collation = index->rd_indcollation[0]; + + if (!IvfflatCheckNorm(normprocinfo, collation, value)) + return; + + value = IvfflatNormValue(typeInfo, collation, value); + } + + /* Ensure index is valid */ + IvfflatGetMetaPageInfo(index, NULL, NULL); + + /* Find the insert page - sets the page and list info */ + FindInsertPage(index, values, &insertPage, &listInfo); + Assert(BlockNumberIsValid(insertPage)); + originalInsertPage = insertPage; + + /* Form tuple */ + itup = index_form_tuple(RelationGetDescr(index), &value, isnull); + itup->t_tid = *heap_tid; + + /* Get tuple size */ + itemsz = MAXALIGN(IndexTupleSize(itup)); + Assert(itemsz <= BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)) - sizeof(ItemIdData)); + + /* Find a page to insert the item */ + for (;;) + { + buf = ReadBuffer(index, insertPage); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + + if (PageGetFreeSpace(page) >= itemsz) + break; + + insertPage = IvfflatPageGetOpaque(page)->nextblkno; + + if (BlockNumberIsValid(insertPage)) + { + /* Move to next page */ + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + } + else + { + Buffer newbuf; + Page newpage; + + /* Add a new page */ + LockRelationForExtension(index, ExclusiveLock); + newbuf = IvfflatNewBuffer(index, MAIN_FORKNUM); + UnlockRelationForExtension(index, ExclusiveLock); + + /* Init new page */ + newpage = GenericXLogRegisterBuffer(state, newbuf, GENERIC_XLOG_FULL_IMAGE); + IvfflatInitPage(newbuf, newpage); + + /* Update insert page */ + insertPage = BufferGetBlockNumber(newbuf); + + /* Update previous buffer */ + IvfflatPageGetOpaque(page)->nextblkno = insertPage; + + /* Commit */ + GenericXLogFinish(state); + + /* Unlock previous buffer */ + UnlockReleaseBuffer(buf); + + /* Prepare new buffer */ + state = GenericXLogStart(index); + buf = newbuf; + page = GenericXLogRegisterBuffer(state, buf, 0); + break; + } + } + + /* Add to next offset */ + if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + IvfflatCommitBuffer(buf, state); + + /* Update the insert page */ + if (insertPage != originalInsertPage) + IvfflatUpdateList(index, listInfo, insertPage, originalInsertPage, InvalidBlockNumber, MAIN_FORKNUM); +} + +/* + * Insert a tuple into the index + */ +bool +ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique) +{ + MemoryContext oldCtx; + MemoryContext insertCtx; + + /* Skip nulls */ + if (isnull[0]) + return false; + + /* + * Use memory context since detoast, IvfflatNormValue, and + * index_form_tuple can allocate + */ + insertCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat insert temporary context", + ALLOCSET_DEFAULT_SIZES); + oldCtx = MemoryContextSwitchTo(insertCtx); + + /* Insert tuple */ + InsertTuple(index, values, isnull, heap_tid, heap); + + /* Delete memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(insertCtx); + + return false; +} diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp new file mode 100644 index 0000000000..f196b80599 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -0,0 +1,583 @@ +#include "postgres.h" + +#include +#include + +#include "access/datavec/bitvec.h" +#include "access/datavec/halfutils.h" +#include "access/datavec/halfvec.h" +#include "access/datavec/ivfflat.h" +#include "miscadmin.h" +#include "utils/builtins.h" +#include "utils/datum.h" +#include "utils/memutils.h" +#include "access/datavec/vector.h" + +/* + * Initialize with kmeans++ + * + * https://theory.stanford.edu/~sergei/papers/kMeansPP-soda.pdf + */ +static void +InitCenters(Relation index, VectorArray samples, VectorArray centers, float *lowerBound) +{ + FmgrInfo *procinfo; + Oid collation; + int64 j; + float *weight = (float *)palloc(samples->length * sizeof(float)); + int numCenters = centers->maxlen; + int numSamples = samples->length; + + procinfo = index_getprocinfo(index, 1, IVFFLAT_KMEANS_DISTANCE_PROC); + collation = index->rd_indcollation[0]; + + /* Choose an initial center uniformly at random */ + VectorArraySet(centers, 0, VectorArrayGet(samples, RandomInt() % samples->length)); + centers->length++; + + for (j = 0; j < numSamples; j++) + weight[j] = FLT_MAX; + + for (int i = 0; i < numCenters; i++) + { + double sum; + double choice; + + CHECK_FOR_INTERRUPTS(); + + sum = 0.0; + + for (j = 0; j < numSamples; j++) + { + Datum vec = PointerGetDatum(VectorArrayGet(samples, j)); + double distance; + + /* Only need to compute distance for new center */ + /* TODO Use triangle inequality to reduce distance calculations */ + distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, i)))); + + /* Set lower bound */ + lowerBound[j * numCenters + i] = distance; + + /* Use distance squared for weighted probability distribution */ + distance *= distance; + + if (distance < weight[j]) + weight[j] = distance; + + sum += weight[j]; + } + + /* Only compute lower bound on last iteration */ + if (i + 1 == numCenters) + break; + + /* Choose new center using weighted probability distribution. */ + choice = sum * RandomDouble(); + for (j = 0; j < numSamples - 1; j++) + { + choice -= weight[j]; + if (choice <= 0) + break; + } + + VectorArraySet(centers, i + 1, VectorArrayGet(samples, j)); + centers->length++; + } + + pfree(weight); +} + +/* + * Norm centers + */ +static void +NormCenters(const IvfflatTypeInfo * typeInfo, Oid collation, VectorArray centers) +{ + MemoryContext normCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat norm temporary context", + ALLOCSET_DEFAULT_SIZES); + MemoryContext oldCtx = MemoryContextSwitchTo(normCtx); + + for (int j = 0; j < centers->length; j++) + { + Datum center = PointerGetDatum(VectorArrayGet(centers, j)); + Datum newCenter = IvfflatNormValue(typeInfo, collation, center); + Size size = VARSIZE_ANY(DatumGetPointer(newCenter)); + + if (size > centers->itemsize) + elog(ERROR, "safety check failed"); + + memcpy(DatumGetPointer(center), DatumGetPointer(newCenter), size); + MemoryContextReset(normCtx); + } + + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(normCtx); +} + +/* + * Quick approach if we have no data + */ +static void +RandomCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeInfo) +{ + int dimensions = centers->dim; + FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); + Oid collation = index->rd_indcollation[0]; + float *x = (float *) palloc(sizeof(float) * dimensions); + + /* Fill with random data */ + while (centers->length < centers->maxlen) + { + Pointer center = VectorArrayGet(centers, centers->length); + + for (int i = 0; i < dimensions; i++) + x[i] = (float) RandomDouble(); + + typeInfo->updateCenter(center, dimensions, x); + + centers->length++; + } + + if (normprocinfo != NULL) + NormCenters(typeInfo, collation, centers); +} + +#ifdef IVFFLAT_MEMORY +/* + * Show memory usage + */ +static void +ShowMemoryUsage(MemoryContext context, Size estimatedSize) +{ +#if PG_VERSION_NUM >= 130000 + elog(INFO, "total memory: %zu MB", + MemoryContextMemAllocated(context, true) / (1024 * 1024)); +#else + MemoryContextStats(context); +#endif + elog(INFO, "estimated memory: %zu MB", estimatedSize / (1024 * 1024)); +} +#endif + +/* + * Sum centers + */ +static void +SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTypeInfo * typeInfo) +{ + for (int j = 0; j < samples->length; j++) + { + float *x = agg + ((int64) closestCenters[j] * samples->dim); + + typeInfo->sumCenter(VectorArrayGet(samples, j), x); + } +} + +/* + * Update centers + */ +static void +UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo) +{ + for (int j = 0; j < centers->length; j++) + { + float *x = agg + ((int64) j * centers->dim); + + typeInfo->updateCenter(VectorArrayGet(centers, j), centers->dim, x); + } +} + +/* + * Compute new centers + */ +static void +ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *centerCounts, int *closestCenters, FmgrInfo *normprocinfo, Oid collation, const IvfflatTypeInfo * typeInfo) +{ + int dimensions = newCenters->dim; + int numCenters = newCenters->length; + int numSamples = samples->length; + + /* Reset sum and count */ + for (int j = 0; j < numCenters; j++) + { + float *x = agg + ((int64) j * dimensions); + + for (int k = 0; k < dimensions; k++) + x[k] = 0.0; + + centerCounts[j] = 0; + } + + /* Increment sum of closest center */ + SumCenters(samples, agg, closestCenters, typeInfo); + + /* Increment count of closest center */ + for (int j = 0; j < numSamples; j++) + centerCounts[closestCenters[j]] += 1; + + /* Divide sum by count */ + for (int j = 0; j < numCenters; j++) + { + float *x = agg + ((int64) j * dimensions); + + if (centerCounts[j] > 0) + { + /* Double avoids overflow, but requires more memory */ + /* TODO Update bounds */ + for (int k = 0; k < dimensions; k++) + { + if (isinf(x[k])) + x[k] = x[k] > 0 ? FLT_MAX : -FLT_MAX; + } + + for (int k = 0; k < dimensions; k++) + x[k] /= centerCounts[j]; + } + else + { + /* TODO Handle empty centers properly */ + for (int k = 0; k < dimensions; k++) + x[k] = RandomDouble(); + } + } + + /* Set new centers */ + UpdateCenters(agg, newCenters, typeInfo); + + /* Normalize if needed */ + if (normprocinfo != NULL) + NormCenters(typeInfo, collation, newCenters); +} + +/* + * Use Elkan for performance. This requires distance function to satisfy triangle inequality. + * + * We use L2 distance for L2 (not L2 squared like index scan) + * and angular distance for inner product and cosine distance + * + * https://www.aaai.org/Papers/ICML/2003/ICML03-022.pdf + */ +static void +ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo) +{ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + int dimensions = centers->dim; + int numCenters = centers->maxlen; + int numSamples = samples->length; + VectorArray newCenters; + float *agg; + int *centerCounts; + int *closestCenters; + float *lowerBound; + float *upperBound; + float *s; + float *halfcdist; + float *newcdist; + + /* Calculate allocation sizes */ + Size samplesSize = VECTOR_ARRAY_SIZE(samples->maxlen, samples->itemsize); + Size centersSize = VECTOR_ARRAY_SIZE(centers->maxlen, centers->itemsize); + Size newCentersSize = VECTOR_ARRAY_SIZE(numCenters, centers->itemsize); + Size aggSize = sizeof(float) * (int64) numCenters * dimensions; + Size centerCountsSize = sizeof(int) * numCenters; + Size closestCentersSize = sizeof(int) * numSamples; + Size lowerBoundSize = sizeof(float) * numSamples * numCenters; + Size upperBoundSize = sizeof(float) * numSamples; + Size sSize = sizeof(float) * numCenters; + Size halfcdistSize = sizeof(float) * numCenters * numCenters; + Size newcdistSize = sizeof(float) * numCenters; + + /* Calculate total size */ + Size totalSize = samplesSize + centersSize + newCentersSize + aggSize + centerCountsSize + closestCentersSize + lowerBoundSize + upperBoundSize + sSize + halfcdistSize + newcdistSize; + + /* Check memory requirements */ + /* Add one to error message to ceil */ + if (totalSize > (Size) u_sess->attr.attr_memory.maintenance_work_mem * 1024L) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("memory required is %zu MB, maintenance_work_mem is %d MB", + totalSize / (1024 * 1024) + 1, u_sess->attr.attr_memory.maintenance_work_mem / 1024))); + + /* Ensure indexing does not overflow */ + if (numCenters * numCenters > INT_MAX) + elog(ERROR, "Indexing overflow detected. Please report a bug."); + + /* Set support functions */ + procinfo = index_getprocinfo(index, 1, IVFFLAT_KMEANS_DISTANCE_PROC); + normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); + collation = index->rd_indcollation[0]; + + /* Allocate space */ + /* Use float instead of double to save memory */ + agg = (float *)palloc(aggSize); + centerCounts = (int *)palloc(centerCountsSize); + closestCenters = (int *)palloc(closestCentersSize); + lowerBound = (float *)MemoryContextAllocExtended(CurrentMemoryContext, lowerBoundSize, MCXT_ALLOC_HUGE); + upperBound = (float *)palloc(upperBoundSize); + s = (float *)palloc(sSize); + halfcdist = (float *)palloc_extended(halfcdistSize, MCXT_ALLOC_HUGE); + newcdist = (float *)palloc(newcdistSize); + + /* Initialize new centers */ + newCenters = VectorArrayInit(numCenters, dimensions, centers->itemsize); + newCenters->length = numCenters; + +#ifdef IVFFLAT_MEMORY + ShowMemoryUsage(MemoryContextGetParent(CurrentMemoryContext)); +#endif + + /* Pick initial centers */ + InitCenters(index, samples, centers, lowerBound); + + /* Assign each x to its closest initial center c(x) = argmin d(x,c) */ + for (int64 j = 0; j < numSamples; j++) + { + float minDistance = FLT_MAX; + int closestCenter = 0; + + /* Find closest center */ + for (int64 k = 0; k < numCenters; k++) + { + /* TODO Use Lemma 1 in k-means++ initialization */ + float distance = lowerBound[j * numCenters + k]; + + if (distance < minDistance) + { + minDistance = distance; + closestCenter = k; + } + } + + upperBound[j] = minDistance; + closestCenters[j] = closestCenter; + } + + /* Give 500 iterations to converge */ + for (int iteration = 0; iteration < 500; iteration++) + { + int changes = 0; + bool rjreset; + + /* Can take a while, so ensure we can interrupt */ + CHECK_FOR_INTERRUPTS(); + + /* Step 1: For all centers, compute distance */ + for (int64 j = 0; j < numCenters; j++) + { + Datum vec = PointerGetDatum(VectorArrayGet(centers, j)); + + for (int64 k = j + 1; k < numCenters; k++) + { + float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + + halfcdist[j * numCenters + k] = distance; + halfcdist[k * numCenters + j] = distance; + } + } + + /* For all centers c, compute s(c) */ + for (int64 j = 0; j < numCenters; j++) + { + float minDistance = FLT_MAX; + + for (int64 k = 0; k < numCenters; k++) + { + float distance; + + if (j == k) + continue; + + distance = halfcdist[j * numCenters + k]; + if (distance < minDistance) + minDistance = distance; + } + + s[j] = minDistance; + } + + rjreset = iteration != 0; + + for (int64 j = 0; j < numSamples; j++) + { + bool rj; + + /* Step 2: Identify all points x such that u(x) <= s(c(x)) */ + if (upperBound[j] <= s[closestCenters[j]]) + continue; + + rj = rjreset; + + for (int64 k = 0; k < numCenters; k++) + { + Datum vec; + float dxcx; + + /* Step 3: For all remaining points x and centers c */ + if (k == closestCenters[j]) + continue; + + if (upperBound[j] <= lowerBound[j * numCenters + k]) + continue; + + if (upperBound[j] <= halfcdist[closestCenters[j] * numCenters + k]) + continue; + + vec = PointerGetDatum(VectorArrayGet(samples, j)); + + /* Step 3a */ + if (rj) + { + dxcx = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j])))); + + /* d(x,c(x)) computed, which is a form of d(x,c) */ + lowerBound[j * numCenters + closestCenters[j]] = dxcx; + upperBound[j] = dxcx; + + rj = false; + } + else + dxcx = upperBound[j]; + + /* Step 3b */ + if (dxcx > lowerBound[j * numCenters + k] || dxcx > halfcdist[closestCenters[j] * numCenters + k]) + { + float dxc = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + + /* d(x,c) calculated */ + lowerBound[j * numCenters + k] = dxc; + + if (dxc < dxcx) + { + closestCenters[j] = k; + + /* c(x) changed */ + upperBound[j] = dxc; + + changes++; + } + } + } + } + + /* Step 4: For each center c, let m(c) be mean of all points assigned */ + ComputeNewCenters(samples, agg, newCenters, centerCounts, closestCenters, normprocinfo, collation, typeInfo); + + /* Step 5 */ + for (int j = 0; j < numCenters; j++) + newcdist[j] = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), PointerGetDatum(VectorArrayGet(newCenters, j)))); + + for (int64 j = 0; j < numSamples; j++) + { + for (int64 k = 0; k < numCenters; k++) + { + float distance = lowerBound[j * numCenters + k] - newcdist[k]; + + if (distance < 0) + distance = 0; + + lowerBound[j * numCenters + k] = distance; + } + } + + /* Step 6 */ + /* We reset r(x) before Step 3 in the next iteration */ + for (int j = 0; j < numSamples; j++) + upperBound[j] += newcdist[closestCenters[j]]; + + /* Step 7 */ + for (int j = 0; j < numCenters; j++) + VectorArraySet(centers, j, VectorArrayGet(newCenters, j)); + + if (changes == 0 && iteration != 0) + break; + } +} + +/* + * Ensure no NaN or infinite values + */ +static void +CheckElements(VectorArray centers, const IvfflatTypeInfo * typeInfo) +{ + float *scratch = (float *)palloc(sizeof(float) * centers->dim); + + for (int i = 0; i < centers->length; i++) + { + for (int j = 0; j < centers->dim; j++) + scratch[j] = 0; + + /* /fp:fast may not propagate NaN with MSVC, but that's alright */ + typeInfo->sumCenter(VectorArrayGet(centers, i), scratch); + + for (int j = 0; j < centers->dim; j++) + { + if (isnan(scratch[j])) + elog(ERROR, "NaN detected. Please report a bug."); + + if (isinf(scratch[j])) + elog(ERROR, "Infinite value detected. Please report a bug."); + } + } +} + +/* + * Ensure no zero vectors for cosine distance + */ +static void +CheckNorms(VectorArray centers, Relation index) +{ + /* Check NORM_PROC instead of KMEANS_NORM_PROC */ + FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + Oid collation = index->rd_indcollation[0]; + + if (normprocinfo == NULL) + return; + + for (int i = 0; i < centers->length; i++) + { + double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); + + if (norm == 0) + elog(ERROR, "Zero norm detected. Please report a bug."); + } +} + +/* + * Detect issues with centers + */ +static void +CheckCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeInfo) +{ + if (centers->length != centers->maxlen) + elog(ERROR, "Not enough centers. Please report a bug."); + + CheckElements(centers, typeInfo); + CheckNorms(centers, index); +} + +/* + * Perform naive k-means centering + * We use spherical k-means for inner product and cosine + */ +void +IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo) +{ + MemoryContext kmeansCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat kmeans temporary context", + ALLOCSET_DEFAULT_SIZES); + MemoryContext oldCtx = MemoryContextSwitchTo(kmeansCtx); + + if (samples->length == 0) + RandomCenters(index, centers, typeInfo); + else + ElkanKmeans(index, samples, centers, typeInfo); + + CheckCenters(index, centers, typeInfo); + + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(kmeansCtx); +} diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp new file mode 100644 index 0000000000..1ce26c5d78 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -0,0 +1,363 @@ +#include "postgres.h" + +#include + +#include "access/relscan.h" +#include "lib/pairingheap.h" +#include "access/datavec/ivfflat.h" +#include "miscadmin.h" +#include "pgstat.h" +#include "storage/buf/bufmgr.h" + +/* + * Compare list distances + */ +static int +CompareLists(const pairingheap_node *a, const pairingheap_node *b, void *arg) +{ + if (((const IvfflatScanList *) a)->distance > ((const IvfflatScanList *) b)->distance) + return 1; + + if (((const IvfflatScanList *) a)->distance < ((const IvfflatScanList *) b)->distance) + return -1; + + return 0; +} + +/* + * Get lists and sort by distance + */ +static void +GetScanLists(IndexScanDesc scan, Datum value) +{ + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; + int listCount = 0; + double maxDistance = DBL_MAX; + + /* Search all list pages */ + while (BlockNumberIsValid(nextblkno)) + { + Buffer cbuf; + Page cpage; + OffsetNumber maxoffno; + + cbuf = ReadBuffer(scan->indexRelation, nextblkno); + LockBuffer(cbuf, BUFFER_LOCK_SHARE); + cpage = BufferGetPage(cbuf); + + maxoffno = PageGetMaxOffsetNumber(cpage); + + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); + double distance; + + /* Use procinfo from the index instead of scan key for performance */ + distance = DatumGetFloat8(so->distfunc(so->procinfo, so->collation, PointerGetDatum(&list->center), value)); + + if (listCount < so->probes) + { + IvfflatScanList *scanlist; + + scanlist = &so->lists[listCount]; + scanlist->startPage = list->startPage; + scanlist->distance = distance; + listCount++; + + /* Add to heap */ + pairingheap_add(so->listQueue, &scanlist->ph_node); + + /* Calculate max distance */ + if (listCount == so->probes) + maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; + } + else if (distance < maxDistance) + { + IvfflatScanList *scanlist; + + /* Remove */ + scanlist = (IvfflatScanList *) pairingheap_remove_first(so->listQueue); + + /* Reuse */ + scanlist->startPage = list->startPage; + scanlist->distance = distance; + pairingheap_add(so->listQueue, &scanlist->ph_node); + + /* Update max distance */ + maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; + } + } + + nextblkno = IvfflatPageGetOpaque(cpage)->nextblkno; + + UnlockReleaseBuffer(cbuf); + } +} + +/* + * Get items + */ +static void +GetScanItems(IndexScanDesc scan, Datum value) +{ + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + TupleDesc tupdesc = RelationGetDescr(scan->indexRelation); + double tuples = 0; + TupleTableSlot *slot = MakeSingleTupleTableSlot(so->tupdesc); + + /* + * Reuse same set of shared buffers for scan + * + * See postgres/src/backend/storage/buffer/README for description + */ + BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); + + /* Search closest probes lists */ + while (!pairingheap_is_empty(so->listQueue)) + { + BlockNumber searchPage = ((IvfflatScanList *) pairingheap_remove_first(so->listQueue))->startPage; + + /* Search all entry pages for list */ + while (BlockNumberIsValid(searchPage)) + { + Buffer buf; + Page page; + OffsetNumber maxoffno; + + buf = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + maxoffno = PageGetMaxOffsetNumber(page); + + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IndexTuple itup; + Datum datum; + bool isnull; + ItemId itemid = PageGetItemId(page, offno); + + itup = (IndexTuple) PageGetItem(page, itemid); + datum = index_getattr(itup, 1, tupdesc, &isnull); + + /* + * Add virtual tuple + * + * Use procinfo from the index instead of scan key for + * performance + */ + ExecClearTuple(slot); + slot->tts_values[0] = so->distfunc(so->procinfo, so->collation, datum, value); + slot->tts_isnull[0] = false; + slot->tts_values[1] = PointerGetDatum(&itup->t_tid); + slot->tts_isnull[1] = false; + ExecStoreVirtualTuple(slot); + + tuplesort_puttupleslot(so->sortstate, slot); + + tuples++; + } + + searchPage = IvfflatPageGetOpaque(page)->nextblkno; + + UnlockReleaseBuffer(buf); + } + } + + FreeAccessStrategy(bas); + + if (tuples < 100) + ereport(DEBUG1, + (errmsg("index scan found few tuples"), + errdetail("Index may have been created with little data."), + errhint("Recreate the index and possibly decrease lists."))); + + tuplesort_performsort(so->sortstate); +} + +/* + * Zero distance + */ +static Datum +ZeroDistance(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) +{ + return Float8GetDatum(0.0); +} + +/* + * Get scan value + */ +static Datum +GetScanValue(IndexScanDesc scan) +{ + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + Datum value; + + if (scan->orderByData->sk_flags & SK_ISNULL) + { + value = PointerGetDatum(NULL); + so->distfunc = ZeroDistance; + } + else + { + value = scan->orderByData->sk_argument; + so->distfunc = FunctionCall2Coll; + + /* Value should not be compressed or toasted */ + Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); + Assert(!VARATT_IS_EXTENDED(DatumGetPointer(value))); + + /* Normalize if needed */ + if (so->normprocinfo != NULL) + value = IvfflatNormValue(so->typeInfo, so->collation, value); + } + + return value; +} + +/* + * Prepare for an index scan + */ +IndexScanDesc +ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) +{ + IndexScanDesc scan; + IvfflatScanOpaque so; + int lists; + int dimensions; + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {FLOAT8LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; + int probes = get_session_context()->ivfflat_probes; + int natts = 2; + int attDistance = 1; + int attHeaptid = 2; + + scan = RelationGetIndexScan(index, nkeys, norderbys); + + /* Get lists and dimensions from metapage */ + IvfflatGetMetaPageInfo(index, &lists, &dimensions); + + if (probes > lists) { + probes = lists; + } + + so = (IvfflatScanOpaque) palloc(offsetof(IvfflatScanOpaqueData, lists) + probes * sizeof(IvfflatScanList)); + so->typeInfo = IvfflatGetTypeInfo(index); + so->first = true; + so->probes = probes; + so->dimensions = dimensions; + + /* Set support functions */ + so->procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC); + so->normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + so->collation = index->rd_indcollation[0]; + + /* Create tuple description for sorting */ + so->tupdesc = CreateTemplateTupleDesc(natts, false); + TupleDescInitEntry(so->tupdesc, (AttrNumber) attDistance, "distance", FLOAT8OID, -1, 0); + TupleDescInitEntry(so->tupdesc, (AttrNumber) attHeaptid, "heaptid", TIDOID, -1, 0); + + /* Prep sort */ + so->sortstate = tuplesort_begin_heap(so->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, + u_sess->attr.attr_memory.work_mem, NULL, false); + + so->slot = MakeSingleTupleTableSlot(so->tupdesc); + + so->listQueue = pairingheap_allocate(CompareLists, scan); + + scan->opaque = so; + + return scan; +} + +/* + * Start or restart an index scan + */ +void +ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) +{ + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + +#if PG_VERSION_NUM >= 130000 + if (!so->first) + tuplesort_reset(so->sortstate); +#endif + + so->first = true; + pairingheap_reset(so->listQueue); + + if (keys && scan->numberOfKeys > 0) + memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData)); + + if (orderbys && scan->numberOfOrderBys > 0) + memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); +} + +/* + * Fetch the next tuple in the given scan + */ +bool +ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) +{ + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + + /* + * Index can be used to scan backward, but Postgres doesn't support + * backward scan on operators + */ + Assert(ScanDirectionIsForward(dir)); + + if (so->first) + { + Datum value; + + /* Count index scan for stats */ + pgstat_count_index_scan(scan->indexRelation); + + /* Safety check */ + if (scan->orderByData == NULL) + elog(ERROR, "cannot scan ivfflat index without order"); + + /* Requires MVCC-compliant snapshot as not able to pin during sorting */ + /* https://www.postgresql.org/docs/current/index-locking.html */ + if (!IsMVCCSnapshot(scan->xs_snapshot)) + elog(ERROR, "non-MVCC snapshots are not supported with ivfflat"); + + value = GetScanValue(scan); + IvfflatBench("GetScanLists", GetScanLists(scan, value)); + IvfflatBench("GetScanItems", GetScanItems(scan, value)); + so->first = false; + + /* Clean up if we allocated a new value */ + if (value != scan->orderByData->sk_argument) + pfree(DatumGetPointer(value)); + } + + if (tuplesort_gettupleslot(so->sortstate, true, so->slot, NULL)) + { + ItemPointer heaptid = (ItemPointer) DatumGetPointer(heap_slot_getattr(so->slot, 2, &so->isnull)); + + scan->xs_ctup.t_self = *heaptid; + scan->xs_recheck = false; + return true; + } + + return false; +} + +/* + * End a scan and release resources + */ +void +ivfflatendscan_internal(IndexScanDesc scan) +{ + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + + pairingheap_free(so->listQueue); + tuplesort_end(so->sortstate); + + pfree(so); + scan->opaque = NULL; +} diff --git a/src/gausskernel/storage/access/datavec/ivfutils.cpp b/src/gausskernel/storage/access/datavec/ivfutils.cpp new file mode 100644 index 0000000000..3e6659f30b --- /dev/null +++ b/src/gausskernel/storage/access/datavec/ivfutils.cpp @@ -0,0 +1,369 @@ +#include "postgres.h" + +#include "access/generic_xlog.h" +#include "access/datavec/bitvec.h" +#include "catalog/pg_type.h" +#include "fmgr.h" +#include "access/datavec/halfutils.h" +#include "access/datavec/halfvec.h" +#include "access/datavec/ivfflat.h" +#include "storage/buf/bufmgr.h" + +/* + * Allocate a vector array + */ +VectorArray +VectorArrayInit(int maxlen, int dimensions, Size itemsize) +{ + VectorArray res = (VectorArray)palloc(sizeof(VectorArrayData)); + + /* Ensure items are aligned to prevent UB */ + itemsize = MAXALIGN(itemsize); + + res->length = 0; + res->maxlen = maxlen; + res->dim = dimensions; + res->itemsize = itemsize; + res->items = (char *)palloc_extended(maxlen * itemsize, MCXT_ALLOC_ZERO | MCXT_ALLOC_HUGE); + return res; +} + +/* + * Free a vector array + */ +void +VectorArrayFree(VectorArray arr) +{ + pfree(arr->items); + pfree(arr); +} + +/* + * Get the number of lists in the index + */ +int +IvfflatGetLists(Relation index) +{ + IvfflatOptions *opts = (IvfflatOptions *) index->rd_options; + + if (opts) + return opts->lists; + + return IVFFLAT_DEFAULT_LISTS; +} + +/* + * Get proc + */ +FmgrInfo * +IvfflatOptionalProcInfo(Relation index, uint16 procnum) +{ + if (!OidIsValid(index_getprocid(index, 1, procnum))) + return NULL; + + return index_getprocinfo(index, 1, procnum); +} + +/* + * Normalize value + */ +Datum +IvfflatNormValue(const IvfflatTypeInfo * typeInfo, Oid collation, Datum value) +{ + return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); +} + +/* + * Check if non-zero norm + */ +bool +IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) +{ + return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; +} + +/* + * New buffer + */ +Buffer +IvfflatNewBuffer(Relation index, ForkNumber forkNum) +{ + Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); + + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + return buf; +} + +/* + * Init page + */ +void +IvfflatInitPage(Buffer buf, Page page) +{ + PageInit(page, BufferGetPageSize(buf), sizeof(IvfflatPageOpaqueData)); + IvfflatPageGetOpaque(page)->nextblkno = InvalidBlockNumber; + IvfflatPageGetOpaque(page)->page_id = IVFFLAT_PAGE_ID; +} + +/* + * Init and register page + */ +void +IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state) +{ + *state = GenericXLogStart(index); + *page = GenericXLogRegisterBuffer(*state, *buf, GENERIC_XLOG_FULL_IMAGE); + IvfflatInitPage(*buf, *page); +} + +/* + * Commit buffer + */ +void +IvfflatCommitBuffer(Buffer buf, GenericXLogState *state) +{ + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); +} + +/* + * Add a new page + * + * The order is very important!! + */ +void +IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum) +{ + /* Get new buffer */ + Buffer newbuf = IvfflatNewBuffer(index, forkNum); + Page newpage = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); + + /* Update the previous buffer */ + IvfflatPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); + + /* Init new page */ + IvfflatInitPage(newbuf, newpage); + + /* Commit */ + GenericXLogFinish(*state); + + /* Unlock */ + UnlockReleaseBuffer(*buf); + + *state = GenericXLogStart(index); + *page = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); + *buf = newbuf; +} + +/* + * Get the metapage info + */ +void +IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) +{ + Buffer buf; + Page page; + IvfflatMetaPage metap; + + buf = ReadBuffer(index, IVFFLAT_METAPAGE_BLKNO); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + metap = IvfflatPageGetMeta(page); + + if (unlikely(metap->magicNumber != IVFFLAT_MAGIC_NUMBER)) + elog(ERROR, "ivfflat index is not valid"); + + if (lists != NULL) + *lists = metap->lists; + + if (dimensions != NULL) + *dimensions = metap->dimensions; + + UnlockReleaseBuffer(buf); +} + +/* + * Update the start or insert page of a list + */ +void +IvfflatUpdateList(Relation index, ListInfo listInfo, + BlockNumber insertPage, BlockNumber originalInsertPage, + BlockNumber startPage, ForkNumber forkNum) +{ + Buffer buf; + Page page; + GenericXLogState *state; + IvfflatList list; + bool changed = false; + + buf = ReadBufferExtended(index, forkNum, listInfo.blkno, RBM_NORMAL, NULL); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + list = (IvfflatList) PageGetItem(page, PageGetItemId(page, listInfo.offno)); + + if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage) + { + /* Skip update if insert page is lower than original insert page */ + /* This is needed to prevent insert from overwriting vacuum */ + if (!BlockNumberIsValid(originalInsertPage) || insertPage >= originalInsertPage) + { + list->insertPage = insertPage; + changed = true; + } + } + + if (BlockNumberIsValid(startPage) && startPage != list->startPage) + { + list->startPage = startPage; + changed = true; + } + + /* Only commit if changed */ + if (changed) + IvfflatCommitBuffer(buf, state); + else + { + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + } +} + +static Size +VectorItemSize(int dimensions) +{ + return VECTOR_SIZE(dimensions); +} + +static Size +HalfvecItemSize(int dimensions) +{ + return HALFVEC_SIZE(dimensions); +} + +static Size +BitItemSize(int dimensions) +{ + return VARBITTOTALLEN(dimensions); +} + +static void +VectorUpdateCenter(Pointer v, int dimensions, float *x) +{ + Vector *vec = (Vector *) v; + + SET_VARSIZE(vec, VECTOR_SIZE(dimensions)); + vec->dim = dimensions; + + for (int k = 0; k < dimensions; k++) + vec->x[k] = x[k]; +} + +static void +HalfvecUpdateCenter(Pointer v, int dimensions, float *x) +{ + HalfVector *vec = (HalfVector *) v; + + SET_VARSIZE(vec, HALFVEC_SIZE(dimensions)); + vec->dim = dimensions; + + for (int k = 0; k < dimensions; k++) + vec->x[k] = Float4ToHalfUnchecked(x[k]); +} + +static void +BitUpdateCenter(Pointer v, int dimensions, float *x) +{ + VarBit *vec = (VarBit *) v; + unsigned char *nx = VARBITS(vec); + + SET_VARSIZE(vec, VARBITTOTALLEN(dimensions)); + VARBITLEN(vec) = dimensions; + + for (uint32 k = 0; k < VARBITBYTES(vec); k++) + nx[k] = 0; + + for (int k = 0; k < dimensions; k++) + nx[k / 8] |= (x[k] > 0.5 ? 1 : 0) << (7 - (k % 8)); +} + +static void +VectorSumCenter(Pointer v, float *x) +{ + Vector *vec = (Vector *) v; + + for (int k = 0; k < vec->dim; k++) + x[k] += vec->x[k]; +} + +static void +HalfvecSumCenter(Pointer v, float *x) +{ + HalfVector *vec = (HalfVector *) v; + + for (int k = 0; k < vec->dim; k++) + x[k] += HalfToFloat4(vec->x[k]); +} + +static void +BitSumCenter(Pointer v, float *x) +{ + VarBit *vec = (VarBit *) v; + + for (int k = 0; k < VARBITLEN(vec); k++) + x[k] += (float) (((VARBITS(vec)[k / 8]) >> (7 - (k % 8))) & 0x01); +} + +/* + * Get type info + */ +const IvfflatTypeInfo * +IvfflatGetTypeInfo(Relation index) +{ + FmgrInfo *procinfo = IvfflatOptionalProcInfo(index, IVFFLAT_TYPE_INFO_PROC); + + if (procinfo == NULL) + { + static const IvfflatTypeInfo typeInfo = { + .maxDimensions = IVFFLAT_MAX_DIM, + .normalize = l2_normalize, + .itemSize = VectorItemSize, + .updateCenter = VectorUpdateCenter, + .sumCenter = VectorSumCenter + }; + + return (&typeInfo); + } + else + return (const IvfflatTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); +} + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflat_halfvec_support); +Datum +ivfflat_halfvec_support(PG_FUNCTION_ARGS) +{ + static const IvfflatTypeInfo typeInfo = { + .maxDimensions = IVFFLAT_MAX_DIM * 2, + .normalize = halfvec_l2_normalize, + .itemSize = HalfvecItemSize, + .updateCenter = HalfvecUpdateCenter, + .sumCenter = HalfvecSumCenter + }; + + PG_RETURN_POINTER(&typeInfo); +}; + +PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflat_bit_support); +Datum +ivfflat_bit_support(PG_FUNCTION_ARGS) +{ + static const IvfflatTypeInfo typeInfo = { + .maxDimensions = IVFFLAT_MAX_DIM * 32, + .normalize = NULL, + .itemSize = BitItemSize, + .updateCenter = BitUpdateCenter, + .sumCenter = BitSumCenter + }; + + PG_RETURN_POINTER(&typeInfo); +}; diff --git a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp new file mode 100644 index 0000000000..2950915681 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp @@ -0,0 +1,157 @@ +#include "postgres.h" + +#include "access/generic_xlog.h" +#include "commands/vacuum.h" +#include "access/datavec/ivfflat.h" +#include "storage/buf/bufmgr.h" + +/* + * Bulk delete tuples from the index + */ +IndexBulkDeleteResult * +ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) +{ + Relation index = info->index; + BlockNumber blkno = IVFFLAT_HEAD_BLKNO; + BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); + + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + + /* Iterate over list pages */ + while (BlockNumberIsValid(blkno)) + { + Buffer cbuf; + Page cpage; + OffsetNumber coffno; + OffsetNumber cmaxoffno; + BlockNumber startPages[MaxOffsetNumber]; + ListInfo listInfo; + + cbuf = ReadBuffer(index, blkno); + LockBuffer(cbuf, BUFFER_LOCK_SHARE); + cpage = BufferGetPage(cbuf); + + cmaxoffno = PageGetMaxOffsetNumber(cpage); + + /* Iterate over lists */ + for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) + { + IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, coffno)); + + startPages[coffno - FirstOffsetNumber] = list->startPage; + } + + listInfo.blkno = blkno; + blkno = IvfflatPageGetOpaque(cpage)->nextblkno; + + UnlockReleaseBuffer(cbuf); + + for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) + { + BlockNumber searchPage = startPages[coffno - FirstOffsetNumber]; + BlockNumber insertPage = InvalidBlockNumber; + + /* Iterate over entry pages */ + while (BlockNumberIsValid(searchPage)) + { + Buffer buf; + Page page; + GenericXLogState *state; + OffsetNumber offno; + OffsetNumber maxoffno; + OffsetNumber deletable[MaxOffsetNumber]; + int ndeletable; + + vacuum_delay_point(); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas); + + /* + * ambulkdelete cannot delete entries from pages that are + * pinned by other backends + * + * https://www.postgresql.org/docs/current/index-locking.html + */ + LockBufferForCleanup(buf); + + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + + maxoffno = PageGetMaxOffsetNumber(page); + ndeletable = 0; + + /* Find deleted tuples */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offno)); + ItemPointer htup = &(itup->t_tid); + + if (callback(htup, callback_state, InvalidOid, InvalidBktId)) + { + deletable[ndeletable++] = offno; + stats->tuples_removed++; + } + else + stats->num_index_tuples++; + } + + /* Set to first free page */ + /* Must be set before searchPage is updated */ + if (!BlockNumberIsValid(insertPage) && ndeletable > 0) + insertPage = searchPage; + + searchPage = IvfflatPageGetOpaque(page)->nextblkno; + + if (ndeletable > 0) + { + /* Delete tuples */ + PageIndexMultiDelete(page, deletable, ndeletable); + GenericXLogFinish(state); + } + else + GenericXLogAbort(state); + + UnlockReleaseBuffer(buf); + } + + /* + * Update after all tuples deleted. + * + * We don't add or delete items from lists pages, so offset won't + * change. + */ + if (BlockNumberIsValid(insertPage)) + { + listInfo.offno = coffno; + IvfflatUpdateList(index, listInfo, insertPage, InvalidBlockNumber, InvalidBlockNumber, MAIN_FORKNUM); + } + } + } + + FreeAccessStrategy(bas); + + return stats; +} + +/* + * Clean up after a VACUUM operation + */ +IndexBulkDeleteResult * +ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) +{ + Relation rel = info->index; + + if (info->analyze_only) + return stats; + + /* stats is NULL if ambulkdelete not called */ + /* OK to return NULL if index not changed */ + if (stats == NULL) + return NULL; + + stats->num_pages = RelationGetNumberOfBlocks(rel); + + return stats; +} diff --git a/src/gausskernel/storage/access/datavec/vecindex.cpp b/src/gausskernel/storage/access/datavec/vecindex.cpp new file mode 100644 index 0000000000..539a55c4ea --- /dev/null +++ b/src/gausskernel/storage/access/datavec/vecindex.cpp @@ -0,0 +1,293 @@ +#include "access/transam.h" +#include "access/datavec/hnsw.h" +#include "storage/procarray.h" +#include "access/datavec/vecindex.h" + +VectorScanData *VecGetScanData(IndexScanDesc scan) +{ + switch (scan->indexRelation->rd_rel->relam) { + case HNSW_AM_OID: + return &((HnswScanOpaque)scan->opaque)->vs; + default: + break; + } + return NULL; +} + +size_t VecDefaultMaxItemSize(IndexScanDesc scan) +{ + switch (scan->indexRelation->rd_rel->relam) { + case HNSW_AM_OID: + return HnswDefaultMaxItemSize; + default: + break; + } + return (size_t)-1; +} + +TransactionIdStatus HnswCheckXid(TransactionId xid) +{ + TransactionIdStatus ts = TransactionIdGetStatus(xid); + /* Please refer to HeapTupleSatisfiesVaccum */ + if (ts == XID_INPROGRESS) { + if (TransactionIdIsInProgress(xid)) { + /* Inprogress */ + } else if (TransactionIdDidCommit(xid)) { + ts = XID_COMMITTED; + } else { + ts = XID_ABORTED; + } + } + return ts; +} + +bool VecItupGetXminXmax(Page page, OffsetNumber offnum, TransactionId oldest_xmin, TransactionId *xmin, + TransactionId *xmax, bool *xminCommitted, bool *xmaxCommitted, bool isToast) +{ + ItemId iid = PageGetItemId(page, offnum); + HnswElementTuple itup = (HnswElementTuple)PageGetItem(page, iid); + IndexTransInfo* idxXid = (IndexTransInfo*)VecIndexTupleGetXid(itup); + bool isDead = false; + bool needCheckXmin = true; + + *xminCommitted = *xmaxCommitted = false; + + if (ItemIdIsDead(iid)) { + *xmin = InvalidTransactionId; + *xmax = InvalidTransactionId; + return true; + } + + *xmin = idxXid->xmin; + *xmax = idxXid->xmax; + + /* examine xmax */ + if (TransactionIdIsValid(*xmax)) { + TransactionIdStatus ts = HnswCheckXid(*xmax); + switch (ts) { + case XID_INPROGRESS: + if (TransactionIdEquals(*xmin, *xmax)) { + needCheckXmin = false; + } + break; + case XID_COMMITTED: + *xminCommitted = *xmaxCommitted = true; + needCheckXmin = false; + break; + case XID_ABORTED: + idxXid->xmax = InvalidTransactionId; + *xmax = InvalidTransactionId; + if (TransactionIdEquals(*xmin, *xmax)) { + /* xmin xmax aborted */ + idxXid->xmin = InvalidTransactionId; + *xmin = InvalidTransactionId; + needCheckXmin = false; + } + break; + } + } + + /* examine xmin */ + if (needCheckXmin) { + if (IndexItemIdIsFrozen(iid)) { + *xminCommitted = true; + } else if (TransactionIdIsValid(*xmin)) { + TransactionIdStatus ts = HnswCheckXid(*xmin); + switch (ts) { + case XID_INPROGRESS: + break; + case XID_COMMITTED: + *xminCommitted = true; + break; + case XID_ABORTED: + idxXid->xmin = InvalidTransactionId; + *xmin = InvalidTransactionId; + break; + } + } + } + + /* if there is no passed oldest_xmin, we will ues the current oldest_xmin */ + if (!TransactionIdIsValid(oldest_xmin)) { + if (isToast) { + GetOldestXminForUndo(&oldest_xmin); + } else { + oldest_xmin = u_sess->utils_cxt.RecentGlobalDataXmin; + } + } + /* we can't do bypass in hotstandby read mode, or there will be different between index scan and seq scan */ + if (RecoveryInProgress()) { + oldest_xmin = InvalidTransactionId; + } + + if (!TransactionIdIsValid(*xmin)) { + isDead = true; + } + /* before we mark the tuple as DEAD because of xmax, must comfirm that xmax has committed */ + if (*xmaxCommitted && TransactionIdPrecedes(*xmax, oldest_xmin)) { + isDead = true; + } + + /* before we mark the tuple as FROZEN, must comfirm that xmin has committed */ + if (IndexItemIdIsFrozen(iid)) { + *xmin = FrozenTransactionId; + } else if (*xminCommitted && TransactionIdPrecedes(*xmin, oldest_xmin)) { + IndexItemIdSetFrozen(iid); + *xmin = FrozenTransactionId; + } + + if (isDead) { + ItemIdMarkDead(iid); + *xmin = InvalidTransactionId; + *xmax = InvalidTransactionId; + *xminCommitted = *xmaxCommitted = false; + } + + return isDead; +} + +static bool VecItupEquals(IndexTuple itup1, IndexTuple itup2) +{ + if (itup1 == NULL || itup2 == NULL) { + return false; + } + if (IndexTupleSize(itup1) == 0 || IndexTupleSize(itup2) == 0) { + return false; + } + /* + * compare the binary directly. If these index tuples are formed from the + * same uheap tuple, they should be exactly the same. + */ + return memcmp(itup1, itup2, IndexTupleSize(itup1)) == 0; +} + +static bool VecVisibilityCheckCid(IndexScanDesc scan, IndexTuple itup, bool *needRecheck) +{ + VectorScanData *vs = VecGetScanData(scan); + Assert(vs != NULL); + + if (VecItupEquals((IndexTuple)vs->lastSelfModifiedItup, itup)) { + *needRecheck = false; + return false; /* tuples with same key and TID will only returned once */ + } + + /* save this index tuple as lastSelfModifiedItup */ + /* Step1: Check that the buffer space is large enough. */ + size_t maxItemSize = VecDefaultMaxItemSize(scan); + uint newSize = 0; + int multiSize = 2; + if (vs->lastSelfModifiedItup == NULL) { + newSize = IndexTupleSize(itup); + } else if (vs->lastSelfModifiedItupBufferSize < IndexTupleSize(itup)) { + newSize = MAX(vs->lastSelfModifiedItupBufferSize * multiSize, IndexTupleSize(itup)); + newSize = MIN(newSize, maxItemSize); + pfree(vs->lastSelfModifiedItup); + } + /* Step2: Extend when necessary. */ + if (newSize != 0) { + vs->lastSelfModifiedItup = (char*)palloc(newSize); + vs->lastSelfModifiedItupBufferSize = newSize; + } + /* Step3: Save the current IndexTuple. */ + errno_t rc = 0; + rc = memcpy_s(vs->lastSelfModifiedItup, maxItemSize, itup, IndexTupleSize(itup)); + securec_check(rc, "\0", "\0"); + + *needRecheck = true; + return true; /* treat as visible, but need recheck */ +} + +static bool VecXidSatisfiesMVCC(TransactionId xid, bool committed, Snapshot snapshot, Buffer buffer) +{ + TransactionIdStatus ignore; + + if (!TransactionIdIsValid(xid)) { + return false; /* invisible */ + } + if (xid == FrozenTransactionId) { + return true; /* frozen */ + } + + /* + * We can use snapshot's xmin/xmax as fast bypass after they become valid again. + * Currently, snapshot's csn and xmin/xmax may be inconsistent. The reavsn is + * that there is a problem with the cooperation of committing and subtransaction. + */ + + /* we can't tell visibility by snapshot's xmin/xmax alone, check snapshot */ + return XidVisibleInSnapshot(xid, snapshot, &ignore, (RecoveryInProgress() ? buffer : InvalidBuffer), NULL); +} + +static bool VecVisibilityCheckXid(TransactionId xmin, TransactionId xmax, bool xminCommitted, bool xmaxCommitted, + Snapshot snapshot, Buffer buffer, bool isUpsert) +{ + if (snapshot->satisfies == SNAPSHOT_DIRTY && isUpsert) { + bool xmaxVisible = xmaxCommitted || TransactionIdIsCurrentTransactionId(xmax); + if (xmaxVisible) { + return false; + } + return true; + } + + /* only support MVCC and NOW, ereport used to locate bug */ + if (snapshot->satisfies != SNAPSHOT_VERSION_MVCC && + snapshot->satisfies != SNAPSHOT_MVCC && snapshot->satisfies != SNAPSHOT_NOW) { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("unsupported snapshot type %u for UBTree index.", snapshot->satisfies), + errhint("This kind of operation may not supported."))); + } + + /* handle snapshot MVCC */ + if (snapshot->satisfies == SNAPSHOT_VERSION_MVCC || snapshot->satisfies == SNAPSHOT_MVCC) { + if (VecXidSatisfiesMVCC(xmax, xmaxCommitted, snapshot, buffer)) { + return false; /* already deleted */ + } + if (!VecXidSatisfiesMVCC(xmin, xminCommitted, snapshot, buffer)) { + return false; /* have not inserted yet */ + } + } + + /* handle snapshot NOW */ + if (snapshot->satisfies == SNAPSHOT_NOW) { + return xminCommitted && !xmaxCommitted; + } + + return true; +} + +bool VecVisibilityCheck(IndexScanDesc scan, Page page, OffsetNumber offnum, bool *needRecheck) +{ + bool needVisibilityCheck = scan->xs_snapshot->satisfies != SNAPSHOT_ANY && + scan->xs_snapshot->satisfies != SNAPSHOT_TOAST; + TransactionId xmin, xmax; + bool xminCommitted = false; + bool xmaxCommitted = false; + bool isDead = VecItupGetXminXmax(page, offnum, InvalidTransactionId, + &xmin, &xmax, &xminCommitted, &xmaxCommitted, + RelationGetNamespace(scan->indexRelation) == PG_TOAST_NAMESPACE); + + if (needRecheck == NULL) { + *needRecheck = false; + } + + bool isVisible = !isDead; + if (needVisibilityCheck && !isDead) { + /* + * If this IndexTuple is not visible to the current Snapshot, try to get the next one. + * We're not going to tell heap to skip visibility check, because it doesn't cost a lot and we need heap + * to check the visibility with CID when snapshot's xid equals to xmin or xmax. + */ + if (scan->xs_snapshot->satisfies == SNAPSHOT_MVCC && + (TransactionIdIsCurrentTransactionId(xmin) || TransactionIdIsCurrentTransactionId(xmax))) { + ItemId iid = PageGetItemId(page, offnum); + IndexTuple tuple = (IndexTuple)PageGetItem(page, iid); + isVisible = VecVisibilityCheckCid(scan, tuple, needRecheck); /* need check cid */ + } else { + VectorScanData *vs = VecGetScanData(scan); + isVisible = VecVisibilityCheckXid(xmin, xmax, xminCommitted, xmaxCommitted, + scan->xs_snapshot, vs->buf, scan->isUpsert); + } + } + + return isVisible; +} diff --git a/src/include/access/datavec/bitvec.h b/src/include/access/datavec/bitvec.h new file mode 100644 index 0000000000..5a1aa58820 --- /dev/null +++ b/src/include/access/datavec/bitvec.h @@ -0,0 +1,17 @@ +#ifndef BITVEC_H +#define BITVEC_H + +#include "postgres.h" +#include "utils/varbit.h" + +extern uint64 (*BitHammingDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance); +extern double (*BitJaccardDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb); + +void BitvecInit(void); + +VarBit *InitBitVector(int dim); + +Datum hamming_distance(PG_FUNCTION_ARGS); +Datum jaccard_distance(PG_FUNCTION_ARGS); + +#endif diff --git a/src/include/access/datavec/halfutils.h b/src/include/access/datavec/halfutils.h new file mode 100644 index 0000000000..6e9d53a66e --- /dev/null +++ b/src/include/access/datavec/halfutils.h @@ -0,0 +1,263 @@ +#ifndef HALFUTILS_H +#define HALFUTILS_H + +#include + +#include "access/datavec/halfvec.h" +#include "access/datavec/shortest_dec.h" + +#ifdef F16C_SUPPORT +#include +#endif + +extern float (*HalfvecL2SquaredDistance) (int dim, half * ax, half * bx); +extern float (*HalfvecInnerProduct) (int dim, half * ax, half * bx); +extern double (*HalfvecCosineSimilarity) (int dim, half * ax, half * bx); +extern float (*HalfvecL1Distance) (int dim, half * ax, half * bx); + +void HalfvecInit(void); + +/* + * Check if half is NaN + */ +static inline bool +HalfIsNan(half num) +{ +#ifdef FLT16_SUPPORT + return isnan(num); +#else + return (num & 0x7C00) == 0x7C00 && (num & 0x7FFF) != 0x7C00; +#endif +} + +/* + * Check if half is infinite + */ +static inline bool +HalfIsInf(half num) +{ +#ifdef FLT16_SUPPORT + return isinf(num); +#else + return (num & 0x7FFF) == 0x7C00; +#endif +} + +/* + * Check if half is zero + */ +static inline bool +HalfIsZero(half num) +{ +#ifdef FLT16_SUPPORT + return num == 0; +#else + return (num & 0x7FFF) == 0x0000; +#endif +} + +/* + * Convert a half to a float4 + */ +static inline float +HalfToFloat4(half num) +{ +#if defined(F16C_SUPPORT) + return _cvtsh_ss(num); +#elif defined(FLT16_SUPPORT) + return (float) num; +#else + union + { + float f; + uint32 i; + } swapfloat; + + union + { + half h; + uint16 i; + } swaphalf; + + uint16 bin; + uint32 exponent; + uint32 mantissa; + uint32 result; + + swaphalf.h = num; + bin = swaphalf.i; + exponent = (bin & 0x7C00) >> 10; + mantissa = bin & 0x03FF; + + /* Sign */ + result = (bin & 0x8000) << 16; + + if (unlikely(exponent == 31)) + { + if (mantissa == 0) + { + /* Infinite */ + result |= 0x7F800000; + } + else + { + /* NaN */ + result |= 0x7FC00000; + } + } + else if (unlikely(exponent == 0)) + { + /* Subnormal */ + if (mantissa != 0) + { + exponent = -14; + + for (int i = 0; i < 10; i++) + { + mantissa <<= 1; + exponent -= 1; + + if ((mantissa >> 10) % 2 == 1) + { + mantissa &= 0x03ff; + break; + } + } + + result |= (exponent + 127) << 23; + } + } + else + { + /* Normal */ + result |= (exponent - 15 + 127) << 23; + } + + result |= mantissa << 13; + + swapfloat.i = result; + return swapfloat.f; +#endif +} + +/* + * Convert a float4 to a half + */ +static inline half +Float4ToHalfUnchecked(float num) +{ +#if defined(F16C_SUPPORT) + return _cvtss_sh(num, 0); +#elif defined(FLT16_SUPPORT) + return num; +#else + union + { + float f; + uint32 i; + } swapfloat; + + union + { + half h; + uint16 i; + } swaphalf; + + uint32 bin; + int exponent; + int mantissa; + uint16 result; + + swapfloat.f = num; + bin = swapfloat.i; + exponent = (bin & 0x7F800000) >> 23; + mantissa = bin & 0x007FFFFF; + + /* Sign */ + result = (bin & 0x80000000) >> 16; + + if (isinf(num)) + { + /* Infinite */ + result |= 0x7C00; + } + else if (isnan(num)) + { + /* NaN */ + result |= 0x7E00; + result |= mantissa >> 13; + } + else if (exponent > 98) + { + int m; + int gr; + int s; + + exponent -= 127; + s = mantissa & 0x00000FFF; + + /* Subnormal */ + if (exponent < -14) + { + int diff = -exponent - 14; + + mantissa >>= diff; + mantissa += 1 << (23 - diff); + s |= mantissa & 0x00000FFF; + } + + m = mantissa >> 13; + + /* Round */ + gr = (mantissa >> 12) % 4; + if (gr == 3 || (gr == 1 && s != 0)) + m += 1; + + if (m == 1024) + { + m = 0; + exponent += 1; + } + + if (exponent > 15) + { + /* Infinite */ + result |= 0x7C00; + } + else + { + if (exponent >= -14) + result |= (exponent + 15) << 10; + + result |= m; + } + } + + swaphalf.i = result; + return swaphalf.h; +#endif +} + +/* + * Convert a float4 to a half + */ +static inline half +Float4ToHalf(float num) +{ + half result = Float4ToHalfUnchecked(num); + + if (unlikely(HalfIsInf(result)) && !isinf(num)) + { + char *buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); + + float_to_shortest_decimal_buf(num, buf); + + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type halfvec", buf))); + } + + return result; +} + +#endif diff --git a/src/include/access/datavec/halfvec.h b/src/include/access/datavec/halfvec.h new file mode 100644 index 0000000000..c46a34f248 --- /dev/null +++ b/src/include/access/datavec/halfvec.h @@ -0,0 +1,112 @@ +#ifndef HALFVEC_H +#define HALFVEC_H + +#define __STDC_WANT_IEC_60559_TYPES_EXT__ + +#include +#include "fmgr.h" + +/* We use two types of dispatching: intrinsics and target_clones */ +/* TODO Move to better place */ +#ifndef DISABLE_DISPATCH +/* Only enable for more recent compilers to keep build process simple */ +#if defined(__x86_64__) && defined(__GNUC__) && __GNUC__ >= 11 +#define USE_DISPATCH +#elif defined(__x86_64__) && defined(__clang_major__) && __clang_major__ >= 7 +#define USE_DISPATCH +#elif defined(_M_AMD64) && defined(_MSC_VER) && _MSC_VER >= 1920 +#define USE_DISPATCH +#endif +#endif + +/* target_clones requires glibc */ +#if defined(USE_DISPATCH) && defined(__gnu_linux__) && defined(__has_attribute) +/* Use separate line for portability */ +#if __has_attribute(target_clones) +#define USE_TARGET_CLONES +#endif +#endif + +/* Apple clang check needed for universal binaries on Mac */ +#if defined(USE_DISPATCH) && (defined(HAVE__GET_CPUID) || defined(__apple_build_version__)) +#define USE__GET_CPUID +#endif + +#if defined(USE_DISPATCH) +#define HALFVEC_DISPATCH +#endif + +/* F16C has better performance than _Float16 (on x86-64) */ +#if defined(__F16C__) +#define F16C_SUPPORT +#elif defined(__FLT16_MAX__) && !defined(HALFVEC_DISPATCH) +#define FLT16_SUPPORT +#endif + +//TODO support _Float16 +#ifdef FLT16_SUPPORT +#define half float +#define HALF_MAX FLT16_MAX +#else +#define half uint16 +#define HALF_MAX 65504 +#endif + +#define HALFVEC_MAX_DIM 16000 + +#define HALFVEC_SIZE(_dim) (offsetof(HalfVector, x) + sizeof(half)*(_dim)) +#define DatumGetHalfVector(x) ((HalfVector *) PG_DETOAST_DATUM(x)) +#define PG_GETARG_HALFVEC_P(x) DatumGetHalfVector(PG_GETARG_DATUM(x)) +#define PG_RETURN_HALFVEC_P(x) PG_RETURN_POINTER(x) + +typedef struct HalfVector +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int16 dim; /* number of dimensions */ + int16 unused; /* reserved for future use, always zero */ + half x[FLEXIBLE_ARRAY_MEMBER]; +} HalfVector; + +HalfVector *InitHalfVector(int dim); + +Datum halfvec_in(PG_FUNCTION_ARGS); +Datum halfvec_out(PG_FUNCTION_ARGS); +Datum halfvec_typmod_in(PG_FUNCTION_ARGS); +Datum halfvec_recv(PG_FUNCTION_ARGS); +Datum halfvec_send(PG_FUNCTION_ARGS); +Datum halfvec_l2_distance(PG_FUNCTION_ARGS); +Datum halfvec_inner_product(PG_FUNCTION_ARGS); +Datum halfvec_cosine_distance(PG_FUNCTION_ARGS); +Datum halfvec_l1_distance(PG_FUNCTION_ARGS); +Datum halfvec_vector_dims(PG_FUNCTION_ARGS); +Datum halfvec_l2_norm(PG_FUNCTION_ARGS); +Datum halfvec_l2_normalize(PG_FUNCTION_ARGS); +Datum halfvec_binary_quantize(PG_FUNCTION_ARGS); +Datum halfvec_subvector(PG_FUNCTION_ARGS); +Datum halfvec_add(PG_FUNCTION_ARGS); +Datum halfvec_sub(PG_FUNCTION_ARGS); +Datum halfvec_mul(PG_FUNCTION_ARGS); +Datum halfvec_concat(PG_FUNCTION_ARGS); +Datum halfvec_lt(PG_FUNCTION_ARGS); +Datum halfvec_le(PG_FUNCTION_ARGS); +Datum halfvec_eq(PG_FUNCTION_ARGS); +Datum halfvec_ne(PG_FUNCTION_ARGS); +Datum halfvec_ge(PG_FUNCTION_ARGS); +Datum halfvec_gt(PG_FUNCTION_ARGS); +Datum halfvec_cmp(PG_FUNCTION_ARGS); +Datum halfvec_l2_squared_distance(PG_FUNCTION_ARGS); +Datum halfvec_negative_inner_product(PG_FUNCTION_ARGS); +Datum halfvec_spherical_distance(PG_FUNCTION_ARGS); +Datum halfvec_accum(PG_FUNCTION_ARGS); +Datum halfvec_avg(PG_FUNCTION_ARGS); +Datum halfvec_combine(PG_FUNCTION_ARGS); +Datum halfvec(PG_FUNCTION_ARGS); +Datum halfvec_to_vector(PG_FUNCTION_ARGS); +Datum vector_to_halfvec(PG_FUNCTION_ARGS); +Datum array_to_halfvec(PG_FUNCTION_ARGS); +Datum array_to_halfvec(PG_FUNCTION_ARGS); +Datum array_to_halfvec(PG_FUNCTION_ARGS); +Datum array_to_halfvec(PG_FUNCTION_ARGS); +Datum halfvec_to_float4(PG_FUNCTION_ARGS); + +#endif diff --git a/src/include/access/datavec/hnsw.h b/src/include/access/datavec/hnsw.h new file mode 100644 index 0000000000..ff1f2fc449 --- /dev/null +++ b/src/include/access/datavec/hnsw.h @@ -0,0 +1,642 @@ +#ifndef HNSW_H +#define HNSW_H + +#include "postgres.h" + +#include "access/genam.h" +#include "lib/pairingheap.h" +#include "nodes/execnodes.h" +#include "port.h" /* for random() */ +#include "access/datavec/vector.h" +#include "access/datavec/vecindex.h" + +#define HNSW_MAX_DIM 2000 +#define HNSW_MAX_NNZ 1000 + +/* Support functions */ +#define HNSW_DISTANCE_PROC 1 +#define HNSW_NORM_PROC 2 +#define HNSW_TYPE_INFO_PROC 3 + +#define HNSW_VERSION 1 +#define HNSW_MAGIC_NUMBER 0xA953A953 +#define HNSW_PAGE_ID 0xFF90 + +/* Preserved page numbers */ +#define HNSW_METAPAGE_BLKNO 0 +#define HNSW_HEAD_BLKNO 1 /* first element page */ +#define HNSW_PQTABLE_START_BLKNO 1 /* pqtable start page */ +#define HNSW_PQTABLE_STORAGE_SIZE (uint16)(6*1024) /* pqtable storage size in each page */ + +/* Append page slot info */ +#define HNSW_DEFAULT_NPAGES_PER_SLOT 50 +#define HNSW_BUFFER_THRESHOLD 4 + +/* Must correspond to page numbers since page lock is used */ +#define HNSW_UPDATE_LOCK 0 +#define HNSW_SCAN_LOCK 1 + +/* HNSW parameters */ +#define HNSW_DEFAULT_M 16 +#define HNSW_MIN_M 2 +#define HNSW_MAX_M 100 +#define HNSW_DEFAULT_EF_CONSTRUCTION 64 +#define HNSW_MIN_EF_CONSTRUCTION 4 +#define HNSW_MAX_EF_CONSTRUCTION 1000 +#define HNSW_DEFAULT_EF_SEARCH 40 +#define HNSW_MIN_EF_SEARCH 1 +#define HNSW_MAX_EF_SEARCH 1000 +#define HNSW_DEFAULT_ENABLE_PQ false +#define HNSW_DEFAULT_PQ_M 1 +#define HNSW_MIN_PQ_M 1 +#define HNSW_MAX_PQ_M 65535 +#define HNSW_DEFAULT_PQ_KSUB 1 +#define HNSW_MIN_PQ_KSUB 1 +#define HNSW_MAX_PQ_KSUB 65535 + +/* Tuple types */ +#define HNSW_ELEMENT_TUPLE_TYPE 1 +#define HNSW_NEIGHBOR_TUPLE_TYPE 2 + +/* page types */ +#define HNSW_DEFAULT_PAGE_TYPE 0 +#define HNSW_ELEMENT_PAGE_TYPE 1 +#define HNSW_NEIGHBOR_PAGE_TYPE 2 +#define HNSW_USTORE_PAGE_TYPE 3 + +/* Make graph robust against non-HOT updates */ +#define HNSW_HEAPTIDS 10 + +#define HNSW_UPDATE_ENTRY_GREATER 1 +#define HNSW_UPDATE_ENTRY_ALWAYS 2 + +/* Build phases */ +/* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 */ +#define PROGRESS_HNSW_PHASE_LOAD 2 + +#define HNSW_MAX_SIZE (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - sizeof(ItemIdData)) +#define HNSW_TUPLE_ALLOC_SIZE BLCKSZ + +#define HNSW_ELEMENT_TUPLE_SIZE(size) MAXALIGN(offsetof(HnswElementTupleData, data) + (size)) +#define HNSW_NEIGHBOR_TUPLE_SIZE(level, m) MAXALIGN(offsetof(HnswNeighborTupleData, indextids) + ((level) + 2) * (m) * sizeof(ItemPointerData)) + +#define HNSW_NEIGHBOR_ARRAY_SIZE(lm) (offsetof(HnswNeighborArray, items) + sizeof(HnswCandidate) * (lm)) + +#define HnswPageGetOpaque(page) ((HnswPageOpaque) PageGetSpecialPointer(page)) +#define HnswPageGetMeta(page) ((HnswMetaPageData *) PageGetContents(page)) +#define HnswPageGetAppendMeta(page) ((HnswAppendMetaPageData *) PageGetContents(page)) + +#define HnswDefaultMaxItemSize \ + MAXALIGN_DOWN((BLCKSZ - \ + MAXALIGN(SizeOfPageHeaderData + \ + sizeof(ItemIdData) + \ + sizeof(ItemPointerData)) - \ + MAXALIGN(sizeof(HnswPageOpaqueData)))) + +#if PG_VERSION_NUM >= 150000 +#define RandomDouble() pg_prng_double(&pg_global_prng_state) +#define SeedRandom(seed) pg_prng_seed(&pg_global_prng_state, seed) +#else +#define RandomDouble() (((double) random()) / MAX_RANDOM_VALUE) +#define SeedRandom(seed) srandom(seed) +#endif + +#if PG_VERSION_NUM < 130000 +#define list_delete_last(list) list_truncate(list, list_length(list) - 1) +#define list_sort(list, cmp) \ + do { \ + ListCell *cell; \ + int i; \ + int len = list_length(list); \ + ListCell **list_arr; \ + List *new_list; \ + \ + if (len == 0) { \ + list = NIL; \ + return list; \ + } \ + i = 0; \ + list_arr = (ListCell **)palloc(sizeof(ListCell *) * len); \ + foreach(cell, list) \ + list_arr[i++] = cell; \ + \ + qsort(list_arr, len, sizeof(ListCell *), cmp); \ + \ + new_list = (List *) palloc(sizeof(List)); \ + new_list->type = list->type; \ + new_list->length = len; \ + new_list->head = list_arr[len - 1]; \ + new_list->tail = list_arr[0]; \ + \ + for (i = len - 1; i > 0; i--) \ + list_arr[i]->next = list_arr[i - 1]; \ + \ + list_arr[0]->next = NULL; \ + pfree(list_arr); \ + list = new_list; \ + } while (0) +#endif + +#define HnswIsElementTuple(tup) ((tup)->type == HNSW_ELEMENT_TUPLE_TYPE) +#define HnswIsNeighborTuple(tup) ((tup)->type == HNSW_NEIGHBOR_TUPLE_TYPE) + +/* 2 * M connections for ground layer */ +#define HnswGetLayerM(m, layer) (layer == 0 ? (m) * 2 : (m)) + +/* Optimal ML from paper */ +#define HnswGetMl(m) (1 / log(m)) + +/* Ensure fits on page and in uint8 */ +#define HnswGetMaxLevel(m) Min(((BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - offsetof(HnswNeighborTupleData, indextids) - sizeof(ItemIdData)) / (sizeof(ItemPointerData)) / (m)) - 2, 255) + +#define HnswGetValue(base, element) PointerGetDatum(HnswPtrAccess(base, (element)->value)) + +#if PG_VERSION_NUM < 140005 +#define relptr_offset(rp) ((rp).relptr_off - 1) +#endif + +/* Pointer macros */ +#define HnswPtrAccess(base, hp) ((base) == NULL ? (hp).ptr : relptr_access(base, (hp).relptr)) +#define HnswPtrStore(base, hp, value) ((base) == NULL ? (void) ((hp).ptr = (value)) : (void) relptr_store(base, (hp).relptr, value)) +#define HnswPtrIsNull(base, hp) ((base) == NULL ? (hp).ptr == NULL : relptr_is_null((hp).relptr)) +#define HnswPtrEqual(base, hp1, hp2) ((base) == NULL ? (hp1).ptr == (hp2).ptr : relptr_offset((hp1).relptr) == relptr_offset((hp2).relptr)) + +/* For code paths dedicated to each type */ +#define HnswPtrPointer(hp) (hp).ptr +#define HnswPtrOffset(hp) relptr_offset((hp).relptr) + +/* Variables */ +extern int hnsw_lock_tranche_id; + +typedef struct HnswElementData HnswElementData; +typedef struct HnswNeighborArray HnswNeighborArray; + + +#define relptr(type) union { type *relptr_type; Size relptr_off; } + +#define relptr_declare(type, relptrtype) \ + typedef relptr(type) relptrtype + +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define relptr_access(base, rp) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + (__typeof__((rp).relptr_type)) ((rp).relptr_off == 0 ? NULL : \ + (base) + (rp).relptr_off - 1)) +#else +/* + * If we don't have __builtin_types_compatible_p, assume we might not have + * __typeof__ either. + */ +#define relptr_access(base, rp) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + (void *) ((rp).relptr_off == 0 ? NULL : (base) + (rp).relptr_off - 1)) +#endif + +#define relptr_is_null(rp) \ + ((rp).relptr_off == 0) + +#define relptr_offset(rp) \ + ((rp).relptr_off - 1) + +/* We use this inline to avoid double eval of "val" in relptr_store */ +static inline Size +relptr_store_eval(char *base, char *val) +{ + if (val == NULL) + return 0; + else + { + Assert(val >= base); + return val - base + 1; + } +} + +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define relptr_store(base, rp, val) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + AssertVariableIsOfTypeMacro(val, __typeof__((rp).relptr_type)), \ + (rp).relptr_off = relptr_store_eval((base), (char *) (val))) +#else +/* + * If we don't have __builtin_types_compatible_p, assume we might not have + * __typeof__ either. + */ +#define relptr_store(base, rp, val) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + (rp).relptr_off = relptr_store_eval((base), (char *) (val))) +#endif + +#define HnswPtrDeclare(type, relptrtype, ptrtype) \ + relptr_declare(type, relptrtype); \ + typedef union { type *ptr; relptrtype relptr; } ptrtype; + +/* Pointers that can be absolute or relative */ +/* Use char for HnswDatumPtr so works with Pointer */ +HnswPtrDeclare(HnswElementData, HnswElementRelptr, HnswElementPtr); +HnswPtrDeclare(HnswNeighborArray, HnswNeighborArrayRelptr, HnswNeighborArrayPtr); +HnswPtrDeclare(HnswNeighborArrayPtr, HnswNeighborsRelptr, HnswNeighborsPtr); +HnswPtrDeclare(char, DatumRelptr, HnswDatumPtr); + +struct HnswElementData +{ + HnswElementPtr next; + ItemPointerData heaptids[HNSW_HEAPTIDS]; + uint8 heaptidsLength; + uint8 level; + uint8 deleted; + uint32 hash; + HnswNeighborsPtr neighbors; + BlockNumber blkno; + OffsetNumber offno; + OffsetNumber neighborOffno; + BlockNumber neighborPage; + HnswDatumPtr value; + uint8 *pqcodes; + LWLock lock; +}; + +typedef HnswElementData * HnswElement; + +typedef struct HnswCandidate +{ + HnswElementPtr element; + float distance; + bool closer; +} HnswCandidate; + +struct HnswNeighborArray +{ + int length; + bool closerSet; + HnswCandidate items[FLEXIBLE_ARRAY_MEMBER]; +}; + +typedef struct HnswPairingHeapNode +{ + pairingheap_node ph_node; + HnswCandidate *inner; +} HnswPairingHeapNode; + +/* HNSW index options */ +typedef struct HnswOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int m; /* number of connections */ + int efConstruction; /* size of dynamic candidate list */ + bool enablePQ; + int pqM; /* number of subquantizer */ + int pqKsub; /* number of centroids for each subquantizer */ + char* storage_type; /* table access method kind */ +} HnswOptions; + +typedef struct HnswGraph +{ + /* Graph state */ + slock_t lock; + HnswElementPtr head; + double indtuples; + + /* Entry state */ + LWLock entryLock; + LWLock entryWaitLock; + HnswElementPtr entryPoint; + + /* Allocations state */ + LWLock allocatorLock; + long memoryUsed; + long memoryTotal; + + /* Flushed state */ + LWLock flushLock; + bool flushed; +} HnswGraph; + +typedef struct HnswShared +{ + /* Immutable state */ + Oid heaprelid; + Oid indexrelid; + + /* Mutex for mutable state */ + slock_t mutex; + + /* Mutable state */ + int nparticipantsdone; + double reltuples; + HnswGraph graphData; + + char *hnswarea; + ParallelHeapScanDescData heapdesc; +} HnswShared; + +typedef struct HnswLeader +{ + int nparticipanttuplesorts; + HnswShared *hnswshared; +} HnswLeader; + +typedef struct HnswAllocator +{ + void *(*alloc) (Size size, void *state); + void *state; +} HnswAllocator; + +typedef struct HnswTypeInfo +{ + int maxDimensions; + Datum (*normalize) (PG_FUNCTION_ARGS); + void (*checkValue) (Pointer v); +} HnswTypeInfo; + +typedef struct HnswBuildState +{ + /* Info */ + Relation heap; + Relation index; + IndexInfo *indexInfo; + ForkNumber forkNum; + const HnswTypeInfo *typeInfo; + + /* Settings */ + int dimensions; + int m; + int efConstruction; + + /* Statistics */ + double indtuples; + double reltuples; + + /* Support functions */ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + + /* Variables */ + HnswGraph graphData; + HnswGraph *graph; + double ml; + int maxLevel; + + /* Memory */ + MemoryContext graphCtx; + MemoryContext tmpCtx; + HnswAllocator allocator; + + /* Parallel builds */ + HnswLeader *hnswleader; + HnswShared *hnswshared; + char *hnswarea; + + /* PQ info */ + bool enablePQ; + int pqM; + int pqKsub; + float *pqTable; + float *centerTable; + uint16 pqcodeSize; + + /* storage page info */ + bool isUStore; /* false means astore */ +} HnswBuildState; + +typedef struct HnswMetaPageData +{ + uint32 magicNumber; + uint32 version; + uint32 dimensions; + uint16 m; + uint16 efConstruction; + BlockNumber entryBlkno; + OffsetNumber entryOffno; + int16 entryLevel; + BlockNumber insertPage; +} HnswMetaPageData; + +typedef HnswMetaPageData * HnswMetaPage; + +typedef struct HnswAppendMetaPageData +{ + uint32 magicNumber; + uint32 version; + uint32 dimensions; + uint16 m; + uint16 efConstruction; + BlockNumber entryBlkno; + OffsetNumber entryOffno; + int16 entryLevel; + + /* PQ info */ + bool enablePQ; + uint16 pqM; /* number of subquantizer */ + uint16 pqKsub; /* number of centroids for each subquantizer */ + uint16 pqcodeSize; /* number of bits per quantization index */ + uint32 centerTableSize; /* dim * sizeof(float) */ + uint32 pqTableSize; /* dim * pqKsub * sizeof(float) */ + uint16 pqTableNblk; /* total number of blks pqtable */ + + /* slot info */ + int npages; /* number of pages per slot */ + BlockNumber slotStartBlkno; + BlockNumber elementInsertSlot; /* the first page of the element type to be inserted into the slot */ + BlockNumber neighborInsertSlot; /* the first page of the neighbor type to be inserted into the slot */ +} HnswAppendMetaPageData; + +typedef HnswAppendMetaPageData *HnswAppendMetaPage; + +typedef struct HnswPageOpaqueData +{ + BlockNumber nextblkno; + uint8 pageType; /* element or neighbor page */ + uint8 unused; + uint16 page_id; /* for identification of HNSW indexes */ +} HnswPageOpaqueData; + +typedef HnswPageOpaqueData * HnswPageOpaque; + +typedef struct HnswElementTupleData +{ + uint8 type; + uint8 level; + uint8 deleted; + uint8 unused; + ItemPointerData heaptids[HNSW_HEAPTIDS]; + ItemPointerData neighbortid; + uint16 unused2; + Vector data; +} HnswElementTupleData; + +typedef HnswElementTupleData * HnswElementTuple; + +typedef struct HnswNeighborTupleData +{ + uint8 type; + uint8 unused; + uint16 count; + ItemPointerData indextids[FLEXIBLE_ARRAY_MEMBER]; +} HnswNeighborTupleData; + +typedef HnswNeighborTupleData * HnswNeighborTuple; + +typedef struct HnswScanOpaqueData +{ + const HnswTypeInfo *typeInfo; + bool first; + List *w; + MemoryContext tmpCtx; + + /* Support functions */ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + + /* used in ustore only */ + VectorScanData vs; +} HnswScanOpaqueData; + +typedef HnswScanOpaqueData * HnswScanOpaque; + +typedef struct HnswVacuumState +{ + /* Info */ + Relation index; + IndexBulkDeleteResult *stats; + IndexBulkDeleteCallback callback; + void *callback_state; + + /* Settings */ + int m; + int efConstruction; + + /* Support functions */ + FmgrInfo *procinfo; + Oid collation; + + /* Variables */ + struct tidhash_hash *deleted; + BufferAccessStrategy bas; + HnswNeighborTuple ntup; + HnswElementData highestPoint; + + /* Memory */ + MemoryContext tmpCtx; +} HnswVacuumState; + +/* Methods */ +int HnswGetM(Relation index); +int HnswGetEfConstruction(Relation index); +bool HnswGetEnablePQ(Relation index); +int HnswGetPqM(Relation index); +int HnswGetPqKsub(Relation index); +FmgrInfo *HnswOptionalProcInfo(Relation index, uint16 procnum); +Datum HnswNormValue(const HnswTypeInfo * typeInfo, Oid collation, Datum value); +bool HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value); +Buffer HnswNewBuffer(Relation index, ForkNumber forkNum); +void HnswInitPage(Buffer buf, Page page); +void HnswInit(void); +List *HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *procinfo, + Oid collation, int m, bool inserting, HnswElement skipElement, IndexScanDesc scan = NULL); +HnswElement HnswGetEntryPoint(Relation index); +void HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint); +void *HnswAlloc(HnswAllocator * allocator, Size size); +HnswElement HnswInitElement(char *base, ItemPointer tid, int m, double ml, int maxLevel, HnswAllocator * alloc); +HnswElement HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno); +void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing); +HnswCandidate *HnswEntryCandidate(char *base, HnswElement em, Datum q, Relation rel, FmgrInfo *procinfo, + Oid collation, bool loadVec, IndexScanDesc scan = NULL); +void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum, bool building); +void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m); +void HnswAddHeapTid(HnswElement element, ItemPointer heaptid); +void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * alloc); +bool HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *isnull, ItemPointer heap_tid, bool building); +void HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting, bool building); +void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec); +bool HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, + Oid collation, bool loadVec, float *maxDistance, IndexScanDesc scan = NULL); +void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element); +void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation); +void HnswLoadNeighbors(HnswElement element, Relation index, int m); +const HnswTypeInfo *HnswGetTypeInfo(Relation index); +bool HnswDelete(Relation index, Datum* values, const bool* isnull, ItemPointer heapTCtid, bool isRollbackIndex); + +Datum hnswhandler(PG_FUNCTION_ARGS); +Datum hnswbuild(PG_FUNCTION_ARGS); +Datum hnswbuildempty(PG_FUNCTION_ARGS); +Datum hnswinsert(PG_FUNCTION_ARGS); +Datum hnswbulkdelete(PG_FUNCTION_ARGS); +Datum hnswvacuumcleanup(PG_FUNCTION_ARGS); +Datum hnswcostestimate(PG_FUNCTION_ARGS); +Datum hnswoptions(PG_FUNCTION_ARGS); +Datum hnswvalidate(PG_FUNCTION_ARGS); +Datum hnswbeginscan(PG_FUNCTION_ARGS); +Datum hnswrescan(PG_FUNCTION_ARGS); +Datum hnswgettuple(PG_FUNCTION_ARGS); +Datum hnswendscan(PG_FUNCTION_ARGS); +Datum hnswdelete(PG_FUNCTION_ARGS); +Datum hnsw_halfvec_support(PG_FUNCTION_ARGS); +Datum hnsw_bit_support(PG_FUNCTION_ARGS); +Datum hnsw_sparsevec_support(PG_FUNCTION_ARGS); + +/* Index access methods */ +IndexBuildResult *hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo); +void hnswbuildempty_internal(Relation index); +bool hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique); +IndexBulkDeleteResult *hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state); +IndexBulkDeleteResult *hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); +IndexScanDesc hnswbeginscan_internal(Relation index, int nkeys, int norderbys); +void hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); +bool hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir); +void hnswendscan_internal(IndexScanDesc scan); +bool hnswdelete_internal(Relation index, Datum* values, const bool* isnull, ItemPointer heapTCtid, + bool isRollbackIndex); + +static inline HnswNeighborArray * +HnswGetNeighbors(char *base, HnswElement element, int lc) +{ + HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *)HnswPtrAccess(base, element->neighbors); + + Assert(element->level >= lc); + + return (HnswNeighborArray *)HnswPtrAccess(base, neighborList[lc]); +} + +/* Hash tables */ +typedef struct TidHashEntry +{ + ItemPointerData tid; + char status; +} TidHashEntry; + +#define SH_PREFIX tidhash +#define SH_ELEMENT_TYPE TidHashEntry +#define SH_KEY_TYPE ItemPointerData +#define SH_SCOPE extern +#define SH_DECLARE +#include "lib/simplehash.h" + +typedef struct PointerHashEntry +{ + uintptr_t ptr; + char status; +} PointerHashEntry; + +#define SH_PREFIX pointerhash +#define SH_ELEMENT_TYPE PointerHashEntry +#define SH_KEY_TYPE uintptr_t +#define SH_SCOPE extern +#define SH_DECLARE +#include "lib/simplehash.h" + +typedef struct OffsetHashEntry +{ + Size offset; + char status; +} OffsetHashEntry; + +#define SH_PREFIX offsethash +#define SH_ELEMENT_TYPE OffsetHashEntry +#define SH_KEY_TYPE Size +#define SH_SCOPE extern +#define SH_DECLARE +#include "lib/simplehash.h" + +#endif diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h new file mode 100644 index 0000000000..492524971d --- /dev/null +++ b/src/include/access/datavec/ivfflat.h @@ -0,0 +1,330 @@ +#ifndef IVFFLAT_H +#define IVFFLAT_H + +#include "postgres.h" + +#include "access/genam.h" +#include "access/generic_xlog.h" +#include "catalog/pg_operator.h" +#include "lib/pairingheap.h" +#include "nodes/execnodes.h" +#include "port.h" /* for random() */ +#include "sampling.h" +#include "utils/tuplesort.h" +#include "access/datavec/vector.h" +#include "postmaster/bgworker.h" + +#if PG_VERSION_NUM >= 150000 +#include "common/pg_prng.h" +#endif + +#ifdef IVFFLAT_BENCH +#include "portability/instr_time.h" +#endif + +#define IVFFLAT_MAX_DIM 2000 + +/* Support functions */ +#define IVFFLAT_DISTANCE_PROC 1 +#define IVFFLAT_NORM_PROC 2 +#define IVFFLAT_KMEANS_DISTANCE_PROC 3 +#define IVFFLAT_KMEANS_NORM_PROC 4 +#define IVFFLAT_TYPE_INFO_PROC 5 + +#define IVFFLAT_VERSION 1 +#define IVFFLAT_MAGIC_NUMBER 0x14FF1A7 +#define IVFFLAT_PAGE_ID 0xFF84 + +/* Preserved page numbers */ +#define IVFFLAT_METAPAGE_BLKNO 0 +#define IVFFLAT_HEAD_BLKNO 1 /* first list page */ + +/* IVFFlat parameters */ +#define IVFFLAT_DEFAULT_LISTS 100 +#define IVFFLAT_MIN_LISTS 1 +#define IVFFLAT_MAX_LISTS 32768 +#define IVFFLAT_DEFAULT_PROBES 1 + +/* Build phases */ +/* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 */ +#define PROGRESS_IVFFLAT_PHASE_KMEANS 2 +#define PROGRESS_IVFFLAT_PHASE_ASSIGN 3 +#define PROGRESS_IVFFLAT_PHASE_LOAD 4 + +#define IVFFLAT_LIST_SIZE(size) (offsetof(IvfflatListData, center) + size) + +#define IvfflatPageGetOpaque(page) ((IvfflatPageOpaque) PageGetSpecialPointer(page)) +#define IvfflatPageGetMeta(page) ((IvfflatMetaPageData *) PageGetContents(page)) + +#ifdef IVFFLAT_BENCH +#define IvfflatBench(name, code) \ + do { \ + instr_time start; \ + instr_time duration; \ + INSTR_TIME_SET_CURRENT(start); \ + (code); \ + INSTR_TIME_SET_CURRENT(duration); \ + INSTR_TIME_SUBTRACT(duration, start); \ + elog(INFO, "%s: %.3f ms", name, INSTR_TIME_GET_MILLISEC(duration)); \ + } while (0) +#else +#define IvfflatBench(name, code) (code) +#endif + +#if PG_VERSION_NUM >= 150000 +#define RandomDouble() pg_prng_double(&pg_global_prng_state) +#define RandomInt() pg_prng_uint32(&pg_global_prng_state) +#else +#define RandomDouble() (((double) random()) / MAX_RANDOM_VALUE) +#define RandomInt() random() +#endif + +typedef struct VectorArrayData +{ + int length; + int maxlen; + int dim; + Size itemsize; + char *items; +} VectorArrayData; + +typedef VectorArrayData * VectorArray; + +typedef struct ListInfo +{ + BlockNumber blkno; + OffsetNumber offno; +} ListInfo; + +/* IVFFlat index options */ +typedef struct IvfflatOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int lists; /* number of lists */ +} IvfflatOptions; + +typedef struct IvfflatSpool +{ + Tuplesortstate *sortstate; + Relation heap; + Relation index; +} IvfflatSpool; + +typedef struct IvfflatShared +{ + /* Immutable state */ + Oid heaprelid; + Oid indexrelid; + int scantuplesortstates; + + /* Mutex for mutable state */ + slock_t mutex; + + /* Mutable state */ + int nparticipantsdone; + double reltuples; + double indtuples; + + Sharedsort *sharedsort; + Vector *ivfcenters; + int workmem; + +#ifdef IVFFLAT_KMEANS_DEBUG + double inertia; +#endif + ParallelHeapScanDescData heapdesc; // must come last +} IvfflatShared; + +#define ParallelTableScanFromIvfflatShared(shared) \ + (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(IvfflatShared))) + +typedef struct IvfflatLeader +{ + int nparticipanttuplesorts; + IvfflatShared *ivfshared; +} IvfflatLeader; + +typedef struct IvfflatTypeInfo +{ + int maxDimensions; + Datum (*normalize) (PG_FUNCTION_ARGS); + Size (*itemSize) (int dimensions); + void (*updateCenter) (Pointer v, int dimensions, float *x); + void (*sumCenter) (Pointer v, float *x); +} IvfflatTypeInfo; + +typedef struct IvfflatBuildState +{ + /* Info */ + Relation heap; + Relation index; + IndexInfo *indexInfo; + const IvfflatTypeInfo *typeInfo; + + /* Settings */ + int dimensions; + int lists; + + /* Statistics */ + double indtuples; + double reltuples; + + /* Support functions */ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + FmgrInfo *kmeansnormprocinfo; + Oid collation; + + /* Variables */ + VectorArray samples; + VectorArray centers; + ListInfo *listInfo; + +#ifdef IVFFLAT_KMEANS_DEBUG + double inertia; + double *listSums; + int *listCounts; +#endif + + /* Sampling */ + BlockSamplerData bs; + double rstate; + int rowstoskip; + + /* Sorting */ + Tuplesortstate *sortstate; + TupleDesc tupdesc; + TupleTableSlot *slot; + + /* Memory */ + MemoryContext tmpCtx; + + /* Parallel builds */ + IvfflatLeader *ivfleader; + +} IvfflatBuildState; + +typedef struct IvfflatMetaPageData +{ + uint32 magicNumber; + uint32 version; + uint16 dimensions; + uint16 lists; +} IvfflatMetaPageData; + +typedef IvfflatMetaPageData * IvfflatMetaPage; + +typedef struct IvfflatPageOpaqueData +{ + BlockNumber nextblkno; + uint16 unused; + uint16 page_id; /* for identification of IVFFlat indexes */ +} IvfflatPageOpaqueData; + +typedef IvfflatPageOpaqueData * IvfflatPageOpaque; + +typedef struct IvfflatListData +{ + BlockNumber startPage; + BlockNumber insertPage; + Vector center; +} IvfflatListData; + +typedef IvfflatListData * IvfflatList; + +typedef struct IvfflatScanList +{ + pairingheap_node ph_node; + BlockNumber startPage; + double distance; +} IvfflatScanList; + +typedef struct IvfflatScanOpaqueData +{ + const IvfflatTypeInfo *typeInfo; + int probes; + int dimensions; + bool first; + + /* Sorting */ + Tuplesortstate *sortstate; + TupleDesc tupdesc; + TupleTableSlot *slot; + bool isnull; + + /* Support functions */ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + Datum (*distfunc) (FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2); + + /* Lists */ + pairingheap *listQueue; + IvfflatScanList lists[FLEXIBLE_ARRAY_MEMBER]; /* must come last */ +} IvfflatScanOpaqueData; + +typedef IvfflatScanOpaqueData * IvfflatScanOpaque; + +#define VECTOR_ARRAY_SIZE(_length, _size) (sizeof(VectorArrayData) + (_length) * MAXALIGN(_size)) + +/* Use functions instead of macros to avoid double evaluation */ + +static inline Pointer +VectorArrayGet(VectorArray arr, int offset) +{ + return ((char *) arr->items) + (offset * arr->itemsize); +} + +static inline void +VectorArraySet(VectorArray arr, int offset, Pointer val) +{ + memcpy(VectorArrayGet(arr, offset), val, VARSIZE_ANY(val)); +} + +/* Methods */ +VectorArray VectorArrayInit(int maxlen, int dimensions, Size itemsize); +void VectorArrayFree(VectorArray arr); +void IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo); +FmgrInfo *IvfflatOptionalProcInfo(Relation index, uint16 procnum); +Datum IvfflatNormValue(const IvfflatTypeInfo * typeInfo, Oid collation, Datum value); +bool IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value); +int IvfflatGetLists(Relation index); +void IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions); +void IvfflatUpdateList(Relation index, ListInfo listInfo, BlockNumber insertPage, BlockNumber originalInsertPage, BlockNumber startPage, ForkNumber forkNum); +void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state); +void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum); +Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum); +void IvfflatInitPage(Buffer buf, Page page); +void IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state); +PGDLLEXPORT void IvfflatParallelBuildMain(const BgWorkerContext *bwc); +void IvfflatInit(void); +const IvfflatTypeInfo *IvfflatGetTypeInfo(Relation index); + +Datum ivfflathandler(PG_FUNCTION_ARGS); +Datum ivfflatbuild(PG_FUNCTION_ARGS); +Datum ivfflatbuildempty(PG_FUNCTION_ARGS); +Datum ivfflatinsert(PG_FUNCTION_ARGS); +Datum ivfflatbulkdelete(PG_FUNCTION_ARGS); +Datum ivfflatvacuumcleanup(PG_FUNCTION_ARGS); +Datum ivfflatcostestimate(PG_FUNCTION_ARGS); +Datum ivfflatoptions(PG_FUNCTION_ARGS); +Datum ivfflatvalidate(PG_FUNCTION_ARGS); +Datum ivfflatbeginscan(PG_FUNCTION_ARGS); +Datum ivfflatrescan(PG_FUNCTION_ARGS); +Datum ivfflatgettuple(PG_FUNCTION_ARGS); +Datum ivfflatendscan(PG_FUNCTION_ARGS); +Datum ivfflat_halfvec_support(PG_FUNCTION_ARGS); +Datum ivfflat_bit_support(PG_FUNCTION_ARGS); + +/* Index access methods */ +IndexBuildResult *ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo); +void ivfflatbuildempty_internal(Relation index); +bool ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique); +IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state); +IndexBulkDeleteResult *ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); +IndexScanDesc ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys); +void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); +bool ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir); +void ivfflatendscan_internal(IndexScanDesc scan); + +#endif diff --git a/src/include/access/datavec/pg_prng.h b/src/include/access/datavec/pg_prng.h new file mode 100644 index 0000000000..e201b95686 --- /dev/null +++ b/src/include/access/datavec/pg_prng.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------- + * + * Pseudo-Random Number Generator + * + * Copyright (c) 2021-2024, PostgreSQL Global Development Group + * + * src/include/common/pg_prng.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_PRNG_H +#define PG_PRNG_H + +/* + * State vector for PRNG generation. Callers should treat this as an + * opaque typedef, but we expose its definition to allow it to be + * embedded in other structs. + */ +typedef struct pg_prng_state +{ + uint64 s0, + s1; +} pg_prng_state; + +/* + * Callers not needing local PRNG series may use this global state vector, + * after initializing it with one of the pg_prng_...seed functions. + */ +extern PGDLLIMPORT pg_prng_state pg_global_prng_state; + +extern void pg_prng_seed(pg_prng_state *state, uint64 seed); +extern void pg_prng_fseed(pg_prng_state *state, double fseed); +extern bool pg_prng_seed_check(pg_prng_state *state); + +/* + * Initialize the PRNG state from the pg_strong_random source, + * taking care that we don't produce all-zeroes. If this returns false, + * caller should initialize the PRNG state from some other random seed, + * using pg_prng_[f]seed. + * + * We implement this as a macro, so that the pg_strong_random() call is + * in the caller. If it were in pg_prng.c, programs using pg_prng.c + * but not needing strong seeding would nonetheless be forced to pull in + * pg_strong_random.c and thence OpenSSL. + */ +#define pg_prng_strong_seed(state) \ + (pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \ + pg_prng_seed_check(state) : false) + +extern uint64 pg_prng_uint64(pg_prng_state *state); +extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax); +extern int64 pg_prng_int64(pg_prng_state *state); +extern int64 pg_prng_int64p(pg_prng_state *state); +extern uint32 pg_prng_uint32(pg_prng_state *state); +extern int32 pg_prng_int32(pg_prng_state *state); +extern int32 pg_prng_int32p(pg_prng_state *state); +extern double pg_prng_double(pg_prng_state *state); +extern double pg_prng_double_normal(pg_prng_state *state); +extern bool pg_prng_bool(pg_prng_state *state); + +#endif /* PG_PRNG_H */ diff --git a/src/include/access/datavec/ryu_common.h b/src/include/access/datavec/ryu_common.h new file mode 100644 index 0000000000..69aa7ac125 --- /dev/null +++ b/src/include/access/datavec/ryu_common.h @@ -0,0 +1,150 @@ +/*--------------------------------------------------------------------------- + * + * Common routines for Ryu floating-point output. + * + * Portions Copyright (c) 2018-2024, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/ryu_common.h + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ +#ifndef RYU_COMMON_H +#define RYU_COMMON_H + +/* + * Upstream Ryu's output is always the shortest possible. But we adjust that + * slightly to improve portability: we avoid outputting the exact midpoint + * value between two representable floats, since that relies on the reader + * getting the round-to-even rule correct, which seems to be the common + * failure mode. + * + * Defining this to 1 would restore the upstream behavior. + */ +#define STRICTLY_SHORTEST 0 + +#if SIZEOF_SIZE_T < 8 +#define RYU_32_BIT_PLATFORM +#endif + +/* + * A table of all two-digit numbers. This is used to speed up decimal digit + * generation by copying pairs of digits into the final output. + */ +static const char DIGIT_TABLE[200] = { + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', + '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', + '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', + '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', + '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', + '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', + '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', + '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', + '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', + '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9' +}; + +/* Returns e == 0 ? 1 : ceil(log_2(5^e)). */ +static inline uint32 +pow5bits(const int32 e) +{ + /* + * This approximation works up to the point that the multiplication + * overflows at e = 3529. + * + * If the multiplication were done in 64 bits, it would fail at 5^4004 + * which is just greater than 2^9297. + */ + Assert(e >= 0); + Assert(e <= 3528); + return ((((uint32) e) * 1217359) >> 19) + 1; +} + +/* Returns floor(log_10(2^e)). */ +static inline int32 +log10Pow2(const int32 e) +{ + /* + * The first value this approximation fails for is 2^1651 which is just + * greater than 10^297. + */ + Assert(e >= 0); + Assert(e <= 1650); + return (int32) ((((uint32) e) * 78913) >> 18); +} + +/* Returns floor(log_10(5^e)). */ +static inline int32 +log10Pow5(const int32 e) +{ + /* + * The first value this approximation fails for is 5^2621 which is just + * greater than 10^1832. + */ + Assert(e >= 0); + Assert(e <= 2620); + return (int32) ((((uint32) e) * 732923) >> 20); +} + +static inline int +copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) +{ + if (mantissa) + { + memcpy(result, "NaN", 3); + return 3; + } + if (sign) + { + result[0] = '-'; + } + if (exponent) + { + memcpy(result + sign, "Infinity", 8); + return sign + 8; + } + result[sign] = '0'; + return sign + 1; +} + +static inline uint32 +float_to_bits(const float f) +{ + uint32 bits = 0; + + memcpy(&bits, &f, sizeof(float)); + return bits; +} + +static inline uint64 +double_to_bits(const double d) +{ + uint64 bits = 0; + + memcpy(&bits, &d, sizeof(double)); + return bits; +} + +#endif /* RYU_COMMON_H */ diff --git a/src/include/access/datavec/sampling.h b/src/include/access/datavec/sampling.h new file mode 100644 index 0000000000..13934f4083 --- /dev/null +++ b/src/include/access/datavec/sampling.h @@ -0,0 +1,45 @@ +#ifndef SAMPLING_H +#define SAMPLING_H + +#include "access/datavec/pg_prng.h" +#include "storage/buf/block.h" /* for typedef BlockNumber */ + + +/* Random generator for sampling code */ +extern void sampler_random_init_state(uint32 seed, + pg_prng_state *randstate); +extern double sampler_random_fract(pg_prng_state *randstate); + +/* Block sampling methods */ + +/* Data structure for Algorithm S from Knuth 3.4.2 */ +typedef struct +{ + BlockNumber N; /* number of blocks, known in advance */ + uint32 n; /* desired sample size */ + BlockNumber t; /* current block number */ + uint32 m; /* blocks selected so far */ + pg_prng_state randstate; /* random generator state */ +} BlockSamplerData2; + +typedef BlockSamplerData2 *BlockSampler2; + +extern BlockNumber BlockSampler_Init2(BlockSampler2 bs, BlockNumber nblocks, + int samplesize, uint32 randseed); +extern bool BlockSampler_HasMore2(BlockSampler2 bs); +extern BlockNumber BlockSampler_Next2(BlockSampler2 bs); + +/* Reservoir sampling methods */ + +typedef struct +{ + double W; + pg_prng_state randstate; /* random generator state */ +} ReservoirStateData; + +typedef ReservoirStateData *ReservoirState; + +extern void reservoir_init_selection_state(ReservoirState rs, int n); +extern double reservoir_get_next_S(ReservoirState rs, double t, int n); + +#endif /* SAMPLING_H */ diff --git a/src/include/access/datavec/shortest_dec.h b/src/include/access/datavec/shortest_dec.h new file mode 100644 index 0000000000..91d9aa5c94 --- /dev/null +++ b/src/include/access/datavec/shortest_dec.h @@ -0,0 +1,9 @@ +#ifndef SHORTEST_DEC_H +#define SHORTEST_DEC_H + +#define FLOAT_SHORTEST_DECIMAL_LEN 16 + +int float_to_shortest_decimal_bufn(float f, char *result); +int float_to_shortest_decimal_buf(float f, char *result); + +#endif /* SHORTEST_DEC_H */ diff --git a/src/include/access/datavec/sparsevec.h b/src/include/access/datavec/sparsevec.h new file mode 100644 index 0000000000..1fcf4e2522 --- /dev/null +++ b/src/include/access/datavec/sparsevec.h @@ -0,0 +1,67 @@ +#ifndef SPARSEVEC_H +#define SPARSEVEC_H + +#define SPARSEVEC_MAX_DIM 1000000000 +#define SPARSEVEC_MAX_NNZ 16000 + +#define DatumGetSparseVector(x) ((SparseVector *) PG_DETOAST_DATUM(x)) +#define PG_GETARG_SPARSEVEC_P(x) DatumGetSparseVector(PG_GETARG_DATUM(x)) +#define PG_RETURN_SPARSEVEC_P(x) PG_RETURN_POINTER(x) + +/* + * Indices use 0-based numbering for the on-disk (and binary) format (consistent with C) + * and are always sorted. Values come after indices. + */ + +Datum sparsevec_in(PG_FUNCTION_ARGS); +Datum sparsevec_out(PG_FUNCTION_ARGS); +Datum sparsevec_typmod_in(PG_FUNCTION_ARGS); +Datum sparsevec_recv(PG_FUNCTION_ARGS); +Datum sparsevec_send(PG_FUNCTION_ARGS); +Datum sparsevec_l2_distance(PG_FUNCTION_ARGS); +Datum sparsevec_inner_product(PG_FUNCTION_ARGS); +Datum sparsevec_cosine_distance(PG_FUNCTION_ARGS); +Datum sparsevec_l1_distance(PG_FUNCTION_ARGS); +Datum sparsevec_l2_norm(PG_FUNCTION_ARGS); +Datum sparsevec_l2_normalize(PG_FUNCTION_ARGS); +Datum sparsevec_lt(PG_FUNCTION_ARGS); +Datum sparsevec_le(PG_FUNCTION_ARGS); +Datum sparsevec_eq(PG_FUNCTION_ARGS); +Datum sparsevec_ne(PG_FUNCTION_ARGS); +Datum sparsevec_ge(PG_FUNCTION_ARGS); +Datum sparsevec_gt(PG_FUNCTION_ARGS); +Datum sparsevec_cmp(PG_FUNCTION_ARGS); +Datum sparsevec_l2_squared_distance(PG_FUNCTION_ARGS); +Datum sparsevec_negative_inner_product(PG_FUNCTION_ARGS); +Datum sparsevec(PG_FUNCTION_ARGS); +Datum vector_to_sparsevec(PG_FUNCTION_ARGS); +Datum sparsevec_to_vector(PG_FUNCTION_ARGS); +Datum halfvec_to_sparsevec(PG_FUNCTION_ARGS); +Datum sparsevec_to_halfvec(PG_FUNCTION_ARGS); + +typedef struct SparseVector +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 dim; /* number of dimensions */ + int32 nnz; /* number of non-zero elements */ + int32 unused; /* reserved for future use, always zero */ + int32 indices[FLEXIBLE_ARRAY_MEMBER]; +} SparseVector; + +/* Use functions instead of macros to avoid double evaluation */ + +static inline Size +SPARSEVEC_SIZE(int nnz) +{ + return offsetof(SparseVector, indices) + (nnz * sizeof(int32)) + (nnz * sizeof(float)); +} + +static inline float * +SPARSEVEC_VALUES(SparseVector * x) +{ + return (float *) (((char *) x) + offsetof(SparseVector, indices) + (x->nnz * sizeof(int32))); +} + +SparseVector *InitSparseVector(int dim, int nnz); + +#endif diff --git a/src/include/access/datavec/vecindex.h b/src/include/access/datavec/vecindex.h new file mode 100644 index 0000000000..410d1d4878 --- /dev/null +++ b/src/include/access/datavec/vecindex.h @@ -0,0 +1,23 @@ +#ifndef VECINDEX_H +#define VECINDEX_H + +#define MIN(A, B) ((B) < (A) ? (B) : (A)) +#define MAX(A, B) ((B) > (A) ? (B) : (A)) + +#define VecIndexTupleGetXid(itup) (((char*)(itup)) + HNSW_ELEMENT_TUPLE_SIZE(VARSIZE_ANY(&(itup)->data))) + +struct VectorScanData { + /* + * used in ustore only, indicate the last returned index tuple which is modified + * by current transaction. see VecVisibilityCheckCid() for more information. + */ + char *lastSelfModifiedItup; + uint16 lastSelfModifiedItupBufferSize; + Buffer buf; +}; + +bool VecItupGetXminXmax(Page page, OffsetNumber offnum, TransactionId oldest_xmin, TransactionId *xmin, + TransactionId *xmax, bool *xminCommitted, bool *xmaxCommitted, bool isToast); +bool VecVisibilityCheck(IndexScanDesc scan, Page page, OffsetNumber offnum, bool *needRecheck); + +#endif //VECINDEX_H diff --git a/src/include/access/datavec/vector.h b/src/include/access/datavec/vector.h new file mode 100644 index 0000000000..6fce5cb71c --- /dev/null +++ b/src/include/access/datavec/vector.h @@ -0,0 +1,72 @@ +#ifndef VECTOR_H +#define VECTOR_H + +#define VECTOR_MAX_DIM 16000 +#define MEM_INFO_NUM (1024 * 1024) + +#define VECTOR_SIZE(_dim) (offsetof(Vector, x) + sizeof(float)*(_dim)) +#define DatumGetVector(x) ((Vector *) PG_DETOAST_DATUM(x)) +#define PG_GETARG_VECTOR_P(x) DatumGetVector(PG_GETARG_DATUM(x)) +#define PG_RETURN_VECTOR_P(x) PG_RETURN_POINTER(x) +#define UpdateProgress(index, val) ((void)val) + +typedef struct Vector +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int16 dim; /* number of dimensions */ + int16 unused; /* reserved for future use, always zero */ + float x[FLEXIBLE_ARRAY_MEMBER]; +} Vector; + +Vector *InitVector(int dim); +void PrintVector(char *msg, Vector * vector); +int vector_cmp_internal(Vector * a, Vector * b); +void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std); +int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo); + +Datum vector_in(PG_FUNCTION_ARGS); +Datum vector_out(PG_FUNCTION_ARGS); +Datum vector_typmod_in(PG_FUNCTION_ARGS); +Datum vector_recv(PG_FUNCTION_ARGS); +Datum vector_send(PG_FUNCTION_ARGS); +Datum vector(PG_FUNCTION_ARGS); +Datum array_to_vector(PG_FUNCTION_ARGS); +Datum vector_to_float4(PG_FUNCTION_ARGS); +Datum l2_distance(PG_FUNCTION_ARGS); +Datum vector_l2_squared_distance(PG_FUNCTION_ARGS); +Datum inner_product(PG_FUNCTION_ARGS); +Datum vector_negative_inner_product(PG_FUNCTION_ARGS); +Datum cosine_distance(PG_FUNCTION_ARGS); +Datum vector_spherical_distance(PG_FUNCTION_ARGS); +Datum vector_dims(PG_FUNCTION_ARGS); +Datum vector_norm(PG_FUNCTION_ARGS); +Datum vector_add(PG_FUNCTION_ARGS); +Datum vector_sub(PG_FUNCTION_ARGS); +Datum vector_le(PG_FUNCTION_ARGS); +Datum vector_lt(PG_FUNCTION_ARGS); +Datum vector_eq(PG_FUNCTION_ARGS); +Datum vector_ne(PG_FUNCTION_ARGS); +Datum vector_ge(PG_FUNCTION_ARGS); +Datum vector_gt(PG_FUNCTION_ARGS); +Datum vector_cmp(PG_FUNCTION_ARGS); +Datum vector_accum(PG_FUNCTION_ARGS); +Datum vector_combine(PG_FUNCTION_ARGS); +Datum vector_avg(PG_FUNCTION_ARGS); +Datum l1_distance(PG_FUNCTION_ARGS); +Datum l2_normalize(PG_FUNCTION_ARGS); +Datum binary_quantize(PG_FUNCTION_ARGS); +Datum subvector(PG_FUNCTION_ARGS); +Datum vector_mul(PG_FUNCTION_ARGS); +Datum vector_concat(PG_FUNCTION_ARGS); +void set_extension_index(uint32 index); +void init_session_vars(void); + +typedef struct datavec_session_context { + int hnsw_ef_search; + int ivfflat_probes; +} datavec_session_context; + +extern uint32 datavec_index; +extern datavec_session_context* get_session_context(); + +#endif -- Gitee From 5b9d5b1a44cd87ad8841b95617c8f4d770b40def Mon Sep 17 00:00:00 2001 From: h30054849 Date: Thu, 31 Oct 2024 11:05:58 +0800 Subject: [PATCH 02/67] =?UTF-8?q?datavec=E8=BF=81=E7=A7=BBopenGauss?= =?UTF-8?q?=E5=86=85=E6=A0=B8=EF=BC=9Acmake+make+index=5Fop+type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/utils/adt/Makefile | 2 +- src/gausskernel/CMakeLists.txt | 1 + src/gausskernel/storage/access/CMakeLists.txt | 4 ++- src/gausskernel/storage/access/Makefile | 2 +- .../storage/access/datavec/Makefile | 16 ++++++++++ src/include/catalog/pg_opfamily.h | 32 +++++++++++++++++++ src/include/catalog/pg_type.h | 10 ++++++ 7 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 src/gausskernel/storage/access/datavec/Makefile diff --git a/src/common/backend/utils/adt/Makefile b/src/common/backend/utils/adt/Makefile index 8875214f15..58a9f99dc9 100644 --- a/src/common/backend/utils/adt/Makefile +++ b/src/common/backend/utils/adt/Makefile @@ -40,7 +40,7 @@ OBJS = acl.o arrayfuncs.o array_selfuncs.o array_typanalyze.o \ tsvector.o tsvector_op.o tsvector_parser.o \ txid.o uuid.o windowfuncs.o xml.o extended_statistics.o clientlogic_bytea.o clientlogicsettings.o \ median_aggs.o expr_distinct.o nlssort.o memory_func.o first_last_agg.o encrypt_decrypt.o expandeddatum.o \ - subtype.o + subtype.o bitvec.o f2s.o halfutils.o halfvec.o sparsevec.o vector.o like.o: like.cpp like_match.cpp diff --git a/src/gausskernel/CMakeLists.txt b/src/gausskernel/CMakeLists.txt index 3774f8e9b7..62208ea794 100755 --- a/src/gausskernel/CMakeLists.txt +++ b/src/gausskernel/CMakeLists.txt @@ -213,6 +213,7 @@ list(APPEND gaussdb_objects $ $ $ + $ $ $ $ diff --git a/src/gausskernel/storage/access/CMakeLists.txt b/src/gausskernel/storage/access/CMakeLists.txt index 6e9ab44f95..6f3f78929d 100755 --- a/src/gausskernel/storage/access/CMakeLists.txt +++ b/src/gausskernel/storage/access/CMakeLists.txt @@ -22,7 +22,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/table ${CMAKE_CURRENT_SOURCE_DIR}/transam ${CMAKE_CURRENT_SOURCE_DIR}/ubtree - ${CMAKE_CURRENT_SOURCE_DIR}/ustore + ${CMAKE_CURRENT_SOURCE_DIR}/ustore + ${CMAKE_CURRENT_SOURCE_DIR}/datavec ) if(NOT "${ENABLE_LITE_MODE}" STREQUAL "ON") @@ -50,3 +51,4 @@ add_subdirectory(table) add_subdirectory(transam) add_subdirectory(ubtree) add_subdirectory(ustore) +add_subdirectory(datavec) diff --git a/src/gausskernel/storage/access/Makefile b/src/gausskernel/storage/access/Makefile index 52c39249cb..fe5b2c81d4 100644 --- a/src/gausskernel/storage/access/Makefile +++ b/src/gausskernel/storage/access/Makefile @@ -2,7 +2,7 @@ subdir = src/gausskernel/storage/access top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -SUBDIRS = cbtree common heap index nbtree ubtree psort rmgrdesc transam obs hash spgist gist gin hbstore redo table ustore +SUBDIRS = cbtree common heap index nbtree ubtree psort rmgrdesc transam obs hash spgist gist gin hbstore redo table ustore datavec ifeq ($(enable_lite_mode), no) SUBDIRS += archive endif diff --git a/src/gausskernel/storage/access/datavec/Makefile b/src/gausskernel/storage/access/datavec/Makefile new file mode 100644 index 0000000000..4fcedca437 --- /dev/null +++ b/src/gausskernel/storage/access/datavec/Makefile @@ -0,0 +1,16 @@ +subdir = src/gausskernel/storage/access/datavec +top_builddir = ../../../../.. +include $(top_builddir)/src/Makefile.global + +ifneq "$(MAKECMDGOALS)" "clean" + ifneq "$(MAKECMDGOALS)" "distclean" + ifneq "$(shell which g++ |grep hutaf_llt |wc -l)" "1" + -include $(DEPEND) + endif + endif +endif + +OBJS = bitutils.o hnsw.o hnswbuild.o hnswdelete.o hnswinsert.o hnswscan.o hnswutils.o hnswvacuum.o \ + ivfbuild.o ivfflat.o ivfinsert.o ivfkmeans.o ivfscan.o ivfutils.o ivfvacuum.o vecindex.o + +include $(top_srcdir)/src/gausskernel/common.mk diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 740f061d18..bf1580e318 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -199,6 +199,38 @@ DATA(insert OID = 4262 (4239 int1_ops PGNSP PGUID)); DATA(insert OID = 4263 (4239 bool_ops PGNSP PGUID)); DATA(insert OID = 4264 (4239 smalldatetime_ops PGNSP PGUID)); +/*datavec index ops*/ +DATA(insert OID = 6030 (4446 vector_l2_ops PGNSP PGUID)); +DATA(insert OID = 6040 (4446 vector_ip_ops PGNSP PGUID)); +DATA(insert OID = 6050 (4446 vector_cosine_ops PGNSP PGUID)); +DATA(insert OID = 6060 (4446 vector_l1_ops PGNSP PGUID)); + +DATA(insert OID = 6035 (4446 halfvec_l2_ops PGNSP PGUID)); +DATA(insert OID = 6045 (4446 halfvec_ip_ops PGNSP PGUID)); +DATA(insert OID = 6055 (4446 halfvec_cosine_ops PGNSP PGUID)); +DATA(insert OID = 6065 (4446 halfvec_l1_ops PGNSP PGUID)); + +DATA(insert OID = 6075 (4446 bit_jaccard_ops PGNSP PGUID)); +DATA(insert OID = 6076 (4446 bit_hamming_ops PGNSP PGUID)); + +DATA(insert OID = 6071 (4446 sparsevec_l2_ops PGNSP PGUID)); +DATA(insert OID = 6072 (4446 sparsevec_ip_ops PGNSP PGUID)); +DATA(insert OID = 6073 (4446 sparsevec_cosine_ops PGNSP PGUID)); +DATA(insert OID = 6074 (4446 sparsevec_l1_ops PGNSP PGUID)); + +DATA(insert OID = 6077 (4447 vector_l2_ops PGNSP PGUID)); +DATA(insert OID = 6078 (4447 vector_ip_ops PGNSP PGUID)); +DATA(insert OID = 6079 (4447 vector_cosine_ops PGNSP PGUID)); +DATA(insert OID = 6070 (4447 vector_l1_ops PGNSP PGUID)); + +DATA(insert OID = 6080 (4447 halfvec_l2_ops PGNSP PGUID)); +DATA(insert OID = 6081 (4447 halfvec_ip_ops PGNSP PGUID)); +DATA(insert OID = 6082 (4447 halfvec_cosine_ops PGNSP PGUID)); +DATA(insert OID = 6083 (4447 halfvec_l1_ops PGNSP PGUID)); + +DATA(insert OID = 6084 (4447 bit_jaccard_ops PGNSP PGUID)); +DATA(insert OID = 6085 (4447 bit_hamming_ops PGNSP PGUID)); + /* ubtree index */ #define BTREE_UBTREE_FAM_OID_DIFF 5000 #define BTREE_UBTREE_FAM_OID_SPECIAL_DIFF 4000 diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 513ea4d1fb..eaca30faf9 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -822,6 +822,16 @@ DATA(insert OID = 3272 ( anyset PGNSP PGUID -1 f s H t t \054 0 0 0 anyset_in DATA(insert OID = 4408 ( undefined PGNSP PGUID -2 f u W f t \054 0 0 0 undefinedin undefinedout undefinedrecv undefinedsend - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("undefined objects as PLSQL compilation time"); #define UNDEFINEDOID 4408 + +DATA(insert OID = 4409 ( vector PGNSP PGUID -1 f b U f t \054 0 0 4411 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +#define VECTOROID 4409 + +DATA(insert OID = 4410 ( halfvec PGNSP PGUID -1 f b U f t \054 0 0 4411 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +#define FLOATVECTOROID 4410 + +DATA(insert OID = 4411 ( sparsevec PGNSP PGUID -1 f b U f t \054 0 0 4411 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +#define SPARSEVECTOROID 4411 + /* * macros */ -- Gitee From 007b48ee2b1bd1e1b755a8dac630d3451d650b20 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Thu, 31 Oct 2024 12:03:30 +0800 Subject: [PATCH 03/67] =?UTF-8?q?=E5=86=85=E6=A0=B8=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=A2=9E=E6=B7=BB=E6=96=B0=E6=96=87=E4=BB=B6=E2=80=94=E2=80=94?= =?UTF-8?q?rmc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 964 ++++++++++++++++++- src/include/catalog/pg_am.h | 6 + src/include/catalog/pg_amop.data | 106 ++ src/include/catalog/pg_amproc.h | 34 + src/include/catalog/pg_opclass.h | 31 + src/include/catalog/pg_operator.data | 53 + 6 files changed, 1193 insertions(+), 1 deletion(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 4b5b0330eb..0fe4d2a7db 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13120,4 +13120,966 @@ AddFuncGroup( AddFuncGroup( "query_imcstore_views", 1, AddBuiltinFunc(_0(6808), _1("query_imcstore_views"), _2(1), _3(true), _4(true), _5(query_imcstore_views), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1000), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(11, 26, 19, 22, 21, 19, 16, 26, 20, 20, 20, 20), _22(11, 'o', 'o', 'o', 'o','o', 'o', 'o', 'o', 'o','o', 'o'), _23(11, "reloid", "relname", "imcs_attrs", "imcs_nattrs", "imcs_status", "is_partition", "parent_oid", "cu_size_in_mem", "cu_num_in_mem", "cu_size_in_disk", "cu_num_in_disk"), _24(NULL), _25("query_imcstore_views"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("query_imcstore_views"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), \ No newline at end of file + ), + AddFuncGroup( + "vector_in", 1, + AddBuiltinFunc( + _0(8000), + _1("vector_in"), + _2(3), _3(true), _4(false), + _5(vector_in), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "vector_out", 1, + AddBuiltinFunc( + _0(8024), + _1("vector_out"), + _2(1), _3(true), _4(false), + _5(vector_out), + _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_typmod_in", 1, + AddBuiltinFunc( + _0(8002), + _1("vector_typmod_in"), + _2(1), _3(true), _4(false), + _5(vector_typmod_in), + _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_recv", 1, + AddBuiltinFunc( + _0(8003), + _1("vector_recv"), + _2(3), _3(true), _4(false), + _5(vector_recv), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_send", 1, + AddBuiltinFunc( + _0(8004), + _1("vector_send"), + _2(1), _3(true), _4(false), + _5(vector_send), + _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + AddFuncGroup( + "vector_dims", 1, + AddBuiltinFunc( + _0(8005), + _1("vector_dims"), + _2(1), _3(true), _4(false), + _5(vector_dims), + _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "array_to_vector", 1, + AddBuiltinFunc( + _0(8006), + _1("array_to_vector"), + _2(1), _3(true), _4(false), + _5(array_to_vector), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_to_float4", 1, + AddBuiltinFunc( + _0(8007), + _1("vector_to_float4"), + _2(1), _3(true), _4(false), + _5(vector_to_float4), + _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_l2_squared_distance", 1, + AddBuiltinFunc( + _0(8008), + _1("vector_l2_squared_distance"), + _2(1), _3(true), _4(false), + _5(vector_l2_squared_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_spherical_distance", 1, + AddBuiltinFunc( + _0(8009), + _1("vector_spherical_distance"), + _2(1), _3(true), _4(false), + _5(vector_spherical_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4009), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + + + AddFuncGroup( + "inner_product", 1, + AddBuiltinFunc( + _0(8011), + _1("inner_product"), + _2(1), _3(true), _4(false), + _5(inner_product), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "vector_norm", 1, + AddBuiltinFunc( + _0(8012), + _1("vector_norm"), + _2(1), _3(true), _4(false), + _5(vector_norm), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_add", 1, + AddBuiltinFunc( + _0(8013), + _1("vector_add"), + _2(1), _3(true), _4(false), + _5(vector_add), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_add"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_sub", 1, + AddBuiltinFunc( + _0(8014), + _1("vector_sub"), + _2(1), _3(true), _4(false), + _5(vector_sub), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_lt", 1, + AddBuiltinFunc( + _0(8015), + _1("vector_lt"), + _2(1), _3(true), _4(false), + _5(vector_lt), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "vector_le", 1, + AddBuiltinFunc( + _0(8016), + _1("vector_le"), + _2(1), _3(true), _4(false), + _5(vector_le), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_eq", 1, + AddBuiltinFunc( + _0(8017), + _1("vector_eq"), + _2(1), _3(true), _4(false), + _5(vector_eq), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_ne", 1, + AddBuiltinFunc( + _0(8018), + _1("vector_ne"), + _2(1), _3(true), _4(false), + _5(vector_ne), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_ge", 1, + AddBuiltinFunc( + _0(8019), + _1("vector_ge"), + _2(1), _3(true), _4(false), + _5(vector_ge), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_gt", 1, + AddBuiltinFunc( + _0(8020), + _1("vector_gt"), + _2(1), _3(true), _4(false), + _5(vector_gt), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + + + + + + + + + + + + + + + AddFuncGroup( + "vector_accum", 1, + AddBuiltinFunc( + _0(8021), + _1("vector_accum"), + _2(1), _3(true), _4(false), + _5(vector_accum), + _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 2277, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "vector_combine", 1, + AddBuiltinFunc( + _0(8022), + _1("vector_combine"), + _2(1), _3(true), _4(false), + _5(vector_combine), + _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_avg", 1, + AddBuiltinFunc( + _0(8023), + _1("vector_avg"), + _2(1), _3(true), _4(false), + _5(vector_avg), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + + + + AddFuncGroup( + "hnswinsert", 1, + AddBuiltinFunc( + _0(8226), + _1("hnswinsert"), + _2(6), _3(true), _4(false), + _5(hnswinsert), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswbeginscan", 1, + AddBuiltinFunc( + _0(8220), + _1("hnswbeginscan"), + _2(3), _3(true), _4(false), + _5(hnswbeginscan), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + +AddFuncGroup( + "hnswgettuple", 1, + AddBuiltinFunc( + _0(8229), + _1("hnswgettuple"), + _2(2), _3(true), _4(false), + _5(hnswgettuple), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswrescan", 1, + AddBuiltinFunc( + _0(8230), + _1("hnswrescan"), + _2(5), _3(true), _4(false), + _5(hnswrescan), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswendscan", 1, + AddBuiltinFunc( + _0(8225), + _1("hnswendscan"), + _2(1), _3(true), _4(false), + _5(hnswendscan), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswbuild", 1, + AddBuiltinFunc( + _0(8221), + _1("hnswbuild"), + _2(3), _3(true), _4(false), + _5(hnswbuild), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswbuildempty", 1, + AddBuiltinFunc( + _0(8222), + _1("hnswbuildempty"), + _2(1), _3(true), _4(false), + _5(hnswbuildempty), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswbulkdelete", 1, + AddBuiltinFunc( + _0(8223), + _1("hnswbulkdelete"), + _2(4), _3(true), _4(false), + _5(hnswbulkdelete), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswvacuumcleanup", 1, + AddBuiltinFunc( + _0(8228), + _1("hnswvacuumcleanup"), + _2(2), _3(true), _4(false), + _5(hnswvacuumcleanup), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswcostestimate", 1, + AddBuiltinFunc( + _0(8224), + _1("hnswcostestimate"), + _2(7), _3(true), _4(false), + _5(hnswcostestimate), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswoptions", 1, + AddBuiltinFunc( + _0(8227), + _1("hnswoptions"), + _2(2), _3(true), _4(false), + _5(hnswoptions), + _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hnswoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "vector_cmp", 1, + AddBuiltinFunc( + _0(8216), + _1("vector_cmp"), + _2(1), _3(true), _4(false), + _5(vector_cmp), + _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_cmp", 1, + AddBuiltinFunc( + _0(8217), + _1("halfvec_cmp"), + _2(1), _3(true), _4(false), + _5(vector_cmp), + _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("halfvec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "l2_distance", 1, + AddBuiltinFunc( + _0(8200), + _1("l2_distance"), + _2(1), _3(true), _4(false), + _5(l2_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_negative_inner_product", 1, + AddBuiltinFunc( + _0(8203), + _1("vector_negative_inner_product"), + _2(1), _3(true), _4(false), + _5(vector_negative_inner_product), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "cosine_distance", 1, + AddBuiltinFunc( + _0(8204), + _1("cosine_distance"), + _2(1), _3(true), _4(false), + _5(cosine_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "l1_distance", 1, + AddBuiltinFunc( + _0(8205), + _1("l1_distance"), + _2(1), _3(true), _4(false), + _5(l1_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + + AddFuncGroup( + "halfvec_in", 1, + AddBuiltinFunc( + _0(8206), + _1("halfvec_in"), + _2(3), _3(true), _4(false), + _5(vector_in), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "halfvec_out", 1, + AddBuiltinFunc( + _0(8207), + _1("halfvec_out"), + _2(1), _3(true), _4(false), + _5(vector_out), + _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("halfvec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_typmod_in", 1, + AddBuiltinFunc( + _0(8208), + _1("halfvec_typmod_in"), + _2(1), _3(true), _4(false), + _5(vector_typmod_in), + _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_recv", 1, + AddBuiltinFunc( + _0(8209), + _1("halfvec_recv"), + _2(3), _3(true), _4(false), + _5(vector_recv), + _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("halfvec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_send", 1, + AddBuiltinFunc( + _0(8210), + _1("halfvec_send"), + _2(1), _3(true), _4(false), + _5(vector_send), + _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("halfvec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_negative_inner_product", 1, + AddBuiltinFunc( + _0(8211), + _1("halfvec_negative_inner_product"), + _2(1), _3(true), _4(false), + _5(halfvec_negative_inner_product), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("halfvec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + AddFuncGroup( + "sparsevec_in", 1, + AddBuiltinFunc( + _0(8231), + _1("sparsevec_in"), + _2(3), _3(true), _4(false), + _5(sparsevec_in), + _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "sparsevec_out", 1, + AddBuiltinFunc( + _0(8232), + _1("sparsevec_out"), + _2(1), _3(true), _4(false), + _5(sparsevec_out), + _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_typmod_in", 1, + AddBuiltinFunc( + _0(8233), + _1("sparsevec_typmod_in"), + _2(1), _3(true), _4(false), + _5(sparsevec_typmod_in), + _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_recv", 1, + AddBuiltinFunc( + _0(8234), + _1("sparsevec_recv"), + _2(3), _3(true), _4(false), + _5(sparsevec_recv), + _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_send", 1, + AddBuiltinFunc( + _0(8218), + _1("sparsevec_send"), + _2(1), _3(true), _4(false), + _5(sparsevec_send), + _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + + + + + AddFuncGroup( + "sparsevec_negative_inner_product", 1, + AddBuiltinFunc( + _0(8219), + _1("sparsevec_negative_inner_product"), + _2(1), _3(true), _4(false), + _5(sparsevec_negative_inner_product), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_cmp", 1, + AddBuiltinFunc( + _0(8235), + _1("sparsevec_cmp"), + _2(1), _3(true), _4(false), + _5(sparsevec_cmp), + _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_l2_distance", 1, + AddBuiltinFunc( + _0(8236), + _1("sparsevec_l2_distance"), + _2(1), _3(true), _4(false), + _5(sparsevec_l2_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "sparsevec_cosine_distance", 1, + AddBuiltinFunc( + _0(8237), + _1("sparsevec_cosine_distance"), + _2(1), _3(true), _4(false), + _5(sparsevec_cosine_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_l1_distance", 1, + AddBuiltinFunc( + _0(8238), + _1("sparsevec_l1_distance"), + _2(1), _3(true), _4(false), + _5(sparsevec_l1_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + AddFuncGroup( + "jaccard_distance", 1, + AddBuiltinFunc( + _0(8239), + _1("jaccard_distance"), + _2(1), _3(true), _4(false), + _5(jaccard_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hamming_distance", 1, + AddBuiltinFunc( + _0(8240), + _1("hamming_distance"), + _2(1), _3(true), _4(false), + _5(hamming_distance), + _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('i'), _19(0), + _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + + + AddFuncGroup( + "ivfflatinsert", 1, + AddBuiltinFunc( + _0(8241), + _1("ivfflatinsert"), + _2(6), _3(true), _4(false), + _5(ivfflatinsert), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatbeginscan", 1, + AddBuiltinFunc( + _0(8242), + _1("ivfflatbeginscan"), + _2(3), _3(true), _4(false), + _5(ivfflatbeginscan), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "ivfflatgettuple", 1, + AddBuiltinFunc( + _0(8243), + _1("ivfflatgettuple"), + _2(2), _3(true), _4(false), + _5(ivfflatgettuple), + _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatrescan", 1, + AddBuiltinFunc( + _0(8244), + _1("ivfflatrescan"), + _2(5), _3(true), _4(false), + _5(ivfflatrescan), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatendscan", 1, + AddBuiltinFunc( + _0(8245), + _1("ivfflatendscan"), + _2(1), _3(true), _4(false), + _5(ivfflatendscan), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatbuild", 1, + AddBuiltinFunc( + _0(8246), + _1("ivfflatbuild"), + _2(3), _3(true), _4(false), + _5(ivfflatbuild), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatbuildempty", 1, + AddBuiltinFunc( + _0(8247), + _1("ivfflatbuildempty"), + _2(1), _3(true), _4(false), + _5(ivfflatbuildempty), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatbulkdelete", 1, + AddBuiltinFunc( + _0(8248), + _1("ivfflatbulkdelete"), + _2(4), _3(true), _4(false), + _5(ivfflatbulkdelete), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatvacuumcleanup", 1, + AddBuiltinFunc( + _0(8249), + _1("ivfflatvacuumcleanup"), + _2(2), _3(true), _4(false), + _5(ivfflatvacuumcleanup), + _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatcostestimate", 1, + AddBuiltinFunc( + _0(8250), + _1("ivfflatcostestimate"), + _2(7), _3(true), _4(false), + _5(ivfflatcostestimate), + _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('v'), _19(0), + _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatoptions", 1, + AddBuiltinFunc( + _0(8251), + _1("ivfflatoptions"), + _2(2), _3(true), _4(false), + _5(ivfflatoptions), + _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), + _18('s'), _19(0), + _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _25("ivfflatoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index 7e77b1eec6..73d63084dc 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -156,8 +156,14 @@ DATA(insert OID = 4439 ( ubtree 5 3 t f t t t t t t f t t 0 ubtinsert ubtbegin DESCR("ustore b-tree index access method"); #define UBTREE_AM_OID 4439 +DATA(insert OID = 4446 ( hnsw 0 3 f t f f f t f f f f f 0 hnswinsert hnswbeginscan hnswgettuple - hnswrescan hnswendscan - - - hnswbuild hnswbuildempty hnswbulkdelete hnswvacuumcleanup - hnswcostestimate hnswoptions - -)); +DESCR("hnsw index access method"); #define HNSW_AM_OID 4446 +DATA(insert OID = 4447 ( ivfflat 0 5 f t f f f t f f f f f 0 ivfflatinsert ivfflatbeginscan ivfflatgettuple - ivfflatrescan ivfflatendscan - - - ivfflatbuild ivfflatbuildempty ivfflatbulkdelete ivfflatvacuumcleanup - ivfflatcostestimate ivfflatoptions - -)); +DESCR("ivfflat index access method"); +#define IVFFLAT_AM_OID 4447 + #define OID_IS_BTREE(oid) ((oid) == BTREE_AM_OID || (oid) == UBTREE_AM_OID) #endif /* PG_AM_H */ diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index ae6fdb342e..10bc9f375e 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1594,3 +1594,109 @@ DATA(insert OID = 7272 ( 9570 9003 9003 2 s 5553 4439 0 )); DATA(insert OID = 7273 ( 9570 9003 9003 3 s 5550 4439 0 )); DATA(insert OID = 7274 ( 9570 9003 9003 4 s 5549 4439 0 )); DATA(insert OID = 7275 ( 9570 9003 9003 5 s 5554 4439 0 )); +DATA(insert OID = 6031 ( 6030 4409 4409 1 o 6019 4446 1970 )); + +DATA(insert OID = 6041 ( 6040 4409 4409 1 o 6020 4446 1970 )); + +DATA(insert OID = 6051 ( 6050 4409 4409 1 o 6019 4446 1970 )); +DATA(insert OID = 6090 ( 6050 4409 4409 2 o 6020 4446 1970 )); +DATA(insert OID = 6059 ( 6050 4409 4409 3 o 6021 4446 1970 )); +DATA(insert OID = 6054 ( 6050 4409 4409 4 o 6052 4446 1970 )); +DATA(insert OID = 6061 ( 6060 4409 4409 1 o 6019 4446 1970 )); +DATA(insert OID = 6062 ( 6060 4409 4409 2 o 6020 4446 1970 )); +DATA(insert OID = 6063 ( 6060 4409 4409 3 o 6021 4446 1970 )); +DATA(insert OID = 6064 ( 6060 4409 4409 4 o 6052 4446 1970 )); + +DATA(insert OID = 6036 ( 6035 4410 4410 1 o 6022 4446 1970 )); +DATA(insert OID = 6136 ( 6035 4410 4410 2 o 6023 4446 1970 )); +DATA(insert OID = 6236 ( 6035 4410 4410 3 o 6024 4446 1970 )); +DATA(insert OID = 6336 ( 6035 4410 4410 4 o 6053 4446 1970 )); +DATA(insert OID = 6046 ( 6045 4410 4410 1 o 6022 4446 1970 )); +DATA(insert OID = 6146 ( 6045 4410 4410 2 o 6023 4446 1970 )); +DATA(insert OID = 6246 ( 6045 4410 4410 3 o 6024 4446 1970 )); +DATA(insert OID = 6346 ( 6045 4410 4410 4 o 6053 4446 1970 )); +DATA(insert OID = 6056 ( 6055 4410 4410 1 o 6022 4446 1970 )); +DATA(insert OID = 6156 ( 6055 4410 4410 2 o 6023 4446 1970 )); +DATA(insert OID = 6256 ( 6055 4410 4410 3 o 6024 4446 1970 )); +DATA(insert OID = 6356 ( 6055 4410 4410 4 o 6053 4446 1970 )); +DATA(insert OID = 6066 ( 6065 4410 4410 1 o 6022 4446 1970 )); +DATA(insert OID = 6166 ( 6065 4410 4410 2 o 6023 4446 1970 )); +DATA(insert OID = 6266 ( 6065 4410 4410 3 o 6024 4446 1970 )); +DATA(insert OID = 6366 ( 6065 4410 4410 4 o 6053 4446 424 )); + +DATA(insert OID = 6091 ( 6071 4411 4411 1 o 6025 4446 1970 )); +DATA(insert OID = 6092 ( 6071 4411 4411 2 o 6026 4446 1970 )); +DATA(insert OID = 6093 ( 6071 4411 4411 3 o 6027 4446 1970 )); +DATA(insert OID = 6094 ( 6071 4411 4411 4 o 6069 4446 1970 )); +DATA(insert OID = 6095 ( 6072 4411 4411 1 o 6025 4446 1970 )); +DATA(insert OID = 6096 ( 6072 4411 4411 2 o 6026 4446 1970 )); +DATA(insert OID = 6097 ( 6072 4411 4411 3 o 6027 4446 1970 )); +DATA(insert OID = 6098 ( 6072 4411 4411 4 o 6069 4446 1970 )); +DATA(insert OID = 6099 ( 6073 4411 4411 1 o 6025 4446 1970 )); +DATA(insert OID = 6100 ( 6073 4411 4411 2 o 6026 4446 1970 )); +DATA(insert OID = 6101 ( 6073 4411 4411 3 o 6027 4446 1970 )); +DATA(insert OID = 6102 ( 6073 4411 4411 4 o 6069 4446 1970 )); +DATA(insert OID = 6103 ( 6074 4411 4411 1 o 6025 4446 1970 )); +DATA(insert OID = 6104 ( 6074 4411 4411 2 o 6026 4446 1970 )); +DATA(insert OID = 6105 ( 6074 4411 4411 3 o 6027 4446 1970 )); +DATA(insert OID = 6106 ( 6074 4411 4411 4 o 6069 4446 1970 )); + + +DATA(insert OID = 6107 ( 6075 1560 1560 1 o 6028 4446 1970 )); +DATA(insert OID = 6108 ( 6075 1560 1560 2 o 6029 4446 1970 )); +DATA(insert OID = 6109 ( 6076 1560 1560 1 o 6028 4446 1970 )); +DATA(insert OID = 6110 ( 6076 1560 1560 2 o 6029 4446 1970 )); + + + + + + +DATA(insert OID = 6111 ( 6077 4409 4409 1 o 6019 4447 1970 )); + + + +DATA(insert OID = 6115 ( 6078 4409 4409 1 o 6019 4447 1970 )); +DATA(insert OID = 6116 ( 6078 4409 4409 2 o 6020 4447 1970 )); +DATA(insert OID = 6117 ( 6078 4409 4409 3 o 6021 4447 1970 )); +DATA(insert OID = 6118 ( 6078 4409 4409 4 o 6052 4447 1970 )); +DATA(insert OID = 6119 ( 6079 4409 4409 1 o 6019 4447 1970 )); +DATA(insert OID = 6120 ( 6079 4409 4409 2 o 6020 4447 1970 )); +DATA(insert OID = 6121 ( 6079 4409 4409 3 o 6021 4447 1970 )); +DATA(insert OID = 6122 ( 6079 4409 4409 4 o 6052 4447 1970 )); +DATA(insert OID = 6123 ( 6070 4409 4409 1 o 6019 4447 1970 )); +DATA(insert OID = 6124 ( 6070 4409 4409 2 o 6020 4447 1970 )); +DATA(insert OID = 6125 ( 6070 4409 4409 3 o 6021 4447 1970 )); +DATA(insert OID = 6126 ( 6070 4409 4409 4 o 6052 4447 1970 )); + + + +DATA(insert OID = 6127 ( 6080 4410 4410 1 o 6022 4447 1970 )); +DATA(insert OID = 6128 ( 6080 4410 4410 2 o 6023 4447 1970 )); +DATA(insert OID = 6129 ( 6080 4410 4410 3 o 6024 4447 1970 )); +DATA(insert OID = 6130 ( 6080 4410 4410 4 o 6053 4447 1970 )); +DATA(insert OID = 6131 ( 6081 4410 4410 1 o 6022 4447 1970 )); +DATA(insert OID = 6132 ( 6081 4410 4410 2 o 6023 4447 1970 )); +DATA(insert OID = 6133 ( 6081 4410 4410 3 o 6024 4447 1970 )); +DATA(insert OID = 6134 ( 6081 4410 4410 4 o 6053 4447 1970 )); +DATA(insert OID = 6135 ( 6082 4410 4410 1 o 6022 4447 1970 )); +DATA(insert OID = 6137 ( 6082 4410 4410 3 o 6023 4447 1970 )); +DATA(insert OID = 6138 ( 6082 4410 4410 4 o 6024 4447 1970 )); +DATA(insert OID = 6139 ( 6082 4410 4410 1 o 6053 4447 1970 )); +DATA(insert OID = 6140 ( 6083 4410 4410 2 o 6022 4447 1970 )); +DATA(insert OID = 6141 ( 6083 4410 4410 3 o 6023 4447 1970 )); +DATA(insert OID = 6142 ( 6083 4410 4410 4 o 6024 4447 1970 )); +DATA(insert OID = 6143 ( 6083 4410 4410 4 o 6053 4447 1970 )); + + + + + + +DATA(insert OID = 6144 ( 6084 1560 1560 1 o 6028 4447 1970 )); +DATA(insert OID = 6145 ( 6084 1560 1560 2 o 6029 4447 1970 )); +DATA(insert OID = 6147 ( 6085 1560 1560 1 o 6028 4447 1970 )); +DATA(insert OID = 6148 ( 6085 1560 1560 2 o 6029 4447 1970 )); + + + diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 138c7d54ea..585e8393aa 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -655,4 +655,38 @@ DATA(insert ( 8901 3831 3831 1 3870 )); DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); +DATA(insert ( 6030 4409 4409 1 8008 )); +DATA(insert ( 6040 4409 4409 1 8216 )); +DATA(insert ( 6050 4409 4409 1 8216 )); +DATA(insert ( 6060 4409 4409 1 8216 )); + +DATA(insert OID = 6038( 6035 4410 4410 1 8217 )); +DATA(insert OID = 6048( 6045 4410 4410 1 8217 )); +DATA(insert OID = 6058( 6055 4410 4410 1 8217 )); +DATA(insert OID = 6068( 6065 4410 4410 1 8217 )); + +DATA(insert OID = 6149( 6075 1560 1560 1 8218 )); +DATA(insert OID = 6150( 6076 1560 1560 1 8218 )); + +DATA(insert OID = 6151( 6071 4411 4411 1 8219 )); +DATA(insert OID = 6152( 6072 4411 4411 1 8219 )); +DATA(insert OID = 6153( 6073 4411 4411 1 8219 )); +DATA(insert OID = 6154( 6074 4411 4411 1 8219 )); + + + +DATA(insert ( 6077 4409 4409 1 8008 )); +DATA(insert ( 6077 4409 4409 3 8200 )); + +DATA(insert ( 6078 4409 4409 1 8216 )); +DATA(insert ( 6079 4409 4409 1 8216 )); +DATA(insert ( 6070 4409 4409 1 8216 )); + +DATA(insert OID = 6155( 6080 4410 4410 1 8217 )); +DATA(insert OID = 6157( 6081 4410 4410 1 8217 )); +DATA(insert OID = 6158( 6082 4410 4410 1 8217 )); +DATA(insert OID = 6159( 6083 4410 4410 1 8217 )); + +DATA(insert OID = 6160( 6084 1560 1560 1 8218 )); +DATA(insert OID = 6161( 6085 1560 1560 1 8218 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 7f83a4c8e2..0aeabe8ee9 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -375,5 +375,36 @@ DATA(insert ( 405 settext_ops PGNSP PGUID 1995 3272 f 0 )); DATA(insert ( 4439 setasint_ops PGNSP PGUID 6976 3272 t 0 )); DATA(insert ( 405 set_ops PGNSP PGUID 8646 3272 t 0 )); + +DATA(insert ( 4446 vector_l2_ops PGNSP PGUID 6030 4409 t 0 )); +DATA(insert ( 4446 vector_ip_ops PGNSP PGUID 6040 4409 t 0 )); +DATA(insert ( 4446 vector_cosine_ops PGNSP PGUID 6050 4409 t 0 )); +DATA(insert ( 4446 vector_l1_ops PGNSP PGUID 6060 4409 t 0 )); +DATA(insert OID = 6037 ( 4446 halfvec_l2_ops PGNSP PGUID 6035 4410 t 0 )); +DATA(insert OID = 6047 ( 4446 halfvec_ip_ops PGNSP PGUID 6045 4410 t 0 )); +DATA(insert OID = 6057 ( 4446 halfvec_cosine_ops PGNSP PGUID 6055 4410 t 0 )); +DATA(insert OID = 6067 ( 4446 halfvec_l1_ops PGNSP PGUID 6065 4410 t 0 )); + +DATA(insert OID = 6010 ( 4446 bit_jaccard_ops PGNSP PGUID 6075 1560 t 0 )); +DATA(insert OID = 6011 ( 4446 bit_hamming_ops PGNSP PGUID 6076 1560 t 0 )); + +DATA(insert OID = 6012 ( 4446 sparsevec_l2_ops PGNSP PGUID 6071 4411 t 0 )); +DATA(insert OID = 6013 ( 4446 sparsevec_ip_ops PGNSP PGUID 6072 4411 t 0 )); +DATA(insert OID = 6014 ( 4446 sparsevec_cosine_ops PGNSP PGUID 6073 4411 t 0 )); +DATA(insert OID = 6015 ( 4446 sparsevec_l1_ops PGNSP PGUID 6074 4411 t 0 )); + +DATA(insert ( 4447 vector_l2_ops PGNSP PGUID 6077 4409 t 0 )); +DATA(insert ( 4447 vector_ip_ops PGNSP PGUID 6078 4409 t 0 )); +DATA(insert ( 4447 vector_cosine_ops PGNSP PGUID 6079 4409 t 0 )); +DATA(insert ( 4447 vector_l1_ops PGNSP PGUID 6070 4409 t 0 )); + +DATA(insert OID = 6016 ( 4447 halfvec_l2_ops PGNSP PGUID 6080 4410 t 0 )); +DATA(insert OID = 6017 ( 4447 halfvec_ip_ops PGNSP PGUID 6081 4410 t 0 )); +DATA(insert OID = 6018 ( 4447 halfvec_cosine_ops PGNSP PGUID 6082 4410 t 0 )); +DATA(insert OID = 6039 ( 4447 halfvec_l1_ops PGNSP PGUID 6083 4410 t 0 )); + +DATA(insert OID = 6049 ( 4447 bit_jaccard_ops PGNSP PGUID 6084 1560 t 0 )); +DATA(insert OID = 6086 ( 4447 bit_hamming_ops PGNSP PGUID 6085 1560 t 0 )); + #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index 67e260f310..fc05ca2902 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1918,6 +1918,59 @@ DESCR("greater than or equal"); DATA(insert OID = 6565 ("-" PGNSP PGUID l f f 0 16 16 0 0 boolum - -)); DESCR("negate"); +DATA(insert OID = 6019 ("<->" PGNSP PGUID b f f 4409 4409 701 6019 0 l2_distance - -)); +DESCR("l2_distance"); +DATA(insert OID = 6020 ("<#>" PGNSP PGUID b f f 4409 4409 701 6020 0 vector_negative_inner_product - -)); +DESCR("vector_negative_inner_product"); +DATA(insert OID = 6021 ("<=>" PGNSP PGUID b f f 4409 4409 701 6021 0 cosine_distance - -)); +DESCR("cosine_distance"); +DATA(insert OID = 6052 ("<+>" PGNSP PGUID b f f 4409 4409 16 6052 0 l1_distance - -)); +DESCR("l1_distance"); + + + +DATA(insert OID = 6162 ("+" PGNSP PGUID b f f 4409 4409 4409 6162 0 vector_add - -)); +DESCR("vector_add"); +DATA(insert OID = 6163 ("-" PGNSP PGUID b f f 4409 4409 4409 6163 0 vector_sub - -)); +DESCR("vector_sub"); +DATA(insert OID = 6164 ("<" PGNSP PGUID b f f 4409 4409 16 6164 6165 vector_lt scalarltsel scalarltjoinsel)); +DESCR("vector less than"); +DATA(insert OID = 6165 ("<=" PGNSP PGUID b f f 4409 4409 16 6165 6164 vector_le scalarltsel scalarltjoinsel)); +DESCR("vector less than or equal"); +DATA(insert OID = 6167 (">" PGNSP PGUID b f f 4409 4409 16 6167 6168 vector_gt scalargtsel scalargtjoinsel)); +DESCR("vector greater than"); +DATA(insert OID = 6168 (">=" PGNSP PGUID b f f 4409 4409 16 6168 6167 vector_ge scalargtsel scalargtjoinsel)); +DESCR("vector greater than or equal"); +DATA(insert OID = 6169 ("=" PGNSP PGUID b f t 4409 4409 16 6169 6170 vector_eq eqsel eqjoinsel)); +DESCR("vector equal"); +DATA(insert OID = 6170 ("<>" PGNSP PGUID b f f 4409 4409 16 6170 6169 vector_ne neqsel neqjoinsel)); +DESCR("vector unequal"); + + + + +DATA(insert OID = 6022 ("<->" PGNSP PGUID b f f 4410 4410 701 6019 0 l2_distance - -)); +DESCR("l2_distance"); +DATA(insert OID = 6023 ("<#>" PGNSP PGUID b f f 4410 4410 701 6020 0 halfvec_negative_inner_product - -)); +DESCR("halfvec_negative_inner_product"); +DATA(insert OID = 6024 ("<=>" PGNSP PGUID b f f 4410 4410 701 6021 0 cosine_distance - -)); +DESCR("cosine_distance"); +DATA(insert OID = 6053 ("<+>" PGNSP PGUID b f f 4410 4410 16 6052 0 l1_distance - -)); +DESCR("l1_distance"); + +DATA(insert OID = 6025 ("<->" PGNSP PGUID b f f 4411 4411 701 6025 0 sparsevec_l2_distance - -)); +DESCR("sparsevec_l2_distance"); +DATA(insert OID = 6026 ("<#>" PGNSP PGUID b f f 4411 4411 701 6026 0 sparsevecvec_negative_inner_product - -)); +DESCR("sparsevecvec_negative_inner_product"); +DATA(insert OID = 6027 ("<=>" PGNSP PGUID b f f 4411 4411 701 6027 0 sparsevec_cosine_distance - -)); +DESCR("sparsevec_cosine_distance"); +DATA(insert OID = 6069 ("<+>" PGNSP PGUID b f f 4411 4411 16 6052 0 sparsevec_l1_distance - -)); +DESCR("sparsevec_l1_distance"); + +DATA(insert OID = 6028 ("<~>" PGNSP PGUID b f f 1560 1560 701 6028 0 jaccard_distance - -)); +DESCR("jaccard_distance"); +DATA(insert OID = 6029 ("<%>" PGNSP PGUID b f f 1560 1560 701 6029 0 hamming_distance - -)); +DESCR("hamming_distance"); /* * function prototypes */ \ No newline at end of file -- Gitee From 6c3323c976137437291eda5d5931f8f41788eb65 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Thu, 31 Oct 2024 14:28:04 +0800 Subject: [PATCH 04/67] =?UTF-8?q?datavec=E8=BF=81=E7=A7=BBopenGauss?= =?UTF-8?q?=E5=86=85=E6=A0=B8=EF=BC=9A=E9=94=99=E8=AF=AF=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 8 ++++---- src/include/catalog/pg_amop.data | 12 ++++++------ src/include/catalog/pg_operator.data | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 0fe4d2a7db..2448f59e47 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13158,7 +13158,7 @@ AddFuncGroup( _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13251,7 +13251,7 @@ AddFuncGroup( _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), - _20(2, 4409, 4009), _21(NULL), _22(NULL), _23(NULL), _24(NULL), + _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13719,7 +13719,7 @@ AddFuncGroup( _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13801,7 +13801,7 @@ AddFuncGroup( _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), + _25("sparsevec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 10bc9f375e..7ed846f6f2 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1680,12 +1680,12 @@ DATA(insert OID = 6132 ( 6081 4410 4410 2 o 6023 4447 1970 )); DATA(insert OID = 6133 ( 6081 4410 4410 3 o 6024 4447 1970 )); DATA(insert OID = 6134 ( 6081 4410 4410 4 o 6053 4447 1970 )); DATA(insert OID = 6135 ( 6082 4410 4410 1 o 6022 4447 1970 )); -DATA(insert OID = 6137 ( 6082 4410 4410 3 o 6023 4447 1970 )); -DATA(insert OID = 6138 ( 6082 4410 4410 4 o 6024 4447 1970 )); -DATA(insert OID = 6139 ( 6082 4410 4410 1 o 6053 4447 1970 )); -DATA(insert OID = 6140 ( 6083 4410 4410 2 o 6022 4447 1970 )); -DATA(insert OID = 6141 ( 6083 4410 4410 3 o 6023 4447 1970 )); -DATA(insert OID = 6142 ( 6083 4410 4410 4 o 6024 4447 1970 )); +DATA(insert OID = 6137 ( 6082 4410 4410 2 o 6023 4447 1970 )); +DATA(insert OID = 6138 ( 6082 4410 4410 3 o 6024 4447 1970 )); +DATA(insert OID = 6139 ( 6082 4410 4410 4 o 6053 4447 1970 )); +DATA(insert OID = 6140 ( 6083 4410 4410 1 o 6022 4447 1970 )); +DATA(insert OID = 6141 ( 6083 4410 4410 2 o 6023 4447 1970 )); +DATA(insert OID = 6142 ( 6083 4410 4410 3 o 6024 4447 1970 )); DATA(insert OID = 6143 ( 6083 4410 4410 4 o 6053 4447 1970 )); diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index fc05ca2902..ff7fc5e3c4 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1929,9 +1929,9 @@ DESCR("l1_distance"); -DATA(insert OID = 6162 ("+" PGNSP PGUID b f f 4409 4409 4409 6162 0 vector_add - -)); +DATA(insert OID = 6162 ("+" PGNSP PGUID b f f 4409 4409 4409 6162 0 vector_add 0 0)); DESCR("vector_add"); -DATA(insert OID = 6163 ("-" PGNSP PGUID b f f 4409 4409 4409 6163 0 vector_sub - -)); +DATA(insert OID = 6163 ("-" PGNSP PGUID b f f 4409 4409 4409 6163 0 vector_sub 0 0)); DESCR("vector_sub"); DATA(insert OID = 6164 ("<" PGNSP PGUID b f f 4409 4409 16 6164 6165 vector_lt scalarltsel scalarltjoinsel)); DESCR("vector less than"); @@ -1960,11 +1960,11 @@ DESCR("l1_distance"); DATA(insert OID = 6025 ("<->" PGNSP PGUID b f f 4411 4411 701 6025 0 sparsevec_l2_distance - -)); DESCR("sparsevec_l2_distance"); -DATA(insert OID = 6026 ("<#>" PGNSP PGUID b f f 4411 4411 701 6026 0 sparsevecvec_negative_inner_product - -)); -DESCR("sparsevecvec_negative_inner_product"); +DATA(insert OID = 6026 ("<#>" PGNSP PGUID b f f 4411 4411 701 6026 0 sparsevec_negative_inner_product - -)); +DESCR("sparsevec_negative_inner_product"); DATA(insert OID = 6027 ("<=>" PGNSP PGUID b f f 4411 4411 701 6027 0 sparsevec_cosine_distance - -)); DESCR("sparsevec_cosine_distance"); -DATA(insert OID = 6069 ("<+>" PGNSP PGUID b f f 4411 4411 16 6052 0 sparsevec_l1_distance - -)); +DATA(insert OID = 6069 ("<+>" PGNSP PGUID b f f 4411 4411 16 6069 0 sparsevec_l1_distance - -)); DESCR("sparsevec_l1_distance"); DATA(insert OID = 6028 ("<~>" PGNSP PGUID b f f 1560 1560 701 6028 0 jaccard_distance - -)); -- Gitee From a28dcc603baa4fd96e0b6c314273241fe5fe66ef Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Thu, 31 Oct 2024 18:13:10 +0800 Subject: [PATCH 05/67] =?UTF-8?q?=E4=BF=AE=E6=94=B9builtin=5Ffuncs.ini?= =?UTF-8?q?=E7=9A=84=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 759 ++----------------- 1 file changed, 69 insertions(+), 690 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 2448f59e47..6df31826c3 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13123,137 +13123,47 @@ AddFuncGroup( ), AddFuncGroup( "vector_in", 1, - AddBuiltinFunc( - _0(8000), - _1("vector_in"), - _2(3), _3(true), _4(false), - _5(vector_in), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8000), _1("vector_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_out", 1, - AddBuiltinFunc( - _0(8024), - _1("vector_out"), - _2(1), _3(true), _4(false), - _5(vector_out), - _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8024), _1("vector_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_typmod_in", 1, - AddBuiltinFunc( - _0(8002), - _1("vector_typmod_in"), - _2(1), _3(true), _4(false), - _5(vector_typmod_in), - _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8002), _1("vector_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_recv", 1, - AddBuiltinFunc( - _0(8003), - _1("vector_recv"), - _2(3), _3(true), _4(false), - _5(vector_recv), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8003), _1("vector_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_send", 1, - AddBuiltinFunc( - _0(8004), - _1("vector_send"), - _2(1), _3(true), _4(false), - _5(vector_send), - _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8004), _1("vector_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_dims", 1, - AddBuiltinFunc( - _0(8005), - _1("vector_dims"), - _2(1), _3(true), _4(false), - _5(vector_dims), - _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8005), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "array_to_vector", 1, - AddBuiltinFunc( - _0(8006), - _1("array_to_vector"), - _2(1), _3(true), _4(false), - _5(array_to_vector), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8006), _1("array_to_vector"), _2(1), _3(true), _4(false), _5(array_to_vector), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_to_float4", 1, - AddBuiltinFunc( - _0(8007), - _1("vector_to_float4"), - _2(1), _3(true), _4(false), - _5(vector_to_float4), - _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8007), _1("vector_to_float4"), _2(1), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_l2_squared_distance", 1, - AddBuiltinFunc( - _0(8008), - _1("vector_l2_squared_distance"), - _2(1), _3(true), _4(false), - _5(vector_l2_squared_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8008), _1("vector_l2_squared_distance"), _2(1), _3(true), _4(false), _5(vector_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_spherical_distance", 1, - AddBuiltinFunc( - _0(8009), - _1("vector_spherical_distance"), - _2(1), _3(true), _4(false), - _5(vector_spherical_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8009), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13262,135 +13172,45 @@ AddFuncGroup( AddFuncGroup( "inner_product", 1, - AddBuiltinFunc( - _0(8011), - _1("inner_product"), - _2(1), _3(true), _4(false), - _5(inner_product), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8011), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_norm", 1, - AddBuiltinFunc( - _0(8012), - _1("vector_norm"), - _2(1), _3(true), _4(false), - _5(vector_norm), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8012), _1("vector_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_add", 1, - AddBuiltinFunc( - _0(8013), - _1("vector_add"), - _2(1), _3(true), _4(false), - _5(vector_add), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_add"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8013), _1("vector_add"), _2(1), _3(true), _4(false), _5(vector_add), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_add"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_sub", 1, - AddBuiltinFunc( - _0(8014), - _1("vector_sub"), - _2(1), _3(true), _4(false), - _5(vector_sub), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8014), _1("vector_sub"), _2(1), _3(true), _4(false), _5(vector_sub), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_lt", 1, - AddBuiltinFunc( - _0(8015), - _1("vector_lt"), - _2(1), _3(true), _4(false), - _5(vector_lt), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8015), _1("vector_lt"), _2(1), _3(true), _4(false), _5(vector_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_le", 1, - AddBuiltinFunc( - _0(8016), - _1("vector_le"), - _2(1), _3(true), _4(false), - _5(vector_le), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8016), _1("vector_le"), _2(1), _3(true), _4(false), _5(vector_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_eq", 1, - AddBuiltinFunc( - _0(8017), - _1("vector_eq"), - _2(1), _3(true), _4(false), - _5(vector_eq), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8017), _1("vector_eq"), _2(1), _3(true), _4(false), _5(vector_eq), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_ne", 1, - AddBuiltinFunc( - _0(8018), - _1("vector_ne"), - _2(1), _3(true), _4(false), - _5(vector_ne), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8018), _1("vector_ne"), _2(1), _3(true), _4(false), _5(vector_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_ge", 1, - AddBuiltinFunc( - _0(8019), - _1("vector_ge"), - _2(1), _3(true), _4(false), - _5(vector_ge), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8019), _1("vector_ge"), _2(1), _3(true), _4(false), _5(vector_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_gt", 1, - AddBuiltinFunc( - _0(8020), - _1("vector_gt"), - _2(1), _3(true), _4(false), - _5(vector_gt), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8020), _1("vector_gt"), _2(1), _3(true), _4(false), _5(vector_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13411,43 +13231,16 @@ AddFuncGroup( AddFuncGroup( "vector_accum", 1, - AddBuiltinFunc( - _0(8021), - _1("vector_accum"), - _2(1), _3(true), _4(false), - _5(vector_accum), - _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 2277, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8021), _1("vector_accum"), _2(1), _3(true), _4(false), _5(vector_accum), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_combine", 1, - AddBuiltinFunc( - _0(8022), - _1("vector_combine"), - _2(1), _3(true), _4(false), - _5(vector_combine), - _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8022), _1("vector_combine"), _2(1), _3(true), _4(false), _5(vector_combine), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_avg", 1, - AddBuiltinFunc( - _0(8023), - _1("vector_avg"), - _2(1), _3(true), _4(false), - _5(vector_avg), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8023), _1("vector_avg"), _2(1), _3(true), _4(false), _5(vector_avg), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13457,226 +13250,73 @@ AddFuncGroup( AddFuncGroup( "hnswinsert", 1, - AddBuiltinFunc( - _0(8226), - _1("hnswinsert"), - _2(6), _3(true), _4(false), - _5(hnswinsert), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8226), _1("hnswinsert"), _2(6), _3(true), _4(false), _5(hnswinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswbeginscan", 1, - AddBuiltinFunc( - _0(8220), - _1("hnswbeginscan"), - _2(3), _3(true), _4(false), - _5(hnswbeginscan), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8220), _1("hnswbeginscan"), _2(3), _3(true), _4(false), _5(hnswbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswgettuple", 1, - AddBuiltinFunc( - _0(8229), - _1("hnswgettuple"), - _2(2), _3(true), _4(false), - _5(hnswgettuple), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8229), _1("hnswgettuple"), _2(2), _3(true), _4(false), _5(hnswgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswrescan", 1, - AddBuiltinFunc( - _0(8230), - _1("hnswrescan"), - _2(5), _3(true), _4(false), - _5(hnswrescan), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8230), _1("hnswrescan"), _2(5), _3(true), _4(false), _5(hnswrescan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswendscan", 1, - AddBuiltinFunc( - _0(8225), - _1("hnswendscan"), - _2(1), _3(true), _4(false), - _5(hnswendscan), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8225), _1("hnswendscan"), _2(1), _3(true), _4(false), _5(hnswendscan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswbuild", 1, - AddBuiltinFunc( - _0(8221), - _1("hnswbuild"), - _2(3), _3(true), _4(false), - _5(hnswbuild), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8221), _1("hnswbuild"), _2(3), _3(true), _4(false), _5(hnswbuild), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswbuildempty", 1, - AddBuiltinFunc( - _0(8222), - _1("hnswbuildempty"), - _2(1), _3(true), _4(false), - _5(hnswbuildempty), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8222), _1("hnswbuildempty"), _2(1), _3(true), _4(false), _5(hnswbuildempty), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswbulkdelete", 1, - AddBuiltinFunc( - _0(8223), - _1("hnswbulkdelete"), - _2(4), _3(true), _4(false), - _5(hnswbulkdelete), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8223), _1("hnswbulkdelete"), _2(4), _3(true), _4(false), _5(hnswbulkdelete), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswvacuumcleanup", 1, - AddBuiltinFunc( - _0(8228), - _1("hnswvacuumcleanup"), - _2(2), _3(true), _4(false), - _5(hnswvacuumcleanup), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8228), _1("hnswvacuumcleanup"), _2(2), _3(true), _4(false), _5(hnswvacuumcleanup), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswcostestimate", 1, - AddBuiltinFunc( - _0(8224), - _1("hnswcostestimate"), - _2(7), _3(true), _4(false), - _5(hnswcostestimate), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8224), _1("hnswcostestimate"), _2(7), _3(true), _4(false), _5(hnswcostestimate), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hnswoptions", 1, - AddBuiltinFunc( - _0(8227), - _1("hnswoptions"), - _2(2), _3(true), _4(false), - _5(hnswoptions), - _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hnswoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8227), _1("hnswoptions"), _2(2), _3(true), _4(false), _5(hnswoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_cmp", 1, - AddBuiltinFunc( - _0(8216), - _1("vector_cmp"), - _2(1), _3(true), _4(false), - _5(vector_cmp), - _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8216), _1("vector_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_cmp", 1, - AddBuiltinFunc( - _0(8217), - _1("halfvec_cmp"), - _2(1), _3(true), _4(false), - _5(vector_cmp), - _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8217), _1("halfvec_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "l2_distance", 1, - AddBuiltinFunc( - _0(8200), - _1("l2_distance"), - _2(1), _3(true), _4(false), - _5(l2_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8200), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_negative_inner_product", 1, - AddBuiltinFunc( - _0(8203), - _1("vector_negative_inner_product"), - _2(1), _3(true), _4(false), - _5(vector_negative_inner_product), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8203), _1("vector_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "cosine_distance", 1, - AddBuiltinFunc( - _0(8204), - _1("cosine_distance"), - _2(1), _3(true), _4(false), - _5(cosine_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8204), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "l1_distance", 1, - AddBuiltinFunc( - _0(8205), - _1("l1_distance"), - _2(1), _3(true), _4(false), - _5(l1_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8205), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13684,151 +13324,52 @@ AddFuncGroup( AddFuncGroup( "halfvec_in", 1, - AddBuiltinFunc( - _0(8206), - _1("halfvec_in"), - _2(3), _3(true), _4(false), - _5(vector_in), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8206), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_out", 1, - AddBuiltinFunc( - _0(8207), - _1("halfvec_out"), - _2(1), _3(true), _4(false), - _5(vector_out), - _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8207), _1("halfvec_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_typmod_in", 1, - AddBuiltinFunc( - _0(8208), - _1("halfvec_typmod_in"), - _2(1), _3(true), _4(false), - _5(vector_typmod_in), - _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8208), _1("halfvec_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_recv", 1, - AddBuiltinFunc( - _0(8209), - _1("halfvec_recv"), - _2(3), _3(true), _4(false), - _5(vector_recv), - _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8209), _1("halfvec_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_send", 1, - AddBuiltinFunc( - _0(8210), - _1("halfvec_send"), - _2(1), _3(true), _4(false), - _5(vector_send), - _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8210), _1("halfvec_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_negative_inner_product", 1, - AddBuiltinFunc( - _0(8211), - _1("halfvec_negative_inner_product"), - _2(1), _3(true), _4(false), - _5(halfvec_negative_inner_product), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("halfvec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8211), _1("halfvec_negative_inner_product"), _2(1), _3(true), _4(false), _5(halfvec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_in", 1, - AddBuiltinFunc( - _0(8231), - _1("sparsevec_in"), - _2(3), _3(true), _4(false), - _5(sparsevec_in), - _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8231), _1("sparsevec_in"), _2(3), _3(true), _4(false), _5(sparsevec_in), _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_out", 1, - AddBuiltinFunc( - _0(8232), - _1("sparsevec_out"), - _2(1), _3(true), _4(false), - _5(sparsevec_out), - _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8232), _1("sparsevec_out"), _2(1), _3(true), _4(false), _5(sparsevec_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_typmod_in", 1, - AddBuiltinFunc( - _0(8233), - _1("sparsevec_typmod_in"), - _2(1), _3(true), _4(false), - _5(sparsevec_typmod_in), - _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8233), _1("sparsevec_typmod_in"), _2(1), _3(true), _4(false), _5(sparsevec_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_recv", 1, - AddBuiltinFunc( - _0(8234), - _1("sparsevec_recv"), - _2(3), _3(true), _4(false), - _5(sparsevec_recv), - _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8234), _1("sparsevec_recv"), _2(3), _3(true), _4(false), _5(sparsevec_recv), _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_send", 1, - AddBuiltinFunc( - _0(8218), - _1("sparsevec_send"), - _2(1), _3(true), _4(false), - _5(sparsevec_send), - _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8218), _1("sparsevec_send"), _2(1), _3(true), _4(false), _5(sparsevec_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13839,97 +13380,34 @@ AddFuncGroup( AddFuncGroup( "sparsevec_negative_inner_product", 1, - AddBuiltinFunc( - _0(8219), - _1("sparsevec_negative_inner_product"), - _2(1), _3(true), _4(false), - _5(sparsevec_negative_inner_product), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8219), _1("sparsevec_negative_inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_cmp", 1, - AddBuiltinFunc( - _0(8235), - _1("sparsevec_cmp"), - _2(1), _3(true), _4(false), - _5(sparsevec_cmp), - _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8235), _1("sparsevec_cmp"), _2(1), _3(true), _4(false), _5(sparsevec_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_l2_distance", 1, - AddBuiltinFunc( - _0(8236), - _1("sparsevec_l2_distance"), - _2(1), _3(true), _4(false), - _5(sparsevec_l2_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8236), _1("sparsevec_l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_cosine_distance", 1, - AddBuiltinFunc( - _0(8237), - _1("sparsevec_cosine_distance"), - _2(1), _3(true), _4(false), - _5(sparsevec_cosine_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8237), _1("sparsevec_cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_l1_distance", 1, - AddBuiltinFunc( - _0(8238), - _1("sparsevec_l1_distance"), - _2(1), _3(true), _4(false), - _5(sparsevec_l1_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8238), _1("sparsevec_l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "jaccard_distance", 1, - AddBuiltinFunc( - _0(8239), - _1("jaccard_distance"), - _2(1), _3(true), _4(false), - _5(jaccard_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8239), _1("jaccard_distance"), _2(1), _3(true), _4(false), _5(jaccard_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hamming_distance", 1, - AddBuiltinFunc( - _0(8240), - _1("hamming_distance"), - _2(1), _3(true), _4(false), - _5(hamming_distance), - _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('i'), _19(0), - _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8240), _1("hamming_distance"), _2(1), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13938,147 +13416,48 @@ AddFuncGroup( AddFuncGroup( "ivfflatinsert", 1, - AddBuiltinFunc( - _0(8241), - _1("ivfflatinsert"), - _2(6), _3(true), _4(false), - _5(ivfflatinsert), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8241), _1("ivfflatinsert"), _2(6), _3(true), _4(false), _5(ivfflatinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatbeginscan", 1, - AddBuiltinFunc( - _0(8242), - _1("ivfflatbeginscan"), - _2(3), _3(true), _4(false), - _5(ivfflatbeginscan), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8242), _1("ivfflatbeginscan"), _2(3), _3(true), _4(false), _5(ivfflatbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatgettuple", 1, - AddBuiltinFunc( - _0(8243), - _1("ivfflatgettuple"), - _2(2), _3(true), _4(false), - _5(ivfflatgettuple), - _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8243), _1("ivfflatgettuple"), _2(2), _3(true), _4(false), _5(ivfflatgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatrescan", 1, - AddBuiltinFunc( - _0(8244), - _1("ivfflatrescan"), - _2(5), _3(true), _4(false), - _5(ivfflatrescan), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8244), _1("ivfflatrescan"), _2(5), _3(true), _4(false), _5(ivfflatrescan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatendscan", 1, - AddBuiltinFunc( - _0(8245), - _1("ivfflatendscan"), - _2(1), _3(true), _4(false), - _5(ivfflatendscan), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8245), _1("ivfflatendscan"), _2(1), _3(true), _4(false), _5(ivfflatendscan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatbuild", 1, - AddBuiltinFunc( - _0(8246), - _1("ivfflatbuild"), - _2(3), _3(true), _4(false), - _5(ivfflatbuild), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8246), _1("ivfflatbuild"), _2(3), _3(true), _4(false), _5(ivfflatbuild), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatbuildempty", 1, - AddBuiltinFunc( - _0(8247), - _1("ivfflatbuildempty"), - _2(1), _3(true), _4(false), - _5(ivfflatbuildempty), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8247), _1("ivfflatbuildempty"), _2(1), _3(true), _4(false), _5(ivfflatbuildempty), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatbulkdelete", 1, - AddBuiltinFunc( - _0(8248), - _1("ivfflatbulkdelete"), - _2(4), _3(true), _4(false), - _5(ivfflatbulkdelete), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc( _0(8248), _1("ivfflatbulkdelete"), _2(4), _3(true), _4(false), _5(ivfflatbulkdelete), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatvacuumcleanup", 1, - AddBuiltinFunc( - _0(8249), - _1("ivfflatvacuumcleanup"), - _2(2), _3(true), _4(false), - _5(ivfflatvacuumcleanup), - _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8249), _1("ivfflatvacuumcleanup"), _2(2), _3(true), _4(false), _5(ivfflatvacuumcleanup), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatcostestimate", 1, - AddBuiltinFunc( - _0(8250), - _1("ivfflatcostestimate"), - _2(7), _3(true), _4(false), - _5(ivfflatcostestimate), - _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('v'), _19(0), - _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8250), _1("ivfflatcostestimate"), _2(7), _3(true), _4(false), _5(ivfflatcostestimate), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflatoptions", 1, - AddBuiltinFunc( - _0(8251), - _1("ivfflatoptions"), - _2(2), _3(true), _4(false), - _5(ivfflatoptions), - _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), - _18('s'), _19(0), - _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), - _25("ivfflatoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), - _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8251), _1("ivfflatoptions"), _2(2), _3(true), _4(false), _5(ivfflatoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), -- Gitee From 7a6baebda7e41d18c280b84549aaadc7224bf4ce Mon Sep 17 00:00:00 2001 From: h30054849 Date: Fri, 1 Nov 2024 11:25:38 +0800 Subject: [PATCH 06/67] clean code --- src/common/backend/catalog/builtin_funcs.ini | 69 +------------------- src/include/catalog/pg_amop.data | 27 -------- src/include/catalog/pg_amproc.h | 2 - src/include/catalog/pg_opclass.h | 1 - src/include/catalog/pg_operator.data | 5 -- src/include/catalog/pg_opfamily.h | 2 +- src/include/catalog/pg_type.h | 6 +- 7 files changed, 6 insertions(+), 106 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 6df31826c3..99e366d3ed 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13125,7 +13125,6 @@ AddFuncGroup( "vector_in", 1, AddBuiltinFunc(_0(8000), _1("vector_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "vector_out", 1, AddBuiltinFunc(_0(8024), _1("vector_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13142,13 +13141,10 @@ AddFuncGroup( "vector_send", 1, AddBuiltinFunc(_0(8004), _1("vector_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - AddFuncGroup( "vector_dims", 1, AddBuiltinFunc(_0(8005), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "array_to_vector", 1, AddBuiltinFunc(_0(8006), _1("array_to_vector"), _2(1), _3(true), _4(false), _5(array_to_vector), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13165,16 +13161,10 @@ AddFuncGroup( "vector_spherical_distance", 1, AddBuiltinFunc(_0(8009), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - - AddFuncGroup( "inner_product", 1, AddBuiltinFunc(_0(8011), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "vector_norm", 1, AddBuiltinFunc(_0(8012), _1("vector_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13191,7 +13181,6 @@ AddFuncGroup( "vector_lt", 1, AddBuiltinFunc(_0(8015), _1("vector_lt"), _2(1), _3(true), _4(false), _5(vector_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "vector_le", 1, AddBuiltinFunc(_0(8016), _1("vector_le"), _2(1), _3(true), _4(false), _5(vector_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13212,28 +13201,10 @@ AddFuncGroup( "vector_gt", 1, AddBuiltinFunc(_0(8020), _1("vector_gt"), _2(1), _3(true), _4(false), _5(vector_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - - - - - - - - - - - - - - AddFuncGroup( "vector_accum", 1, AddBuiltinFunc(_0(8021), _1("vector_accum"), _2(1), _3(true), _4(false), _5(vector_accum), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "vector_combine", 1, AddBuiltinFunc(_0(8022), _1("vector_combine"), _2(1), _3(true), _4(false), _5(vector_combine), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13242,12 +13213,6 @@ AddFuncGroup( "vector_avg", 1, AddBuiltinFunc(_0(8023), _1("vector_avg"), _2(1), _3(true), _4(false), _5(vector_avg), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - - - AddFuncGroup( "hnswinsert", 1, AddBuiltinFunc(_0(8226), _1("hnswinsert"), _2(6), _3(true), _4(false), _5(hnswinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13256,8 +13221,7 @@ AddFuncGroup( "hnswbeginscan", 1, AddBuiltinFunc(_0(8220), _1("hnswbeginscan"), _2(3), _3(true), _4(false), _5(hnswbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - -AddFuncGroup( + AddFuncGroup( "hnswgettuple", 1, AddBuiltinFunc(_0(8229), _1("hnswgettuple"), _2(2), _3(true), _4(false), _5(hnswgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13293,7 +13257,6 @@ AddFuncGroup( "hnswoptions", 1, AddBuiltinFunc(_0(8227), _1("hnswoptions"), _2(2), _3(true), _4(false), _5(hnswoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "vector_cmp", 1, AddBuiltinFunc(_0(8216), _1("vector_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13318,15 +13281,10 @@ AddFuncGroup( "l1_distance", 1, AddBuiltinFunc(_0(8205), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - AddFuncGroup( "halfvec_in", 1, AddBuiltinFunc(_0(8206), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "halfvec_out", 1, AddBuiltinFunc(_0(8207), _1("halfvec_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13347,14 +13305,10 @@ AddFuncGroup( "halfvec_negative_inner_product", 1, AddBuiltinFunc(_0(8211), _1("halfvec_negative_inner_product"), _2(1), _3(true), _4(false), _5(halfvec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - AddFuncGroup( "sparsevec_in", 1, AddBuiltinFunc(_0(8231), _1("sparsevec_in"), _2(3), _3(true), _4(false), _5(sparsevec_in), _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "sparsevec_out", 1, AddBuiltinFunc(_0(8232), _1("sparsevec_out"), _2(1), _3(true), _4(false), _5(sparsevec_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13371,13 +13325,6 @@ AddFuncGroup( "sparsevec_send", 1, AddBuiltinFunc(_0(8218), _1("sparsevec_send"), _2(1), _3(true), _4(false), _5(sparsevec_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - - - - AddFuncGroup( "sparsevec_negative_inner_product", 1, AddBuiltinFunc(_0(8219), _1("sparsevec_negative_inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13390,7 +13337,6 @@ AddFuncGroup( "sparsevec_l2_distance", 1, AddBuiltinFunc(_0(8236), _1("sparsevec_l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "sparsevec_cosine_distance", 1, AddBuiltinFunc(_0(8237), _1("sparsevec_cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13399,8 +13345,6 @@ AddFuncGroup( "sparsevec_l1_distance", 1, AddBuiltinFunc(_0(8238), _1("sparsevec_l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - AddFuncGroup( "jaccard_distance", 1, AddBuiltinFunc(_0(8239), _1("jaccard_distance"), _2(1), _3(true), _4(false), _5(jaccard_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13409,11 +13353,6 @@ AddFuncGroup( "hamming_distance", 1, AddBuiltinFunc(_0(8240), _1("hamming_distance"), _2(1), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - - AddFuncGroup( "ivfflatinsert", 1, AddBuiltinFunc(_0(8241), _1("ivfflatinsert"), _2(6), _3(true), _4(false), _5(ivfflatinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13422,7 +13361,6 @@ AddFuncGroup( "ivfflatbeginscan", 1, AddBuiltinFunc(_0(8242), _1("ivfflatbeginscan"), _2(3), _3(true), _4(false), _5(ivfflatbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "ivfflatgettuple", 1, AddBuiltinFunc(_0(8243), _1("ivfflatgettuple"), _2(2), _3(true), _4(false), _5(ivfflatgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13458,7 +13396,4 @@ AddFuncGroup( AddFuncGroup( "ivfflatoptions", 1, AddBuiltinFunc(_0(8251), _1("ivfflatoptions"), _2(2), _3(true), _4(false), _5(ivfflatoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - - - + ), \ No newline at end of file diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 7ed846f6f2..76293159dc 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1595,9 +1595,7 @@ DATA(insert OID = 7273 ( 9570 9003 9003 3 s 5550 4439 0 )); DATA(insert OID = 7274 ( 9570 9003 9003 4 s 5549 4439 0 )); DATA(insert OID = 7275 ( 9570 9003 9003 5 s 5554 4439 0 )); DATA(insert OID = 6031 ( 6030 4409 4409 1 o 6019 4446 1970 )); - DATA(insert OID = 6041 ( 6040 4409 4409 1 o 6020 4446 1970 )); - DATA(insert OID = 6051 ( 6050 4409 4409 1 o 6019 4446 1970 )); DATA(insert OID = 6090 ( 6050 4409 4409 2 o 6020 4446 1970 )); DATA(insert OID = 6059 ( 6050 4409 4409 3 o 6021 4446 1970 )); @@ -1606,7 +1604,6 @@ DATA(insert OID = 6061 ( 6060 4409 4409 1 o 6019 4446 1970 )); DATA(insert OID = 6062 ( 6060 4409 4409 2 o 6020 4446 1970 )); DATA(insert OID = 6063 ( 6060 4409 4409 3 o 6021 4446 1970 )); DATA(insert OID = 6064 ( 6060 4409 4409 4 o 6052 4446 1970 )); - DATA(insert OID = 6036 ( 6035 4410 4410 1 o 6022 4446 1970 )); DATA(insert OID = 6136 ( 6035 4410 4410 2 o 6023 4446 1970 )); DATA(insert OID = 6236 ( 6035 4410 4410 3 o 6024 4446 1970 )); @@ -1623,7 +1620,6 @@ DATA(insert OID = 6066 ( 6065 4410 4410 1 o 6022 4446 1970 )); DATA(insert OID = 6166 ( 6065 4410 4410 2 o 6023 4446 1970 )); DATA(insert OID = 6266 ( 6065 4410 4410 3 o 6024 4446 1970 )); DATA(insert OID = 6366 ( 6065 4410 4410 4 o 6053 4446 424 )); - DATA(insert OID = 6091 ( 6071 4411 4411 1 o 6025 4446 1970 )); DATA(insert OID = 6092 ( 6071 4411 4411 2 o 6026 4446 1970 )); DATA(insert OID = 6093 ( 6071 4411 4411 3 o 6027 4446 1970 )); @@ -1640,22 +1636,11 @@ DATA(insert OID = 6103 ( 6074 4411 4411 1 o 6025 4446 1970 )); DATA(insert OID = 6104 ( 6074 4411 4411 2 o 6026 4446 1970 )); DATA(insert OID = 6105 ( 6074 4411 4411 3 o 6027 4446 1970 )); DATA(insert OID = 6106 ( 6074 4411 4411 4 o 6069 4446 1970 )); - - DATA(insert OID = 6107 ( 6075 1560 1560 1 o 6028 4446 1970 )); DATA(insert OID = 6108 ( 6075 1560 1560 2 o 6029 4446 1970 )); DATA(insert OID = 6109 ( 6076 1560 1560 1 o 6028 4446 1970 )); DATA(insert OID = 6110 ( 6076 1560 1560 2 o 6029 4446 1970 )); - - - - - - DATA(insert OID = 6111 ( 6077 4409 4409 1 o 6019 4447 1970 )); - - - DATA(insert OID = 6115 ( 6078 4409 4409 1 o 6019 4447 1970 )); DATA(insert OID = 6116 ( 6078 4409 4409 2 o 6020 4447 1970 )); DATA(insert OID = 6117 ( 6078 4409 4409 3 o 6021 4447 1970 )); @@ -1668,9 +1653,6 @@ DATA(insert OID = 6123 ( 6070 4409 4409 1 o 6019 4447 1970 )); DATA(insert OID = 6124 ( 6070 4409 4409 2 o 6020 4447 1970 )); DATA(insert OID = 6125 ( 6070 4409 4409 3 o 6021 4447 1970 )); DATA(insert OID = 6126 ( 6070 4409 4409 4 o 6052 4447 1970 )); - - - DATA(insert OID = 6127 ( 6080 4410 4410 1 o 6022 4447 1970 )); DATA(insert OID = 6128 ( 6080 4410 4410 2 o 6023 4447 1970 )); DATA(insert OID = 6129 ( 6080 4410 4410 3 o 6024 4447 1970 )); @@ -1687,16 +1669,7 @@ DATA(insert OID = 6140 ( 6083 4410 4410 1 o 6022 4447 1970 )); DATA(insert OID = 6141 ( 6083 4410 4410 2 o 6023 4447 1970 )); DATA(insert OID = 6142 ( 6083 4410 4410 3 o 6024 4447 1970 )); DATA(insert OID = 6143 ( 6083 4410 4410 4 o 6053 4447 1970 )); - - - - - - DATA(insert OID = 6144 ( 6084 1560 1560 1 o 6028 4447 1970 )); DATA(insert OID = 6145 ( 6084 1560 1560 2 o 6029 4447 1970 )); DATA(insert OID = 6147 ( 6085 1560 1560 1 o 6028 4447 1970 )); DATA(insert OID = 6148 ( 6085 1560 1560 2 o 6029 4447 1970 )); - - - diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 585e8393aa..e8f0a71aa1 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -673,8 +673,6 @@ DATA(insert OID = 6152( 6072 4411 4411 1 8219 )); DATA(insert OID = 6153( 6073 4411 4411 1 8219 )); DATA(insert OID = 6154( 6074 4411 4411 1 8219 )); - - DATA(insert ( 6077 4409 4409 1 8008 )); DATA(insert ( 6077 4409 4409 3 8200 )); diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 0aeabe8ee9..7b000a04f2 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -375,7 +375,6 @@ DATA(insert ( 405 settext_ops PGNSP PGUID 1995 3272 f 0 )); DATA(insert ( 4439 setasint_ops PGNSP PGUID 6976 3272 t 0 )); DATA(insert ( 405 set_ops PGNSP PGUID 8646 3272 t 0 )); - DATA(insert ( 4446 vector_l2_ops PGNSP PGUID 6030 4409 t 0 )); DATA(insert ( 4446 vector_ip_ops PGNSP PGUID 6040 4409 t 0 )); DATA(insert ( 4446 vector_cosine_ops PGNSP PGUID 6050 4409 t 0 )); diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index ff7fc5e3c4..4a4398bef1 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1927,8 +1927,6 @@ DESCR("cosine_distance"); DATA(insert OID = 6052 ("<+>" PGNSP PGUID b f f 4409 4409 16 6052 0 l1_distance - -)); DESCR("l1_distance"); - - DATA(insert OID = 6162 ("+" PGNSP PGUID b f f 4409 4409 4409 6162 0 vector_add 0 0)); DESCR("vector_add"); DATA(insert OID = 6163 ("-" PGNSP PGUID b f f 4409 4409 4409 6163 0 vector_sub 0 0)); @@ -1946,9 +1944,6 @@ DESCR("vector equal"); DATA(insert OID = 6170 ("<>" PGNSP PGUID b f f 4409 4409 16 6170 6169 vector_ne neqsel neqjoinsel)); DESCR("vector unequal"); - - - DATA(insert OID = 6022 ("<->" PGNSP PGUID b f f 4410 4410 701 6019 0 l2_distance - -)); DESCR("l2_distance"); DATA(insert OID = 6023 ("<#>" PGNSP PGUID b f f 4410 4410 701 6020 0 halfvec_negative_inner_product - -)); diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index bf1580e318..724ed1aa8f 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -199,7 +199,7 @@ DATA(insert OID = 4262 (4239 int1_ops PGNSP PGUID)); DATA(insert OID = 4263 (4239 bool_ops PGNSP PGUID)); DATA(insert OID = 4264 (4239 smalldatetime_ops PGNSP PGUID)); -/*datavec index ops*/ +/* datavec index */ DATA(insert OID = 6030 (4446 vector_l2_ops PGNSP PGUID)); DATA(insert OID = 6040 (4446 vector_ip_ops PGNSP PGUID)); DATA(insert OID = 6050 (4446 vector_cosine_ops PGNSP PGUID)); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index eaca30faf9..e848f0c9ed 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -823,13 +823,13 @@ DATA(insert OID = 4408 ( undefined PGNSP PGUID -2 f u W f t \054 0 0 0 undefin DESCR("undefined objects as PLSQL compilation time"); #define UNDEFINEDOID 4408 -DATA(insert OID = 4409 ( vector PGNSP PGUID -1 f b U f t \054 0 0 4411 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 4409 ( vector PGNSP PGUID -1 f b U f t \054 0 0 0 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); #define VECTOROID 4409 -DATA(insert OID = 4410 ( halfvec PGNSP PGUID -1 f b U f t \054 0 0 4411 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 4410 ( halfvec PGNSP PGUID -1 f b U f t \054 0 0 0 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); #define FLOATVECTOROID 4410 -DATA(insert OID = 4411 ( sparsevec PGNSP PGUID -1 f b U f t \054 0 0 4411 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 4411 ( sparsevec PGNSP PGUID -1 f b U f t \054 0 0 0 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); #define SPARSEVECTOROID 4411 /* -- Gitee From 38b7e00d863b15c68e33361ce69ac950d0a9cf0a Mon Sep 17 00:00:00 2001 From: h30054849 Date: Fri, 1 Nov 2024 14:49:22 +0800 Subject: [PATCH 07/67] clean code: indentation --- src/common/backend/utils/adt/bitvec.cpp | 37 +- src/common/backend/utils/adt/f2s.cpp | 1227 ++++++------- src/common/backend/utils/adt/halfutils.cpp | 330 ++-- src/common/backend/utils/adt/halfvec.cpp | 1360 +++++++------- src/common/backend/utils/adt/sparsevec.cpp | 1476 ++++++++-------- src/common/backend/utils/adt/vector.cpp | 1562 ++++++++--------- .../storage/access/datavec/bitutils.cpp | 192 +- .../storage/access/datavec/hnsw.cpp | 216 +-- .../storage/access/datavec/hnswbuild.cpp | 836 ++++----- .../storage/access/datavec/hnswinsert.cpp | 688 ++++---- .../storage/access/datavec/hnswscan.cpp | 30 +- .../storage/access/datavec/hnswutils.cpp | 1040 +++++------ .../storage/access/datavec/hnswvacuum.cpp | 1072 +++++------ .../storage/access/datavec/ivfbuild.cpp | 948 +++++----- .../storage/access/datavec/ivfflat.cpp | 250 +-- .../storage/access/datavec/ivfinsert.cpp | 350 ++-- .../storage/access/datavec/ivfkmeans.cpp | 802 ++++----- .../storage/access/datavec/ivfscan.cpp | 444 ++--- .../storage/access/datavec/ivfutils.cpp | 324 ++-- .../storage/access/datavec/ivfvacuum.cpp | 262 +-- src/include/access/datavec/halfutils.h | 348 ++-- src/include/access/datavec/halfvec.h | 8 +- src/include/access/datavec/hnsw.h | 226 +-- src/include/access/datavec/ivfflat.h | 232 +-- src/include/access/datavec/pg_prng.h | 8 +- src/include/access/datavec/ryu_common.h | 92 +- src/include/access/datavec/sampling.h | 18 +- src/include/access/datavec/sparsevec.h | 14 +- src/include/access/datavec/vector.h | 8 +- 29 files changed, 7155 insertions(+), 7245 deletions(-) diff --git a/src/common/backend/utils/adt/bitvec.cpp b/src/common/backend/utils/adt/bitvec.cpp index bbaeb4e9f7..46f86ad9b1 100644 --- a/src/common/backend/utils/adt/bitvec.cpp +++ b/src/common/backend/utils/adt/bitvec.cpp @@ -7,21 +7,20 @@ #include "varatt.h" #endif -uint64 (*BitHammingDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance); -double (*BitJaccardDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb); +uint64 (*BitHammingDistance)(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance); +double (*BitJaccardDistance)(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb); static THR_LOCAL bool BitvecNeedInitialization = true; /* * Allocate and initialize a new bit vector */ -VarBit * -InitBitVector(int dim) +VarBit *InitBitVector(int dim) { - VarBit *result; - int size; + VarBit *result; + int size; size = VARBITTOTALLEN(dim); - result = (VarBit *) palloc0(size); + result = (VarBit *)palloc0(size); SET_VARSIZE(result, size); VARBITLEN(result) = dim; @@ -31,24 +30,21 @@ InitBitVector(int dim) /* * Ensure same dimensions */ -static inline void -CheckDims(VarBit *a, VarBit *b) +static inline void CheckDims(VarBit *a, VarBit *b) { if (VARBITLEN(a) != VARBITLEN(b)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("different bit lengths %u and %u", VARBITLEN(a), VARBITLEN(b)))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different bit lengths %u and %u", VARBITLEN(a), VARBITLEN(b)))); } /* * Get the Hamming distance between two bit vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(hamming_distance); -Datum -hamming_distance(PG_FUNCTION_ARGS) +Datum hamming_distance(PG_FUNCTION_ARGS) { - VarBit *a = PG_GETARG_VARBIT_P(0); - VarBit *b = PG_GETARG_VARBIT_P(1); + VarBit *a = PG_GETARG_VARBIT_P(0); + VarBit *b = PG_GETARG_VARBIT_P(1); if (BitvecNeedInitialization) { BitvecInit(); @@ -57,18 +53,17 @@ hamming_distance(PG_FUNCTION_ARGS) CheckDims(a, b); - PG_RETURN_FLOAT8((double) BitHammingDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0)); + PG_RETURN_FLOAT8((double)BitHammingDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0)); } /* * Get the Jaccard distance between two bit vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(jaccard_distance); -Datum -jaccard_distance(PG_FUNCTION_ARGS) +Datum jaccard_distance(PG_FUNCTION_ARGS) { - VarBit *a = PG_GETARG_VARBIT_P(0); - VarBit *b = PG_GETARG_VARBIT_P(1); + VarBit *a = PG_GETARG_VARBIT_P(0); + VarBit *b = PG_GETARG_VARBIT_P(1); if (BitvecNeedInitialization) { BitvecInit(); diff --git a/src/common/backend/utils/adt/f2s.cpp b/src/common/backend/utils/adt/f2s.cpp index 56432680b2..6e10791fe0 100644 --- a/src/common/backend/utils/adt/f2s.cpp +++ b/src/common/backend/utils/adt/f2s.cpp @@ -52,683 +52,603 @@ */ #define FLOAT_POW5_INV_BITCOUNT 59 static const uint64 FLOAT_POW5_INV_SPLIT[31] = { - UINT64CONST(576460752303423489), UINT64CONST(461168601842738791), UINT64CONST(368934881474191033), UINT64CONST(295147905179352826), - UINT64CONST(472236648286964522), UINT64CONST(377789318629571618), UINT64CONST(302231454903657294), UINT64CONST(483570327845851670), - UINT64CONST(386856262276681336), UINT64CONST(309485009821345069), UINT64CONST(495176015714152110), UINT64CONST(396140812571321688), - UINT64CONST(316912650057057351), UINT64CONST(507060240091291761), UINT64CONST(405648192073033409), UINT64CONST(324518553658426727), - UINT64CONST(519229685853482763), UINT64CONST(415383748682786211), UINT64CONST(332306998946228969), UINT64CONST(531691198313966350), - UINT64CONST(425352958651173080), UINT64CONST(340282366920938464), UINT64CONST(544451787073501542), UINT64CONST(435561429658801234), - UINT64CONST(348449143727040987), UINT64CONST(557518629963265579), UINT64CONST(446014903970612463), UINT64CONST(356811923176489971), - UINT64CONST(570899077082383953), UINT64CONST(456719261665907162), UINT64CONST(365375409332725730) -}; + UINT64CONST(576460752303423489), UINT64CONST(461168601842738791), UINT64CONST(368934881474191033), + UINT64CONST(295147905179352826), UINT64CONST(472236648286964522), UINT64CONST(377789318629571618), + UINT64CONST(302231454903657294), UINT64CONST(483570327845851670), UINT64CONST(386856262276681336), + UINT64CONST(309485009821345069), UINT64CONST(495176015714152110), UINT64CONST(396140812571321688), + UINT64CONST(316912650057057351), UINT64CONST(507060240091291761), UINT64CONST(405648192073033409), + UINT64CONST(324518553658426727), UINT64CONST(519229685853482763), UINT64CONST(415383748682786211), + UINT64CONST(332306998946228969), UINT64CONST(531691198313966350), UINT64CONST(425352958651173080), + UINT64CONST(340282366920938464), UINT64CONST(544451787073501542), UINT64CONST(435561429658801234), + UINT64CONST(348449143727040987), UINT64CONST(557518629963265579), UINT64CONST(446014903970612463), + UINT64CONST(356811923176489971), UINT64CONST(570899077082383953), UINT64CONST(456719261665907162), + UINT64CONST(365375409332725730)}; #define FLOAT_POW5_BITCOUNT 61 static const uint64 FLOAT_POW5_SPLIT[47] = { - UINT64CONST(1152921504606846976), UINT64CONST(1441151880758558720), UINT64CONST(1801439850948198400), UINT64CONST(2251799813685248000), - UINT64CONST(1407374883553280000), UINT64CONST(1759218604441600000), UINT64CONST(2199023255552000000), UINT64CONST(1374389534720000000), - UINT64CONST(1717986918400000000), UINT64CONST(2147483648000000000), UINT64CONST(1342177280000000000), UINT64CONST(1677721600000000000), - UINT64CONST(2097152000000000000), UINT64CONST(1310720000000000000), UINT64CONST(1638400000000000000), UINT64CONST(2048000000000000000), - UINT64CONST(1280000000000000000), UINT64CONST(1600000000000000000), UINT64CONST(2000000000000000000), UINT64CONST(1250000000000000000), - UINT64CONST(1562500000000000000), UINT64CONST(1953125000000000000), UINT64CONST(1220703125000000000), UINT64CONST(1525878906250000000), - UINT64CONST(1907348632812500000), UINT64CONST(1192092895507812500), UINT64CONST(1490116119384765625), UINT64CONST(1862645149230957031), - UINT64CONST(1164153218269348144), UINT64CONST(1455191522836685180), UINT64CONST(1818989403545856475), UINT64CONST(2273736754432320594), - UINT64CONST(1421085471520200371), UINT64CONST(1776356839400250464), UINT64CONST(2220446049250313080), UINT64CONST(1387778780781445675), - UINT64CONST(1734723475976807094), UINT64CONST(2168404344971008868), UINT64CONST(1355252715606880542), UINT64CONST(1694065894508600678), - UINT64CONST(2117582368135750847), UINT64CONST(1323488980084844279), UINT64CONST(1654361225106055349), UINT64CONST(2067951531382569187), - UINT64CONST(1292469707114105741), UINT64CONST(1615587133892632177), UINT64CONST(2019483917365790221) -}; - -static inline uint32 -pow5Factor(uint32 value) + UINT64CONST(1152921504606846976), UINT64CONST(1441151880758558720), UINT64CONST(1801439850948198400), + UINT64CONST(2251799813685248000), UINT64CONST(1407374883553280000), UINT64CONST(1759218604441600000), + UINT64CONST(2199023255552000000), UINT64CONST(1374389534720000000), UINT64CONST(1717986918400000000), + UINT64CONST(2147483648000000000), UINT64CONST(1342177280000000000), UINT64CONST(1677721600000000000), + UINT64CONST(2097152000000000000), UINT64CONST(1310720000000000000), UINT64CONST(1638400000000000000), + UINT64CONST(2048000000000000000), UINT64CONST(1280000000000000000), UINT64CONST(1600000000000000000), + UINT64CONST(2000000000000000000), UINT64CONST(1250000000000000000), UINT64CONST(1562500000000000000), + UINT64CONST(1953125000000000000), UINT64CONST(1220703125000000000), UINT64CONST(1525878906250000000), + UINT64CONST(1907348632812500000), UINT64CONST(1192092895507812500), UINT64CONST(1490116119384765625), + UINT64CONST(1862645149230957031), UINT64CONST(1164153218269348144), UINT64CONST(1455191522836685180), + UINT64CONST(1818989403545856475), UINT64CONST(2273736754432320594), UINT64CONST(1421085471520200371), + UINT64CONST(1776356839400250464), UINT64CONST(2220446049250313080), UINT64CONST(1387778780781445675), + UINT64CONST(1734723475976807094), UINT64CONST(2168404344971008868), UINT64CONST(1355252715606880542), + UINT64CONST(1694065894508600678), UINT64CONST(2117582368135750847), UINT64CONST(1323488980084844279), + UINT64CONST(1654361225106055349), UINT64CONST(2067951531382569187), UINT64CONST(1292469707114105741), + UINT64CONST(1615587133892632177), UINT64CONST(2019483917365790221)}; + +static inline uint32 pow5Factor(uint32 value) { - uint32 count = 0; + uint32 count = 0; - for (;;) - { - Assert(value != 0); - const uint32 q = value / 5; - const uint32 r = value % 5; + for (;;) { + Assert(value != 0); + const uint32 q = value / 5; + const uint32 r = value % 5; - if (r != 0) - break; + if (r != 0) + break; - value = q; - ++count; - } - return count; + value = q; + ++count; + } + return count; } /* Returns true if value is divisible by 5^p. */ -static inline bool -multipleOfPowerOf5(const uint32 value, const uint32 p) +static inline bool multipleOfPowerOf5(const uint32 value, const uint32 p) { - return pow5Factor(value) >= p; + return pow5Factor(value) >= p; } /* Returns true if value is divisible by 2^p. */ -static inline bool -multipleOfPowerOf2(const uint32 value, const uint32 p) +static inline bool multipleOfPowerOf2(const uint32 value, const uint32 p) { - /* return __builtin_ctz(value) >= p; */ - return (value & ((1u << p) - 1)) == 0; + /* return __builtin_ctz(value) >= p; */ + return (value & ((1u << p) - 1)) == 0; } /* * It seems to be slightly faster to avoid uint128_t here, although the * generated code for uint128_t looks slightly nicer. */ -static inline uint32 -mulShift(const uint32 m, const uint64 factor, const int32 shift) +static inline uint32 mulShift(const uint32 m, const uint64 factor, const int32 shift) { - /* - * The casts here help MSVC to avoid calls to the __allmul library - * function. - */ - const uint32 factorLo = (uint32) (factor); - const uint32 factorHi = (uint32) (factor >> 32); - const uint64 bits0 = (uint64) m * factorLo; - const uint64 bits1 = (uint64) m * factorHi; + /* + * The casts here help MSVC to avoid calls to the __allmul library + * function. + */ + const uint32 factorLo = (uint32)(factor); + const uint32 factorHi = (uint32)(factor >> 32); + const uint64 bits0 = (uint64)m * factorLo; + const uint64 bits1 = (uint64)m * factorHi; - Assert(shift > 32); + Assert(shift > 32); #ifdef RYU_32_BIT_PLATFORM - /* - * On 32-bit platforms we can avoid a 64-bit shift-right since we only - * need the upper 32 bits of the result and the shift value is > 32. - */ - const uint32 bits0Hi = (uint32) (bits0 >> 32); - uint32 bits1Lo = (uint32) (bits1); - uint32 bits1Hi = (uint32) (bits1 >> 32); + /* + * On 32-bit platforms we can avoid a 64-bit shift-right since we only + * need the upper 32 bits of the result and the shift value is > 32. + */ + const uint32 bits0Hi = (uint32)(bits0 >> 32); + uint32 bits1Lo = (uint32)(bits1); + uint32 bits1Hi = (uint32)(bits1 >> 32); - bits1Lo += bits0Hi; - bits1Hi += (bits1Lo < bits0Hi); + bits1Lo += bits0Hi; + bits1Hi += (bits1Lo < bits0Hi); - const int32 s = shift - 32; + const int32 s = shift - 32; - return (bits1Hi << (32 - s)) | (bits1Lo >> s); + return (bits1Hi << (32 - s)) | (bits1Lo >> s); -#else /* RYU_32_BIT_PLATFORM */ +#else /* RYU_32_BIT_PLATFORM */ - const uint64 sum = (bits0 >> 32) + bits1; - const uint64 shiftedSum = sum >> (shift - 32); + const uint64 sum = (bits0 >> 32) + bits1; + const uint64 shiftedSum = sum >> (shift - 32); - Assert(shiftedSum <= UINT32_MAX); - return (uint32) shiftedSum; + Assert(shiftedSum <= UINT32_MAX); + return (uint32)shiftedSum; -#endif /* RYU_32_BIT_PLATFORM */ +#endif /* RYU_32_BIT_PLATFORM */ } -static inline uint32 -mulPow5InvDivPow2(const uint32 m, const uint32 q, const int32 j) +static inline uint32 mulPow5InvDivPow2(const uint32 m, const uint32 q, const int32 j) { - return mulShift(m, FLOAT_POW5_INV_SPLIT[q], j); + return mulShift(m, FLOAT_POW5_INV_SPLIT[q], j); } -static inline uint32 -mulPow5divPow2(const uint32 m, const uint32 i, const int32 j) +static inline uint32 mulPow5divPow2(const uint32 m, const uint32 i, const int32 j) { - return mulShift(m, FLOAT_POW5_SPLIT[i], j); + return mulShift(m, FLOAT_POW5_SPLIT[i], j); } -static inline uint32 -decimalLength(const uint32 v) +static inline uint32 decimalLength(const uint32 v) { - /* Function precondition: v is not a 10-digit number. */ - /* (9 digits are sufficient for round-tripping.) */ - Assert(v < 1000000000); - if (v >= 100000000) - { - return 9; - } - if (v >= 10000000) - { - return 8; - } - if (v >= 1000000) - { - return 7; - } - if (v >= 100000) - { - return 6; - } - if (v >= 10000) - { - return 5; - } - if (v >= 1000) - { - return 4; - } - if (v >= 100) - { - return 3; - } - if (v >= 10) - { - return 2; - } - return 1; + /* Function precondition: v is not a 10-digit number. */ + /* (9 digits are sufficient for round-tripping.) */ + Assert(v < 1000000000); + if (v >= 100000000) { + return 9; + } + if (v >= 10000000) { + return 8; + } + if (v >= 1000000) { + return 7; + } + if (v >= 100000) { + return 6; + } + if (v >= 10000) { + return 5; + } + if (v >= 1000) { + return 4; + } + if (v >= 100) { + return 3; + } + if (v >= 10) { + return 2; + } + return 1; } /* A floating decimal representing m * 10^e. */ -typedef struct floating_decimal_32 -{ - uint32 mantissa; - int32 exponent; +typedef struct floating_decimal_32 { + uint32 mantissa; + int32 exponent; } floating_decimal_32; -static inline floating_decimal_32 -f2d(const uint32 ieeeMantissa, const uint32 ieeeExponent) +static inline floating_decimal_32 f2d(const uint32 ieeeMantissa, const uint32 ieeeExponent) { - int32 e2; - uint32 m2; - - if (ieeeExponent == 0) - { - /* We subtract 2 so that the bounds computation has 2 additional bits. */ - e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; - m2 = ieeeMantissa; - } - else - { - e2 = ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; - m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa; - } + int32 e2; + uint32 m2; + + if (ieeeExponent == 0) { + /* We subtract 2 so that the bounds computation has 2 additional bits. */ + e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; + m2 = ieeeMantissa; + } else { + e2 = ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; + m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa; + } #if STRICTLY_SHORTEST - const bool even = (m2 & 1) == 0; - const bool acceptBounds = even; + const bool even = (m2 & 1) == 0; + const bool acceptBounds = even; #else - const bool acceptBounds = false; + const bool acceptBounds = false; #endif - /* Step 2: Determine the interval of legal decimal representations. */ - const uint32 mv = 4 * m2; - const uint32 mp = 4 * m2 + 2; - - /* Implicit bool -> int conversion. True is 1, false is 0. */ - const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; - const uint32 mm = 4 * m2 - 1 - mmShift; - - /* Step 3: Convert to a decimal power base using 64-bit arithmetic. */ - uint32 vr, - vp, - vm; - int32 e10; - bool vmIsTrailingZeros = false; - bool vrIsTrailingZeros = false; - uint8 lastRemovedDigit = 0; - - if (e2 >= 0) - { - const uint32 q = log10Pow2(e2); - - e10 = q; - - const int32 k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1; - const int32 i = -e2 + q + k; - - vr = mulPow5InvDivPow2(mv, q, i); - vp = mulPow5InvDivPow2(mp, q, i); - vm = mulPow5InvDivPow2(mm, q, i); - - if (q != 0 && (vp - 1) / 10 <= vm / 10) - { - /* - * We need to know one removed digit even if we are not going to - * loop below. We could use q = X - 1 above, except that would - * require 33 bits for the result, and we've found that 32-bit - * arithmetic is faster even on 64-bit machines. - */ - const int32 l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q - 1) - 1; - - lastRemovedDigit = (uint8) (mulPow5InvDivPow2(mv, q - 1, -e2 + q - 1 + l) % 10); - } - if (q <= 9) - { - /* - * The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 - * seems to be safe as well. - * - * Only one of mp, mv, and mm can be a multiple of 5, if any. - */ - if (mv % 5 == 0) - { - vrIsTrailingZeros = multipleOfPowerOf5(mv, q); - } - else if (acceptBounds) - { - vmIsTrailingZeros = multipleOfPowerOf5(mm, q); - } - else - { - vp -= multipleOfPowerOf5(mp, q); - } - } - } - else - { - const uint32 q = log10Pow5(-e2); - - e10 = q + e2; - - const int32 i = -e2 - q; - const int32 k = pow5bits(i) - FLOAT_POW5_BITCOUNT; - int32 j = q - k; - - vr = mulPow5divPow2(mv, i, j); - vp = mulPow5divPow2(mp, i, j); - vm = mulPow5divPow2(mm, i, j); - - if (q != 0 && (vp - 1) / 10 <= vm / 10) - { - j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); - lastRemovedDigit = (uint8) (mulPow5divPow2(mv, i + 1, j) % 10); - } - if (q <= 1) - { - /* - * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q - * trailing 0 bits. - */ - /* mv = 4 * m2, so it always has at least two trailing 0 bits. */ - vrIsTrailingZeros = true; - if (acceptBounds) - { - /* - * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff - * mmShift == 1. - */ - vmIsTrailingZeros = mmShift == 1; - } - else - { - /* - * mp = mv + 2, so it always has at least one trailing 0 bit. - */ - --vp; - } - } - else if (q < 31) - { - /* TODO(ulfjack):Use a tighter bound here. */ - vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); - } - } - - /* - * Step 4: Find the shortest decimal representation in the interval of - * legal representations. - */ - uint32 removed = 0; - uint32 output; - - if (vmIsTrailingZeros || vrIsTrailingZeros) - { - /* General case, which happens rarely (~4.0%). */ - while (vp / 10 > vm / 10) - { - vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0; - vrIsTrailingZeros &= lastRemovedDigit == 0; - lastRemovedDigit = (uint8) (vr % 10); - vr /= 10; - vp /= 10; - vm /= 10; - ++removed; - } - if (vmIsTrailingZeros) - { - while (vm % 10 == 0) - { - vrIsTrailingZeros &= lastRemovedDigit == 0; - lastRemovedDigit = (uint8) (vr % 10); - vr /= 10; - vp /= 10; - vm /= 10; - ++removed; - } - } - - if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) - { - /* Round even if the exact number is .....50..0. */ - lastRemovedDigit = 4; - } - - /* - * We need to take vr + 1 if vr is outside bounds or we need to round - * up. - */ - output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); - } - else - { - /* - * Specialized for the common case (~96.0%). Percentages below are - * relative to this. - * - * Loop iterations below (approximately): 0: 13.6%, 1: 70.7%, 2: - * 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% - */ - while (vp / 10 > vm / 10) - { - lastRemovedDigit = (uint8) (vr % 10); - vr /= 10; - vp /= 10; - vm /= 10; - ++removed; - } - - /* - * We need to take vr + 1 if vr is outside bounds or we need to round - * up. - */ - output = vr + (vr == vm || lastRemovedDigit >= 5); - } - - const int32 exp = e10 + removed; - - floating_decimal_32 fd; - - fd.exponent = exp; - fd.mantissa = output; - return fd; + /* Step 2: Determine the interval of legal decimal representations. */ + const uint32 mv = 4 * m2; + const uint32 mp = 4 * m2 + 2; + + /* Implicit bool -> int conversion. True is 1, false is 0. */ + const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; + const uint32 mm = 4 * m2 - 1 - mmShift; + + /* Step 3: Convert to a decimal power base using 64-bit arithmetic. */ + uint32 vr, vp, vm; + int32 e10; + bool vmIsTrailingZeros = false; + bool vrIsTrailingZeros = false; + uint8 lastRemovedDigit = 0; + + if (e2 >= 0) { + const uint32 q = log10Pow2(e2); + + e10 = q; + + const int32 k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1; + const int32 i = -e2 + q + k; + + vr = mulPow5InvDivPow2(mv, q, i); + vp = mulPow5InvDivPow2(mp, q, i); + vm = mulPow5InvDivPow2(mm, q, i); + + if (q != 0 && (vp - 1) / 10 <= vm / 10) { + /* + * We need to know one removed digit even if we are not going to + * loop below. We could use q = X - 1 above, except that would + * require 33 bits for the result, and we've found that 32-bit + * arithmetic is faster even on 64-bit machines. + */ + const int32 l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q - 1) - 1; + + lastRemovedDigit = (uint8)(mulPow5InvDivPow2(mv, q - 1, -e2 + q - 1 + l) % 10); + } + if (q <= 9) { + /* + * The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 + * seems to be safe as well. + * + * Only one of mp, mv, and mm can be a multiple of 5, if any. + */ + if (mv % 5 == 0) { + vrIsTrailingZeros = multipleOfPowerOf5(mv, q); + } else if (acceptBounds) { + vmIsTrailingZeros = multipleOfPowerOf5(mm, q); + } else { + vp -= multipleOfPowerOf5(mp, q); + } + } + } else { + const uint32 q = log10Pow5(-e2); + + e10 = q + e2; + + const int32 i = -e2 - q; + const int32 k = pow5bits(i) - FLOAT_POW5_BITCOUNT; + int32 j = q - k; + + vr = mulPow5divPow2(mv, i, j); + vp = mulPow5divPow2(mp, i, j); + vm = mulPow5divPow2(mm, i, j); + + if (q != 0 && (vp - 1) / 10 <= vm / 10) { + j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); + lastRemovedDigit = (uint8)(mulPow5divPow2(mv, i + 1, j) % 10); + } + if (q <= 1) { + /* + * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q + * trailing 0 bits. + */ + /* mv = 4 * m2, so it always has at least two trailing 0 bits. */ + vrIsTrailingZeros = true; + if (acceptBounds) { + /* + * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff + * mmShift == 1. + */ + vmIsTrailingZeros = mmShift == 1; + } else { + /* + * mp = mv + 2, so it always has at least one trailing 0 bit. + */ + --vp; + } + } else if (q < 31) { + /* TODO(ulfjack):Use a tighter bound here. */ + vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); + } + } + + /* + * Step 4: Find the shortest decimal representation in the interval of + * legal representations. + */ + uint32 removed = 0; + uint32 output; + + if (vmIsTrailingZeros || vrIsTrailingZeros) { + /* General case, which happens rarely (~4.0%). */ + while (vp / 10 > vm / 10) { + vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0; + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8)(vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + if (vmIsTrailingZeros) { + while (vm % 10 == 0) { + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8)(vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + } + + if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) { + /* Round even if the exact number is .....50..0. */ + lastRemovedDigit = 4; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); + } else { + /* + * Specialized for the common case (~96.0%). Percentages below are + * relative to this. + * + * Loop iterations below (approximately): 0: 13.6%, 1: 70.7%, 2: + * 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% + */ + while (vp / 10 > vm / 10) { + lastRemovedDigit = (uint8)(vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + (vr == vm || lastRemovedDigit >= 5); + } + + const int32 exp = e10 + removed; + + floating_decimal_32 fd; + + fd.exponent = exp; + fd.mantissa = output; + return fd; } -static inline int -to_chars_f(const floating_decimal_32 v, const uint32 olength, char *const result) +static inline int to_chars_f(const floating_decimal_32 v, const uint32 olength, char *const result) { - /* Step 5: Print the decimal representation. */ - int index = 0; - - uint32 output = v.mantissa; - int32 exp = v.exponent; - - /*---- - * On entry, mantissa * 10^exp is the result to be output. - * Caller has already done the - sign if needed. - * - * We want to insert the point somewhere depending on the output length - * and exponent, which might mean adding zeros: - * - * exp | format - * 1+ | ddddddddd000000 - * 0 | ddddddddd - * -1 .. -len+1 | dddddddd.d to d.ddddddddd - * -len ... | 0.ddddddddd to 0.000dddddd - */ - uint32 i = 0; - int32 nexp = exp + olength; - - if (nexp <= 0) - { - /* -nexp is number of 0s to add after '.' */ - Assert(nexp >= -3); - /* 0.000ddddd */ - index = 2 - nexp; - /* copy 8 bytes rather than 5 to let compiler optimize */ - memcpy(result, "0.000000", 8); - } - else if (exp < 0) - { - /* - * dddd.dddd; leave space at the start and move the '.' in after - */ - index = 1; - } - else - { - /* - * We can save some code later by pre-filling with zeros. We know - * that there can be no more than 6 output digits in this form, - * otherwise we would not choose fixed-point output. memset 8 - * rather than 6 bytes to let the compiler optimize it. - */ - Assert(exp < 6 && exp + olength <= 6); - memset(result, '0', 8); - } - - while (output >= 10000) - { - const uint32 c = output - 10000 * (output / 10000); - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - - output /= 10000; - - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); - i += 4; - } - if (output >= 100) - { - const uint32 c = (output % 100) << 1; - - output /= 100; - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); - i += 2; - } - if (output >= 10) - { - const uint32 c = output << 1; - - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); - } - else - { - result[index] = (char) ('0' + output); - } - - if (index == 1) - { - /* - * nexp is 1..6 here, representing the number of digits before the - * point. A value of 7+ is not possible because we switch to - * scientific notation when the display exponent reaches 6. - */ - Assert(nexp < 7); - /* gcc only seems to want to optimize memmove for small 2^n */ - if (nexp & 4) - { - memmove(result + index - 1, result + index, 4); - index += 4; - } - if (nexp & 2) - { - memmove(result + index - 1, result + index, 2); - index += 2; - } - if (nexp & 1) - { - result[index - 1] = result[index]; - } - result[nexp] = '.'; - index = olength + 1; - } - else if (exp >= 0) - { - /* we supplied the trailing zeros earlier, now just set the length. */ - index = olength + exp; - } - else - { - index = olength + (2 - nexp); - } - - return index; + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint32 output = v.mantissa; + int32 exp = v.exponent; + + /*---- + * On entry, mantissa * 10^exp is the result to be output. + * Caller has already done the - sign if needed. + * + * We want to insert the point somewhere depending on the output length + * and exponent, which might mean adding zeros: + * + * exp | format + * 1+ | ddddddddd000000 + * 0 | ddddddddd + * -1 .. -len+1 | dddddddd.d to d.ddddddddd + * -len ... | 0.ddddddddd to 0.000dddddd + */ + uint32 i = 0; + int32 nexp = exp + olength; + + if (nexp <= 0) { + /* -nexp is number of 0s to add after '.' */ + Assert(nexp >= -3); + /* 0.000ddddd */ + index = 2 - nexp; + /* copy 8 bytes rather than 5 to let compiler optimize */ + memcpy(result, "0.000000", 8); + } else if (exp < 0) { + /* + * dddd.dddd; leave space at the start and move the '.' in after + */ + index = 1; + } else { + /* + * We can save some code later by pre-filling with zeros. We know + * that there can be no more than 6 output digits in this form, + * otherwise we would not choose fixed-point output. memset 8 + * rather than 6 bytes to let the compiler optimize it. + */ + Assert(exp < 6 && exp + olength <= 6); + memset(result, '0', 8); + } + + while (output >= 10000) { + const uint32 c = output - 10000 * (output / 10000); + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + output /= 10000; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output >= 100) { + const uint32 c = (output % 100) << 1; + + output /= 100; + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + i += 2; + } + if (output >= 10) { + const uint32 c = output << 1; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + } else { + result[index] = (char)('0' + output); + } + + if (index == 1) { + /* + * nexp is 1..6 here, representing the number of digits before the + * point. A value of 7+ is not possible because we switch to + * scientific notation when the display exponent reaches 6. + */ + Assert(nexp < 7); + /* gcc only seems to want to optimize memmove for small 2^n */ + if (nexp & 4) { + memmove(result + index - 1, result + index, 4); + index += 4; + } + if (nexp & 2) { + memmove(result + index - 1, result + index, 2); + index += 2; + } + if (nexp & 1) { + result[index - 1] = result[index]; + } + result[nexp] = '.'; + index = olength + 1; + } else if (exp >= 0) { + /* we supplied the trailing zeros earlier, now just set the length. */ + index = olength + exp; + } else { + index = olength + (2 - nexp); + } + + return index; } -static inline int -to_chars(const floating_decimal_32 v, const bool sign, char *const result) +static inline int to_chars(const floating_decimal_32 v, const bool sign, char *const result) { - /* Step 5: Print the decimal representation. */ - int index = 0; - - uint32 output = v.mantissa; - uint32 olength = decimalLength(output); - int32 exp = v.exponent + olength - 1; - - if (sign) - result[index++] = '-'; - - /* - * The thresholds for fixed-point output are chosen to match printf - * defaults. Beware that both the code of to_chars_f and the value - * of FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. - */ - if (exp >= -4 && exp < 6) - return to_chars_f(v, olength, result + index) + sign; - - /* - * If v.exponent is exactly 0, we might have reached here via the small - * integer fast path, in which case v.mantissa might contain trailing - * (decimal) zeros. For scientific notation we need to move these zeros - * into the exponent. (For fixed point this doesn't matter, which is why - * we do this here rather than above.) - * - * Since we already calculated the display exponent (exp) above based on - * the old decimal length, that value does not change here. Instead, we - * just reduce the display length for each digit removed. - * - * If we didn't get here via the fast path, the raw exponent will not - * usually be 0, and there will be no trailing zeros, so we pay no more - * than one div10/multiply extra cost. We claw back half of that by - * checking for divisibility by 2 before dividing by 10. - */ - if (v.exponent == 0) - { - while ((output & 1) == 0) - { - const uint32 q = output / 10; - const uint32 r = output - 10 * q; - - if (r != 0) - break; - output = q; - --olength; - } - } - - /*---- - * Print the decimal digits. - * The following code is equivalent to: - * - * for (uint32 i = 0; i < olength - 1; ++i) { - * const uint32 c = output % 10; output /= 10; - * result[index + olength - i] = (char) ('0' + c); - * } - * result[index] = '0' + output % 10; - */ - uint32 i = 0; - - while (output >= 10000) - { - const uint32 c = output - 10000 * (output / 10000); - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - - output /= 10000; - - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); - i += 4; - } - if (output >= 100) - { - const uint32 c = (output % 100) << 1; - - output /= 100; - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); - i += 2; - } - if (output >= 10) - { - const uint32 c = output << 1; - - /* - * We can't use memcpy here: the decimal dot goes between these two - * digits. - */ - result[index + olength - i] = DIGIT_TABLE[c + 1]; - result[index] = DIGIT_TABLE[c]; - } - else - { - result[index] = (char) ('0' + output); - } - - /* Print decimal point if needed. */ - if (olength > 1) - { - result[index + 1] = '.'; - index += olength + 1; - } - else - { - ++index; - } - - /* Print the exponent. */ - result[index++] = 'e'; - if (exp < 0) - { - result[index++] = '-'; - exp = -exp; - } - else - result[index++] = '+'; - - memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); - index += 2; - - return index; + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint32 output = v.mantissa; + uint32 olength = decimalLength(output); + int32 exp = v.exponent + olength - 1; + + if (sign) + result[index++] = '-'; + + /* + * The thresholds for fixed-point output are chosen to match printf + * defaults. Beware that both the code of to_chars_f and the value + * of FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. + */ + if (exp >= -4 && exp < 6) + return to_chars_f(v, olength, result + index) + sign; + + /* + * If v.exponent is exactly 0, we might have reached here via the small + * integer fast path, in which case v.mantissa might contain trailing + * (decimal) zeros. For scientific notation we need to move these zeros + * into the exponent. (For fixed point this doesn't matter, which is why + * we do this here rather than above.) + * + * Since we already calculated the display exponent (exp) above based on + * the old decimal length, that value does not change here. Instead, we + * just reduce the display length for each digit removed. + * + * If we didn't get here via the fast path, the raw exponent will not + * usually be 0, and there will be no trailing zeros, so we pay no more + * than one div10/multiply extra cost. We claw back half of that by + * checking for divisibility by 2 before dividing by 10. + */ + if (v.exponent == 0) { + while ((output & 1) == 0) { + const uint32 q = output / 10; + const uint32 r = output - 10 * q; + + if (r != 0) + break; + output = q; + --olength; + } + } + + /*---- + * Print the decimal digits. + * The following code is equivalent to: + * + * for (uint32 i = 0; i < olength - 1; ++i) { + * const uint32 c = output % 10; output /= 10; + * result[index + olength - i] = (char) ('0' + c); + * } + * result[index] = '0' + output % 10; + */ + uint32 i = 0; + + while (output >= 10000) { + const uint32 c = output - 10000 * (output / 10000); + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + output /= 10000; + + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output >= 100) { + const uint32 c = (output % 100) << 1; + + output /= 100; + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); + i += 2; + } + if (output >= 10) { + const uint32 c = output << 1; + + /* + * We can't use memcpy here: the decimal dot goes between these two + * digits. + */ + result[index + olength - i] = DIGIT_TABLE[c + 1]; + result[index] = DIGIT_TABLE[c]; + } else { + result[index] = (char)('0' + output); + } + + /* Print decimal point if needed. */ + if (olength > 1) { + result[index + 1] = '.'; + index += olength + 1; + } else { + ++index; + } + + /* Print the exponent. */ + result[index++] = 'e'; + if (exp < 0) { + result[index++] = '-'; + exp = -exp; + } else + result[index++] = '+'; + + memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); + index += 2; + + return index; } -static inline bool -f2d_small_int(const uint32 ieeeMantissa, - const uint32 ieeeExponent, - floating_decimal_32 *v) +static inline bool f2d_small_int(const uint32 ieeeMantissa, const uint32 ieeeExponent, floating_decimal_32 *v) { - const int32 e2 = (int32) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS; - - /* - * Avoid using multiple "return false;" here since it tends to provoke the - * compiler into inlining multiple copies of f2d, which is undesirable. - */ - - if (e2 >= -FLOAT_MANTISSA_BITS && e2 <= 0) - { - /*---- - * Since 2^23 <= m2 < 2^24 and 0 <= -e2 <= 23: - * 1 <= f = m2 / 2^-e2 < 2^24. - * - * Test if the lower -e2 bits of the significand are 0, i.e. whether - * the fraction is 0. We can use ieeeMantissa here, since the implied - * 1 bit can never be tested by this; the implied 1 can only be part - * of a fraction if e2 < -FLOAT_MANTISSA_BITS which we already - * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -24) - */ - const uint32 mask = (1U << -e2) - 1; - const uint32 fraction = ieeeMantissa & mask; - - if (fraction == 0) - { - /*---- - * f is an integer in the range [1, 2^24). - * Note: mantissa might contain trailing (decimal) 0's. - * Note: since 2^24 < 10^9, there is no need to adjust - * decimalLength(). - */ - const uint32 m2 = (1U << FLOAT_MANTISSA_BITS) | ieeeMantissa; - - v->mantissa = m2 >> -e2; - v->exponent = 0; - return true; - } - } - - return false; + const int32 e2 = (int32)ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS; + + /* + * Avoid using multiple "return false;" here since it tends to provoke the + * compiler into inlining multiple copies of f2d, which is undesirable. + */ + + if (e2 >= -FLOAT_MANTISSA_BITS && e2 <= 0) { + /*---- + * Since 2^23 <= m2 < 2^24 and 0 <= -e2 <= 23: + * 1 <= f = m2 / 2^-e2 < 2^24. + * + * Test if the lower -e2 bits of the significand are 0, i.e. whether + * the fraction is 0. We can use ieeeMantissa here, since the implied + * 1 bit can never be tested by this; the implied 1 can only be part + * of a fraction if e2 < -FLOAT_MANTISSA_BITS which we already + * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -24) + */ + const uint32 mask = (1U << -e2) - 1; + const uint32 fraction = ieeeMantissa & mask; + + if (fraction == 0) { + /*---- + * f is an integer in the range [1, 2^24). + * Note: mantissa might contain trailing (decimal) 0's. + * Note: since 2^24 < 10^9, there is no need to adjust + * decimalLength(). + */ + const uint32 m2 = (1U << FLOAT_MANTISSA_BITS) | ieeeMantissa; + + v->mantissa = m2 >> -e2; + v->exponent = 0; + return true; + } + } + + return false; } /* @@ -738,35 +658,32 @@ f2d_small_int(const uint32 ieeeMantissa, * * Returns the number of bytes stored. */ -int -float_to_shortest_decimal_bufn(float f, char *result) +int float_to_shortest_decimal_bufn(float f, char *result) { - /* - * Step 1: Decode the floating-point number, and unify normalized and - * subnormal cases. - */ - const uint32 bits = float_to_bits(f); - - /* Decode bits into sign, mantissa, and exponent. */ - const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; - const uint32 ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1); - const uint32 ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1); - - /* Case distinction; exit early for the easy cases. */ - if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) - { - return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa); - } - - floating_decimal_32 v; - const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v); - - if (!isSmallInt) - { - v = f2d(ieeeMantissa, ieeeExponent); - } - - return to_chars(v, ieeeSign, result); + /* + * Step 1: Decode the floating-point number, and unify normalized and + * subnormal cases. + */ + const uint32 bits = float_to_bits(f); + + /* Decode bits into sign, mantissa, and exponent. */ + const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; + const uint32 ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1); + const uint32 ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1); + + /* Case distinction; exit early for the easy cases. */ + if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) { + return copy_special_str(result, ieeeSign, ieeeExponent, ieeeMantissa); + } + + floating_decimal_32 v; + const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v); + + if (!isSmallInt) { + v = f2d(ieeeMantissa, ieeeExponent); + } + + return to_chars(v, ieeeSign, result); } /* @@ -776,15 +693,14 @@ float_to_shortest_decimal_bufn(float f, char *result) * * Returns the string length. */ -int -float_to_shortest_decimal_buf(float f, char *result) +int float_to_shortest_decimal_buf(float f, char *result) { - const int index = float_to_shortest_decimal_bufn(f, result); + const int index = float_to_shortest_decimal_bufn(f, result); - /* Terminate the string. */ - Assert(index < FLOAT_SHORTEST_DECIMAL_LEN); - result[index] = '\0'; - return index; + /* Terminate the string. */ + Assert(index < FLOAT_SHORTEST_DECIMAL_LEN); + result[index] = '\0'; + return index; } /* @@ -793,11 +709,10 @@ float_to_shortest_decimal_buf(float f, char *result) * * Caller is responsible for freeing the result. */ -char * -float_to_shortest_decimal(float f) +char *float_to_shortest_decimal(float f) { - char *const result = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN); + char *const result = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); - float_to_shortest_decimal_buf(f, result); - return result; + float_to_shortest_decimal_buf(f, result); + return result; } diff --git a/src/common/backend/utils/adt/halfutils.cpp b/src/common/backend/utils/adt/halfutils.cpp index 6269af642c..7da0c3c198 100644 --- a/src/common/backend/utils/adt/halfutils.cpp +++ b/src/common/backend/utils/adt/halfutils.cpp @@ -23,181 +23,181 @@ float (*HalfvecL1Distance) (int dim, half * ax, half * bx); static float HalfvecL2SquaredDistanceDefault(int dim, half * ax, half * bx) { - float distance = 0.0; + float distance = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { - float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); - distance += diff * diff; - } + distance += diff * diff; + } - return distance; + return distance; } #ifdef HALFVEC_DISPATCH TARGET_F16C static float HalfvecL2SquaredDistanceF16c(int dim, half * ax, half * bx) { - float distance; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 dist = _mm256_setzero_ps(); + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); - __m256 diff = _mm256_sub_ps(axs, bxs); + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); + __m256 diff = _mm256_sub_ps(axs, bxs); - dist = _mm256_fmadd_ps(diff, diff, dist); - } + dist = _mm256_fmadd_ps(diff, diff, dist); + } - _mm256_storeu_ps(s, dist); + _mm256_storeu_ps(s, dist); - distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; - for (; i < dim; i++) - { - float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); + for (; i < dim; i++) + { + float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); - distance += diff * diff; - } + distance += diff * diff; + } - return distance; + return distance; } #endif static float HalfvecInnerProductDefault(int dim, half * ax, half * bx) { - float distance = 0.0; + float distance = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - distance += HalfToFloat4(ax[i]) * HalfToFloat4(bx[i]); + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += HalfToFloat4(ax[i]) * HalfToFloat4(bx[i]); - return distance; + return distance; } #ifdef HALFVEC_DISPATCH TARGET_F16C static float HalfvecInnerProductF16c(int dim, half * ax, half * bx) { - float distance; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 dist = _mm256_setzero_ps(); + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); - dist = _mm256_fmadd_ps(axs, bxs, dist); - } + dist = _mm256_fmadd_ps(axs, bxs, dist); + } - _mm256_storeu_ps(s, dist); + _mm256_storeu_ps(s, dist); - distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; - for (; i < dim; i++) - distance += HalfToFloat4(ax[i]) * HalfToFloat4(bx[i]); + for (; i < dim; i++) + distance += HalfToFloat4(ax[i]) * HalfToFloat4(bx[i]); - return distance; + return distance; } #endif static double HalfvecCosineSimilarityDefault(int dim, half * ax, half * bx) { - float similarity = 0.0; - float norma = 0.0; - float normb = 0.0; - - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { - float axi = HalfToFloat4(ax[i]); - float bxi = HalfToFloat4(bx[i]); - - similarity += axi * bxi; - norma += axi * axi; - normb += bxi * bxi; - } - - /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double) similarity / sqrt((double) norma * (double) normb); + float similarity = 0.0; + float norma = 0.0; + float normb = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + float axi = HalfToFloat4(ax[i]); + float bxi = HalfToFloat4(bx[i]); + + similarity += axi * bxi; + norma += axi * axi; + normb += bxi * bxi; + } + + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + return (double) similarity / sqrt((double) norma * (double) normb); } #ifdef HALFVEC_DISPATCH TARGET_F16C static double HalfvecCosineSimilarityF16c(int dim, half * ax, half * bx) { - float similarity; - float norma; - float normb; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 sim = _mm256_setzero_ps(); - __m256 na = _mm256_setzero_ps(); - __m256 nb = _mm256_setzero_ps(); - - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); - - sim = _mm256_fmadd_ps(axs, bxs, sim); - na = _mm256_fmadd_ps(axs, axs, na); - nb = _mm256_fmadd_ps(bxs, bxs, nb); - } - - _mm256_storeu_ps(s, sim); - similarity = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; - - _mm256_storeu_ps(s, na); - norma = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; - - _mm256_storeu_ps(s, nb); - normb = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; - - /* Auto-vectorized */ - for (; i < dim; i++) - { - float axi = HalfToFloat4(ax[i]); - float bxi = HalfToFloat4(bx[i]); - - similarity += axi * bxi; - norma += axi * axi; - normb += bxi * bxi; - } - - /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double) similarity / sqrt((double) norma * (double) normb); + float similarity; + float norma; + float normb; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 sim = _mm256_setzero_ps(); + __m256 na = _mm256_setzero_ps(); + __m256 nb = _mm256_setzero_ps(); + + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); + + sim = _mm256_fmadd_ps(axs, bxs, sim); + na = _mm256_fmadd_ps(axs, axs, na); + nb = _mm256_fmadd_ps(bxs, bxs, nb); + } + + _mm256_storeu_ps(s, sim); + similarity = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + _mm256_storeu_ps(s, na); + norma = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + _mm256_storeu_ps(s, nb); + normb = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + + /* Auto-vectorized */ + for (; i < dim; i++) + { + float axi = HalfToFloat4(ax[i]); + float bxi = HalfToFloat4(bx[i]); + + similarity += axi * bxi; + norma += axi * axi; + normb += bxi * bxi; + } + + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + return (double) similarity / sqrt((double) norma * (double) normb); } #endif static float HalfvecL1DistanceDefault(int dim, half * ax, half * bx) { - float distance = 0.0; + float distance = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - distance += fabsf(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += fabsf(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); - return distance; + return distance; } #ifdef HALFVEC_DISPATCH @@ -205,31 +205,31 @@ HalfvecL1DistanceDefault(int dim, half * ax, half * bx) TARGET_F16C static float HalfvecL1DistanceF16c(int dim, half * ax, half * bx) { - float distance; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 dist = _mm256_setzero_ps(); - __m256 sign = _mm256_set1_ps(-0.0); + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); + __m256 sign = _mm256_set1_ps(-0.0); - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); + for (i = 0; i < count; i += 8) + { + __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); - dist = _mm256_add_ps(dist, _mm256_andnot_ps(sign, _mm256_sub_ps(axs, bxs))); - } + dist = _mm256_add_ps(dist, _mm256_andnot_ps(sign, _mm256_sub_ps(axs, bxs))); + } - _mm256_storeu_ps(s, dist); + _mm256_storeu_ps(s, dist); - distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; + distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; - for (; i < dim; i++) - distance += fabsf(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); + for (; i < dim; i++) + distance += fabsf(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); - return distance; + return distance; } #endif @@ -248,47 +248,47 @@ HalfvecL1DistanceF16c(int dim, half * ax, half * bx) TARGET_XSAVE static bool SupportsCpuFeature(unsigned int feature) { - unsigned int exx[4] = {0, 0, 0, 0}; + unsigned int exx[4] = {0, 0, 0, 0}; #if defined(USE__GET_CPUID) - __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); + __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); #else - __cpuid(exx, 1); + __cpuid(exx, 1); #endif - /* Check OS supports XSAVE */ - if ((exx[2] & CPU_FEATURE_OSXSAVE) != CPU_FEATURE_OSXSAVE) - return false; + /* Check OS supports XSAVE */ + if ((exx[2] & CPU_FEATURE_OSXSAVE) != CPU_FEATURE_OSXSAVE) + return false; - /* Check XMM and YMM registers are enabled */ - if ((_xgetbv(0) & 6) != 6) - return false; + /* Check XMM and YMM registers are enabled */ + if ((_xgetbv(0) & 6) != 6) + return false; - /* Now check features */ - return (exx[2] & feature) == feature; + /* Now check features */ + return (exx[2] & feature) == feature; } #endif void HalfvecInit(void) { - /* - * Could skip pointer when single function, but no difference in - * performance - */ - HalfvecL2SquaredDistance = HalfvecL2SquaredDistanceDefault; - HalfvecInnerProduct = HalfvecInnerProductDefault; - HalfvecCosineSimilarity = HalfvecCosineSimilarityDefault; - HalfvecL1Distance = HalfvecL1DistanceDefault; + /* + * Could skip pointer when single function, but no difference in + * performance + */ + HalfvecL2SquaredDistance = HalfvecL2SquaredDistanceDefault; + HalfvecInnerProduct = HalfvecInnerProductDefault; + HalfvecCosineSimilarity = HalfvecCosineSimilarityDefault; + HalfvecL1Distance = HalfvecL1DistanceDefault; #ifdef HALFVEC_DISPATCH - if (SupportsCpuFeature(CPU_FEATURE_AVX | CPU_FEATURE_F16C | CPU_FEATURE_FMA)) - { - HalfvecL2SquaredDistance = HalfvecL2SquaredDistanceF16c; - HalfvecInnerProduct = HalfvecInnerProductF16c; - HalfvecCosineSimilarity = HalfvecCosineSimilarityF16c; - /* Does not require FMA, but keep logic simple */ - HalfvecL1Distance = HalfvecL1DistanceF16c; - } + if (SupportsCpuFeature(CPU_FEATURE_AVX | CPU_FEATURE_F16C | CPU_FEATURE_FMA)) + { + HalfvecL2SquaredDistance = HalfvecL2SquaredDistanceF16c; + HalfvecInnerProduct = HalfvecInnerProductF16c; + HalfvecCosineSimilarity = HalfvecCosineSimilarityF16c; + /* Does not require FMA, but keep logic simple */ + HalfvecL1Distance = HalfvecL1DistanceF16c; + } #endif } diff --git a/src/common/backend/utils/adt/halfvec.cpp b/src/common/backend/utils/adt/halfvec.cpp index 4fab3462f4..3c272f26e9 100644 --- a/src/common/backend/utils/adt/halfvec.cpp +++ b/src/common/backend/utils/adt/halfvec.cpp @@ -32,14 +32,14 @@ static half pq_getmsghalf(StringInfo msg) { - union - { - half h; - uint16 i; - } swap; - - swap.i = pq_getmsgint(msg, 2); - return swap.h; + union + { + half h; + uint16 i; + } swap; + + swap.i = pq_getmsgint(msg, 2); + return swap.h; } /* @@ -48,14 +48,14 @@ pq_getmsghalf(StringInfo msg) static void pq_sendhalf(StringInfo buf, half h) { - union - { - half h; - uint16 i; - } swap; - - swap.h = h; - pq_sendint16(buf, swap.i); + union + { + half h; + uint16 i; + } swap; + + swap.h = h; + pq_sendint16(buf, swap.i); } /* @@ -64,10 +64,10 @@ pq_sendhalf(StringInfo buf, half h) static inline void CheckDims(HalfVector * a, HalfVector * b) { - if (a->dim != b->dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("different halfvec dimensions %d and %d", a->dim, b->dim))); + if (a->dim != b->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different halfvec dimensions %d and %d", a->dim, b->dim))); } /* @@ -76,10 +76,10 @@ CheckDims(HalfVector * a, HalfVector * b) static inline void CheckExpectedDim(int32 typmod, int dim) { - if (typmod != -1 && typmod != dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected %d dimensions, not %d", typmod, dim))); + if (typmod != -1 && typmod != dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected %d dimensions, not %d", typmod, dim))); } /* @@ -88,15 +88,15 @@ CheckExpectedDim(int32 typmod, int dim) static inline void CheckDim(int dim) { - if (dim < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); - - if (dim > HALFVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); + if (dim < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + if (dim > HALFVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); } /* @@ -105,15 +105,15 @@ CheckDim(int dim) static inline void CheckElement(half value) { - if (HalfIsNan(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("NaN not allowed in halfvec"))); - - if (HalfIsInf(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("infinite value not allowed in halfvec"))); + if (HalfIsNan(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("NaN not allowed in halfvec"))); + + if (HalfIsInf(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("infinite value not allowed in halfvec"))); } /* @@ -122,15 +122,15 @@ CheckElement(half value) HalfVector * InitHalfVector(int dim) { - HalfVector *result; - int size; + HalfVector *result; + int size; - size = HALFVEC_SIZE(dim); - result = (HalfVector *) palloc0(size); - SET_VARSIZE(result, size); - result->dim = dim; + size = HALFVEC_SIZE(dim); + result = (HalfVector *) palloc0(size); + SET_VARSIZE(result, size); + result->dim = dim; - return result; + return result; } /* @@ -139,14 +139,14 @@ InitHalfVector(int dim) static inline bool halfvec_isspace(char ch) { - if (ch == ' ' || - ch == '\t' || - ch == '\n' || - ch == '\r' || - ch == '\v' || - ch == '\f') - return true; - return false; + if (ch == ' ' || + ch == '\t' || + ch == '\n' || + ch == '\r' || + ch == '\v' || + ch == '\f') + return true; + return false; } /* @@ -155,29 +155,29 @@ halfvec_isspace(char ch) static float8 * CheckStateArray(ArrayType *statearray, const char *caller) { - if (ARR_NDIM(statearray) != 1 || - ARR_DIMS(statearray)[0] < 1 || - ARR_HASNULL(statearray) || - ARR_ELEMTYPE(statearray) != FLOAT8OID) - elog(ERROR, "%s: expected state array", caller); - return (float8 *) ARR_DATA_PTR(statearray); + if (ARR_NDIM(statearray) != 1 || + ARR_DIMS(statearray)[0] < 1 || + ARR_HASNULL(statearray) || + ARR_ELEMTYPE(statearray) != FLOAT8OID) + elog(ERROR, "%s: expected state array", caller); + return (float8 *) ARR_DATA_PTR(statearray); } #if PG_VERSION_NUM < 120003 static pg_noinline void float_overflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: overflow"))); + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); } static pg_noinline void float_underflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: underflow"))); + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: underflow"))); } #endif @@ -188,108 +188,108 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_in); Datum halfvec_in(PG_FUNCTION_ARGS) { - char *lit = PG_GETARG_CSTRING(0); - int32 typmod = PG_GETARG_INT32(2); - half x[HALFVEC_MAX_DIM]; - int dim = 0; - char *pt = lit; - HalfVector *result; - - while (halfvec_isspace(*pt)) - pt++; - - if (*pt != '[') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit), - errdetail("Vector contents must start with \"[\"."))); - - pt++; - - while (halfvec_isspace(*pt)) - pt++; - - if (*pt == ']') - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); - - for (;;) - { - float val; - char *stringEnd; - - if (dim == HALFVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); - - while (halfvec_isspace(*pt)) - pt++; - - /* Check for empty string like float4in */ - if (*pt == '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); - - errno = 0; - - /* Postgres sets LC_NUMERIC to C on startup */ - val = strtof(pt, &stringEnd); - - if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); - - x[dim] = Float4ToHalfUnchecked(val); - - /* Check for range error like float4in */ - if ((errno == ERANGE && isinf(val)) || (HalfIsInf(x[dim]) && !isinf(val))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt)))); - - CheckElement(x[dim]); - dim++; - - pt = stringEnd; - - while (halfvec_isspace(*pt)) - pt++; - - if (*pt == ',') - pt++; - else if (*pt == ']') - { - pt++; - break; - } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); - } - - /* Only whitespace is allowed after the closing brace */ - while (halfvec_isspace(*pt)) - pt++; - - if (*pt != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit), - errdetail("Junk after closing right brace."))); - - CheckDim(dim); - CheckExpectedDim(typmod, dim); - - result = InitHalfVector(dim); - for (int i = 0; i < dim; i++) - result->x[i] = x[i]; - - PG_RETURN_POINTER(result); + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + half x[HALFVEC_MAX_DIM]; + int dim = 0; + char *pt = lit; + HalfVector *result; + + while (halfvec_isspace(*pt)) + pt++; + + if (*pt != '[') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit), + errdetail("Vector contents must start with \"[\"."))); + + pt++; + + while (halfvec_isspace(*pt)) + pt++; + + if (*pt == ']') + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + for (;;) + { + float val; + char *stringEnd; + + if (dim == HALFVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); + + while (halfvec_isspace(*pt)) + pt++; + + /* Check for empty string like float4in */ + if (*pt == '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + + errno = 0; + + /* Postgres sets LC_NUMERIC to C on startup */ + val = strtof(pt, &stringEnd); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + + x[dim] = Float4ToHalfUnchecked(val); + + /* Check for range error like float4in */ + if ((errno == ERANGE && isinf(val)) || (HalfIsInf(x[dim]) && !isinf(val))) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt)))); + + CheckElement(x[dim]); + dim++; + + pt = stringEnd; + + while (halfvec_isspace(*pt)) + pt++; + + if (*pt == ',') + pt++; + else if (*pt == ']') + { + pt++; + break; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + } + + /* Only whitespace is allowed after the closing brace */ + while (halfvec_isspace(*pt)) + pt++; + + if (*pt != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit), + errdetail("Junk after closing right brace."))); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + result = InitHalfVector(dim); + for (int i = 0; i < dim; i++) + result->x[i] = x[i]; + + PG_RETURN_POINTER(result); } #define AppendChar(ptr, c) (*(ptr)++ = (c)) @@ -302,43 +302,43 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_out); Datum halfvec_out(PG_FUNCTION_ARGS) { - HalfVector *vector = PG_GETARG_HALFVEC_P(0); - int dim = vector->dim; - char *buf; - char *ptr; - - /* - * Need: - * - * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for - * float_to_shortest_decimal_bufn - * - * dim - 1 bytes for separator - * - * 3 bytes for [, ], and \0 - */ - buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); - ptr = buf; - - AppendChar(ptr, '['); - - for (int i = 0; i < dim; i++) - { - if (i > 0) - AppendChar(ptr, ','); - - /* - * Use shortest decimal representation of single-precision float for - * simplicity - */ - AppendFloat(ptr, HalfToFloat4(vector->x[i])); - } - - AppendChar(ptr, ']'); - *ptr = '\0'; - - PG_FREE_IF_COPY(vector, 0); - PG_RETURN_CSTRING(buf); + HalfVector *vector = PG_GETARG_HALFVEC_P(0); + int dim = vector->dim; + char *buf; + char *ptr; + + /* + * Need: + * + * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for + * float_to_shortest_decimal_bufn + * + * dim - 1 bytes for separator + * + * 3 bytes for [, ], and \0 + */ + buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); + ptr = buf; + + AppendChar(ptr, '['); + + for (int i = 0; i < dim; i++) + { + if (i > 0) + AppendChar(ptr, ','); + + /* + * Use shortest decimal representation of single-precision float for + * simplicity + */ + AppendFloat(ptr, HalfToFloat4(vector->x[i])); + } + + AppendChar(ptr, ']'); + *ptr = '\0'; + + PG_FREE_IF_COPY(vector, 0); + PG_RETURN_CSTRING(buf); } /* @@ -348,28 +348,28 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_typmod_in); Datum halfvec_typmod_in(PG_FUNCTION_ARGS) { - ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); - int32 *tl; - int n; + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; - tl = ArrayGetIntegerTypmods(ta, &n); + tl = ArrayGetIntegerTypmods(ta, &n); - if (n != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid type modifier"))); + if (n != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid type modifier"))); - if (*tl < 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type halfvec must be at least 1"))); + if (*tl < 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type halfvec must be at least 1"))); - if (*tl > HALFVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type halfvec cannot exceed %d", HALFVEC_MAX_DIM))); + if (*tl > HALFVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type halfvec cannot exceed %d", HALFVEC_MAX_DIM))); - PG_RETURN_INT32(*tl); + PG_RETURN_INT32(*tl); } /* @@ -379,31 +379,31 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_recv); Datum halfvec_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - int32 typmod = PG_GETARG_INT32(2); - HalfVector *result; - int16 dim; - int16 unused; - - dim = pq_getmsgint(buf, sizeof(int16)); - unused = pq_getmsgint(buf, sizeof(int16)); - - CheckDim(dim); - CheckExpectedDim(typmod, dim); - - if (unused != 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected unused to be 0, not %d", unused))); - - result = InitHalfVector(dim); - for (int i = 0; i < dim; i++) - { - result->x[i] = pq_getmsghalf(buf); - CheckElement(result->x[i]); - } - - PG_RETURN_POINTER(result); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); + HalfVector *result; + int16 dim; + int16 unused; + + dim = pq_getmsgint(buf, sizeof(int16)); + unused = pq_getmsgint(buf, sizeof(int16)); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + if (unused != 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected unused to be 0, not %d", unused))); + + result = InitHalfVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = pq_getmsghalf(buf); + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); } /* @@ -413,16 +413,16 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_send); Datum halfvec_send(PG_FUNCTION_ARGS) { - HalfVector *vec = PG_GETARG_HALFVEC_P(0); - StringInfoData buf; + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + StringInfoData buf; - pq_begintypsend(&buf); - pq_sendint(&buf, vec->dim, sizeof(int16)); - pq_sendint(&buf, vec->unused, sizeof(int16)); - for (int i = 0; i < vec->dim; i++) - pq_sendhalf(&buf, vec->x[i]); + pq_begintypsend(&buf); + pq_sendint(&buf, vec->dim, sizeof(int16)); + pq_sendint(&buf, vec->unused, sizeof(int16)); + for (int i = 0; i < vec->dim; i++) + pq_sendhalf(&buf, vec->x[i]); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } /* @@ -433,12 +433,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec); Datum halfvec(PG_FUNCTION_ARGS) { - HalfVector *vec = PG_GETARG_HALFVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); - CheckExpectedDim(typmod, vec->dim); + CheckExpectedDim(typmod, vec->dim); - PG_RETURN_POINTER(vec); + PG_RETURN_POINTER(vec); } /* @@ -448,71 +448,71 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(array_to_halfvec); Datum array_to_halfvec(PG_FUNCTION_ARGS) { - ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); - int32 typmod = PG_GETARG_INT32(1); - HalfVector *result; - int16 typlen; - bool typbyval; - char typalign; - Datum *elemsp; - int nelemsp; - - if (ARR_NDIM(array) > 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("array must be 1-D"))); - - if (ARR_HASNULL(array) && array_contains_nulls(array)) - ereport(ERROR, - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("array must not contain nulls"))); - - get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); - deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); - - CheckDim(nelemsp); - CheckExpectedDim(typmod, nelemsp); - - result = InitHalfVector(nelemsp); - - if (ARR_ELEMTYPE(array) == INT4OID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = Float4ToHalf(DatumGetInt32(elemsp[i])); - } - else if (ARR_ELEMTYPE(array) == FLOAT8OID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = Float4ToHalf(DatumGetFloat8(elemsp[i])); - } - else if (ARR_ELEMTYPE(array) == FLOAT4OID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = Float4ToHalf(DatumGetFloat4(elemsp[i])); - } - else if (ARR_ELEMTYPE(array) == NUMERICOID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = Float4ToHalf(DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i]))); - } - else - { - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("unsupported array type"))); - } - - /* - * Free allocation from deconstruct_array. Do not free individual elements - * when pass-by-reference since they point to original array. - */ - pfree(elemsp); - - /* Check elements */ - for (int i = 0; i < result->dim; i++) - CheckElement(result->x[i]); - - PG_RETURN_POINTER(result); + ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); + int32 typmod = PG_GETARG_INT32(1); + HalfVector *result; + int16 typlen; + bool typbyval; + char typalign; + Datum *elemsp; + int nelemsp; + + if (ARR_NDIM(array) > 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("array must be 1-D"))); + + if (ARR_HASNULL(array) && array_contains_nulls(array)) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("array must not contain nulls"))); + + get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); + deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); + + CheckDim(nelemsp); + CheckExpectedDim(typmod, nelemsp); + + result = InitHalfVector(nelemsp); + + if (ARR_ELEMTYPE(array) == INT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetInt32(elemsp[i])); + } + else if (ARR_ELEMTYPE(array) == FLOAT8OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetFloat8(elemsp[i])); + } + else if (ARR_ELEMTYPE(array) == FLOAT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetFloat4(elemsp[i])); + } + else if (ARR_ELEMTYPE(array) == NUMERICOID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = Float4ToHalf(DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i]))); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("unsupported array type"))); + } + + /* + * Free allocation from deconstruct_array. Do not free individual elements + * when pass-by-reference since they point to original array. + */ + pfree(elemsp); + + /* Check elements */ + for (int i = 0; i < result->dim; i++) + CheckElement(result->x[i]); + + PG_RETURN_POINTER(result); } /* @@ -522,21 +522,21 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_float4); Datum halfvec_to_float4(PG_FUNCTION_ARGS) { - HalfVector *vec = PG_GETARG_HALFVEC_P(0); - Datum *datums; - ArrayType *result; + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + Datum *datums; + ArrayType *result; - datums = (Datum *) palloc(sizeof(Datum) * vec->dim); + datums = (Datum *) palloc(sizeof(Datum) * vec->dim); - for (int i = 0; i < vec->dim; i++) - datums[i] = Float4GetDatum(HalfToFloat4(vec->x[i])); + for (int i = 0; i < vec->dim; i++) + datums[i] = Float4GetDatum(HalfToFloat4(vec->x[i])); - /* Use TYPALIGN_INT for float4 */ - result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); + /* Use TYPALIGN_INT for float4 */ + result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); - pfree(datums); + pfree(datums); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -546,19 +546,19 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_halfvec); Datum vector_to_halfvec(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - int32 typmod = PG_GETARG_INT32(1); - HalfVector *result; + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); + HalfVector *result; - CheckDim(vec->dim); - CheckExpectedDim(typmod, vec->dim); + CheckDim(vec->dim); + CheckExpectedDim(typmod, vec->dim); - result = InitHalfVector(vec->dim); + result = InitHalfVector(vec->dim); - for (int i = 0; i < vec->dim; i++) - result->x[i] = Float4ToHalf(vec->x[i]); + for (int i = 0; i < vec->dim; i++) + result->x[i] = Float4ToHalf(vec->x[i]); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -568,12 +568,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_distance); Datum halfvec_l2_distance(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8(sqrt((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x))); + PG_RETURN_FLOAT8(sqrt((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x))); } /* @@ -583,12 +583,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_squared_distance); Datum halfvec_l2_squared_distance(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x)); } /* @@ -598,12 +598,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_inner_product); Datum halfvec_inner_product(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) HalfvecInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) HalfvecInnerProduct(a->dim, a->x, b->x)); } /* @@ -613,12 +613,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_negative_inner_product); Datum halfvec_negative_inner_product(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) -HalfvecInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) -HalfvecInnerProduct(a->dim, a->x, b->x)); } /* @@ -628,27 +628,27 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_cosine_distance); Datum halfvec_cosine_distance(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); - double similarity; + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + double similarity; - CheckDims(a, b); + CheckDims(a, b); - similarity = HalfvecCosineSimilarity(a->dim, a->x, b->x); + similarity = HalfvecCosineSimilarity(a->dim, a->x, b->x); #ifdef _MSC_VER - /* /fp:fast may not propagate NaN */ - if (isnan(similarity)) - PG_RETURN_FLOAT8(NAN); + /* /fp:fast may not propagate NaN */ + if (isnan(similarity)) + PG_RETURN_FLOAT8(NAN); #endif - /* Keep in range */ - if (similarity > 1) - similarity = 1; - else if (similarity < -1) - similarity = -1; + /* Keep in range */ + if (similarity > 1) + similarity = 1; + else if (similarity < -1) + similarity = -1; - PG_RETURN_FLOAT8(1 - similarity); + PG_RETURN_FLOAT8(1 - similarity); } /* @@ -660,21 +660,21 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_spherical_distance); Datum halfvec_spherical_distance(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); - double distance; + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + double distance; - CheckDims(a, b); + CheckDims(a, b); - distance = (double) HalfvecInnerProduct(a->dim, a->x, b->x); + distance = (double) HalfvecInnerProduct(a->dim, a->x, b->x); - /* Prevent NaN with acos with loss of precision */ - if (distance > 1) - distance = 1; - else if (distance < -1) - distance = -1; + /* Prevent NaN with acos with loss of precision */ + if (distance > 1) + distance = 1; + else if (distance < -1) + distance = -1; - PG_RETURN_FLOAT8(acos(distance) / M_PI); + PG_RETURN_FLOAT8(acos(distance) / M_PI); } /* @@ -684,12 +684,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l1_distance); Datum halfvec_l1_distance(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) HalfvecL1Distance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) HalfvecL1Distance(a->dim, a->x, b->x)); } /* @@ -699,9 +699,9 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_vector_dims); Datum halfvec_vector_dims(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *a = PG_GETARG_HALFVEC_P(0); - PG_RETURN_INT32(a->dim); + PG_RETURN_INT32(a->dim); } /* @@ -711,19 +711,19 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_norm); Datum halfvec_l2_norm(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - half *ax = a->x; - double norm = 0.0; + HalfVector *a = PG_GETARG_HALFVEC_P(0); + half *ax = a->x; + double norm = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < a->dim; i++) - { - double axi = (double) HalfToFloat4(ax[i]); + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + { + double axi = (double) HalfToFloat4(ax[i]); - norm += axi * axi; - } + norm += axi * axi; + } - PG_RETURN_FLOAT8(sqrt(norm)); + PG_RETURN_FLOAT8(sqrt(norm)); } /* @@ -733,36 +733,36 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_normalize); Datum halfvec_l2_normalize(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - half *ax = a->x; - double norm = 0; - HalfVector *result; - half *rx; - - result = InitHalfVector(a->dim); - rx = result->x; - - /* Auto-vectorized */ - for (int i = 0; i < a->dim; i++) - norm += (double) HalfToFloat4(ax[i]) * (double) HalfToFloat4(ax[i]); - - norm = sqrt(norm); - - /* Return zero vector for zero norm */ - if (norm > 0) - { - for (int i = 0; i < a->dim; i++) - rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) / norm); - - /* Check for overflow */ - for (int i = 0; i < a->dim; i++) - { - if (HalfIsInf(rx[i])) - float_overflow_error(); - } - } - - PG_RETURN_POINTER(result); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + half *ax = a->x; + double norm = 0; + HalfVector *result; + half *rx; + + result = InitHalfVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + norm += (double) HalfToFloat4(ax[i]) * (double) HalfToFloat4(ax[i]); + + norm = sqrt(norm); + + /* Return zero vector for zero norm */ + if (norm > 0) + { + for (int i = 0; i < a->dim; i++) + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) / norm); + + /* Check for overflow */ + for (int i = 0; i < a->dim; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); + } + } + + PG_RETURN_POINTER(result); } /* @@ -772,36 +772,36 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_add); Datum halfvec_add(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); - half *ax = a->x; - half *bx = b->x; - HalfVector *result; - half *rx; + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + half *ax = a->x; + half *bx = b->x; + HalfVector *result; + half *rx; - CheckDims(a, b); + CheckDims(a, b); - result = InitHalfVector(a->dim); - rx = result->x; + result = InitHalfVector(a->dim); + rx = result->x; - /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + { #ifdef FLT16_SUPPORT - rx[i] = ax[i] + bx[i]; + rx[i] = ax[i] + bx[i]; #else - rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) + HalfToFloat4(bx[i])); + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) + HalfToFloat4(bx[i])); #endif - } + } - /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { - if (HalfIsInf(rx[i])) - float_overflow_error(); - } + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); + } - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -811,36 +811,36 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_sub); Datum halfvec_sub(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); - half *ax = a->x; - half *bx = b->x; - HalfVector *result; - half *rx; + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + half *ax = a->x; + half *bx = b->x; + HalfVector *result; + half *rx; - CheckDims(a, b); + CheckDims(a, b); - result = InitHalfVector(a->dim); - rx = result->x; + result = InitHalfVector(a->dim); + rx = result->x; - /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + { #ifdef FLT16_SUPPORT - rx[i] = ax[i] - bx[i]; + rx[i] = ax[i] - bx[i]; #else - rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) - HalfToFloat4(bx[i])); #endif - } + } - /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { - if (HalfIsInf(rx[i])) - float_overflow_error(); - } + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); + } - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -850,39 +850,39 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_mul); Datum halfvec_mul(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); - half *ax = a->x; - half *bx = b->x; - HalfVector *result; - half *rx; + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + half *ax = a->x; + half *bx = b->x; + HalfVector *result; + half *rx; - CheckDims(a, b); + CheckDims(a, b); - result = InitHalfVector(a->dim); - rx = result->x; + result = InitHalfVector(a->dim); + rx = result->x; - /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + { #ifdef FLT16_SUPPORT - rx[i] = ax[i] * bx[i]; + rx[i] = ax[i] * bx[i]; #else - rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) * HalfToFloat4(bx[i])); + rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) * HalfToFloat4(bx[i])); #endif - } + } - /* Check for overflow and underflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { - if (HalfIsInf(rx[i])) - float_overflow_error(); + /* Check for overflow and underflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (HalfIsInf(rx[i])) + float_overflow_error(); - if (HalfIsZero(rx[i]) && !(HalfIsZero(ax[i]) || HalfIsZero(bx[i]))) - float_underflow_error(); - } + if (HalfIsZero(rx[i]) && !(HalfIsZero(ax[i]) || HalfIsZero(bx[i]))) + float_underflow_error(); + } - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -892,21 +892,21 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_concat); Datum halfvec_concat(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); - HalfVector *result; - int dim = a->dim + b->dim; + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *result; + int dim = a->dim + b->dim; - CheckDim(dim); - result = InitHalfVector(dim); + CheckDim(dim); + result = InitHalfVector(dim); - for (int i = 0; i < a->dim; i++) - result->x[i] = a->x[i]; + for (int i = 0; i < a->dim; i++) + result->x[i] = a->x[i]; - for (int i = 0; i < b->dim; i++) - result->x[i + a->dim] = b->x[i]; + for (int i = 0; i < b->dim; i++) + result->x[i + a->dim] = b->x[i]; - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -916,15 +916,15 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_binary_quantize); Datum halfvec_binary_quantize(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - half *ax = a->x; - VarBit *result = InitBitVector(a->dim); - unsigned char *rx = VARBITS(result); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + half *ax = a->x; + VarBit *result = InitBitVector(a->dim); + unsigned char *rx = VARBITS(result); - for (int i = 0; i < a->dim; i++) - rx[i / 8] |= (HalfToFloat4(ax[i]) > 0) << (7 - (i % 8)); + for (int i = 0; i < a->dim; i++) + rx[i / 8] |= (HalfToFloat4(ax[i]) > 0) << (7 - (i % 8)); - PG_RETURN_VARBIT_P(result); + PG_RETURN_VARBIT_P(result); } /* @@ -934,44 +934,44 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_subvector); Datum halfvec_subvector(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - int32 start = PG_GETARG_INT32(1); - int32 count = PG_GETARG_INT32(2); - int32 end; - half *ax = a->x; - HalfVector *result; - int32 dim; - - if (count < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); - - /* - * Check if (start + count > a->dim), avoiding integer overflow. a->dim - * and count are both positive, so a->dim - count won't overflow. - */ - if (start > a->dim - count) - end = a->dim + 1; - else - end = start + count; - - /* Indexing starts at 1, like substring */ - if (start < 1) - start = 1; - else if (start > a->dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); - - dim = end - start; - CheckDim(dim); - result = InitHalfVector(dim); - - for (int i = 0; i < dim; i++) - result->x[i] = ax[start - 1 + i]; - - PG_RETURN_POINTER(result); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + int32 start = PG_GETARG_INT32(1); + int32 count = PG_GETARG_INT32(2); + int32 end; + half *ax = a->x; + HalfVector *result; + int32 dim; + + if (count < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + /* + * Check if (start + count > a->dim), avoiding integer overflow. a->dim + * and count are both positive, so a->dim - count won't overflow. + */ + if (start > a->dim - count) + end = a->dim + 1; + else + end = start + count; + + /* Indexing starts at 1, like substring */ + if (start < 1) + start = 1; + else if (start > a->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("halfvec must have at least 1 dimension"))); + + dim = end - start; + CheckDim(dim); + result = InitHalfVector(dim); + + for (int i = 0; i < dim; i++) + result->x[i] = ax[start - 1 + i]; + + PG_RETURN_POINTER(result); } /* @@ -980,25 +980,25 @@ halfvec_subvector(PG_FUNCTION_ARGS) static int halfvec_cmp_internal(HalfVector * a, HalfVector * b) { - int dim = Min(a->dim, b->dim); + int dim = Min(a->dim, b->dim); - /* Check values before dimensions to be consistent with Postgres arrays */ - for (int i = 0; i < dim; i++) - { - if (HalfToFloat4(a->x[i]) < HalfToFloat4(b->x[i])) - return -1; + /* Check values before dimensions to be consistent with Postgres arrays */ + for (int i = 0; i < dim; i++) + { + if (HalfToFloat4(a->x[i]) < HalfToFloat4(b->x[i])) + return -1; - if (HalfToFloat4(a->x[i]) > HalfToFloat4(b->x[i])) - return 1; - } + if (HalfToFloat4(a->x[i]) > HalfToFloat4(b->x[i])) + return 1; + } - if (a->dim < b->dim) - return -1; + if (a->dim < b->dim) + return -1; - if (a->dim > b->dim) - return 1; + if (a->dim > b->dim) + return 1; - return 0; + return 0; } /* @@ -1008,10 +1008,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_lt); Datum halfvec_lt(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - PG_RETURN_BOOL(halfvec_cmp_internal(a, b) < 0); + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) < 0); } /* @@ -1021,10 +1021,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_le); Datum halfvec_le(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - PG_RETURN_BOOL(halfvec_cmp_internal(a, b) <= 0); + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) <= 0); } /* @@ -1034,10 +1034,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_eq); Datum halfvec_eq(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - PG_RETURN_BOOL(halfvec_cmp_internal(a, b) == 0); + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) == 0); } /* @@ -1047,10 +1047,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ne); Datum halfvec_ne(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - PG_RETURN_BOOL(halfvec_cmp_internal(a, b) != 0); + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) != 0); } /* @@ -1060,10 +1060,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ge); Datum halfvec_ge(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - PG_RETURN_BOOL(halfvec_cmp_internal(a, b) >= 0); + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) >= 0); } /* @@ -1073,10 +1073,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_gt); Datum halfvec_gt(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - PG_RETURN_BOOL(halfvec_cmp_internal(a, b) > 0); + PG_RETURN_BOOL(halfvec_cmp_internal(a, b) > 0); } /* @@ -1086,10 +1086,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_cmp); Datum halfvec_cmp(PG_FUNCTION_ARGS) { - HalfVector *a = PG_GETARG_HALFVEC_P(0); - HalfVector *b = PG_GETARG_HALFVEC_P(1); + HalfVector *a = PG_GETARG_HALFVEC_P(0); + HalfVector *b = PG_GETARG_HALFVEC_P(1); - PG_RETURN_INT32(halfvec_cmp_internal(a, b)); + PG_RETURN_INT32(halfvec_cmp_internal(a, b)); } /* @@ -1099,58 +1099,58 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_accum); Datum halfvec_accum(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); - HalfVector *newval = PG_GETARG_HALFVEC_P(1); - float8 *statevalues; - int16 dim; - bool newarr; - float8 n; - Datum *statedatums; - half *x = newval->x; - ArrayType *result; - - /* Check array before using */ - statevalues = CheckStateArray(statearray, "halfvec_accum"); - dim = STATE_DIMS(statearray); - newarr = dim == 0; - - if (newarr) - dim = newval->dim; - else - CheckExpectedDim(dim, newval->dim); - - n = statevalues[0] + 1.0; - - statedatums = (Datum *)CreateStateDatums(dim); - statedatums[0] = Float8GetDatum(n); - - if (newarr) - { - for (int i = 0; i < dim; i++) - statedatums[i + 1] = Float8GetDatum((double) HalfToFloat4(x[i])); - } - else - { - for (int i = 0; i < dim; i++) - { - double v = statevalues[i + 1] + (double) HalfToFloat4(x[i]); - - /* Check for overflow */ - if (isinf(v)) - float_overflow_error(); - - statedatums[i + 1] = Float8GetDatum(v); - } - } - - /* Use float8 array like float4_accum */ - result = construct_array(statedatums, dim + 1, - FLOAT8OID, - sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); - - pfree(statedatums); - - PG_RETURN_ARRAYTYPE_P(result); + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + HalfVector *newval = PG_GETARG_HALFVEC_P(1); + float8 *statevalues; + int16 dim; + bool newarr; + float8 n; + Datum *statedatums; + half *x = newval->x; + ArrayType *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "halfvec_accum"); + dim = STATE_DIMS(statearray); + newarr = dim == 0; + + if (newarr) + dim = newval->dim; + else + CheckExpectedDim(dim, newval->dim); + + n = statevalues[0] + 1.0; + + statedatums = (Datum *)CreateStateDatums(dim); + statedatums[0] = Float8GetDatum(n); + + if (newarr) + { + for (int i = 0; i < dim; i++) + statedatums[i + 1] = Float8GetDatum((double) HalfToFloat4(x[i])); + } + else + { + for (int i = 0; i < dim; i++) + { + double v = statevalues[i + 1] + (double) HalfToFloat4(x[i]); + + /* Check for overflow */ + if (isinf(v)) + float_overflow_error(); + + statedatums[i + 1] = Float8GetDatum(v); + } + } + + /* Use float8 array like float4_accum */ + result = construct_array(statedatums, dim + 1, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + + pfree(statedatums); + + PG_RETURN_ARRAYTYPE_P(result); } /* @@ -1160,31 +1160,31 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_avg); Datum halfvec_avg(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); - float8 *statevalues; - float8 n; - uint16 dim; - HalfVector *result; - - /* Check array before using */ - statevalues = CheckStateArray(statearray, "halfvec_avg"); - n = statevalues[0]; - - /* SQL defines AVG of no values to be NULL */ - if (n == 0.0) - PG_RETURN_NULL(); - - /* Create half vector */ - dim = STATE_DIMS(statearray); - CheckDim(dim); - result = InitHalfVector(dim); - for (int i = 0; i < dim; i++) - { - result->x[i] = Float4ToHalf(statevalues[i + 1] / n); - CheckElement(result->x[i]); - } - - PG_RETURN_POINTER(result); + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + float8 *statevalues; + float8 n; + uint16 dim; + HalfVector *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "halfvec_avg"); + n = statevalues[0]; + + /* SQL defines AVG of no values to be NULL */ + if (n == 0.0) + PG_RETURN_NULL(); + + /* Create half vector */ + dim = STATE_DIMS(statearray); + CheckDim(dim); + result = InitHalfVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = Float4ToHalf(statevalues[i + 1] / n); + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); } /* @@ -1194,18 +1194,18 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_to_halfvec); Datum sparsevec_to_halfvec(PG_FUNCTION_ARGS) { - SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); - HalfVector *result; - int dim = svec->dim; - float *values = SPARSEVEC_VALUES(svec); + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + HalfVector *result; + int dim = svec->dim; + float *values = SPARSEVEC_VALUES(svec); - CheckDim(dim); - CheckExpectedDim(typmod, dim); + CheckDim(dim); + CheckExpectedDim(typmod, dim); - result = InitHalfVector(dim); - for (int i = 0; i < svec->nnz; i++) - result->x[svec->indices[i]] = Float4ToHalf(values[i]); + result = InitHalfVector(dim); + for (int i = 0; i < svec->nnz; i++) + result->x[svec->indices[i]] = Float4ToHalf(values[i]); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index 0a3262bb72..85d8097eef 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -23,8 +23,8 @@ typedef struct SparseInputElement { - int32 index; - float value; + int32 index; + float value; } SparseInputElement; /* @@ -33,10 +33,10 @@ typedef struct SparseInputElement static inline void CheckDims(SparseVector * a, SparseVector * b) { - if (a->dim != b->dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("different sparsevec dimensions %d and %d", a->dim, b->dim))); + if (a->dim != b->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different sparsevec dimensions %d and %d", a->dim, b->dim))); } /* @@ -45,10 +45,10 @@ CheckDims(SparseVector * a, SparseVector * b) static inline void CheckExpectedDim(int32 typmod, int dim) { - if (typmod != -1 && typmod != dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected %d dimensions, not %d", typmod, dim))); + if (typmod != -1 && typmod != dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected %d dimensions, not %d", typmod, dim))); } /* @@ -57,15 +57,15 @@ CheckExpectedDim(int32 typmod, int dim) static inline void CheckDim(int dim) { - if (dim < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec must have at least 1 dimension"))); - - if (dim > SPARSEVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more than %d dimensions", SPARSEVEC_MAX_DIM))); + if (dim < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec must have at least 1 dimension"))); + + if (dim > SPARSEVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d dimensions", SPARSEVEC_MAX_DIM))); } /* @@ -74,20 +74,20 @@ CheckDim(int dim) static inline void CheckNnz(int nnz, int dim) { - if (nnz < 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec cannot have negative number of elements"))); - - if (nnz > SPARSEVEC_MAX_NNZ) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); - - if (nnz > dim) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more elements than dimensions"))); + if (nnz < 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec cannot have negative number of elements"))); + + if (nnz > SPARSEVEC_MAX_NNZ) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); + + if (nnz > dim) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more elements than dimensions"))); } /* @@ -96,27 +96,27 @@ CheckNnz(int nnz, int dim) static inline void CheckIndex(int32 *indices, int i, int dim) { - int32 index = indices[i]; - - if (index < 0 || index >= dim) - { - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec index out of bounds"))); - } - - if (i > 0) - { - if (index < indices[i - 1]) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec indices must be in ascending order"))); - - if (index == indices[i - 1]) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec indices must not contain duplicates"))); - } + int32 index = indices[i]; + + if (index < 0 || index >= dim) + { + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec index out of bounds"))); + } + + if (i > 0) + { + if (index < indices[i - 1]) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec indices must be in ascending order"))); + + if (index == indices[i - 1]) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("sparsevec indices must not contain duplicates"))); + } } /* @@ -125,15 +125,15 @@ CheckIndex(int32 *indices, int i, int dim) static inline void CheckElement(float value) { - if (isnan(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("NaN not allowed in sparsevec"))); - - if (isinf(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("infinite value not allowed in sparsevec"))); + if (isnan(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("NaN not allowed in sparsevec"))); + + if (isinf(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("infinite value not allowed in sparsevec"))); } /* @@ -142,16 +142,16 @@ CheckElement(float value) SparseVector * InitSparseVector(int dim, int nnz) { - SparseVector *result; - int size; + SparseVector *result; + int size; - size = SPARSEVEC_SIZE(nnz); - result = (SparseVector *) palloc0(size); - SET_VARSIZE(result, size); - result->dim = dim; - result->nnz = nnz; + size = SPARSEVEC_SIZE(nnz); + result = (SparseVector *) palloc0(size); + SET_VARSIZE(result, size); + result->dim = dim; + result->nnz = nnz; - return result; + return result; } /* @@ -160,14 +160,14 @@ InitSparseVector(int dim, int nnz) static inline bool sparsevec_isspace(char ch) { - if (ch == ' ' || - ch == '\t' || - ch == '\n' || - ch == '\r' || - ch == '\v' || - ch == '\f') - return true; - return false; + if (ch == ' ' || + ch == '\t' || + ch == '\n' || + ch == '\r' || + ch == '\v' || + ch == '\f') + return true; + return false; } /* @@ -176,13 +176,13 @@ sparsevec_isspace(char ch) static int CompareIndices(const void *a, const void *b) { - if (((SparseInputElement *) a)->index < ((SparseInputElement *) b)->index) - return -1; + if (((SparseInputElement *) a)->index < ((SparseInputElement *) b)->index) + return -1; - if (((SparseInputElement *) a)->index > ((SparseInputElement *) b)->index) - return 1; + if (((SparseInputElement *) a)->index > ((SparseInputElement *) b)->index) + return 1; - return 0; + return 0; } /* @@ -192,204 +192,204 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_in); Datum sparsevec_in(PG_FUNCTION_ARGS) { - char *lit = PG_GETARG_CSTRING(0); - int32 typmod = PG_GETARG_INT32(2); - long dim; - char *pt = lit; - char *stringEnd; - SparseVector *result; - float *rvalues; - SparseInputElement *elements; - int maxNnz; - int nnz = 0; - - maxNnz = 1; - while (*pt != '\0') - { - if (*pt == ',') - maxNnz++; - - pt++; - } - - if (maxNnz > SPARSEVEC_MAX_NNZ) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); - - elements = (SparseInputElement *)palloc(maxNnz * sizeof(SparseInputElement)); - - pt = lit; - - while (sparsevec_isspace(*pt)) - pt++; - - if (*pt != '{') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), - errdetail("Vector contents must start with \"{\"."))); - - pt++; - - while (sparsevec_isspace(*pt)) - pt++; - - if (*pt == '}') - pt++; - else - { - for (;;) - { - long index; - float value; - - if (nnz == maxNnz) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("ran out of buffer: \"%s\"", lit))); - - while (sparsevec_isspace(*pt)) - pt++; - - /* Check for empty string like float4in */ - if (*pt == '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); - - /* Use similar logic as int2vectorin */ - index = strtol(pt, &stringEnd, 10); - - if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); - - /* Keep in int range for correct error message later */ - if (index > INT_MAX) - index = INT_MAX; - else if (index < INT_MIN + 1) - index = INT_MIN + 1; - - pt = stringEnd; - - while (sparsevec_isspace(*pt)) - pt++; - - if (*pt != ':') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); - - pt++; - - while (sparsevec_isspace(*pt)) - pt++; - - errno = 0; - - /* Use strtof like float4in to avoid a double-rounding problem */ - /* Postgres sets LC_NUMERIC to C on startup */ - value = strtof(pt, &stringEnd); - - if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); - - /* Check for range error like float4in */ - if (errno == ERANGE && (value == 0 || isinf(value))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type sparsevec", pnstrdup(pt, stringEnd - pt)))); - - CheckElement(value); - - /* Do not store zero values */ - if (value != 0) - { - /* Convert 1-based numbering (SQL) to 0-based (C) */ - elements[nnz].index = index - 1; - elements[nnz].value = value; - nnz++; - } - - pt = stringEnd; - - while (sparsevec_isspace(*pt)) - pt++; - - if (*pt == ',') - pt++; - else if (*pt == '}') - { - pt++; - break; - } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); - } - } - - while (sparsevec_isspace(*pt)) - pt++; - - if (*pt != '/') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), - errdetail("Unexpected end of input."))); - - pt++; - - while (sparsevec_isspace(*pt)) - pt++; - - /* Use similar logic as int2vectorin */ - dim = strtol(pt, &stringEnd, 10); - - if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); - - /* Keep in int range for correct error message later */ - if (dim > INT_MAX) - dim = INT_MAX; - else if (dim < INT_MIN) - dim = INT_MIN; - - pt = stringEnd; - - /* Only whitespace is allowed after the closing brace */ - while (sparsevec_isspace(*pt)) - pt++; - - if (*pt != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), - errdetail("Junk after closing."))); - - CheckDim(dim); - CheckExpectedDim(typmod, dim); - - qsort(elements, nnz, sizeof(SparseInputElement), CompareIndices); - - result = InitSparseVector(dim, nnz); - rvalues = SPARSEVEC_VALUES(result); - for (int i = 0; i < nnz; i++) - { - result->indices[i] = elements[i].index; - rvalues[i] = elements[i].value; - - CheckIndex(result->indices, i, dim); - } - - PG_RETURN_POINTER(result); + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + long dim; + char *pt = lit; + char *stringEnd; + SparseVector *result; + float *rvalues; + SparseInputElement *elements; + int maxNnz; + int nnz = 0; + + maxNnz = 1; + while (*pt != '\0') + { + if (*pt == ',') + maxNnz++; + + pt++; + } + + if (maxNnz > SPARSEVEC_MAX_NNZ) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); + + elements = (SparseInputElement *)palloc(maxNnz * sizeof(SparseInputElement)); + + pt = lit; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != '{') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Vector contents must start with \"{\"."))); + + pt++; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt == '}') + pt++; + else + { + for (;;) + { + long index; + float value; + + if (nnz == maxNnz) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("ran out of buffer: \"%s\"", lit))); + + while (sparsevec_isspace(*pt)) + pt++; + + /* Check for empty string like float4in */ + if (*pt == '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Use similar logic as int2vectorin */ + index = strtol(pt, &stringEnd, 10); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Keep in int range for correct error message later */ + if (index > INT_MAX) + index = INT_MAX; + else if (index < INT_MIN + 1) + index = INT_MIN + 1; + + pt = stringEnd; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != ':') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + pt++; + + while (sparsevec_isspace(*pt)) + pt++; + + errno = 0; + + /* Use strtof like float4in to avoid a double-rounding problem */ + /* Postgres sets LC_NUMERIC to C on startup */ + value = strtof(pt, &stringEnd); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Check for range error like float4in */ + if (errno == ERANGE && (value == 0 || isinf(value))) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type sparsevec", pnstrdup(pt, stringEnd - pt)))); + + CheckElement(value); + + /* Do not store zero values */ + if (value != 0) + { + /* Convert 1-based numbering (SQL) to 0-based (C) */ + elements[nnz].index = index - 1; + elements[nnz].value = value; + nnz++; + } + + pt = stringEnd; + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt == ',') + pt++; + else if (*pt == '}') + { + pt++; + break; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + } + } + + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != '/') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Unexpected end of input."))); + + pt++; + + while (sparsevec_isspace(*pt)) + pt++; + + /* Use similar logic as int2vectorin */ + dim = strtol(pt, &stringEnd, 10); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + + /* Keep in int range for correct error message later */ + if (dim > INT_MAX) + dim = INT_MAX; + else if (dim < INT_MIN) + dim = INT_MIN; + + pt = stringEnd; + + /* Only whitespace is allowed after the closing brace */ + while (sparsevec_isspace(*pt)) + pt++; + + if (*pt != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Junk after closing."))); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + qsort(elements, nnz, sizeof(SparseInputElement), CompareIndices); + + result = InitSparseVector(dim, nnz); + rvalues = SPARSEVEC_VALUES(result); + for (int i = 0; i < nnz; i++) + { + result->indices[i] = elements[i].index; + rvalues[i] = elements[i].value; + + CheckIndex(result->indices, i, dim); + } + + PG_RETURN_POINTER(result); } #define AppendChar(ptr, c) (*(ptr)++ = (c)) @@ -399,11 +399,11 @@ sparsevec_in(PG_FUNCTION_ARGS) #define AppendInt(ptr, i) ((ptr) += pg_ltoa((i), (ptr))) #else #define AppendInt(ptr, i) \ - do { \ - pg_ltoa(i, ptr); \ - while (*ptr != '\0') \ - ptr++; \ - } while (0) + do { \ + pg_ltoa(i, ptr); \ + while (*ptr != '\0') \ + ptr++; \ + } while (0) #endif /* @@ -413,50 +413,50 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_out); Datum sparsevec_out(PG_FUNCTION_ARGS) { - SparseVector *sparsevec = PG_GETARG_SPARSEVEC_P(0); - float *values = SPARSEVEC_VALUES(sparsevec); - char *buf; - char *ptr; - - /* - * Need: - * - * nnz * 10 bytes for index (positive integer) - * - * nnz bytes for : - * - * nnz * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for - * float_to_shortest_decimal_bufn - * - * nnz - 1 bytes for , - * - * 10 bytes for dimensions - * - * 4 bytes for {, }, /, and \0 - */ - buf = (char *) palloc((11 + FLOAT_SHORTEST_DECIMAL_LEN) * sparsevec->nnz + 13); - ptr = buf; - - AppendChar(ptr, '{'); - - for (int i = 0; i < sparsevec->nnz; i++) - { - if (i > 0) - AppendChar(ptr, ','); - - /* Convert 0-based numbering (C) to 1-based (SQL) */ - AppendInt(ptr, sparsevec->indices[i] + 1); - AppendChar(ptr, ':'); - AppendFloat(ptr, values[i]); - } - - AppendChar(ptr, '}'); - AppendChar(ptr, '/'); - AppendInt(ptr, sparsevec->dim); - *ptr = '\0'; - - PG_FREE_IF_COPY(sparsevec, 0); - PG_RETURN_CSTRING(buf); + SparseVector *sparsevec = PG_GETARG_SPARSEVEC_P(0); + float *values = SPARSEVEC_VALUES(sparsevec); + char *buf; + char *ptr; + + /* + * Need: + * + * nnz * 10 bytes for index (positive integer) + * + * nnz bytes for : + * + * nnz * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for + * float_to_shortest_decimal_bufn + * + * nnz - 1 bytes for , + * + * 10 bytes for dimensions + * + * 4 bytes for {, }, /, and \0 + */ + buf = (char *) palloc((11 + FLOAT_SHORTEST_DECIMAL_LEN) * sparsevec->nnz + 13); + ptr = buf; + + AppendChar(ptr, '{'); + + for (int i = 0; i < sparsevec->nnz; i++) + { + if (i > 0) + AppendChar(ptr, ','); + + /* Convert 0-based numbering (C) to 1-based (SQL) */ + AppendInt(ptr, sparsevec->indices[i] + 1); + AppendChar(ptr, ':'); + AppendFloat(ptr, values[i]); + } + + AppendChar(ptr, '}'); + AppendChar(ptr, '/'); + AppendInt(ptr, sparsevec->dim); + *ptr = '\0'; + + PG_FREE_IF_COPY(sparsevec, 0); + PG_RETURN_CSTRING(buf); } /* @@ -466,28 +466,28 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_typmod_in); Datum sparsevec_typmod_in(PG_FUNCTION_ARGS) { - ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); - int32 *tl; - int n; + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; - tl = ArrayGetIntegerTypmods(ta, &n); + tl = ArrayGetIntegerTypmods(ta, &n); - if (n != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid type modifier"))); + if (n != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid type modifier"))); - if (*tl < 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type sparsevec must be at least 1"))); + if (*tl < 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type sparsevec must be at least 1"))); - if (*tl > SPARSEVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type sparsevec cannot exceed %d", SPARSEVEC_MAX_DIM))); + if (*tl > SPARSEVEC_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type sparsevec cannot exceed %d", SPARSEVEC_MAX_DIM))); - PG_RETURN_INT32(*tl); + PG_RETURN_INT32(*tl); } /* @@ -497,49 +497,49 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_recv); Datum sparsevec_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - int32 typmod = PG_GETARG_INT32(2); - SparseVector *result; - int32 dim; - int32 nnz; - int32 unused; - float *values; - - dim = pq_getmsgint(buf, sizeof(int32)); - nnz = pq_getmsgint(buf, sizeof(int32)); - unused = pq_getmsgint(buf, sizeof(int32)); - - CheckDim(dim); - CheckNnz(nnz, dim); - CheckExpectedDim(typmod, dim); - - if (unused != 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected unused to be 0, not %d", unused))); - - result = InitSparseVector(dim, nnz); - values = SPARSEVEC_VALUES(result); - - /* Binary representation uses zero-based numbering for indices */ - for (int i = 0; i < nnz; i++) - { - result->indices[i] = pq_getmsgint(buf, sizeof(int32)); - CheckIndex(result->indices, i, dim); - } - - for (int i = 0; i < nnz; i++) - { - values[i] = pq_getmsgfloat4(buf); - CheckElement(values[i]); - - if (values[i] == 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("binary representation of sparsevec cannot contain zero values"))); - } - - PG_RETURN_POINTER(result); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); + SparseVector *result; + int32 dim; + int32 nnz; + int32 unused; + float *values; + + dim = pq_getmsgint(buf, sizeof(int32)); + nnz = pq_getmsgint(buf, sizeof(int32)); + unused = pq_getmsgint(buf, sizeof(int32)); + + CheckDim(dim); + CheckNnz(nnz, dim); + CheckExpectedDim(typmod, dim); + + if (unused != 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected unused to be 0, not %d", unused))); + + result = InitSparseVector(dim, nnz); + values = SPARSEVEC_VALUES(result); + + /* Binary representation uses zero-based numbering for indices */ + for (int i = 0; i < nnz; i++) + { + result->indices[i] = pq_getmsgint(buf, sizeof(int32)); + CheckIndex(result->indices, i, dim); + } + + for (int i = 0; i < nnz; i++) + { + values[i] = pq_getmsgfloat4(buf); + CheckElement(values[i]); + + if (values[i] == 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("binary representation of sparsevec cannot contain zero values"))); + } + + PG_RETURN_POINTER(result); } /* @@ -549,23 +549,23 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_send); Datum sparsevec_send(PG_FUNCTION_ARGS) { - SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - float *values = SPARSEVEC_VALUES(svec); - StringInfoData buf; + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + float *values = SPARSEVEC_VALUES(svec); + StringInfoData buf; - pq_begintypsend(&buf); - pq_sendint(&buf, svec->dim, sizeof(int32)); - pq_sendint(&buf, svec->nnz, sizeof(int32)); - pq_sendint(&buf, svec->unused, sizeof(int32)); + pq_begintypsend(&buf); + pq_sendint(&buf, svec->dim, sizeof(int32)); + pq_sendint(&buf, svec->nnz, sizeof(int32)); + pq_sendint(&buf, svec->unused, sizeof(int32)); - /* Binary representation uses zero-based numbering for indices */ - for (int i = 0; i < svec->nnz; i++) - pq_sendint(&buf, svec->indices[i], sizeof(int32)); + /* Binary representation uses zero-based numbering for indices */ + for (int i = 0; i < svec->nnz; i++) + pq_sendint(&buf, svec->indices[i], sizeof(int32)); - for (int i = 0; i < svec->nnz; i++) - pq_sendfloat4(&buf, values[i]); + for (int i = 0; i < svec->nnz; i++) + pq_sendfloat4(&buf, values[i]); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } /* @@ -576,12 +576,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec); Datum sparsevec(PG_FUNCTION_ARGS) { - SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); - CheckExpectedDim(typmod, svec->dim); + CheckExpectedDim(typmod, svec->dim); - PG_RETURN_POINTER(svec); + PG_RETURN_POINTER(svec); } /* @@ -591,40 +591,40 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_sparsevec); Datum vector_to_sparsevec(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - int32 typmod = PG_GETARG_INT32(1); - SparseVector *result; - int dim = vec->dim; - int nnz = 0; - float *values; - int j = 0; - - CheckDim(dim); - CheckExpectedDim(typmod, dim); - - for (int i = 0; i < dim; i++) - { - if (vec->x[i] != 0) - nnz++; - } - - result = InitSparseVector(dim, nnz); - values = SPARSEVEC_VALUES(result); - for (int i = 0; i < dim; i++) - { - if (vec->x[i] != 0) - { - /* Safety check */ - if (j >= result->nnz) - elog(ERROR, "safety check failed"); - - result->indices[j] = i; - values[j] = vec->x[i]; - j++; - } - } - - PG_RETURN_POINTER(result); + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); + SparseVector *result; + int dim = vec->dim; + int nnz = 0; + float *values; + int j = 0; + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + for (int i = 0; i < dim; i++) + { + if (vec->x[i] != 0) + nnz++; + } + + result = InitSparseVector(dim, nnz); + values = SPARSEVEC_VALUES(result); + for (int i = 0; i < dim; i++) + { + if (vec->x[i] != 0) + { + /* Safety check */ + if (j >= result->nnz) + elog(ERROR, "safety check failed"); + + result->indices[j] = i; + values[j] = vec->x[i]; + j++; + } + } + + PG_RETURN_POINTER(result); } /* @@ -634,40 +634,40 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_sparsevec); Datum halfvec_to_sparsevec(PG_FUNCTION_ARGS) { - HalfVector *vec = PG_GETARG_HALFVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); - SparseVector *result; - int dim = vec->dim; - int nnz = 0; - float *values; - int j = 0; - - CheckDim(dim); - CheckExpectedDim(typmod, dim); - - for (int i = 0; i < dim; i++) - { - if (!HalfIsZero(vec->x[i])) - nnz++; - } - - result = InitSparseVector(dim, nnz); - values = SPARSEVEC_VALUES(result); - for (int i = 0; i < dim; i++) - { - if (!HalfIsZero(vec->x[i])) - { - /* Safety check */ - if (j >= result->nnz) - elog(ERROR, "safety check failed"); - - result->indices[j] = i; - values[j] = HalfToFloat4(vec->x[i]); - j++; - } - } - - PG_RETURN_POINTER(result); + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + SparseVector *result; + int dim = vec->dim; + int nnz = 0; + float *values; + int j = 0; + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + for (int i = 0; i < dim; i++) + { + if (!HalfIsZero(vec->x[i])) + nnz++; + } + + result = InitSparseVector(dim, nnz); + values = SPARSEVEC_VALUES(result); + for (int i = 0; i < dim; i++) + { + if (!HalfIsZero(vec->x[i])) + { + /* Safety check */ + if (j >= result->nnz) + elog(ERROR, "safety check failed"); + + result->indices[j] = i; + values[j] = HalfToFloat4(vec->x[i]); + j++; + } + } + + PG_RETURN_POINTER(result); } /* @@ -676,46 +676,46 @@ halfvec_to_sparsevec(PG_FUNCTION_ARGS) static float SparsevecL2SquaredDistance(SparseVector * a, SparseVector * b) { - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float distance = 0.0; - int bpos = 0; - - for (int i = 0; i < a->nnz; i++) - { - int ai = a->indices[i]; - int bi = -1; - - for (int j = bpos; j < b->nnz; j++) - { - bi = b->indices[j]; - - if (ai == bi) - { - float diff = ax[i] - bx[j]; - - distance += diff * diff; - } - else if (ai > bi) - distance += bx[j] * bx[j]; - - /* Update start for next iteration */ - if (ai >= bi) - bpos = j + 1; - - /* Found or passed it */ - if (bi >= ai) - break; - } - - if (ai != bi) - distance += ax[i] * ax[i]; - } - - for (int j = bpos; j < b->nnz; j++) - distance += bx[j] * bx[j]; - - return distance; + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; + + for (int i = 0; i < a->nnz; i++) + { + int ai = a->indices[i]; + int bi = -1; + + for (int j = bpos; j < b->nnz; j++) + { + bi = b->indices[j]; + + if (ai == bi) + { + float diff = ax[i] - bx[j]; + + distance += diff * diff; + } + else if (ai > bi) + distance += bx[j] * bx[j]; + + /* Update start for next iteration */ + if (ai >= bi) + bpos = j + 1; + + /* Found or passed it */ + if (bi >= ai) + break; + } + + if (ai != bi) + distance += ax[i] * ax[i]; + } + + for (int j = bpos; j < b->nnz; j++) + distance += bx[j] * bx[j]; + + return distance; } /* @@ -725,12 +725,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_distance); Datum sparsevec_l2_distance(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8(sqrt((double) SparsevecL2SquaredDistance(a, b))); + PG_RETURN_FLOAT8(sqrt((double) SparsevecL2SquaredDistance(a, b))); } /* @@ -741,12 +741,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_squared_distance); Datum sparsevec_l2_squared_distance(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) SparsevecL2SquaredDistance(a, b)); + PG_RETURN_FLOAT8((double) SparsevecL2SquaredDistance(a, b)); } /* @@ -755,34 +755,34 @@ sparsevec_l2_squared_distance(PG_FUNCTION_ARGS) static float SparsevecInnerProduct(SparseVector * a, SparseVector * b) { - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float distance = 0.0; - int bpos = 0; - - for (int i = 0; i < a->nnz; i++) - { - int ai = a->indices[i]; - - for (int j = bpos; j < b->nnz; j++) - { - int bi = b->indices[j]; - - /* Only update when the same index */ - if (ai == bi) - distance += ax[i] * bx[j]; - - /* Update start for next iteration */ - if (ai >= bi) - bpos = j + 1; - - /* Found or passed it */ - if (bi >= ai) - break; - } - } - - return distance; + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; + + for (int i = 0; i < a->nnz; i++) + { + int ai = a->indices[i]; + + for (int j = bpos; j < b->nnz; j++) + { + int bi = b->indices[j]; + + /* Only update when the same index */ + if (ai == bi) + distance += ax[i] * bx[j]; + + /* Update start for next iteration */ + if (ai >= bi) + bpos = j + 1; + + /* Found or passed it */ + if (bi >= ai) + break; + } + } + + return distance; } /* @@ -792,12 +792,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_inner_product); Datum sparsevec_inner_product(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) SparsevecInnerProduct(a, b)); + PG_RETURN_FLOAT8((double) SparsevecInnerProduct(a, b)); } /* @@ -807,12 +807,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_negative_inner_product); Datum sparsevec_negative_inner_product(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) -SparsevecInnerProduct(a, b)); + PG_RETURN_FLOAT8((double) -SparsevecInnerProduct(a, b)); } /* @@ -822,42 +822,42 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_cosine_distance); Datum sparsevec_cosine_distance(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float norma = 0.0; - float normb = 0.0; - double similarity; + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float norma = 0.0; + float normb = 0.0; + double similarity; - CheckDims(a, b); + CheckDims(a, b); - similarity = SparsevecInnerProduct(a, b); + similarity = SparsevecInnerProduct(a, b); - /* Auto-vectorized */ - for (int i = 0; i < a->nnz; i++) - norma += ax[i] * ax[i]; + /* Auto-vectorized */ + for (int i = 0; i < a->nnz; i++) + norma += ax[i] * ax[i]; - /* Auto-vectorized */ - for (int i = 0; i < b->nnz; i++) - normb += bx[i] * bx[i]; + /* Auto-vectorized */ + for (int i = 0; i < b->nnz; i++) + normb += bx[i] * bx[i]; - /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - similarity /= sqrt((double) norma * (double) normb); + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + similarity /= sqrt((double) norma * (double) normb); #ifdef _MSC_VER - /* /fp:fast may not propagate NaN */ - if (isnan(similarity)) - PG_RETURN_FLOAT8(NAN); + /* /fp:fast may not propagate NaN */ + if (isnan(similarity)) + PG_RETURN_FLOAT8(NAN); #endif - /* Keep in range */ - if (similarity > 1) - similarity = 1.0; - else if (similarity < -1) - similarity = -1.0; + /* Keep in range */ + if (similarity > 1) + similarity = 1.0; + else if (similarity < -1) + similarity = -1.0; - PG_RETURN_FLOAT8(1.0 - similarity); + PG_RETURN_FLOAT8(1.0 - similarity); } /* @@ -867,46 +867,46 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l1_distance); Datum sparsevec_l1_distance(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float distance = 0.0; - int bpos = 0; - - CheckDims(a, b); - - for (int i = 0; i < a->nnz; i++) - { - int ai = a->indices[i]; - int bi = -1; - - for (int j = bpos; j < b->nnz; j++) - { - bi = b->indices[j]; - - if (ai == bi) - distance += fabsf(ax[i] - bx[j]); - else if (ai > bi) - distance += fabsf(bx[j]); - - /* Update start for next iteration */ - if (ai >= bi) - bpos = j + 1; - - /* Found or passed it */ - if (bi >= ai) - break; - } - - if (ai != bi) - distance += fabsf(ax[i]); - } - - for (int j = bpos; j < b->nnz; j++) - distance += fabsf(bx[j]); - - PG_RETURN_FLOAT8((double) distance); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; + + CheckDims(a, b); + + for (int i = 0; i < a->nnz; i++) + { + int ai = a->indices[i]; + int bi = -1; + + for (int j = bpos; j < b->nnz; j++) + { + bi = b->indices[j]; + + if (ai == bi) + distance += fabsf(ax[i] - bx[j]); + else if (ai > bi) + distance += fabsf(bx[j]); + + /* Update start for next iteration */ + if (ai >= bi) + bpos = j + 1; + + /* Found or passed it */ + if (bi >= ai) + break; + } + + if (ai != bi) + distance += fabsf(ax[i]); + } + + for (int j = bpos; j < b->nnz; j++) + distance += fabsf(bx[j]); + + PG_RETURN_FLOAT8((double) distance); } /* @@ -916,15 +916,15 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_norm); Datum sparsevec_l2_norm(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - float *ax = SPARSEVEC_VALUES(a); - double norm = 0.0; + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + float *ax = SPARSEVEC_VALUES(a); + double norm = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < a->nnz; i++) - norm += (double) ax[i] * (double) ax[i]; + /* Auto-vectorized */ + for (int i = 0; i < a->nnz; i++) + norm += (double) ax[i] * (double) ax[i]; - PG_RETURN_FLOAT8(sqrt(norm)); + PG_RETURN_FLOAT8(sqrt(norm)); } static pg_noinline void @@ -942,66 +942,66 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_normalize); Datum sparsevec_l2_normalize(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - float *ax = SPARSEVEC_VALUES(a); - double norm = 0; - SparseVector *result; - float *rx; - - result = InitSparseVector(a->dim, a->nnz); - rx = SPARSEVEC_VALUES(result); - - /* Auto-vectorized */ - for (int i = 0; i < a->nnz; i++) - norm += (double) ax[i] * (double) ax[i]; - - norm = sqrt(norm); - - /* Return zero vector for zero norm */ - if (norm > 0) - { - int zeros = 0; - - for (int i = 0; i < a->nnz; i++) - { - result->indices[i] = a->indices[i]; - rx[i] = ax[i] / norm; - - if (isinf(rx[i])) - float_overflow_error(); - - if (rx[i] == 0) - zeros++; - } - - /* Allocate a new vector in the unlikely event there are zeros */ - if (zeros > 0) - { - SparseVector *newResult = InitSparseVector(result->dim, result->nnz - zeros); - float *nx = SPARSEVEC_VALUES(newResult); - int j = 0; - - for (int i = 0; i < result->nnz; i++) - { - if (rx[i] == 0) - continue; - - /* Safety check */ - if (j >= newResult->nnz) - elog(ERROR, "safety check failed"); - - newResult->indices[j] = result->indices[i]; - nx[j] = rx[i]; - j++; - } - - pfree(result); - - PG_RETURN_POINTER(newResult); - } - } - - PG_RETURN_POINTER(result); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + float *ax = SPARSEVEC_VALUES(a); + double norm = 0; + SparseVector *result; + float *rx; + + result = InitSparseVector(a->dim, a->nnz); + rx = SPARSEVEC_VALUES(result); + + /* Auto-vectorized */ + for (int i = 0; i < a->nnz; i++) + norm += (double) ax[i] * (double) ax[i]; + + norm = sqrt(norm); + + /* Return zero vector for zero norm */ + if (norm > 0) + { + int zeros = 0; + + for (int i = 0; i < a->nnz; i++) + { + result->indices[i] = a->indices[i]; + rx[i] = ax[i] / norm; + + if (isinf(rx[i])) + float_overflow_error(); + + if (rx[i] == 0) + zeros++; + } + + /* Allocate a new vector in the unlikely event there are zeros */ + if (zeros > 0) + { + SparseVector *newResult = InitSparseVector(result->dim, result->nnz - zeros); + float *nx = SPARSEVEC_VALUES(newResult); + int j = 0; + + for (int i = 0; i < result->nnz; i++) + { + if (rx[i] == 0) + continue; + + /* Safety check */ + if (j >= newResult->nnz) + elog(ERROR, "safety check failed"); + + newResult->indices[j] = result->indices[i]; + nx[j] = rx[i]; + j++; + } + + pfree(result); + + PG_RETURN_POINTER(newResult); + } + } + + PG_RETURN_POINTER(result); } /* @@ -1010,39 +1010,39 @@ sparsevec_l2_normalize(PG_FUNCTION_ARGS) static int sparsevec_cmp_internal(SparseVector * a, SparseVector * b) { - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - int nnz = Min(a->nnz, b->nnz); + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + int nnz = Min(a->nnz, b->nnz); - /* Check values before dimensions to be consistent with Postgres arrays */ - for (int i = 0; i < nnz; i++) - { - if (a->indices[i] < b->indices[i]) - return ax[i] < 0 ? -1 : 1; + /* Check values before dimensions to be consistent with Postgres arrays */ + for (int i = 0; i < nnz; i++) + { + if (a->indices[i] < b->indices[i]) + return ax[i] < 0 ? -1 : 1; - if (a->indices[i] > b->indices[i]) - return bx[i] < 0 ? 1 : -1; + if (a->indices[i] > b->indices[i]) + return bx[i] < 0 ? 1 : -1; - if (ax[i] < bx[i]) - return -1; + if (ax[i] < bx[i]) + return -1; - if (ax[i] > bx[i]) - return 1; - } + if (ax[i] > bx[i]) + return 1; + } - if (a->nnz < b->nnz && b->indices[nnz] < a->dim) - return bx[nnz] < 0 ? 1 : -1; + if (a->nnz < b->nnz && b->indices[nnz] < a->dim) + return bx[nnz] < 0 ? 1 : -1; - if (a->nnz > b->nnz && a->indices[nnz] < b->dim) - return ax[nnz] < 0 ? -1 : 1; + if (a->nnz > b->nnz && a->indices[nnz] < b->dim) + return ax[nnz] < 0 ? -1 : 1; - if (a->dim < b->dim) - return -1; + if (a->dim < b->dim) + return -1; - if (a->dim > b->dim) - return 1; + if (a->dim > b->dim) + return 1; - return 0; + return 0; } /* @@ -1052,10 +1052,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_lt); Datum sparsevec_lt(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) < 0); + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) < 0); } /* @@ -1065,10 +1065,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_le); Datum sparsevec_le(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) <= 0); + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) <= 0); } /* @@ -1078,10 +1078,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_eq); Datum sparsevec_eq(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) == 0); + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) == 0); } /* @@ -1091,10 +1091,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_ne); Datum sparsevec_ne(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) != 0); + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) != 0); } /* @@ -1104,10 +1104,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_ge); Datum sparsevec_ge(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) >= 0); + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) >= 0); } /* @@ -1117,10 +1117,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_gt); Datum sparsevec_gt(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) > 0); + PG_RETURN_BOOL(sparsevec_cmp_internal(a, b) > 0); } /* @@ -1130,8 +1130,8 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_cmp); Datum sparsevec_cmp(PG_FUNCTION_ARGS) { - SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - SparseVector *b = PG_GETARG_SPARSEVEC_P(1); + SparseVector *a = PG_GETARG_SPARSEVEC_P(0); + SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - PG_RETURN_INT32(sparsevec_cmp_internal(a, b)); + PG_RETURN_INT32(sparsevec_cmp_internal(a, b)); } diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 549b1f9ba6..c9bd66af0c 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -90,10 +90,10 @@ void init_session_vars(void) static inline void CheckDims(Vector * a, Vector * b) { - if (a->dim != b->dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("different vector dimensions %d and %d", a->dim, b->dim))); + if (a->dim != b->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("different vector dimensions %d and %d", a->dim, b->dim))); } /* @@ -102,10 +102,10 @@ CheckDims(Vector * a, Vector * b) static inline void CheckExpectedDim(int32 typmod, int dim) { - if (typmod != -1 && typmod != dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected %d dimensions, not %d", typmod, dim))); + if (typmod != -1 && typmod != dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected %d dimensions, not %d", typmod, dim))); } /* @@ -114,15 +114,15 @@ CheckExpectedDim(int32 typmod, int dim) static inline void CheckDim(int dim) { - if (dim < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); - - if (dim > VECTOR_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); + if (dim < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + if (dim > VECTOR_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); } /* @@ -131,15 +131,15 @@ CheckDim(int dim) static inline void CheckElement(float value) { - if (isnan(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("NaN not allowed in vector"))); - - if (isinf(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("infinite value not allowed in vector"))); + if (isnan(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("NaN not allowed in vector"))); + + if (isinf(value)) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("infinite value not allowed in vector"))); } /* @@ -148,15 +148,15 @@ CheckElement(float value) Vector * InitVector(int dim) { - Vector *result; - int size; + Vector *result; + int size; - size = VECTOR_SIZE(dim); - result = (Vector *) palloc0(size); - SET_VARSIZE(result, size); - result->dim = dim; + size = VECTOR_SIZE(dim); + result = (Vector *) palloc0(size); + SET_VARSIZE(result, size); + result->dim = dim; - return result; + return result; } /* @@ -165,14 +165,14 @@ InitVector(int dim) static inline bool vector_isspace(char ch) { - if (ch == ' ' || - ch == '\t' || - ch == '\n' || - ch == '\r' || - ch == '\v' || - ch == '\f') - return true; - return false; + if (ch == ' ' || + ch == '\t' || + ch == '\n' || + ch == '\r' || + ch == '\v' || + ch == '\f') + return true; + return false; } /* @@ -181,29 +181,29 @@ vector_isspace(char ch) static float8 * CheckStateArray(ArrayType *statearray, const char *caller) { - if (ARR_NDIM(statearray) != 1 || - ARR_DIMS(statearray)[0] < 1 || - ARR_HASNULL(statearray) || - ARR_ELEMTYPE(statearray) != FLOAT8OID) - elog(ERROR, "%s: expected state array", caller); - return (float8 *) ARR_DATA_PTR(statearray); + if (ARR_NDIM(statearray) != 1 || + ARR_DIMS(statearray)[0] < 1 || + ARR_HASNULL(statearray) || + ARR_ELEMTYPE(statearray) != FLOAT8OID) + elog(ERROR, "%s: expected state array", caller); + return (float8 *) ARR_DATA_PTR(statearray); } #if PG_VERSION_NUM < 120003 static pg_noinline void float_overflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: overflow"))); + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); } static pg_noinline void float_underflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: underflow"))); + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: underflow"))); } #endif @@ -214,107 +214,107 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_in); Datum vector_in(PG_FUNCTION_ARGS) { - char *lit = PG_GETARG_CSTRING(0); - int32 typmod = PG_GETARG_INT32(2); - float x[VECTOR_MAX_DIM]; - int dim = 0; - char *pt = lit; - Vector *result; - - while (vector_isspace(*pt)) - pt++; - - if (*pt != '[') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit), - errdetail("Vector contents must start with \"[\"."))); - - pt++; - - while (vector_isspace(*pt)) - pt++; - - if (*pt == ']') - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); - - for (;;) - { - float val; - char *stringEnd; - - if (dim == VECTOR_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); - - while (vector_isspace(*pt)) - pt++; - - /* Check for empty string like float4in */ - if (*pt == '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit))); - - errno = 0; - - /* Use strtof like float4in to avoid a double-rounding problem */ - /* Postgres sets LC_NUMERIC to C on startup */ - val = strtof(pt, &stringEnd); - - if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit))); - - /* Check for range error like float4in */ - if (errno == ERANGE && isinf(val)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type vector", pnstrdup(pt, stringEnd - pt)))); - - CheckElement(val); - x[dim++] = val; - - pt = stringEnd; - - while (vector_isspace(*pt)) - pt++; - - if (*pt == ',') - pt++; - else if (*pt == ']') - { - pt++; - break; - } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit))); - } - - /* Only whitespace is allowed after the closing brace */ - while (vector_isspace(*pt)) - pt++; - - if (*pt != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit), - errdetail("Junk after closing right brace."))); - - CheckDim(dim); - CheckExpectedDim(typmod, dim); - - result = InitVector(dim); - for (int i = 0; i < dim; i++) - result->x[i] = x[i]; - - PG_RETURN_POINTER(result); + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + float x[VECTOR_MAX_DIM]; + int dim = 0; + char *pt = lit; + Vector *result; + + while (vector_isspace(*pt)) + pt++; + + if (*pt != '[') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit), + errdetail("Vector contents must start with \"[\"."))); + + pt++; + + while (vector_isspace(*pt)) + pt++; + + if (*pt == ']') + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + for (;;) + { + float val; + char *stringEnd; + + if (dim == VECTOR_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); + + while (vector_isspace(*pt)) + pt++; + + /* Check for empty string like float4in */ + if (*pt == '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); + + errno = 0; + + /* Use strtof like float4in to avoid a double-rounding problem */ + /* Postgres sets LC_NUMERIC to C on startup */ + val = strtof(pt, &stringEnd); + + if (stringEnd == pt) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); + + /* Check for range error like float4in */ + if (errno == ERANGE && isinf(val)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type vector", pnstrdup(pt, stringEnd - pt)))); + + CheckElement(val); + x[dim++] = val; + + pt = stringEnd; + + while (vector_isspace(*pt)) + pt++; + + if (*pt == ',') + pt++; + else if (*pt == ']') + { + pt++; + break; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); + } + + /* Only whitespace is allowed after the closing brace */ + while (vector_isspace(*pt)) + pt++; + + if (*pt != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit), + errdetail("Junk after closing right brace."))); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + result = InitVector(dim); + for (int i = 0; i < dim; i++) + result->x[i] = x[i]; + + PG_RETURN_POINTER(result); } #define AppendChar(ptr, c) (*(ptr)++ = (c)) @@ -327,39 +327,39 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_out); Datum vector_out(PG_FUNCTION_ARGS) { - Vector *vector = PG_GETARG_VECTOR_P(0); - int dim = vector->dim; - char *buf; - char *ptr; - - /* - * Need: - * - * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for - * float_to_shortest_decimal_bufn - * - * dim - 1 bytes for separator - * - * 3 bytes for [, ], and \0 - */ - buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); - ptr = buf; - - AppendChar(ptr, '['); - - for (int i = 0; i < dim; i++) - { - if (i > 0) - AppendChar(ptr, ','); - - AppendFloat(ptr, vector->x[i]); - } - - AppendChar(ptr, ']'); - *ptr = '\0'; - - PG_FREE_IF_COPY(vector, 0); - PG_RETURN_CSTRING(buf); + Vector *vector = PG_GETARG_VECTOR_P(0); + int dim = vector->dim; + char *buf; + char *ptr; + + /* + * Need: + * + * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for + * float_to_shortest_decimal_bufn + * + * dim - 1 bytes for separator + * + * 3 bytes for [, ], and \0 + */ + buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); + ptr = buf; + + AppendChar(ptr, '['); + + for (int i = 0; i < dim; i++) + { + if (i > 0) + AppendChar(ptr, ','); + + AppendFloat(ptr, vector->x[i]); + } + + AppendChar(ptr, ']'); + *ptr = '\0'; + + PG_FREE_IF_COPY(vector, 0); + PG_RETURN_CSTRING(buf); } /* @@ -368,10 +368,10 @@ vector_out(PG_FUNCTION_ARGS) void PrintVector(char *msg, Vector * vector) { - char *out = DatumGetPointer(DirectFunctionCall1(vector_out, PointerGetDatum(vector))); + char *out = DatumGetPointer(DirectFunctionCall1(vector_out, PointerGetDatum(vector))); - elog(INFO, "%s = %s", msg, out); - pfree(out); + elog(INFO, "%s = %s", msg, out); + pfree(out); } /* @@ -381,28 +381,28 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_typmod_in); Datum vector_typmod_in(PG_FUNCTION_ARGS) { - ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); - int32 *tl; - int n; + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; - tl = ArrayGetIntegerTypmods(ta, &n); + tl = ArrayGetIntegerTypmods(ta, &n); - if (n != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid type modifier"))); + if (n != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid type modifier"))); - if (*tl < 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type vector must be at least 1"))); + if (*tl < 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type vector must be at least 1"))); - if (*tl > VECTOR_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type vector cannot exceed %d", VECTOR_MAX_DIM))); + if (*tl > VECTOR_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type vector cannot exceed %d", VECTOR_MAX_DIM))); - PG_RETURN_INT32(*tl); + PG_RETURN_INT32(*tl); } /* @@ -412,31 +412,31 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_recv); Datum vector_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - int32 typmod = PG_GETARG_INT32(2); - Vector *result; - int16 dim; - int16 unused; - - dim = pq_getmsgint(buf, sizeof(int16)); - unused = pq_getmsgint(buf, sizeof(int16)); - - CheckDim(dim); - CheckExpectedDim(typmod, dim); - - if (unused != 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected unused to be 0, not %d", unused))); - - result = InitVector(dim); - for (int i = 0; i < dim; i++) - { - result->x[i] = pq_getmsgfloat4(buf); - CheckElement(result->x[i]); - } - - PG_RETURN_POINTER(result); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); + Vector *result; + int16 dim; + int16 unused; + + dim = pq_getmsgint(buf, sizeof(int16)); + unused = pq_getmsgint(buf, sizeof(int16)); + + CheckDim(dim); + CheckExpectedDim(typmod, dim); + + if (unused != 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("expected unused to be 0, not %d", unused))); + + result = InitVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = pq_getmsgfloat4(buf); + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); } /* @@ -446,16 +446,16 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_send); Datum vector_send(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - StringInfoData buf; + Vector *vec = PG_GETARG_VECTOR_P(0); + StringInfoData buf; - pq_begintypsend(&buf); - pq_sendint(&buf, vec->dim, sizeof(int16)); - pq_sendint(&buf, vec->unused, sizeof(int16)); - for (int i = 0; i < vec->dim; i++) - pq_sendfloat4(&buf, vec->x[i]); + pq_begintypsend(&buf); + pq_sendint(&buf, vec->dim, sizeof(int16)); + pq_sendint(&buf, vec->unused, sizeof(int16)); + for (int i = 0; i < vec->dim; i++) + pq_sendfloat4(&buf, vec->x[i]); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } /* @@ -466,12 +466,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector); Datum vector(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - int32 typmod = PG_GETARG_INT32(1); + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); - CheckExpectedDim(typmod, vec->dim); + CheckExpectedDim(typmod, vec->dim); - PG_RETURN_POINTER(vec); + PG_RETURN_POINTER(vec); } /* @@ -481,71 +481,71 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(array_to_vector); Datum array_to_vector(PG_FUNCTION_ARGS) { - ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); - int32 typmod = PG_GETARG_INT32(1); - Vector *result; - int16 typlen; - bool typbyval; - char typalign; - Datum *elemsp; - int nelemsp; - - if (ARR_NDIM(array) > 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("array must be 1-D"))); - - if (ARR_HASNULL(array) && array_contains_nulls(array)) - ereport(ERROR, - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("array must not contain nulls"))); - - get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); - deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); - - CheckDim(nelemsp); - CheckExpectedDim(typmod, nelemsp); - - result = InitVector(nelemsp); - - if (ARR_ELEMTYPE(array) == INT4OID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = DatumGetInt32(elemsp[i]); - } - else if (ARR_ELEMTYPE(array) == FLOAT8OID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = DatumGetFloat8(elemsp[i]); - } - else if (ARR_ELEMTYPE(array) == FLOAT4OID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = DatumGetFloat4(elemsp[i]); - } - else if (ARR_ELEMTYPE(array) == NUMERICOID) - { - for (int i = 0; i < nelemsp; i++) - result->x[i] = DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i])); - } - else - { - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("unsupported array type"))); - } - - /* - * Free allocation from deconstruct_array. Do not free individual elements - * when pass-by-reference since they point to original array. - */ - pfree(elemsp); - - /* Check elements */ - for (int i = 0; i < result->dim; i++) - CheckElement(result->x[i]); - - PG_RETURN_POINTER(result); + ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; + int16 typlen; + bool typbyval; + char typalign; + Datum *elemsp; + int nelemsp; + + if (ARR_NDIM(array) > 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("array must be 1-D"))); + + if (ARR_HASNULL(array) && array_contains_nulls(array)) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("array must not contain nulls"))); + + get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); + deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); + + CheckDim(nelemsp); + CheckExpectedDim(typmod, nelemsp); + + result = InitVector(nelemsp); + + if (ARR_ELEMTYPE(array) == INT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetInt32(elemsp[i]); + } + else if (ARR_ELEMTYPE(array) == FLOAT8OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetFloat8(elemsp[i]); + } + else if (ARR_ELEMTYPE(array) == FLOAT4OID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetFloat4(elemsp[i]); + } + else if (ARR_ELEMTYPE(array) == NUMERICOID) + { + for (int i = 0; i < nelemsp; i++) + result->x[i] = DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i])); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("unsupported array type"))); + } + + /* + * Free allocation from deconstruct_array. Do not free individual elements + * when pass-by-reference since they point to original array. + */ + pfree(elemsp); + + /* Check elements */ + for (int i = 0; i < result->dim; i++) + CheckElement(result->x[i]); + + PG_RETURN_POINTER(result); } /* @@ -555,21 +555,21 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_float4); Datum vector_to_float4(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - Datum *datums; - ArrayType *result; + Vector *vec = PG_GETARG_VECTOR_P(0); + Datum *datums; + ArrayType *result; - datums = (Datum *) palloc(sizeof(Datum) * vec->dim); + datums = (Datum *) palloc(sizeof(Datum) * vec->dim); - for (int i = 0; i < vec->dim; i++) - datums[i] = Float4GetDatum(vec->x[i]); + for (int i = 0; i < vec->dim; i++) + datums[i] = Float4GetDatum(vec->x[i]); - /* Use TYPALIGN_INT for float4 */ - result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); + /* Use TYPALIGN_INT for float4 */ + result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); - pfree(datums); + pfree(datums); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -579,35 +579,35 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_vector); Datum halfvec_to_vector(PG_FUNCTION_ARGS) { - HalfVector *vec = PG_GETARG_HALFVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); - Vector *result; + HalfVector *vec = PG_GETARG_HALFVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; - CheckDim(vec->dim); - CheckExpectedDim(typmod, vec->dim); + CheckDim(vec->dim); + CheckExpectedDim(typmod, vec->dim); - result = InitVector(vec->dim); + result = InitVector(vec->dim); - for (int i = 0; i < vec->dim; i++) - result->x[i] = HalfToFloat4(vec->x[i]); + for (int i = 0; i < vec->dim; i++) + result->x[i] = HalfToFloat4(vec->x[i]); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } VECTOR_TARGET_CLONES static float VectorL2SquaredDistance(int dim, float *ax, float *bx) { - float distance = 0.0; + float distance = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { - float diff = ax[i] - bx[i]; + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + float diff = ax[i] - bx[i]; - distance += diff * diff; - } + distance += diff * diff; + } - return distance; + return distance; } /* @@ -617,12 +617,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(l2_distance); Datum l2_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8(sqrt((double) VectorL2SquaredDistance(a->dim, a->x, b->x))); + PG_RETURN_FLOAT8(sqrt((double) VectorL2SquaredDistance(a->dim, a->x, b->x))); } /* @@ -633,24 +633,24 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_l2_squared_distance); Datum vector_l2_squared_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) VectorL2SquaredDistance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) VectorL2SquaredDistance(a->dim, a->x, b->x)); } VECTOR_TARGET_CLONES static float VectorInnerProduct(int dim, float *ax, float *bx) { - float distance = 0.0; + float distance = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - distance += ax[i] * bx[i]; + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += ax[i] * bx[i]; - return distance; + return distance; } /* @@ -660,12 +660,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(inner_product); Datum inner_product(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) VectorInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) VectorInnerProduct(a->dim, a->x, b->x)); } /* @@ -675,31 +675,31 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_negative_inner_product); Datum vector_negative_inner_product(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) -VectorInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) -VectorInnerProduct(a->dim, a->x, b->x)); } VECTOR_TARGET_CLONES static double VectorCosineSimilarity(int dim, float *ax, float *bx) { - float similarity = 0.0; - float norma = 0.0; - float normb = 0.0; - - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { - similarity += ax[i] * bx[i]; - norma += ax[i] * ax[i]; - normb += bx[i] * bx[i]; - } - - /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double) similarity / sqrt((double) norma * (double) normb); + float similarity = 0.0; + float norma = 0.0; + float normb = 0.0; + + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + { + similarity += ax[i] * bx[i]; + norma += ax[i] * ax[i]; + normb += bx[i] * bx[i]; + } + + /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ + return (double) similarity / sqrt((double) norma * (double) normb); } /* @@ -709,27 +709,27 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(cosine_distance); Datum cosine_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - double similarity; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + double similarity; - CheckDims(a, b); + CheckDims(a, b); - similarity = VectorCosineSimilarity(a->dim, a->x, b->x); + similarity = VectorCosineSimilarity(a->dim, a->x, b->x); #ifdef _MSC_VER - /* /fp:fast may not propagate NaN */ - if (isnan(similarity)) - PG_RETURN_FLOAT8(NAN); + /* /fp:fast may not propagate NaN */ + if (isnan(similarity)) + PG_RETURN_FLOAT8(NAN); #endif - /* Keep in range */ - if (similarity > 1) - similarity = 1.0; - else if (similarity < -1) - similarity = -1.0; + /* Keep in range */ + if (similarity > 1) + similarity = 1.0; + else if (similarity < -1) + similarity = -1.0; - PG_RETURN_FLOAT8(1.0 - similarity); + PG_RETURN_FLOAT8(1.0 - similarity); } /* @@ -741,34 +741,34 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_spherical_distance); Datum vector_spherical_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - double distance; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + double distance; - CheckDims(a, b); + CheckDims(a, b); - distance = (double) VectorInnerProduct(a->dim, a->x, b->x); + distance = (double) VectorInnerProduct(a->dim, a->x, b->x); - /* Prevent NaN with acos with loss of precision */ - if (distance > 1) - distance = 1; - else if (distance < -1) - distance = -1; + /* Prevent NaN with acos with loss of precision */ + if (distance > 1) + distance = 1; + else if (distance < -1) + distance = -1; - PG_RETURN_FLOAT8(acos(distance) / M_PI); + PG_RETURN_FLOAT8(acos(distance) / M_PI); } /* Does not require FMA, but keep logic simple */ VECTOR_TARGET_CLONES static float VectorL1Distance(int dim, float *ax, float *bx) { - float distance = 0.0; + float distance = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - distance += fabsf(ax[i] - bx[i]); + /* Auto-vectorized */ + for (int i = 0; i < dim; i++) + distance += fabsf(ax[i] - bx[i]); - return distance; + return distance; } /* @@ -778,12 +778,12 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(l1_distance); Datum l1_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - CheckDims(a, b); + CheckDims(a, b); - PG_RETURN_FLOAT8((double) VectorL1Distance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double) VectorL1Distance(a->dim, a->x, b->x)); } /* @@ -793,9 +793,9 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_dims); Datum vector_dims(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); + Vector *a = PG_GETARG_VECTOR_P(0); - PG_RETURN_INT32(a->dim); + PG_RETURN_INT32(a->dim); } /* @@ -805,15 +805,15 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_norm); Datum vector_norm(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - float *ax = a->x; - double norm = 0.0; + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + double norm = 0.0; - /* Auto-vectorized */ - for (int i = 0; i < a->dim; i++) - norm += (double) ax[i] * (double) ax[i]; + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + norm += (double) ax[i] * (double) ax[i]; - PG_RETURN_FLOAT8(sqrt(norm)); + PG_RETURN_FLOAT8(sqrt(norm)); } /* @@ -823,36 +823,36 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(l2_normalize); Datum l2_normalize(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - float *ax = a->x; - double norm = 0; - Vector *result; - float *rx; - - result = InitVector(a->dim); - rx = result->x; - - /* Auto-vectorized */ - for (int i = 0; i < a->dim; i++) - norm += (double) ax[i] * (double) ax[i]; - - norm = sqrt(norm); - - /* Return zero vector for zero norm */ - if (norm > 0) - { - for (int i = 0; i < a->dim; i++) - rx[i] = ax[i] / norm; - - /* Check for overflow */ - for (int i = 0; i < a->dim; i++) - { - if (isinf(rx[i])) - float_overflow_error(); - } - } - - PG_RETURN_POINTER(result); + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + double norm = 0; + Vector *result; + float *rx; + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0; i < a->dim; i++) + norm += (double) ax[i] * (double) ax[i]; + + norm = sqrt(norm); + + /* Return zero vector for zero norm */ + if (norm > 0) + { + for (int i = 0; i < a->dim; i++) + rx[i] = ax[i] / norm; + + /* Check for overflow */ + for (int i = 0; i < a->dim; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + } + } + + PG_RETURN_POINTER(result); } /* @@ -862,30 +862,30 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_add); Datum vector_add(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - float *ax = a->x; - float *bx = b->x; - Vector *result; - float *rx; - - CheckDims(a, b); - - result = InitVector(a->dim); - rx = result->x; - - /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - rx[i] = ax[i] + bx[i]; - - /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { - if (isinf(rx[i])) - float_overflow_error(); - } - - PG_RETURN_POINTER(result); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; + + CheckDims(a, b); + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + rx[i] = ax[i] + bx[i]; + + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + } + + PG_RETURN_POINTER(result); } /* @@ -895,30 +895,30 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_sub); Datum vector_sub(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - float *ax = a->x; - float *bx = b->x; - Vector *result; - float *rx; - - CheckDims(a, b); - - result = InitVector(a->dim); - rx = result->x; - - /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - rx[i] = ax[i] - bx[i]; - - /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { - if (isinf(rx[i])) - float_overflow_error(); - } - - PG_RETURN_POINTER(result); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; + + CheckDims(a, b); + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + rx[i] = ax[i] - bx[i]; + + /* Check for overflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + } + + PG_RETURN_POINTER(result); } /* @@ -928,33 +928,33 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_mul); Datum vector_mul(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - float *ax = a->x; - float *bx = b->x; - Vector *result; - float *rx; - - CheckDims(a, b); - - result = InitVector(a->dim); - rx = result->x; - - /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - rx[i] = ax[i] * bx[i]; - - /* Check for overflow and underflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { - if (isinf(rx[i])) - float_overflow_error(); - - if (rx[i] == 0 && !(ax[i] == 0 || bx[i] == 0)) - float_underflow_error(); - } + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; + + CheckDims(a, b); + + result = InitVector(a->dim); + rx = result->x; + + /* Auto-vectorized */ + for (int i = 0, imax = a->dim; i < imax; i++) + rx[i] = ax[i] * bx[i]; + + /* Check for overflow and underflow */ + for (int i = 0, imax = a->dim; i < imax; i++) + { + if (isinf(rx[i])) + float_overflow_error(); + + if (rx[i] == 0 && !(ax[i] == 0 || bx[i] == 0)) + float_underflow_error(); + } - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -964,21 +964,21 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_concat); Datum vector_concat(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - Vector *result; - int dim = a->dim + b->dim; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + Vector *result; + int dim = a->dim + b->dim; - CheckDim(dim); - result = InitVector(dim); + CheckDim(dim); + result = InitVector(dim); - for (int i = 0; i < a->dim; i++) - result->x[i] = a->x[i]; + for (int i = 0; i < a->dim; i++) + result->x[i] = a->x[i]; - for (int i = 0; i < b->dim; i++) - result->x[i + a->dim] = b->x[i]; + for (int i = 0; i < b->dim; i++) + result->x[i + a->dim] = b->x[i]; - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -988,15 +988,15 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(binary_quantize); Datum binary_quantize(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - float *ax = a->x; - VarBit *result = InitBitVector(a->dim); - unsigned char *rx = VARBITS(result); + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + VarBit *result = InitBitVector(a->dim); + unsigned char *rx = VARBITS(result); - for (int i = 0; i < a->dim; i++) - rx[i / 8] |= (ax[i] > 0) << (7 - (i % 8)); + for (int i = 0; i < a->dim; i++) + rx[i / 8] |= (ax[i] > 0) << (7 - (i % 8)); - PG_RETURN_VARBIT_P(result); + PG_RETURN_VARBIT_P(result); } /* @@ -1006,44 +1006,44 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(subvector); Datum subvector(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - int32 start = PG_GETARG_INT32(1); - int32 count = PG_GETARG_INT32(2); - int32 end; - float *ax = a->x; - Vector *result; - int dim; - - if (count < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); - - /* - * Check if (start + count > a->dim), avoiding integer overflow. a->dim - * and count are both positive, so a->dim - count won't overflow. - */ - if (start > a->dim - count) - end = a->dim + 1; - else - end = start + count; - - /* Indexing starts at 1, like substring */ - if (start < 1) - start = 1; - else if (start > a->dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); - - dim = end - start; - CheckDim(dim); - result = InitVector(dim); - - for (int i = 0; i < dim; i++) - result->x[i] = ax[start - 1 + i]; - - PG_RETURN_POINTER(result); + Vector *a = PG_GETARG_VECTOR_P(0); + int32 start = PG_GETARG_INT32(1); + int32 count = PG_GETARG_INT32(2); + int32 end; + float *ax = a->x; + Vector *result; + int dim; + + if (count < 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + /* + * Check if (start + count > a->dim), avoiding integer overflow. a->dim + * and count are both positive, so a->dim - count won't overflow. + */ + if (start > a->dim - count) + end = a->dim + 1; + else + end = start + count; + + /* Indexing starts at 1, like substring */ + if (start < 1) + start = 1; + else if (start > a->dim) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("vector must have at least 1 dimension"))); + + dim = end - start; + CheckDim(dim); + result = InitVector(dim); + + for (int i = 0; i < dim; i++) + result->x[i] = ax[start - 1 + i]; + + PG_RETURN_POINTER(result); } /* @@ -1052,25 +1052,25 @@ subvector(PG_FUNCTION_ARGS) int vector_cmp_internal(Vector * a, Vector * b) { - int dim = Min(a->dim, b->dim); + int dim = Min(a->dim, b->dim); - /* Check values before dimensions to be consistent with Postgres arrays */ - for (int i = 0; i < dim; i++) - { - if (a->x[i] < b->x[i]) - return -1; + /* Check values before dimensions to be consistent with Postgres arrays */ + for (int i = 0; i < dim; i++) + { + if (a->x[i] < b->x[i]) + return -1; - if (a->x[i] > b->x[i]) - return 1; - } + if (a->x[i] > b->x[i]) + return 1; + } - if (a->dim < b->dim) - return -1; + if (a->dim < b->dim) + return -1; - if (a->dim > b->dim) - return 1; + if (a->dim > b->dim) + return 1; - return 0; + return 0; } /* @@ -1080,10 +1080,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_lt); Datum vector_lt(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - PG_RETURN_BOOL(vector_cmp_internal(a, b) < 0); + PG_RETURN_BOOL(vector_cmp_internal(a, b) < 0); } /* @@ -1093,10 +1093,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_le); Datum vector_le(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - PG_RETURN_BOOL(vector_cmp_internal(a, b) <= 0); + PG_RETURN_BOOL(vector_cmp_internal(a, b) <= 0); } /* @@ -1106,10 +1106,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_eq); Datum vector_eq(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - PG_RETURN_BOOL(vector_cmp_internal(a, b) == 0); + PG_RETURN_BOOL(vector_cmp_internal(a, b) == 0); } /* @@ -1119,10 +1119,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ne); Datum vector_ne(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - PG_RETURN_BOOL(vector_cmp_internal(a, b) != 0); + PG_RETURN_BOOL(vector_cmp_internal(a, b) != 0); } /* @@ -1132,10 +1132,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ge); Datum vector_ge(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - PG_RETURN_BOOL(vector_cmp_internal(a, b) >= 0); + PG_RETURN_BOOL(vector_cmp_internal(a, b) >= 0); } /* @@ -1145,10 +1145,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_gt); Datum vector_gt(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - PG_RETURN_BOOL(vector_cmp_internal(a, b) > 0); + PG_RETURN_BOOL(vector_cmp_internal(a, b) > 0); } /* @@ -1158,10 +1158,10 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_cmp); Datum vector_cmp(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); - PG_RETURN_INT32(vector_cmp_internal(a, b)); + PG_RETURN_INT32(vector_cmp_internal(a, b)); } /* @@ -1171,58 +1171,58 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_accum); Datum vector_accum(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); - Vector *newval = PG_GETARG_VECTOR_P(1); - float8 *statevalues; - int16 dim; - bool newarr; - float8 n; - Datum *statedatums; - float *x = newval->x; - ArrayType *result; - - /* Check array before using */ - statevalues = CheckStateArray(statearray, "vector_accum"); - dim = STATE_DIMS(statearray); - newarr = dim == 0; - - if (newarr) - dim = newval->dim; - else - CheckExpectedDim(dim, newval->dim); - - n = statevalues[0] + 1.0; - - statedatums = (Datum *)CreateStateDatums(dim); - statedatums[0] = Float8GetDatum(n); - - if (newarr) - { - for (int i = 0; i < dim; i++) - statedatums[i + 1] = Float8GetDatum((double) x[i]); - } - else - { - for (int i = 0; i < dim; i++) - { - double v = statevalues[i + 1] + x[i]; - - /* Check for overflow */ - if (isinf(v)) - float_overflow_error(); - - statedatums[i + 1] = Float8GetDatum(v); - } - } - - /* Use float8 array like float4_accum */ - result = construct_array(statedatums, dim + 1, - FLOAT8OID, - sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); - - pfree(statedatums); - - PG_RETURN_ARRAYTYPE_P(result); + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + Vector *newval = PG_GETARG_VECTOR_P(1); + float8 *statevalues; + int16 dim; + bool newarr; + float8 n; + Datum *statedatums; + float *x = newval->x; + ArrayType *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "vector_accum"); + dim = STATE_DIMS(statearray); + newarr = dim == 0; + + if (newarr) + dim = newval->dim; + else + CheckExpectedDim(dim, newval->dim); + + n = statevalues[0] + 1.0; + + statedatums = (Datum *)CreateStateDatums(dim); + statedatums[0] = Float8GetDatum(n); + + if (newarr) + { + for (int i = 0; i < dim; i++) + statedatums[i + 1] = Float8GetDatum((double) x[i]); + } + else + { + for (int i = 0; i < dim; i++) + { + double v = statevalues[i + 1] + x[i]; + + /* Check for overflow */ + if (isinf(v)) + float_overflow_error(); + + statedatums[i + 1] = Float8GetDatum(v); + } + } + + /* Use float8 array like float4_accum */ + result = construct_array(statedatums, dim + 1, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + + pfree(statedatums); + + PG_RETURN_ARRAYTYPE_P(result); } /* @@ -1232,68 +1232,68 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_combine); Datum vector_combine(PG_FUNCTION_ARGS) { - /* Must also update parameters of halfvec_combine if modifying */ - ArrayType *statearray1 = PG_GETARG_ARRAYTYPE_P(0); - ArrayType *statearray2 = PG_GETARG_ARRAYTYPE_P(1); - float8 *statevalues1; - float8 *statevalues2; - float8 n; - float8 n1; - float8 n2; - int16 dim; - Datum *statedatums; - ArrayType *result; - - /* Check arrays before using */ - statevalues1 = CheckStateArray(statearray1, "vector_combine"); - statevalues2 = CheckStateArray(statearray2, "vector_combine"); - - n1 = statevalues1[0]; - n2 = statevalues2[0]; - - if (n1 == 0.0) - { - n = n2; - dim = STATE_DIMS(statearray2); - statedatums = (Datum *)CreateStateDatums(dim); - for (int i = 1; i <= dim; i++) - statedatums[i] = Float8GetDatum(statevalues2[i]); - } - else if (n2 == 0.0) - { - n = n1; - dim = STATE_DIMS(statearray1); - statedatums = (Datum *)CreateStateDatums(dim); - for (int i = 1; i <= dim; i++) - statedatums[i] = Float8GetDatum(statevalues1[i]); - } - else - { - n = n1 + n2; - dim = STATE_DIMS(statearray1); - CheckExpectedDim(dim, STATE_DIMS(statearray2)); - statedatums = (Datum *)CreateStateDatums(dim); - for (int i = 1; i <= dim; i++) - { - double v = statevalues1[i] + statevalues2[i]; - - /* Check for overflow */ - if (isinf(v)) - float_overflow_error(); - - statedatums[i] = Float8GetDatum(v); - } - } - - statedatums[0] = Float8GetDatum(n); - - result = construct_array(statedatums, dim + 1, - FLOAT8OID, - sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); - - pfree(statedatums); - - PG_RETURN_ARRAYTYPE_P(result); + /* Must also update parameters of halfvec_combine if modifying */ + ArrayType *statearray1 = PG_GETARG_ARRAYTYPE_P(0); + ArrayType *statearray2 = PG_GETARG_ARRAYTYPE_P(1); + float8 *statevalues1; + float8 *statevalues2; + float8 n; + float8 n1; + float8 n2; + int16 dim; + Datum *statedatums; + ArrayType *result; + + /* Check arrays before using */ + statevalues1 = CheckStateArray(statearray1, "vector_combine"); + statevalues2 = CheckStateArray(statearray2, "vector_combine"); + + n1 = statevalues1[0]; + n2 = statevalues2[0]; + + if (n1 == 0.0) + { + n = n2; + dim = STATE_DIMS(statearray2); + statedatums = (Datum *)CreateStateDatums(dim); + for (int i = 1; i <= dim; i++) + statedatums[i] = Float8GetDatum(statevalues2[i]); + } + else if (n2 == 0.0) + { + n = n1; + dim = STATE_DIMS(statearray1); + statedatums = (Datum *)CreateStateDatums(dim); + for (int i = 1; i <= dim; i++) + statedatums[i] = Float8GetDatum(statevalues1[i]); + } + else + { + n = n1 + n2; + dim = STATE_DIMS(statearray1); + CheckExpectedDim(dim, STATE_DIMS(statearray2)); + statedatums = (Datum *)CreateStateDatums(dim); + for (int i = 1; i <= dim; i++) + { + double v = statevalues1[i] + statevalues2[i]; + + /* Check for overflow */ + if (isinf(v)) + float_overflow_error(); + + statedatums[i] = Float8GetDatum(v); + } + } + + statedatums[0] = Float8GetDatum(n); + + result = construct_array(statedatums, dim + 1, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + + pfree(statedatums); + + PG_RETURN_ARRAYTYPE_P(result); } /* @@ -1303,31 +1303,31 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_avg); Datum vector_avg(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); - float8 *statevalues; - float8 n; - uint16 dim; - Vector *result; - - /* Check array before using */ - statevalues = CheckStateArray(statearray, "vector_avg"); - n = statevalues[0]; - - /* SQL defines AVG of no values to be NULL */ - if (n == 0.0) - PG_RETURN_NULL(); - - /* Create vector */ - dim = STATE_DIMS(statearray); - CheckDim(dim); - result = InitVector(dim); - for (int i = 0; i < dim; i++) - { - result->x[i] = statevalues[i + 1] / n; - CheckElement(result->x[i]); - } - - PG_RETURN_POINTER(result); + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + float8 *statevalues; + float8 n; + uint16 dim; + Vector *result; + + /* Check array before using */ + statevalues = CheckStateArray(statearray, "vector_avg"); + n = statevalues[0]; + + /* SQL defines AVG of no values to be NULL */ + if (n == 0.0) + PG_RETURN_NULL(); + + /* Create vector */ + dim = STATE_DIMS(statearray); + CheckDim(dim); + result = InitVector(dim); + for (int i = 0; i < dim; i++) + { + result->x[i] = statevalues[i + 1] / n; + CheckElement(result->x[i]); + } + + PG_RETURN_POINTER(result); } /* @@ -1337,20 +1337,20 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_to_vector); Datum sparsevec_to_vector(PG_FUNCTION_ARGS) { - SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); - Vector *result; - int dim = svec->dim; - float *values = SPARSEVEC_VALUES(svec); + SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; + int dim = svec->dim; + float *values = SPARSEVEC_VALUES(svec); - CheckDim(dim); - CheckExpectedDim(typmod, dim); + CheckDim(dim); + CheckExpectedDim(typmod, dim); - result = InitVector(dim); - for (int i = 0; i < svec->nnz; i++) - result->x[svec->indices[i]] = values[i]; + result = InitVector(dim); + for (int i = 0; i < svec->nnz; i++) + result->x[svec->indices[i]] = values[i]; - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* @@ -1447,26 +1447,26 @@ log_newpage_range(Relation rel, ForkNumber forknum, int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo) { - int parallelWorkers = RelationGetParallelWorkers(heapRelation, 0); - int max_hashbucket_index_worker = 32; - - if (parallelWorkers != 0) { - parallelWorkers = Min(max_hashbucket_index_worker, parallelWorkers); - } - - if (indexInfo->ii_Concurrent && indexInfo->ii_ParallelWorkers > 0) { - ereport(NOTICE, (errmsg("switch off parallel mode when concurrently flag is set"))); - parallelWorkers = 0; - } - - if (heapRelation->rd_rel->relpersistence == RELPERSISTENCE_GLOBAL_TEMP && indexInfo->ii_ParallelWorkers > 0) { - ereport(NOTICE, (errmsg("switch off parallel mode for global temp table"))); - parallelWorkers = 0; - } - - /* disable parallel building index for system table*/ - if (IsCatalogRelation(heapRelation)) { - parallelWorkers = 0; - } - return parallelWorkers; + int parallelWorkers = RelationGetParallelWorkers(heapRelation, 0); + int max_hashbucket_index_worker = 32; + + if (parallelWorkers != 0) { + parallelWorkers = Min(max_hashbucket_index_worker, parallelWorkers); + } + + if (indexInfo->ii_Concurrent && indexInfo->ii_ParallelWorkers > 0) { + ereport(NOTICE, (errmsg("switch off parallel mode when concurrently flag is set"))); + parallelWorkers = 0; + } + + if (heapRelation->rd_rel->relpersistence == RELPERSISTENCE_GLOBAL_TEMP && indexInfo->ii_ParallelWorkers > 0) { + ereport(NOTICE, (errmsg("switch off parallel mode for global temp table"))); + parallelWorkers = 0; + } + + /* disable parallel building index for system table*/ + if (IsCatalogRelation(heapRelation)) { + parallelWorkers = 0; + } + return parallelWorkers; } diff --git a/src/gausskernel/storage/access/datavec/bitutils.cpp b/src/gausskernel/storage/access/datavec/bitutils.cpp index fcbf97c893..36f43929cc 100644 --- a/src/gausskernel/storage/access/datavec/bitutils.cpp +++ b/src/gausskernel/storage/access/datavec/bitutils.cpp @@ -41,48 +41,48 @@ BIT_TARGET_CLONES static uint64 BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance) { #ifdef popcount64 - for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) - { - uint64 axs; - uint64 bxs; + for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) + { + uint64 axs; + uint64 bxs; - /* Ensure aligned */ - memcpy(&axs, ax, sizeof(uint64)); - memcpy(&bxs, bx, sizeof(uint64)); + /* Ensure aligned */ + memcpy(&axs, ax, sizeof(uint64)); + memcpy(&bxs, bx, sizeof(uint64)); - distance += popcount64(axs ^ bxs); + distance += popcount64(axs ^ bxs); - ax += sizeof(uint64); - bx += sizeof(uint64); - } + ax += sizeof(uint64); + bx += sizeof(uint64); + } #endif - for (uint32 i = 0; i < bytes; i++) - distance += pg_number_of_ones[ax[i] ^ bx[i]]; + for (uint32 i = 0; i < bytes; i++) + distance += pg_number_of_ones[ax[i] ^ bx[i]]; - return distance; + return distance; } #ifdef BIT_DISPATCH TARGET_AVX512_POPCOUNT static uint64 BitHammingDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance) { - __m512i dist = _mm512_setzero_si512(); + __m512i dist = _mm512_setzero_si512(); - for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) - { - __m512i axs = _mm512_loadu_si512((const __m512i *) ax); - __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) + { + __m512i axs = _mm512_loadu_si512((const __m512i *) ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); - dist = _mm512_add_epi64(dist, _mm512_popcnt_epi64(_mm512_xor_si512(axs, bxs))); + dist = _mm512_add_epi64(dist, _mm512_popcnt_epi64(_mm512_xor_si512(axs, bxs))); - ax += sizeof(__m512i); - bx += sizeof(__m512i); - } + ax += sizeof(__m512i); + bx += sizeof(__m512i); + } - distance += _mm512_reduce_add_epi64(dist); + distance += _mm512_reduce_add_epi64(dist); - return BitHammingDistanceDefault(bytes, ax, bx, distance); + return BitHammingDistanceDefault(bytes, ax, bx, distance); } #endif @@ -90,63 +90,63 @@ BIT_TARGET_CLONES static double BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) { #ifdef popcount64 - for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) - { - uint64 axs; - uint64 bxs; - - /* Ensure aligned */ - memcpy(&axs, ax, sizeof(uint64)); - memcpy(&bxs, bx, sizeof(uint64)); - - ab += popcount64(axs & bxs); - aa += popcount64(axs); - bb += popcount64(bxs); - - ax += sizeof(uint64); - bx += sizeof(uint64); - } + for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) + { + uint64 axs; + uint64 bxs; + + /* Ensure aligned */ + memcpy(&axs, ax, sizeof(uint64)); + memcpy(&bxs, bx, sizeof(uint64)); + + ab += popcount64(axs & bxs); + aa += popcount64(axs); + bb += popcount64(bxs); + + ax += sizeof(uint64); + bx += sizeof(uint64); + } #endif - for (uint32 i = 0; i < bytes; i++) - { - ab += pg_number_of_ones[ax[i] & bx[i]]; - aa += pg_number_of_ones[ax[i]]; - bb += pg_number_of_ones[bx[i]]; - } - - if (ab == 0) - return 1; - else - return 1 - (ab / ((double) (aa + bb - ab))); + for (uint32 i = 0; i < bytes; i++) + { + ab += pg_number_of_ones[ax[i] & bx[i]]; + aa += pg_number_of_ones[ax[i]]; + bb += pg_number_of_ones[bx[i]]; + } + + if (ab == 0) + return 1; + else + return 1 - (ab / ((double) (aa + bb - ab))); } #ifdef BIT_DISPATCH TARGET_AVX512_POPCOUNT static double BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) { - __m512i abx = _mm512_setzero_si512(); - __m512i aax = _mm512_setzero_si512(); - __m512i bbx = _mm512_setzero_si512(); + __m512i abx = _mm512_setzero_si512(); + __m512i aax = _mm512_setzero_si512(); + __m512i bbx = _mm512_setzero_si512(); - for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) - { - __m512i axs = _mm512_loadu_si512((const __m512i *) ax); - __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) + { + __m512i axs = _mm512_loadu_si512((const __m512i *) ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); - abx = _mm512_add_epi64(abx, _mm512_popcnt_epi64(_mm512_and_si512(axs, bxs))); - aax = _mm512_add_epi64(aax, _mm512_popcnt_epi64(axs)); - bbx = _mm512_add_epi64(bbx, _mm512_popcnt_epi64(bxs)); + abx = _mm512_add_epi64(abx, _mm512_popcnt_epi64(_mm512_and_si512(axs, bxs))); + aax = _mm512_add_epi64(aax, _mm512_popcnt_epi64(axs)); + bbx = _mm512_add_epi64(bbx, _mm512_popcnt_epi64(bxs)); - ax += sizeof(__m512i); - bx += sizeof(__m512i); - } + ax += sizeof(__m512i); + bx += sizeof(__m512i); + } - ab += _mm512_reduce_add_epi64(abx); - aa += _mm512_reduce_add_epi64(aax); - bb += _mm512_reduce_add_epi64(bbx); + ab += _mm512_reduce_add_epi64(abx); + aa += _mm512_reduce_add_epi64(aax); + bb += _mm512_reduce_add_epi64(bbx); - return BitJaccardDistanceDefault(bytes, ax, bx, ab, aa, bb); + return BitJaccardDistanceDefault(bytes, ax, bx, ab, aa, bb); } #endif @@ -164,52 +164,52 @@ BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char TARGET_XSAVE static bool SupportsAvx512Popcount() { - unsigned int exx[4] = {0, 0, 0, 0}; + unsigned int exx[4] = {0, 0, 0, 0}; #if defined(USE__GET_CPUID) - __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); + __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); #else - __cpuid(exx, 1); + __cpuid(exx, 1); #endif - /* Check OS supports XSAVE */ - if ((exx[2] & CPU_FEATURE_OSXSAVE) != CPU_FEATURE_OSXSAVE) - return false; + /* Check OS supports XSAVE */ + if ((exx[2] & CPU_FEATURE_OSXSAVE) != CPU_FEATURE_OSXSAVE) + return false; - /* Check XMM, YMM, and ZMM registers are enabled */ - if ((_xgetbv(0) & 0xe6) != 0xe6) - return false; + /* Check XMM, YMM, and ZMM registers are enabled */ + if ((_xgetbv(0) & 0xe6) != 0xe6) + return false; #if defined(USE__GET_CPUID) - __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]); + __get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]); #else - __cpuidex(exx, 7, 0); + __cpuidex(exx, 7, 0); #endif - /* Check AVX512F */ - if ((exx[1] & CPU_FEATURE_AVX512F) != CPU_FEATURE_AVX512F) - return false; + /* Check AVX512F */ + if ((exx[1] & CPU_FEATURE_AVX512F) != CPU_FEATURE_AVX512F) + return false; - /* Check AVX512VPOPCNTDQ */ - return (exx[2] & CPU_FEATURE_AVX512VPOPCNTDQ) == CPU_FEATURE_AVX512VPOPCNTDQ; + /* Check AVX512VPOPCNTDQ */ + return (exx[2] & CPU_FEATURE_AVX512VPOPCNTDQ) == CPU_FEATURE_AVX512VPOPCNTDQ; } #endif void BitvecInit(void) { - /* - * Could skip pointer when single function, but no difference in - * performance - */ - BitHammingDistance = BitHammingDistanceDefault; - BitJaccardDistance = BitJaccardDistanceDefault; + /* + * Could skip pointer when single function, but no difference in + * performance + */ + BitHammingDistance = BitHammingDistanceDefault; + BitJaccardDistance = BitJaccardDistanceDefault; #ifdef BIT_DISPATCH - if (SupportsAvx512Popcount()) - { - BitHammingDistance = BitHammingDistanceAvx512Popcount; - BitJaccardDistance = BitJaccardDistanceAvx512Popcount; - } + if (SupportsAvx512Popcount()) + { + BitHammingDistance = BitHammingDistanceAvx512Popcount; + BitJaccardDistance = BitJaccardDistanceAvx512Popcount; + } #endif } diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp index 18aa9e33df..cd860a37bb 100644 --- a/src/gausskernel/storage/access/datavec/hnsw.cpp +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -38,45 +38,45 @@ HnswInit(void) */ static void hnswcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, - Cost *indexStartupCost, Cost *indexTotalCost, - Selectivity *indexSelectivity, double *indexCorrelation) + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation) { - GenericCosts costs; - int m; - int entryLevel; - Relation index; - - /* Never use index without order */ - if (path->indexorderbys == NULL) - { - *indexStartupCost = DBL_MAX; - *indexTotalCost = DBL_MAX; - *indexSelectivity = 0; - *indexCorrelation = 0; - return; - } - - MemSet(&costs, 0, sizeof(costs)); - - index = index_open(path->indexinfo->indexoid, NoLock); - HnswGetMetaPageInfo(index, &m, NULL); - index_close(index, NoLock); - - /* Approximate entry level */ - entryLevel = (int) -log(1.0 / path->indexinfo->tuples) * HnswGetMl(m); - - /* TODO Improve estimate of visited tuples (currently underestimates) */ - /* Account for number of tuples (or entry level), m, and ef_search */ - costs.numIndexTuples = (entryLevel + 2) * m; - - genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, - &costs.indexTotalCost, &costs.indexSelectivity, &costs.indexCorrelation); - - /* Use total cost since most work happens before first tuple is returned */ - *indexStartupCost = costs.indexTotalCost; - *indexTotalCost = costs.indexTotalCost; - *indexSelectivity = costs.indexSelectivity; - *indexCorrelation = costs.indexCorrelation; + GenericCosts costs; + int m; + int entryLevel; + Relation index; + + /* Never use index without order */ + if (path->indexorderbys == NULL) + { + *indexStartupCost = DBL_MAX; + *indexTotalCost = DBL_MAX; + *indexSelectivity = 0; + *indexCorrelation = 0; + return; + } + + MemSet(&costs, 0, sizeof(costs)); + + index = index_open(path->indexinfo->indexoid, NoLock); + HnswGetMetaPageInfo(index, &m, NULL); + index_close(index, NoLock); + + /* Approximate entry level */ + entryLevel = (int) -log(1.0 / path->indexinfo->tuples) * HnswGetMl(m); + + /* TODO Improve estimate of visited tuples (currently underestimates) */ + /* Account for number of tuples (or entry level), m, and ef_search */ + costs.numIndexTuples = (entryLevel + 2) * m; + + genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, + &costs.indexTotalCost, &costs.indexSelectivity, &costs.indexCorrelation); + + /* Use total cost since most work happens before first tuple is returned */ + *indexStartupCost = costs.indexTotalCost; + *indexTotalCost = costs.indexTotalCost; + *indexSelectivity = costs.indexSelectivity; + *indexCorrelation = costs.indexCorrelation; } /* @@ -124,7 +124,7 @@ hnswoptions_internal(Datum reloptions, bool validate) static bool hnswvalidate_internal(Oid opclassoid) { - return true; + return true; } /* @@ -198,152 +198,152 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbuild); Datum hnswbuild(PG_FUNCTION_ARGS) { - Relation heap = (Relation)PG_GETARG_POINTER(0); - Relation index = (Relation)PG_GETARG_POINTER(1); - IndexInfo *indexinfo = (IndexInfo *)PG_GETARG_POINTER(2); - IndexBuildResult *result = hnswbuild_internal(heap, index, indexinfo); + Relation heap = (Relation)PG_GETARG_POINTER(0); + Relation index = (Relation)PG_GETARG_POINTER(1); + IndexInfo *indexinfo = (IndexInfo *)PG_GETARG_POINTER(2); + IndexBuildResult *result = hnswbuild_internal(heap, index, indexinfo); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbuildempty); Datum hnswbuildempty(PG_FUNCTION_ARGS) { - Relation index = (Relation)PG_GETARG_POINTER(0); - hnswbuildempty_internal(index); + Relation index = (Relation)PG_GETARG_POINTER(0); + hnswbuildempty_internal(index); - PG_RETURN_VOID(); + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswinsert); Datum hnswinsert(PG_FUNCTION_ARGS) { - Relation rel = (Relation)PG_GETARG_POINTER(0); - Datum * values = (Datum *)PG_GETARG_POINTER(1); - bool *isnull = (bool *)PG_GETARG_POINTER(2); - ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); - Relation heaprel = (Relation)PG_GETARG_POINTER(4); - IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); - bool result = hnswinsert_internal(rel, values, isnull, ht_ctid, heaprel, checkunique); - - PG_RETURN_BOOL(result); + Relation rel = (Relation)PG_GETARG_POINTER(0); + Datum * values = (Datum *)PG_GETARG_POINTER(1); + bool *isnull = (bool *)PG_GETARG_POINTER(2); + ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); + Relation heaprel = (Relation)PG_GETARG_POINTER(4); + IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); + bool result = hnswinsert_internal(rel, values, isnull, ht_ctid, heaprel, checkunique); + + PG_RETURN_BOOL(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbulkdelete); Datum hnswbulkdelete(PG_FUNCTION_ARGS) { - IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); - IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); - IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); - void *callback_state = (void *)PG_GETARG_POINTER(3); - stats = hnswbulkdelete_internal(info, stats, callback, callback_state); + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); + void *callback_state = (void *)PG_GETARG_POINTER(3); + stats = hnswbulkdelete_internal(info, stats, callback, callback_state); - PG_RETURN_POINTER(stats); + PG_RETURN_POINTER(stats); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswvacuumcleanup); Datum hnswvacuumcleanup(PG_FUNCTION_ARGS) { - IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); - IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); - stats = hnswvacuumcleanup_internal(info, stats); + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + stats = hnswvacuumcleanup_internal(info, stats); - PG_RETURN_POINTER(stats); + PG_RETURN_POINTER(stats); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswcostestimate); Datum hnswcostestimate(PG_FUNCTION_ARGS) { - PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); - double loopcount = (double)PG_GETARG_FLOAT8(2); - Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); - Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); - Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); - double *correlation = (double *)PG_GETARG_POINTER(6); - hnswcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); - - PG_RETURN_VOID(); + PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); + IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); + double loopcount = (double)PG_GETARG_FLOAT8(2); + Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); + Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); + Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); + double *correlation = (double *)PG_GETARG_POINTER(6); + hnswcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); + + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswoptions); Datum hnswoptions(PG_FUNCTION_ARGS) { - Datum reloptions = PG_GETARG_DATUM(0); - bool validate = PG_GETARG_BOOL(1); - bytea *result = hnswoptions_internal(reloptions, validate); + Datum reloptions = PG_GETARG_DATUM(0); + bool validate = PG_GETARG_BOOL(1); + bytea *result = hnswoptions_internal(reloptions, validate); - if (NULL != result) - PG_RETURN_BYTEA_P(result); + if (NULL != result) + PG_RETURN_BYTEA_P(result); - PG_RETURN_NULL(); + PG_RETURN_NULL(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswvalidate); Datum hnswvalidate(PG_FUNCTION_ARGS) { - Oid opclassoid = PG_GETARG_OID(0); - bool result = hnswvalidate_internal(opclassoid); + Oid opclassoid = PG_GETARG_OID(0); + bool result = hnswvalidate_internal(opclassoid); - PG_RETURN_BOOL(result); + PG_RETURN_BOOL(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbeginscan); Datum hnswbeginscan(PG_FUNCTION_ARGS) { - Relation rel = (Relation)PG_GETARG_POINTER(0); - int nkeys = PG_GETARG_INT32(1); - int norderbys = PG_GETARG_INT32(2); - IndexScanDesc scan = hnswbeginscan_internal(rel, nkeys, norderbys); + Relation rel = (Relation)PG_GETARG_POINTER(0); + int nkeys = PG_GETARG_INT32(1); + int norderbys = PG_GETARG_INT32(2); + IndexScanDesc scan = hnswbeginscan_internal(rel, nkeys, norderbys); - PG_RETURN_POINTER(scan); + PG_RETURN_POINTER(scan); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswrescan); Datum hnswrescan(PG_FUNCTION_ARGS) { - IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); - ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); - int nkeys = PG_GETARG_INT32(2); - ScanKey orderbys = (ScanKey)PG_GETARG_POINTER(3); - int norderbys = PG_GETARG_INT32(4); - hnswrescan_internal(scan, scankey, nkeys, orderbys, norderbys); - - PG_RETURN_VOID(); + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); + int nkeys = PG_GETARG_INT32(2); + ScanKey orderbys = (ScanKey)PG_GETARG_POINTER(3); + int norderbys = PG_GETARG_INT32(4); + hnswrescan_internal(scan, scankey, nkeys, orderbys, norderbys); + + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswgettuple); Datum hnswgettuple(PG_FUNCTION_ARGS) { - IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); - ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); - if (NULL == scan) - ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function hnswgettuple"))); - - bool result = hnswgettuple_internal(scan, direction); + if (NULL == scan) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function hnswgettuple"))); + + bool result = hnswgettuple_internal(scan, direction); - PG_RETURN_BOOL(result); + PG_RETURN_BOOL(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswendscan); Datum hnswendscan(PG_FUNCTION_ARGS) { - IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); - hnswendscan_internal(scan); + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + hnswendscan_internal(scan); - PG_RETURN_VOID(); + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswdelete); diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp index 234dd23840..2203f38006 100644 --- a/src/gausskernel/storage/access/datavec/hnswbuild.cpp +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -179,26 +179,26 @@ CreateAppendMetaPage(HnswBuildState *buildstate) static void HnswBuildAppendPage(Relation index, Buffer *buf, Page *page, ForkNumber forkNum) { - /* Add a new page */ - Buffer newbuf = HnswNewBuffer(index, forkNum); - - /* Update previous page */ - HnswPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); - - /* Commit */ - MarkBufferDirty(*buf); - UnlockReleaseBuffer(*buf); - - /* Can take a while, so ensure we can interrupt */ - /* Needs to be called when no buffer locks are held */ - LockBuffer(newbuf, BUFFER_LOCK_UNLOCK); - CHECK_FOR_INTERRUPTS(); - LockBuffer(newbuf, BUFFER_LOCK_EXCLUSIVE); - - /* Prepare new page */ - *buf = newbuf; - *page = BufferGetPage(*buf); - HnswInitPage(*buf, *page); + /* Add a new page */ + Buffer newbuf = HnswNewBuffer(index, forkNum); + + /* Update previous page */ + HnswPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); + + /* Commit */ + MarkBufferDirty(*buf); + UnlockReleaseBuffer(*buf); + + /* Can take a while, so ensure we can interrupt */ + /* Needs to be called when no buffer locks are held */ + LockBuffer(newbuf, BUFFER_LOCK_UNLOCK); + CHECK_FOR_INTERRUPTS(); + LockBuffer(newbuf, BUFFER_LOCK_EXCLUSIVE); + + /* Prepare new page */ + *buf = newbuf; + *page = BufferGetPage(*buf); + HnswInitPage(*buf, *page); } /* @@ -330,48 +330,48 @@ CreateGraphPages(HnswBuildState * buildstate) static void WriteNeighborTuples(HnswBuildState * buildstate) { - Relation index = buildstate->index; - ForkNumber forkNum = buildstate->forkNum; - int m = buildstate->m; - HnswElementPtr iter = buildstate->graph->head; - char *base = buildstate->hnswarea; - HnswNeighborTuple ntup; + Relation index = buildstate->index; + ForkNumber forkNum = buildstate->forkNum; + int m = buildstate->m; + HnswElementPtr iter = buildstate->graph->head; + char *base = buildstate->hnswarea; + HnswNeighborTuple ntup; - /* Allocate once */ - ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); + /* Allocate once */ + ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); - while (!HnswPtrIsNull(base, iter)) - { - HnswElement element = (HnswElement)HnswPtrAccess(base, iter); - Buffer buf; - Page page; - Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); + while (!HnswPtrIsNull(base, iter)) + { + HnswElement element = (HnswElement)HnswPtrAccess(base, iter); + Buffer buf; + Page page; + Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); - /* Update iterator */ - iter = element->next; + /* Update iterator */ + iter = element->next; - /* Zero memory for each element */ - MemSet(ntup, 0, HNSW_TUPLE_ALLOC_SIZE); + /* Zero memory for each element */ + MemSet(ntup, 0, HNSW_TUPLE_ALLOC_SIZE); - /* Can take a while, so ensure we can interrupt */ - /* Needs to be called when no buffer locks are held */ - CHECK_FOR_INTERRUPTS(); + /* Can take a while, so ensure we can interrupt */ + /* Needs to be called when no buffer locks are held */ + CHECK_FOR_INTERRUPTS(); - buf = ReadBufferExtended(index, forkNum, element->neighborPage, RBM_NORMAL, NULL); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - page = BufferGetPage(buf); + buf = ReadBufferExtended(index, forkNum, element->neighborPage, RBM_NORMAL, NULL); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + page = BufferGetPage(buf); - HnswSetNeighborTuple(base, ntup, element, m); + HnswSetNeighborTuple(base, ntup, element, m); - if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) - elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); - /* Commit */ - MarkBufferDirty(buf); - UnlockReleaseBuffer(buf); - } + /* Commit */ + MarkBufferDirty(buf); + UnlockReleaseBuffer(buf); + } - pfree(ntup); + pfree(ntup); } /* @@ -381,15 +381,15 @@ static void FlushPages(HnswBuildState * buildstate) { #ifdef HNSW_MEMORY - elog(INFO, "memory: %zu MB", buildstate->graph->memoryUsed / (1024 * 1024)); + elog(INFO, "memory: %zu MB", buildstate->graph->memoryUsed / (1024 * 1024)); #endif - CreateMetaPage(buildstate); - CreateGraphPages(buildstate); - WriteNeighborTuples(buildstate); + CreateMetaPage(buildstate); + CreateGraphPages(buildstate); + WriteNeighborTuples(buildstate); - buildstate->graph->flushed = true; - MemoryContextReset(buildstate->graphCtx); + buildstate->graph->flushed = true; + MemoryContextReset(buildstate->graphCtx); } /* @@ -398,19 +398,19 @@ FlushPages(HnswBuildState * buildstate) static bool AddDuplicateInMemory(HnswElement element, HnswElement dup) { - LWLockAcquire(&dup->lock, LW_EXCLUSIVE); + LWLockAcquire(&dup->lock, LW_EXCLUSIVE); - if (dup->heaptidsLength == HNSW_HEAPTIDS) - { - LWLockRelease(&dup->lock); - return false; - } + if (dup->heaptidsLength == HNSW_HEAPTIDS) + { + LWLockRelease(&dup->lock); + return false; + } - HnswAddHeapTid(dup, &element->heaptids[0]); + HnswAddHeapTid(dup, &element->heaptids[0]); - LWLockRelease(&dup->lock); + LWLockRelease(&dup->lock); - return true; + return true; } /* @@ -419,25 +419,25 @@ AddDuplicateInMemory(HnswElement element, HnswElement dup) static bool FindDuplicateInMemory(char *base, HnswElement element) { - HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); - Datum value = HnswGetValue(base, element); - - for (int i = 0; i < neighbors->length; i++) - { - HnswCandidate *neighbor = &neighbors->items[i]; - HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); - Datum neighborValue = HnswGetValue(base, neighborElement); - - /* Exit early since ordered by distance */ - if (!datumIsEqual(value, neighborValue, false, -1)) - return false; - - /* Check for space */ - if (AddDuplicateInMemory(element, neighborElement)) - return true; - } + HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); + Datum value = HnswGetValue(base, element); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *neighbor = &neighbors->items[i]; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); + Datum neighborValue = HnswGetValue(base, neighborElement); + + /* Exit early since ordered by distance */ + if (!datumIsEqual(value, neighborValue, false, -1)) + return false; + + /* Check for space */ + if (AddDuplicateInMemory(element, neighborElement)) + return true; + } - return false; + return false; } /* @@ -446,10 +446,10 @@ FindDuplicateInMemory(char *base, HnswElement element) static void AddElementInMemory(char *base, HnswGraph * graph, HnswElement element) { - SpinLockAcquire(&graph->lock); - element->next = graph->head; - HnswPtrStore(base, graph->head, element); - SpinLockRelease(&graph->lock); + SpinLockAcquire(&graph->lock); + element->next = graph->head; + HnswPtrStore(base, graph->head, element); + SpinLockRelease(&graph->lock); } /* @@ -458,25 +458,25 @@ AddElementInMemory(char *base, HnswGraph * graph, HnswElement element) static void UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswElement e, int m) { - for (int lc = e->level; lc >= 0; lc--) - { - int lm = HnswGetLayerM(m, lc); - HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); - - for (int i = 0; i < neighbors->length; i++) - { - HnswCandidate *hc = &neighbors->items[i]; - HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); - - /* Keep scan-build happy on Mac x86-64 */ - Assert(neighborElement); - - /* Use element for lock instead of hc since hc can be replaced */ - LWLockAcquire(&neighborElement->lock, LW_EXCLUSIVE); - HnswUpdateConnection(base, e, hc, lm, lc, NULL, NULL, procinfo, collation); - LWLockRelease(&neighborElement->lock); - } - } + for (int lc = e->level; lc >= 0; lc--) + { + int lm = HnswGetLayerM(m, lc); + HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *hc = &neighbors->items[i]; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); + + /* Keep scan-build happy on Mac x86-64 */ + Assert(neighborElement); + + /* Use element for lock instead of hc since hc can be replaced */ + LWLockAcquire(&neighborElement->lock, LW_EXCLUSIVE); + HnswUpdateConnection(base, e, hc, lm, lc, NULL, NULL, procinfo, collation); + LWLockRelease(&neighborElement->lock); + } + } } /* @@ -485,22 +485,22 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme static void UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, HnswBuildState * buildstate) { - HnswGraph *graph = buildstate->graph; - char *base = buildstate->hnswarea; + HnswGraph *graph = buildstate->graph; + char *base = buildstate->hnswarea; - /* Look for duplicate */ - if (FindDuplicateInMemory(base, element)) - return; + /* Look for duplicate */ + if (FindDuplicateInMemory(base, element)) + return; - /* Add element */ - AddElementInMemory(base, graph, element); + /* Add element */ + AddElementInMemory(base, graph, element); - /* Update neighbors */ - UpdateNeighborsInMemory(base, procinfo, collation, element, m); + /* Update neighbors */ + UpdateNeighborsInMemory(base, procinfo, collation, element, m); - /* Update entry point if needed (already have lock) */ - if (entryPoint == NULL || element->level > entryPoint->level) - HnswPtrStore(base, graph->entryPoint, element); + /* Update entry point if needed (already have lock) */ + if (entryPoint == NULL || element->level > entryPoint->level) + HnswPtrStore(base, graph->entryPoint, element); } /* @@ -509,47 +509,47 @@ UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int static void InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) { - FmgrInfo *procinfo = buildstate->procinfo; - Oid collation = buildstate->collation; - HnswGraph *graph = buildstate->graph; - HnswElement entryPoint; - LWLock *entryLock = &graph->entryLock; - LWLock *entryWaitLock = &graph->entryWaitLock; - int efConstruction = buildstate->efConstruction; - int m = buildstate->m; - char *base = buildstate->hnswarea; - - /* Wait if another process needs exclusive lock on entry lock */ - LWLockAcquire(entryWaitLock, LW_EXCLUSIVE); - LWLockRelease(entryWaitLock); - - /* Get entry point */ - LWLockAcquire(entryLock, LW_SHARED); - entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); - - /* Prevent concurrent inserts when likely updating entry point */ - if (entryPoint == NULL || element->level > entryPoint->level) - { - /* Release shared lock */ - LWLockRelease(entryLock); - - /* Tell other processes to wait and get exclusive lock */ - LWLockAcquire(entryWaitLock, LW_EXCLUSIVE); - LWLockAcquire(entryLock, LW_EXCLUSIVE); - LWLockRelease(entryWaitLock); - - /* Get latest entry point after lock is acquired */ - entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); - } - - /* Find neighbors for element */ - HnswFindElementNeighbors(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false); - - /* Update graph in memory */ - UpdateGraphInMemory(procinfo, collation, element, m, efConstruction, entryPoint, buildstate); - - /* Release entry lock */ - LWLockRelease(entryLock); + FmgrInfo *procinfo = buildstate->procinfo; + Oid collation = buildstate->collation; + HnswGraph *graph = buildstate->graph; + HnswElement entryPoint; + LWLock *entryLock = &graph->entryLock; + LWLock *entryWaitLock = &graph->entryWaitLock; + int efConstruction = buildstate->efConstruction; + int m = buildstate->m; + char *base = buildstate->hnswarea; + + /* Wait if another process needs exclusive lock on entry lock */ + LWLockAcquire(entryWaitLock, LW_EXCLUSIVE); + LWLockRelease(entryWaitLock); + + /* Get entry point */ + LWLockAcquire(entryLock, LW_SHARED); + entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); + + /* Prevent concurrent inserts when likely updating entry point */ + if (entryPoint == NULL || element->level > entryPoint->level) + { + /* Release shared lock */ + LWLockRelease(entryLock); + + /* Tell other processes to wait and get exclusive lock */ + LWLockAcquire(entryWaitLock, LW_EXCLUSIVE); + LWLockAcquire(entryLock, LW_EXCLUSIVE); + LWLockRelease(entryWaitLock); + + /* Get latest entry point after lock is acquired */ + entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); + } + + /* Find neighbors for element */ + HnswFindElementNeighbors(base, element, entryPoint, NULL, procinfo, collation, m, efConstruction, false); + + /* Update graph in memory */ + UpdateGraphInMemory(procinfo, collation, element, m, efConstruction, entryPoint, buildstate); + + /* Release entry lock */ + LWLockRelease(entryLock); } /* @@ -558,102 +558,102 @@ InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) static bool InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heaptid, HnswBuildState * buildstate) { - const HnswTypeInfo *typeInfo = buildstate->typeInfo; - HnswGraph *graph = buildstate->graph; - HnswElement element; - HnswAllocator *allocator = &buildstate->allocator; - Size valueSize; - Pointer valuePtr; - LWLock *flushLock = &graph->flushLock; - char *base = buildstate->hnswarea; - - /* Detoast once for all calls */ - Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); - - /* Check value */ - if (typeInfo->checkValue != NULL) - typeInfo->checkValue(DatumGetPointer(value)); - - /* Normalize if needed */ - if (buildstate->normprocinfo != NULL) - { - if (!HnswCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) - return false; - - value = HnswNormValue(typeInfo, buildstate->collation, value); - } - - /* Get datum size */ - valueSize = VARSIZE_ANY(DatumGetPointer(value)); - - /* Ensure graph not flushed when inserting */ - LWLockAcquire(flushLock, LW_SHARED); - - /* Are we in the on-disk phase? */ - if (graph->flushed) - { - LWLockRelease(flushLock); - - return HnswInsertTupleOnDisk(index, value, values, isnull, heaptid, true); - } - - /* - * In a parallel build, the HnswElement is allocated from the shared - * memory area, so we need to coordinate with other processes. - */ - LWLockAcquire(&graph->allocatorLock, LW_EXCLUSIVE); - - /* - * Check that we have enough memory available for the new element now that - * we have the allocator lock, and flush pages if needed. - */ - if (graph->memoryUsed >= graph->memoryTotal) - { - LWLockRelease(&graph->allocatorLock); - - LWLockRelease(flushLock); - LWLockAcquire(flushLock, LW_EXCLUSIVE); - - if (!graph->flushed) - { - ereport(NOTICE, - (errmsg("hnsw graph no longer fits into maintenance_work_mem after " INT64_FORMAT " tuples", (int64) graph->indtuples), - errdetail("Building will take significantly more time."), - errhint("Increase maintenance_work_mem to speed up builds."))); - - FlushPages(buildstate); - } - - LWLockRelease(flushLock); - - return HnswInsertTupleOnDisk(index, value, values, isnull, heaptid, true); - } - - /* Ok, we can proceed to allocate the element */ - element = HnswInitElement(base, heaptid, buildstate->m, buildstate->ml, buildstate->maxLevel, allocator); - valuePtr = (Pointer)HnswAlloc(allocator, valueSize); - - /* - * We have now allocated the space needed for the element, so we don't - * need the allocator lock anymore. Release it and initialize the rest of - * the element. - */ - LWLockRelease(&graph->allocatorLock); - - /* Copy the datum */ - memcpy(valuePtr, DatumGetPointer(value), valueSize); - HnswPtrStore(base, element->value, valuePtr); - - /* Create a lock for the element */ - LWLockInitialize(&element->lock, hnsw_lock_tranche_id); - - /* Insert tuple */ - InsertTupleInMemory(buildstate, element); - - /* Release flush lock */ - LWLockRelease(flushLock); - - return true; + const HnswTypeInfo *typeInfo = buildstate->typeInfo; + HnswGraph *graph = buildstate->graph; + HnswElement element; + HnswAllocator *allocator = &buildstate->allocator; + Size valueSize; + Pointer valuePtr; + LWLock *flushLock = &graph->flushLock; + char *base = buildstate->hnswarea; + + /* Detoast once for all calls */ + Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Check value */ + if (typeInfo->checkValue != NULL) + typeInfo->checkValue(DatumGetPointer(value)); + + /* Normalize if needed */ + if (buildstate->normprocinfo != NULL) + { + if (!HnswCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) + return false; + + value = HnswNormValue(typeInfo, buildstate->collation, value); + } + + /* Get datum size */ + valueSize = VARSIZE_ANY(DatumGetPointer(value)); + + /* Ensure graph not flushed when inserting */ + LWLockAcquire(flushLock, LW_SHARED); + + /* Are we in the on-disk phase? */ + if (graph->flushed) + { + LWLockRelease(flushLock); + + return HnswInsertTupleOnDisk(index, value, values, isnull, heaptid, true); + } + + /* + * In a parallel build, the HnswElement is allocated from the shared + * memory area, so we need to coordinate with other processes. + */ + LWLockAcquire(&graph->allocatorLock, LW_EXCLUSIVE); + + /* + * Check that we have enough memory available for the new element now that + * we have the allocator lock, and flush pages if needed. + */ + if (graph->memoryUsed >= graph->memoryTotal) + { + LWLockRelease(&graph->allocatorLock); + + LWLockRelease(flushLock); + LWLockAcquire(flushLock, LW_EXCLUSIVE); + + if (!graph->flushed) + { + ereport(NOTICE, + (errmsg("hnsw graph no longer fits into maintenance_work_mem after " INT64_FORMAT " tuples", (int64) graph->indtuples), + errdetail("Building will take significantly more time."), + errhint("Increase maintenance_work_mem to speed up builds."))); + + FlushPages(buildstate); + } + + LWLockRelease(flushLock); + + return HnswInsertTupleOnDisk(index, value, values, isnull, heaptid, true); + } + + /* Ok, we can proceed to allocate the element */ + element = HnswInitElement(base, heaptid, buildstate->m, buildstate->ml, buildstate->maxLevel, allocator); + valuePtr = (Pointer)HnswAlloc(allocator, valueSize); + + /* + * We have now allocated the space needed for the element, so we don't + * need the allocator lock anymore. Release it and initialize the rest of + * the element. + */ + LWLockRelease(&graph->allocatorLock); + + /* Copy the datum */ + memcpy(valuePtr, DatumGetPointer(value), valueSize); + HnswPtrStore(base, element->value, valuePtr); + + /* Create a lock for the element */ + LWLockInitialize(&element->lock, hnsw_lock_tranche_id); + + /* Insert tuple */ + InsertTupleInMemory(buildstate, element); + + /* Release flush lock */ + LWLockRelease(flushLock); + + return true; } /* @@ -661,35 +661,35 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heapt */ static void BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, - const bool *isnull, bool tupleIsAlive, void *state) + const bool *isnull, bool tupleIsAlive, void *state) { - HnswBuildState *buildstate = (HnswBuildState *) state; - HnswGraph *graph = buildstate->graph; - MemoryContext oldCtx; + HnswBuildState *buildstate = (HnswBuildState *) state; + HnswGraph *graph = buildstate->graph; + MemoryContext oldCtx; #if PG_VERSION_NUM < 130000 - ItemPointer tid = &hup->t_self; + ItemPointer tid = &hup->t_self; #endif - /* Skip nulls */ - if (isnull[0]) - return; - - /* Use memory context */ - oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); - - /* Insert tuple */ - if (InsertTuple(index, values, isnull, tid, buildstate)) - { - /* Update progress */ - SpinLockAcquire(&graph->lock); - UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++graph->indtuples); - SpinLockRelease(&graph->lock); - } - - /* Reset memory context */ - MemoryContextSwitchTo(oldCtx); - MemoryContextReset(buildstate->tmpCtx); + /* Skip nulls */ + if (isnull[0]) + return; + + /* Use memory context */ + oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); + + /* Insert tuple */ + if (InsertTuple(index, values, isnull, tid, buildstate)) + { + /* Update progress */ + SpinLockAcquire(&graph->lock); + UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++graph->indtuples); + SpinLockRelease(&graph->lock); + } + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(buildstate->tmpCtx); } /* @@ -698,17 +698,17 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, static void InitGraph(HnswGraph * graph, char *base, long memoryTotal) { - HnswPtrStore(base, graph->head, (HnswElement) NULL); - HnswPtrStore(base, graph->entryPoint, (HnswElement) NULL); - graph->memoryUsed = 0; - graph->memoryTotal = memoryTotal; - graph->flushed = false; - graph->indtuples = 0; - SpinLockInit(&graph->lock); - LWLockInitialize(&graph->entryLock, hnsw_lock_tranche_id); - LWLockInitialize(&graph->entryWaitLock, hnsw_lock_tranche_id); - LWLockInitialize(&graph->allocatorLock, hnsw_lock_tranche_id); - LWLockInitialize(&graph->flushLock, hnsw_lock_tranche_id); + HnswPtrStore(base, graph->head, (HnswElement) NULL); + HnswPtrStore(base, graph->entryPoint, (HnswElement) NULL); + graph->memoryUsed = 0; + graph->memoryTotal = memoryTotal; + graph->flushed = false; + graph->indtuples = 0; + SpinLockInit(&graph->lock); + LWLockInitialize(&graph->entryLock, hnsw_lock_tranche_id); + LWLockInitialize(&graph->entryWaitLock, hnsw_lock_tranche_id); + LWLockInitialize(&graph->allocatorLock, hnsw_lock_tranche_id); + LWLockInitialize(&graph->flushLock, hnsw_lock_tranche_id); } /* @@ -717,8 +717,8 @@ InitGraph(HnswGraph * graph, char *base, long memoryTotal) static void InitAllocator(HnswAllocator * allocator, void *(*alloc) (Size size, void *state), void *state) { - allocator->alloc = alloc; - allocator->state = state; + allocator->alloc = alloc; + allocator->state = state; } /* @@ -727,16 +727,16 @@ InitAllocator(HnswAllocator * allocator, void *(*alloc) (Size size, void *state) static void * HnswMemoryContextAlloc(Size size, void *state) { - HnswBuildState *buildstate = (HnswBuildState *) state; - void *chunk = MemoryContextAlloc(buildstate->graphCtx, size); + HnswBuildState *buildstate = (HnswBuildState *) state; + void *chunk = MemoryContextAlloc(buildstate->graphCtx, size); #if PG_VERSION_NUM >= 130000 - buildstate->graphData.memoryUsed = MemoryContextMemAllocated(buildstate->graphCtx, false); + buildstate->graphData.memoryUsed = MemoryContextMemAllocated(buildstate->graphCtx, false); #else - buildstate->graphData.memoryUsed += MAXALIGN(size); + buildstate->graphData.memoryUsed += MAXALIGN(size); #endif - return chunk; + return chunk; } /* @@ -828,25 +828,25 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index static void FreeBuildState(HnswBuildState * buildstate) { - MemoryContextDelete(buildstate->graphCtx); - MemoryContextDelete(buildstate->tmpCtx); + MemoryContextDelete(buildstate->graphCtx); + MemoryContextDelete(buildstate->tmpCtx); } static double ParallelHeapScan(HnswBuildState * buildstate, int* nparticipanttuplesorts) { - HnswShared *hnswshared = buildstate->hnswleader->hnswshared; - double reltuples; + HnswShared *hnswshared = buildstate->hnswleader->hnswshared; + double reltuples; - BgworkerListWaitFinish(&buildstate->hnswleader->nparticipanttuplesorts); - pg_memory_barrier(); + BgworkerListWaitFinish(&buildstate->hnswleader->nparticipanttuplesorts); + pg_memory_barrier(); - *nparticipanttuplesorts = buildstate->hnswleader->nparticipanttuplesorts; - buildstate->graph = &hnswshared->graphData; - buildstate->hnswarea = hnswshared->hnswarea; - reltuples = hnswshared->reltuples; + *nparticipanttuplesorts = buildstate->hnswleader->nparticipanttuplesorts; + buildstate->graph = &hnswshared->graphData; + buildstate->hnswarea = hnswshared->hnswarea; + reltuples = hnswshared->reltuples; - return reltuples; + return reltuples; } /* @@ -855,28 +855,28 @@ ParallelHeapScan(HnswBuildState * buildstate, int* nparticipanttuplesorts) static void HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared * hnswshared, char *hnswarea) { - HnswBuildState buildstate; - TableScanDesc scan; - double reltuples; - IndexInfo *indexInfo; - - /* Join parallel scan */ - indexInfo = BuildIndexInfo(indexRel); - InitBuildState(&buildstate, heapRel, indexRel, indexInfo, MAIN_FORKNUM); - buildstate.graph = &hnswshared->graphData; - buildstate.hnswarea = hnswarea; - InitAllocator(&buildstate.allocator, &HnswSharedMemoryAlloc, &buildstate); - scan = tableam_scan_begin_parallel(heapRel, &hnswshared->heapdesc); - reltuples = tableam_index_build_scan(heapRel, indexRel, indexInfo, - true, BuildCallback, (void *) &buildstate, scan); - - /* Record statistics */ - SpinLockAcquire(&hnswshared->mutex); - hnswshared->nparticipantsdone++; - hnswshared->reltuples += reltuples; - SpinLockRelease(&hnswshared->mutex); - - FreeBuildState(&buildstate); + HnswBuildState buildstate; + TableScanDesc scan; + double reltuples; + IndexInfo *indexInfo; + + /* Join parallel scan */ + indexInfo = BuildIndexInfo(indexRel); + InitBuildState(&buildstate, heapRel, indexRel, indexInfo, MAIN_FORKNUM); + buildstate.graph = &hnswshared->graphData; + buildstate.hnswarea = hnswarea; + InitAllocator(&buildstate.allocator, &HnswSharedMemoryAlloc, &buildstate); + scan = tableam_scan_begin_parallel(heapRel, &hnswshared->heapdesc); + reltuples = tableam_index_build_scan(heapRel, indexRel, indexInfo, + true, BuildCallback, (void *) &buildstate, scan); + + /* Record statistics */ + SpinLockAcquire(&hnswshared->mutex); + hnswshared->nparticipantsdone++; + hnswshared->reltuples += reltuples; + SpinLockRelease(&hnswshared->mutex); + + FreeBuildState(&buildstate); } /* @@ -885,26 +885,26 @@ HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared * hnsw void HnswParallelBuildMain(const BgWorkerContext *bwc) { - HnswShared *hnswshared; - char *hnswarea; - Relation heapRel; - Relation indexRel; + HnswShared *hnswshared; + char *hnswarea; + Relation heapRel; + Relation indexRel; - /* Look up shared state */ - hnswshared = (HnswShared*)bwc->bgshared; + /* Look up shared state */ + hnswshared = (HnswShared*)bwc->bgshared; - /* Open relations within worker */ - heapRel = heap_open(hnswshared->heaprelid, NoLock); - indexRel = index_open(hnswshared->indexrelid, NoLock); + /* Open relations within worker */ + heapRel = heap_open(hnswshared->heaprelid, NoLock); + indexRel = index_open(hnswshared->indexrelid, NoLock); - hnswarea = hnswshared->hnswarea; + hnswarea = hnswshared->hnswarea; - /* Perform inserts */ - HnswParallelScanAndInsert(heapRel, indexRel, hnswshared, hnswarea); + /* Perform inserts */ + HnswParallelScanAndInsert(heapRel, indexRel, hnswshared, hnswarea); - /* Close relations within worker */ - index_close(indexRel, NoLock); - heap_close(heapRel, NoLock); + /* Close relations within worker */ + index_close(indexRel, NoLock); + heap_close(heapRel, NoLock); } /* @@ -913,51 +913,51 @@ HnswParallelBuildMain(const BgWorkerContext *bwc) static void HnswEndParallel() { - BgworkerListSyncQuit(); + BgworkerListSyncQuit(); } static HnswShared* HnswParallelInitshared(HnswBuildState * buildstate) { - HnswShared *hnswshared; - char *hnswarea; - Size esthnswarea; - Size estother; - - /* Store shared build state, for which we reserved space */ - hnswshared = (HnswShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(HnswShared)); - - /* Initialize immutable state */ - hnswshared->heaprelid = RelationGetRelid(buildstate->heap); - hnswshared->indexrelid = RelationGetRelid(buildstate->index); - SpinLockInit(&hnswshared->mutex); - /* Initialize mutable state */ - hnswshared->nparticipantsdone = 0; - hnswshared->reltuples = 0; - HeapParallelscanInitialize(&hnswshared->heapdesc, buildstate->heap); - - /* Leave space for other objects in shared memory */ - /* Docker has a default limit of 64 MB for shm_size */ - /* which happens to be the default value of maintenance_work_mem */ - esthnswarea = u_sess->attr.attr_memory.maintenance_work_mem * 1024L; - estother = 3 * 1024 * 1024; - if (esthnswarea > estother) - esthnswarea -= estother; - - hnswarea = (char *) palloc0_huge(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), esthnswarea); - /* Report less than allocated so never fails */ - InitGraph(&hnswshared->graphData, hnswarea, esthnswarea - 1024 * 1024); - - /* - * Avoid base address for relptr for Postgres < 14.5 - * https://github.com/postgres/postgres/commit/7201cd18627afc64850537806da7f22150d1a83b - */ + HnswShared *hnswshared; + char *hnswarea; + Size esthnswarea; + Size estother; + + /* Store shared build state, for which we reserved space */ + hnswshared = (HnswShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(HnswShared)); + + /* Initialize immutable state */ + hnswshared->heaprelid = RelationGetRelid(buildstate->heap); + hnswshared->indexrelid = RelationGetRelid(buildstate->index); + SpinLockInit(&hnswshared->mutex); + /* Initialize mutable state */ + hnswshared->nparticipantsdone = 0; + hnswshared->reltuples = 0; + HeapParallelscanInitialize(&hnswshared->heapdesc, buildstate->heap); + + /* Leave space for other objects in shared memory */ + /* Docker has a default limit of 64 MB for shm_size */ + /* which happens to be the default value of maintenance_work_mem */ + esthnswarea = u_sess->attr.attr_memory.maintenance_work_mem * 1024L; + estother = 3 * 1024 * 1024; + if (esthnswarea > estother) + esthnswarea -= estother; + + hnswarea = (char *) palloc0_huge(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), esthnswarea); + /* Report less than allocated so never fails */ + InitGraph(&hnswshared->graphData, hnswarea, esthnswarea - 1024 * 1024); + + /* + * Avoid base address for relptr for Postgres < 14.5 + * https://github.com/postgres/postgres/commit/7201cd18627afc64850537806da7f22150d1a83b + */ #if PG_VERSION_NUM < 140005 - hnswshared->graphData.memoryUsed += MAXALIGN(1); + hnswshared->graphData.memoryUsed += MAXALIGN(1); #endif - hnswshared->hnswarea = hnswarea; - return hnswshared; + hnswshared->hnswarea = hnswarea; + return hnswshared; } /* @@ -966,28 +966,28 @@ HnswParallelInitshared(HnswBuildState * buildstate) static void HnswBeginParallel(HnswBuildState * buildstate, int request) { - HnswShared *hnswshared; - HnswLeader *hnswleader = (HnswLeader *) palloc0(sizeof(HnswLeader)); + HnswShared *hnswshared; + HnswLeader *hnswleader = (HnswLeader *) palloc0(sizeof(HnswLeader)); - Assert(request > 0); + Assert(request > 0); - hnswshared = HnswParallelInitshared(buildstate); - /* Launch workers, saving status for leader/caller */ - hnswleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, hnswshared, HnswParallelBuildMain, NULL); - hnswleader->hnswshared = hnswshared; + hnswshared = HnswParallelInitshared(buildstate); + /* Launch workers, saving status for leader/caller */ + hnswleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, hnswshared, HnswParallelBuildMain, NULL); + hnswleader->hnswshared = hnswshared; - /* If no workers were successfully launched, back out (do serial build) */ - if (hnswleader->nparticipanttuplesorts == 0) - { - HnswEndParallel(); - return; - } + /* If no workers were successfully launched, back out (do serial build) */ + if (hnswleader->nparticipanttuplesorts == 0) + { + HnswEndParallel(); + return; + } - /* Log participants */ - ereport(DEBUG1, (errmsg("using %d parallel workers", hnswleader->nparticipanttuplesorts))); + /* Log participants */ + ereport(DEBUG1, (errmsg("using %d parallel workers", hnswleader->nparticipanttuplesorts))); - /* Save leader state now that it's clear build will be parallel */ - buildstate->hnswleader = hnswleader; + /* Save leader state now that it's clear build will be parallel */ + buildstate->hnswleader = hnswleader; } /* @@ -1042,20 +1042,20 @@ serial_build: */ static void BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, - HnswBuildState * buildstate, ForkNumber forkNum) + HnswBuildState * buildstate, ForkNumber forkNum) { #ifdef HNSW_MEMORY - SeedRandom(42); + SeedRandom(42); #endif - InitBuildState(buildstate, heap, index, indexInfo, forkNum); + InitBuildState(buildstate, heap, index, indexInfo, forkNum); - BuildGraph(buildstate, forkNum); + BuildGraph(buildstate, forkNum); - if (RelationNeedsWAL(index) || forkNum == INIT_FORKNUM) - log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); + if (RelationNeedsWAL(index) || forkNum == INIT_FORKNUM) + log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); - FreeBuildState(buildstate); + FreeBuildState(buildstate); } /* @@ -1064,16 +1064,16 @@ BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, IndexBuildResult * hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) { - IndexBuildResult *result; - HnswBuildState buildstate; + IndexBuildResult *result; + HnswBuildState buildstate; - BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); + BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); - result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); - result->heap_tuples = buildstate.reltuples; - result->index_tuples = buildstate.indtuples; + result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + result->heap_tuples = buildstate.reltuples; + result->index_tuples = buildstate.indtuples; - return result; + return result; } /* @@ -1082,8 +1082,8 @@ hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) void hnswbuildempty_internal(Relation index) { - IndexInfo *indexInfo = BuildIndexInfo(index); - HnswBuildState buildstate; + IndexInfo *indexInfo = BuildIndexInfo(index); + HnswBuildState buildstate; - BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); + BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); } diff --git a/src/gausskernel/storage/access/datavec/hnswinsert.cpp b/src/gausskernel/storage/access/datavec/hnswinsert.cpp index 90720293f2..bf23fb30bd 100644 --- a/src/gausskernel/storage/access/datavec/hnswinsert.cpp +++ b/src/gausskernel/storage/access/datavec/hnswinsert.cpp @@ -16,21 +16,21 @@ static BlockNumber GetInsertPage(Relation index) { - Buffer buf; - Page page; - HnswMetaPage metap; - BlockNumber insertPage; + Buffer buf; + Page page; + HnswMetaPage metap; + BlockNumber insertPage; - buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); - LockBuffer(buf, BUFFER_LOCK_SHARE); - page = BufferGetPage(buf); - metap = HnswPageGetMeta(page); + buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + metap = HnswPageGetMeta(page); - insertPage = metap->insertPage; + insertPage = metap->insertPage; - UnlockReleaseBuffer(buf); + UnlockReleaseBuffer(buf); - return insertPage; + return insertPage; } /* @@ -39,56 +39,56 @@ GetInsertPage(Relation index) static bool HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size ntupSize, Buffer *nbuf, Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, BlockNumber *newInsertPage) { - OffsetNumber offno; - OffsetNumber maxoffno = PageGetMaxOffsetNumber(page); - - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); - - /* Skip neighbor tuples */ - if (!HnswIsElementTuple(etup)) - continue; - - if (etup->deleted) - { - BlockNumber elementPage = BufferGetBlockNumber(buf); - BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); - OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - ItemId itemid; - - if (!BlockNumberIsValid(*newInsertPage)) - *newInsertPage = elementPage; - - if (neighborPage == elementPage) - { - *nbuf = buf; - *npage = page; - } - else - { - *nbuf = ReadBuffer(index, neighborPage); - LockBuffer(*nbuf, BUFFER_LOCK_EXCLUSIVE); - - /* Skip WAL for now */ - *npage = BufferGetPage(*nbuf); - } - - itemid = PageGetItemId(*npage, neighborOffno); - - /* Check for space on neighbor tuple page */ - if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize) - { - *freeOffno = offno; - *freeNeighborOffno = neighborOffno; - return true; - } - else if (*nbuf != buf) - UnlockReleaseBuffer(*nbuf); - } - } - - return false; + OffsetNumber offno; + OffsetNumber maxoffno = PageGetMaxOffsetNumber(page); + + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + if (etup->deleted) + { + BlockNumber elementPage = BufferGetBlockNumber(buf); + BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); + OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); + ItemId itemid; + + if (!BlockNumberIsValid(*newInsertPage)) + *newInsertPage = elementPage; + + if (neighborPage == elementPage) + { + *nbuf = buf; + *npage = page; + } + else + { + *nbuf = ReadBuffer(index, neighborPage); + LockBuffer(*nbuf, BUFFER_LOCK_EXCLUSIVE); + + /* Skip WAL for now */ + *npage = BufferGetPage(*nbuf); + } + + itemid = PageGetItemId(*npage, neighborOffno); + + /* Check for space on neighbor tuple page */ + if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize) + { + *freeOffno = offno; + *freeNeighborOffno = neighborOffno; + return true; + } + else if (*nbuf != buf) + UnlockReleaseBuffer(*nbuf); + } + } + + return false; } /* @@ -97,21 +97,21 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size static void HnswInsertAppendPage(Relation index, Buffer *nbuf, Page *npage, GenericXLogState *state, Page page, bool building) { - /* Add a new page */ - LockRelationForExtension(index, ExclusiveLock); - *nbuf = HnswNewBuffer(index, MAIN_FORKNUM); - UnlockRelationForExtension(index, ExclusiveLock); + /* Add a new page */ + LockRelationForExtension(index, ExclusiveLock); + *nbuf = HnswNewBuffer(index, MAIN_FORKNUM); + UnlockRelationForExtension(index, ExclusiveLock); - /* Init new page */ - if (building) - *npage = BufferGetPage(*nbuf); - else - *npage = GenericXLogRegisterBuffer(state, *nbuf, GENERIC_XLOG_FULL_IMAGE); + /* Init new page */ + if (building) + *npage = BufferGetPage(*nbuf); + else + *npage = GenericXLogRegisterBuffer(state, *nbuf, GENERIC_XLOG_FULL_IMAGE); - HnswInitPage(*nbuf, *npage); + HnswInitPage(*nbuf, *npage); - /* Update previous buffer */ - HnswPageGetOpaque(page)->nextblkno = BufferGetBlockNumber(*nbuf); + /* Update previous buffer */ + HnswPageGetOpaque(page)->nextblkno = BufferGetBlockNumber(*nbuf); } /* @@ -337,18 +337,18 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B static bool ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) { - for (int i = 0; i < lm; i++) - { - ItemPointer indextid = &ntup->indextids[startIdx + i]; + for (int i = 0; i < lm; i++) + { + ItemPointer indextid = &ntup->indextids[startIdx + i]; - if (!ItemPointerIsValid(indextid)) - break; + if (!ItemPointerIsValid(indextid)) + break; - if (ItemPointerGetBlockNumber(indextid) == e->blkno && ItemPointerGetOffsetNumber(indextid) == e->offno) - return true; - } + if (ItemPointerGetBlockNumber(indextid) == e->blkno && ItemPointerGetOffsetNumber(indextid) == e->offno) + return true; + } - return false; + return false; } /* @@ -357,102 +357,102 @@ ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) void HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting, bool building) { - char *base = NULL; - - for (int lc = e->level; lc >= 0; lc--) - { - int lm = HnswGetLayerM(m, lc); - HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); - - for (int i = 0; i < neighbors->length; i++) - { - HnswCandidate *hc = &neighbors->items[i]; - Buffer buf; - Page page; - GenericXLogState *state; - HnswNeighborTuple ntup; - int idx = -1; - int startIdx; - HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); - OffsetNumber offno = neighborElement->neighborOffno; - - /* Get latest neighbors since they may have changed */ - /* Do not lock yet since selecting neighbors can take time */ - HnswLoadNeighbors(neighborElement, index, m); - - /* - * Could improve performance for vacuuming by checking neighbors - * against list of elements being deleted to find index. It's - * important to exclude already deleted elements for this since - * they can be replaced at any time. - */ - - /* Select neighbors */ - HnswUpdateConnection(NULL, e, hc, lm, lc, &idx, index, procinfo, collation); - - /* New element was not selected as a neighbor */ - if (idx == -1) - continue; - - /* Register page */ - buf = ReadBuffer(index, neighborElement->neighborPage); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - if (building) - { - state = NULL; - page = BufferGetPage(buf); - } - else - { - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - } - - /* Get tuple */ - ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, offno)); - - /* Calculate index for update */ - startIdx = (neighborElement->level - lc) * m; - - /* Check for existing connection */ - if (checkExisting && ConnectionExists(e, ntup, startIdx, lm)) - idx = -1; - else if (idx == -2) - { - /* Find free offset if still exists */ - /* TODO Retry updating connections if not */ - for (int j = 0; j < lm; j++) - { - if (!ItemPointerIsValid(&ntup->indextids[startIdx + j])) - { - idx = startIdx + j; - break; - } - } - } - else - idx += startIdx; - - /* Make robust to issues */ - if (idx >= 0 && idx < ntup->count) - { - ItemPointer indextid = &ntup->indextids[idx]; - - /* Update neighbor on the buffer */ - ItemPointerSet(indextid, e->blkno, e->offno); - - /* Commit */ - if (building) - MarkBufferDirty(buf); - else - GenericXLogFinish(state); - } - else if (!building) - GenericXLogAbort(state); - - UnlockReleaseBuffer(buf); - } - } + char *base = NULL; + + for (int lc = e->level; lc >= 0; lc--) + { + int lm = HnswGetLayerM(m, lc); + HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *hc = &neighbors->items[i]; + Buffer buf; + Page page; + GenericXLogState *state; + HnswNeighborTuple ntup; + int idx = -1; + int startIdx; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); + OffsetNumber offno = neighborElement->neighborOffno; + + /* Get latest neighbors since they may have changed */ + /* Do not lock yet since selecting neighbors can take time */ + HnswLoadNeighbors(neighborElement, index, m); + + /* + * Could improve performance for vacuuming by checking neighbors + * against list of elements being deleted to find index. It's + * important to exclude already deleted elements for this since + * they can be replaced at any time. + */ + + /* Select neighbors */ + HnswUpdateConnection(NULL, e, hc, lm, lc, &idx, index, procinfo, collation); + + /* New element was not selected as a neighbor */ + if (idx == -1) + continue; + + /* Register page */ + buf = ReadBuffer(index, neighborElement->neighborPage); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (building) + { + state = NULL; + page = BufferGetPage(buf); + } + else + { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + /* Get tuple */ + ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, offno)); + + /* Calculate index for update */ + startIdx = (neighborElement->level - lc) * m; + + /* Check for existing connection */ + if (checkExisting && ConnectionExists(e, ntup, startIdx, lm)) + idx = -1; + else if (idx == -2) + { + /* Find free offset if still exists */ + /* TODO Retry updating connections if not */ + for (int j = 0; j < lm; j++) + { + if (!ItemPointerIsValid(&ntup->indextids[startIdx + j])) + { + idx = startIdx + j; + break; + } + } + } + else + idx += startIdx; + + /* Make robust to issues */ + if (idx >= 0 && idx < ntup->count) + { + ItemPointer indextid = &ntup->indextids[idx]; + + /* Update neighbor on the buffer */ + ItemPointerSet(indextid, e->blkno, e->offno); + + /* Commit */ + if (building) + MarkBufferDirty(buf); + else + GenericXLogFinish(state); + } + else if (!building) + GenericXLogAbort(state); + + UnlockReleaseBuffer(buf); + } + } } /* @@ -461,54 +461,54 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns static bool AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool building) { - Buffer buf; - Page page; - GenericXLogState *state; - HnswElementTuple etup; - int i; - - /* Read page */ - buf = ReadBuffer(index, dup->blkno); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - if (building) - { - state = NULL; - page = BufferGetPage(buf); - } - else - { - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - } - - /* Find space */ - etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, dup->offno)); - for (i = 0; i < HNSW_HEAPTIDS; i++) - { - if (!ItemPointerIsValid(&etup->heaptids[i])) - break; - } - - /* Either being deleted or we lost our chance to another backend */ - if (i == 0 || i == HNSW_HEAPTIDS) - { - if (!building) - GenericXLogAbort(state); - UnlockReleaseBuffer(buf); - return false; - } - - /* Add heap TID, modifying the tuple on the page directly */ - etup->heaptids[i] = element->heaptids[0]; - - /* Commit */ - if (building) - MarkBufferDirty(buf); - else - GenericXLogFinish(state); - UnlockReleaseBuffer(buf); - - return true; + Buffer buf; + Page page; + GenericXLogState *state; + HnswElementTuple etup; + int i; + + /* Read page */ + buf = ReadBuffer(index, dup->blkno); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (building) + { + state = NULL; + page = BufferGetPage(buf); + } + else + { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + /* Find space */ + etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, dup->offno)); + for (i = 0; i < HNSW_HEAPTIDS; i++) + { + if (!ItemPointerIsValid(&etup->heaptids[i])) + break; + } + + /* Either being deleted or we lost our chance to another backend */ + if (i == 0 || i == HNSW_HEAPTIDS) + { + if (!building) + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + return false; + } + + /* Add heap TID, modifying the tuple on the page directly */ + etup->heaptids[i] = element->heaptids[0]; + + /* Commit */ + if (building) + MarkBufferDirty(buf); + else + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); + + return true; } /* @@ -517,25 +517,25 @@ AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool bu static bool FindDuplicateOnDisk(Relation index, HnswElement element, bool building) { - char *base = NULL; - HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); - Datum value = HnswGetValue(base, element); - - for (int i = 0; i < neighbors->length; i++) - { - HnswCandidate *neighbor = &neighbors->items[i]; - HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); - Datum neighborValue = HnswGetValue(base, neighborElement); - - /* Exit early since ordered by distance */ - if (!datumIsEqual(value, neighborValue, false, -1)) - return false; - - if (AddDuplicateOnDisk(index, element, neighborElement, building)) - return true; - } + char *base = NULL; + HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); + Datum value = HnswGetValue(base, element); + + for (int i = 0; i < neighbors->length; i++) + { + HnswCandidate *neighbor = &neighbors->items[i]; + HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); + Datum neighborValue = HnswGetValue(base, neighborElement); + + /* Exit early since ordered by distance */ + if (!datumIsEqual(value, neighborValue, false, -1)) + return false; + + if (AddDuplicateOnDisk(index, element, neighborElement, building)) + return true; + } - return false; + return false; } /* @@ -544,25 +544,25 @@ FindDuplicateOnDisk(Relation index, HnswElement element, bool building) static void UpdateGraphOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, bool building) { - BlockNumber newInsertPage = InvalidBlockNumber; + BlockNumber newInsertPage = InvalidBlockNumber; - /* Look for duplicate */ - if (FindDuplicateOnDisk(index, element, building)) - return; + /* Look for duplicate */ + if (FindDuplicateOnDisk(index, element, building)) + return; - /* Add element */ - AddElementOnDisk(index, element, m, GetInsertPage(index), &newInsertPage, building); + /* Add element */ + AddElementOnDisk(index, element, m, GetInsertPage(index), &newInsertPage, building); - /* Update insert page if needed */ - if (BlockNumberIsValid(newInsertPage)) - HnswUpdateMetaPage(index, 0, NULL, newInsertPage, MAIN_FORKNUM, building); + /* Update insert page if needed */ + if (BlockNumberIsValid(newInsertPage)) + HnswUpdateMetaPage(index, 0, NULL, newInsertPage, MAIN_FORKNUM, building); - /* Update neighbors */ - HnswUpdateNeighborsOnDisk(index, procinfo, collation, element, m, false, building); + /* Update neighbors */ + HnswUpdateNeighborsOnDisk(index, procinfo, collation, element, m, false, building); - /* Update entry point if needed */ - if (entryPoint == NULL || element->level > entryPoint->level) - HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM, building); + /* Update entry point if needed */ + if (entryPoint == NULL || element->level > entryPoint->level) + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM, building); } /* @@ -571,53 +571,53 @@ UpdateGraphOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement bool HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *isnull, ItemPointer heap_tid, bool building) { - HnswElement entryPoint; - HnswElement element; - int m; - int efConstruction = HnswGetEfConstruction(index); - FmgrInfo *procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); - Oid collation = index->rd_indcollation[0]; - LOCKMODE lockmode = ShareLock; - char *base = NULL; - - /* - * Get a shared lock. This allows vacuum to ensure no in-flight inserts - * before repairing graph. Use a page lock so it does not interfere with - * buffer lock (or reads when vacuuming). - */ - LockPage(index, HNSW_UPDATE_LOCK, lockmode); - - /* Get m and entry point */ - HnswGetMetaPageInfo(index, &m, &entryPoint); - - /* Create an element */ - element = HnswInitElement(base, heap_tid, m, HnswGetMl(m), HnswGetMaxLevel(m), NULL); - HnswPtrStore(base, element->value, DatumGetPointer(value)); - - /* Prevent concurrent inserts when likely updating entry point */ - if (entryPoint == NULL || element->level > entryPoint->level) - { - /* Release shared lock */ - UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); - - /* Get exclusive lock */ - lockmode = ExclusiveLock; - LockPage(index, HNSW_UPDATE_LOCK, lockmode); - - /* Get latest entry point after lock is acquired */ - entryPoint = HnswGetEntryPoint(index); - } - - /* Find neighbors for element */ - HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, false); - - /* Update graph on disk */ - UpdateGraphOnDisk(index, procinfo, collation, element, m, efConstruction, entryPoint, building); - - /* Release lock */ - UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); - - return true; + HnswElement entryPoint; + HnswElement element; + int m; + int efConstruction = HnswGetEfConstruction(index); + FmgrInfo *procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); + Oid collation = index->rd_indcollation[0]; + LOCKMODE lockmode = ShareLock; + char *base = NULL; + + /* + * Get a shared lock. This allows vacuum to ensure no in-flight inserts + * before repairing graph. Use a page lock so it does not interfere with + * buffer lock (or reads when vacuuming). + */ + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get m and entry point */ + HnswGetMetaPageInfo(index, &m, &entryPoint); + + /* Create an element */ + element = HnswInitElement(base, heap_tid, m, HnswGetMl(m), HnswGetMaxLevel(m), NULL); + HnswPtrStore(base, element->value, DatumGetPointer(value)); + + /* Prevent concurrent inserts when likely updating entry point */ + if (entryPoint == NULL || element->level > entryPoint->level) + { + /* Release shared lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get exclusive lock */ + lockmode = ExclusiveLock; + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get latest entry point after lock is acquired */ + entryPoint = HnswGetEntryPoint(index); + } + + /* Find neighbors for element */ + HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, false); + + /* Update graph on disk */ + UpdateGraphOnDisk(index, procinfo, collation, element, m, efConstruction, entryPoint, building); + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + + return true; } /* @@ -626,29 +626,29 @@ HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *is static void HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid) { - Datum value; - const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index); - FmgrInfo *normprocinfo; - Oid collation = index->rd_indcollation[0]; - - /* Detoast once for all calls */ - value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); - - /* Check value */ - if (typeInfo->checkValue != NULL) - typeInfo->checkValue(DatumGetPointer(value)); - - /* Normalize if needed */ - normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); - if (normprocinfo != NULL) - { - if (!HnswCheckNorm(normprocinfo, collation, value)) - return; - - value = HnswNormValue(typeInfo, collation, value); - } + Datum value; + const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index); + FmgrInfo *normprocinfo; + Oid collation = index->rd_indcollation[0]; + + /* Detoast once for all calls */ + value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Check value */ + if (typeInfo->checkValue != NULL) + typeInfo->checkValue(DatumGetPointer(value)); + + /* Normalize if needed */ + normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); + if (normprocinfo != NULL) + { + if (!HnswCheckNorm(normprocinfo, collation, value)) + return; + + value = HnswNormValue(typeInfo, collation, value); + } - HnswInsertTupleOnDisk(index, value, values, isnull, heap_tid, false); + HnswInsertTupleOnDisk(index, value, values, isnull, heap_tid, false); } /* @@ -656,27 +656,27 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti */ bool hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, - Relation heap, IndexUniqueCheck checkUnique) + Relation heap, IndexUniqueCheck checkUnique) { - MemoryContext oldCtx; - MemoryContext insertCtx; + MemoryContext oldCtx; + MemoryContext insertCtx; - /* Skip nulls */ - if (isnull[0]) - return false; + /* Skip nulls */ + if (isnull[0]) + return false; - /* Create memory context */ - insertCtx = AllocSetContextCreate(CurrentMemoryContext, - "Hnsw insert temporary context", - ALLOCSET_DEFAULT_SIZES); - oldCtx = MemoryContextSwitchTo(insertCtx); + /* Create memory context */ + insertCtx = AllocSetContextCreate(CurrentMemoryContext, + "Hnsw insert temporary context", + ALLOCSET_DEFAULT_SIZES); + oldCtx = MemoryContextSwitchTo(insertCtx); - /* Insert tuple */ - HnswInsertTuple(index, values, isnull, heap_tid); + /* Insert tuple */ + HnswInsertTuple(index, values, isnull, heap_tid); - /* Delete memory context */ - MemoryContextSwitchTo(oldCtx); - MemoryContextDelete(insertCtx); + /* Delete memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(insertCtx); - return false; + return false; } diff --git a/src/gausskernel/storage/access/datavec/hnswscan.cpp b/src/gausskernel/storage/access/datavec/hnswscan.cpp index a9c68a3628..c8962028d1 100644 --- a/src/gausskernel/storage/access/datavec/hnswscan.cpp +++ b/src/gausskernel/storage/access/datavec/hnswscan.cpp @@ -46,25 +46,25 @@ GetScanItems(IndexScanDesc scan, Datum q) static Datum GetScanValue(IndexScanDesc scan) { - HnswScanOpaque so = (HnswScanOpaque) scan->opaque; - Datum value; + HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + Datum value; - if (scan->orderByData->sk_flags & SK_ISNULL) - value = PointerGetDatum(NULL); - else - { - value = scan->orderByData->sk_argument; + if (scan->orderByData->sk_flags & SK_ISNULL) + value = PointerGetDatum(NULL); + else + { + value = scan->orderByData->sk_argument; - /* Value should not be compressed or toasted */ - Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); - Assert(!VARATT_IS_EXTENDED(DatumGetPointer(value))); + /* Value should not be compressed or toasted */ + Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); + Assert(!VARATT_IS_EXTENDED(DatumGetPointer(value))); - /* Normalize if needed */ - if (so->normprocinfo != NULL) - value = HnswNormValue(so->typeInfo, so->collation, value); - } + /* Normalize if needed */ + if (so->normprocinfo != NULL) + value = HnswNormValue(so->typeInfo, so->collation, value); + } - return value; + return value; } /* diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index a198d9713c..043725e153 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -23,15 +23,15 @@ static inline uint64 murmurhash64(uint64 data) { - uint64 h = data; + uint64 h = data; - h ^= h >> 33; - h *= 0xff51afd7ed558ccd; - h ^= h >> 33; - h *= 0xc4ceb9fe1a85ec53; - h ^= h >> 33; + h ^= h >> 33; + h *= 0xff51afd7ed558ccd; + h ^= h >> 33; + h *= 0xc4ceb9fe1a85ec53; + h ^= h >> 33; - return h; + return h; } #endif @@ -39,17 +39,17 @@ murmurhash64(uint64 data) static uint32 hash_tid(ItemPointerData tid) { - union - { - uint64 i; - ItemPointerData tid; - } x; + union + { + uint64 i; + ItemPointerData tid; + } x; - /* Initialize unused bytes */ - x.i = 0; - x.tid = tid; + /* Initialize unused bytes */ + x.i = 0; + x.tid = tid; - return murmurhash64(x.i); + return murmurhash64(x.i); } #define VALGRIND_MAKE_MEM_DEFINED(addr, size) do {} while (0) @@ -69,9 +69,9 @@ static uint32 hash_pointer(uintptr_t ptr) { #if SIZEOF_VOID_P == 8 - return murmurhash64((uint64) ptr); + return murmurhash64((uint64) ptr); #else - return murmurhash32((uint32) ptr); + return murmurhash32((uint32) ptr); #endif } @@ -90,9 +90,9 @@ static uint32 hash_offset(Size offset) { #if SIZEOF_SIZE_T == 8 - return murmurhash64((uint64) offset); + return murmurhash64((uint64) offset); #else - return murmurhash32((uint32) offset); + return murmurhash32((uint32) offset); #endif } @@ -108,9 +108,9 @@ hash_offset(Size offset) typedef union { - pointerhash_hash *pointers; - offsethash_hash *offsets; - tidhash_hash *tids; + pointerhash_hash *pointers; + offsethash_hash *offsets; + tidhash_hash *tids; } visited_hash; /* @@ -119,12 +119,12 @@ typedef union int HnswGetM(Relation index) { - HnswOptions *opts = (HnswOptions *) index->rd_options; + HnswOptions *opts = (HnswOptions *) index->rd_options; - if (opts) - return opts->m; + if (opts) + return opts->m; - return HNSW_DEFAULT_M; + return HNSW_DEFAULT_M; } /* @@ -133,12 +133,12 @@ HnswGetM(Relation index) int HnswGetEfConstruction(Relation index) { - HnswOptions *opts = (HnswOptions *) index->rd_options; + HnswOptions *opts = (HnswOptions *) index->rd_options; - if (opts) - return opts->efConstruction; + if (opts) + return opts->efConstruction; - return HNSW_DEFAULT_EF_CONSTRUCTION; + return HNSW_DEFAULT_EF_CONSTRUCTION; } /* @@ -193,10 +193,10 @@ HnswGetPqKsub(Relation index) FmgrInfo * HnswOptionalProcInfo(Relation index, uint16 procnum) { - if (!OidIsValid(index_getprocid(index, 1, procnum))) - return NULL; + if (!OidIsValid(index_getprocid(index, 1, procnum))) + return NULL; - return index_getprocinfo(index, 1, procnum); + return index_getprocinfo(index, 1, procnum); } /* @@ -205,7 +205,7 @@ HnswOptionalProcInfo(Relation index, uint16 procnum) Datum HnswNormValue(const HnswTypeInfo * typeInfo, Oid collation, Datum value) { - return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); + return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); } /* @@ -214,7 +214,7 @@ HnswNormValue(const HnswTypeInfo * typeInfo, Oid collation, Datum value) bool HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) { - return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; + return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; } /* @@ -223,10 +223,10 @@ HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) Buffer HnswNewBuffer(Relation index, ForkNumber forkNum) { - Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); + Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - return buf; + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + return buf; } /* @@ -247,11 +247,11 @@ HnswInitPage(Buffer buf, Page page) static HnswNeighborArray * HnswInitNeighborArray(int lm, HnswAllocator * allocator) { - HnswNeighborArray *a = (HnswNeighborArray *)HnswAlloc(allocator, HNSW_NEIGHBOR_ARRAY_SIZE(lm)); + HnswNeighborArray *a = (HnswNeighborArray *)HnswAlloc(allocator, HNSW_NEIGHBOR_ARRAY_SIZE(lm)); - a->length = 0; - a->closerSet = false; - return a; + a->length = 0; + a->closerSet = false; + return a; } /* @@ -260,13 +260,13 @@ HnswInitNeighborArray(int lm, HnswAllocator * allocator) void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * allocator) { - int level = element->level; - HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *) HnswAlloc(allocator, sizeof(HnswNeighborArrayPtr) * (level + 1)); + int level = element->level; + HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *) HnswAlloc(allocator, sizeof(HnswNeighborArrayPtr) * (level + 1)); - HnswPtrStore(base, element->neighbors, neighborList); + HnswPtrStore(base, element->neighbors, neighborList); - for (int lc = 0; lc <= level; lc++) - HnswPtrStore(base, neighborList[lc], HnswInitNeighborArray(HnswGetLayerM(m, lc), allocator)); + for (int lc = 0; lc <= level; lc++) + HnswPtrStore(base, neighborList[lc], HnswInitNeighborArray(HnswGetLayerM(m, lc), allocator)); } /* @@ -275,10 +275,10 @@ HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * alloca void * HnswAlloc(HnswAllocator * allocator, Size size) { - if (allocator) - return (*(allocator)->alloc) (size, (allocator)->state); + if (allocator) + return (*(allocator)->alloc) (size, (allocator)->state); - return palloc(size); + return palloc(size); } /* @@ -287,25 +287,25 @@ HnswAlloc(HnswAllocator * allocator, Size size) HnswElement HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, HnswAllocator * allocator) { - HnswElement element = (HnswElement)HnswAlloc(allocator, sizeof(HnswElementData)); + HnswElement element = (HnswElement)HnswAlloc(allocator, sizeof(HnswElementData)); - int level = (int) (-log(RandomDouble()) * ml); + int level = (int) (-log(RandomDouble()) * ml); - /* Cap level */ - if (level > maxLevel) - level = maxLevel; + /* Cap level */ + if (level > maxLevel) + level = maxLevel; - element->heaptidsLength = 0; - HnswAddHeapTid(element, heaptid); + element->heaptidsLength = 0; + HnswAddHeapTid(element, heaptid); - element->level = level; - element->deleted = 0; + element->level = level; + element->deleted = 0; - HnswInitNeighbors(base, element, m, allocator); + HnswInitNeighbors(base, element, m, allocator); - HnswPtrStore(base, element->value, (Pointer) NULL); + HnswPtrStore(base, element->value, (Pointer) NULL); - return element; + return element; } /* @@ -314,7 +314,7 @@ HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, void HnswAddHeapTid(HnswElement element, ItemPointer heaptid) { - element->heaptids[element->heaptidsLength++] = *heaptid; + element->heaptids[element->heaptidsLength++] = *heaptid; } /* @@ -323,14 +323,14 @@ HnswAddHeapTid(HnswElement element, ItemPointer heaptid) HnswElement HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno) { - HnswElement element = (HnswElement)palloc(sizeof(HnswElementData)); - char *base = NULL; - - element->blkno = blkno; - element->offno = offno; - HnswPtrStore(base, element->neighbors, (HnswNeighborArrayPtr *) NULL); - HnswPtrStore(base, element->value, (Pointer) NULL); - return element; + HnswElement element = (HnswElement)palloc(sizeof(HnswElementData)); + char *base = NULL; + + element->blkno = blkno; + element->offno = offno; + HnswPtrStore(base, element->neighbors, (HnswNeighborArrayPtr *) NULL); + HnswPtrStore(base, element->value, (Pointer) NULL); + return element; } /* @@ -339,33 +339,33 @@ HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno) void HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint) { - Buffer buf; - Page page; - HnswMetaPage metap; - - buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); - LockBuffer(buf, BUFFER_LOCK_SHARE); - page = BufferGetPage(buf); - metap = HnswPageGetMeta(page); - - if (unlikely(metap->magicNumber != HNSW_MAGIC_NUMBER)) - elog(ERROR, "hnsw index is not valid"); - - if (m != NULL) - *m = metap->m; - - if (entryPoint != NULL) - { - if (BlockNumberIsValid(metap->entryBlkno)) - { - *entryPoint = HnswInitElementFromBlock(metap->entryBlkno, metap->entryOffno); - (*entryPoint)->level = metap->entryLevel; - } - else - *entryPoint = NULL; - } - - UnlockReleaseBuffer(buf); + Buffer buf; + Page page; + HnswMetaPage metap; + + buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + metap = HnswPageGetMeta(page); + + if (unlikely(metap->magicNumber != HNSW_MAGIC_NUMBER)) + elog(ERROR, "hnsw index is not valid"); + + if (m != NULL) + *m = metap->m; + + if (entryPoint != NULL) + { + if (BlockNumberIsValid(metap->entryBlkno)) + { + *entryPoint = HnswInitElementFromBlock(metap->entryBlkno, metap->entryOffno); + (*entryPoint)->level = metap->entryLevel; + } + else + *entryPoint = NULL; + } + + UnlockReleaseBuffer(buf); } /* @@ -374,11 +374,11 @@ HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint) HnswElement HnswGetEntryPoint(Relation index) { - HnswElement entryPoint; + HnswElement entryPoint; - HnswGetMetaPageInfo(index, NULL, &entryPoint); + HnswGetMetaPageInfo(index, NULL, &entryPoint); - return entryPoint; + return entryPoint; } /* @@ -387,26 +387,26 @@ HnswGetEntryPoint(Relation index) static void HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, BlockNumber insertPage) { - HnswMetaPage metap = HnswPageGetMeta(page); - - if (updateEntry) - { - if (entryPoint == NULL) - { - metap->entryBlkno = InvalidBlockNumber; - metap->entryOffno = InvalidOffsetNumber; - metap->entryLevel = -1; - } - else if (entryPoint->level > metap->entryLevel || updateEntry == HNSW_UPDATE_ENTRY_ALWAYS) - { - metap->entryBlkno = entryPoint->blkno; - metap->entryOffno = entryPoint->offno; - metap->entryLevel = entryPoint->level; - } - } - - if (BlockNumberIsValid(insertPage)) - metap->insertPage = insertPage; + HnswMetaPage metap = HnswPageGetMeta(page); + + if (updateEntry) + { + if (entryPoint == NULL) + { + metap->entryBlkno = InvalidBlockNumber; + metap->entryOffno = InvalidOffsetNumber; + metap->entryLevel = -1; + } + else if (entryPoint->level > metap->entryLevel || updateEntry == HNSW_UPDATE_ENTRY_ALWAYS) + { + metap->entryBlkno = entryPoint->blkno; + metap->entryOffno = entryPoint->offno; + metap->entryLevel = entryPoint->level; + } + } + + if (BlockNumberIsValid(insertPage)) + metap->insertPage = insertPage; } /* @@ -445,30 +445,30 @@ HnswUpdateAppendMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum, bool building) { - Buffer buf; - Page page; - GenericXLogState *state; - - buf = ReadBufferExtended(index, forkNum, HNSW_METAPAGE_BLKNO, RBM_NORMAL, NULL); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - if (building) - { - state = NULL; - page = BufferGetPage(buf); - } - else - { - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - } - - HnswUpdateMetaPageInfo(page, updateEntry, entryPoint, insertPage); - - if (building) - MarkBufferDirty(buf); - else - GenericXLogFinish(state); - UnlockReleaseBuffer(buf); + Buffer buf; + Page page; + GenericXLogState *state; + + buf = ReadBufferExtended(index, forkNum, HNSW_METAPAGE_BLKNO, RBM_NORMAL, NULL); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (building) + { + state = NULL; + page = BufferGetPage(buf); + } + else + { + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + HnswUpdateMetaPageInfo(page, updateEntry, entryPoint, insertPage); + + if (building) + MarkBufferDirty(buf); + else + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); } /* @@ -508,19 +508,19 @@ HnswUpdateAppendMetaPage(Relation index, int updateEntry, HnswElement entryPoint void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) { - Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); - - etup->type = HNSW_ELEMENT_TUPLE_TYPE; - etup->level = element->level; - etup->deleted = 0; - for (int i = 0; i < HNSW_HEAPTIDS; i++) - { - if (i < element->heaptidsLength) - etup->heaptids[i] = element->heaptids[i]; - else - ItemPointerSetInvalid(&etup->heaptids[i]); - } - memcpy(&etup->data, valuePtr, VARSIZE_ANY(valuePtr)); + Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); + + etup->type = HNSW_ELEMENT_TUPLE_TYPE; + etup->level = element->level; + etup->deleted = 0; + for (int i = 0; i < HNSW_HEAPTIDS; i++) + { + if (i < element->heaptidsLength) + etup->heaptids[i] = element->heaptids[i]; + else + ItemPointerSetInvalid(&etup->heaptids[i]); + } + memcpy(&etup->data, valuePtr, VARSIZE_ANY(valuePtr)); } /* @@ -529,32 +529,32 @@ HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) { - int idx = 0; + int idx = 0; - ntup->type = HNSW_NEIGHBOR_TUPLE_TYPE; + ntup->type = HNSW_NEIGHBOR_TUPLE_TYPE; - for (int lc = e->level; lc >= 0; lc--) - { - HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); - int lm = HnswGetLayerM(m, lc); + for (int lc = e->level; lc >= 0; lc--) + { + HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); + int lm = HnswGetLayerM(m, lc); - for (int i = 0; i < lm; i++) - { - ItemPointer indextid = &ntup->indextids[idx++]; + for (int i = 0; i < lm; i++) + { + ItemPointer indextid = &ntup->indextids[idx++]; - if (i < neighbors->length) - { - HnswCandidate *hc = &neighbors->items[i]; - HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + if (i < neighbors->length) + { + HnswCandidate *hc = &neighbors->items[i]; + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); - ItemPointerSet(indextid, hce->blkno, hce->offno); - } - else - ItemPointerSetInvalid(indextid); - } - } + ItemPointerSet(indextid, hce->blkno, hce->offno); + } + else + ItemPointerSetInvalid(indextid); + } + } - ntup->count = idx; + ntup->count = idx; } /* @@ -563,43 +563,43 @@ HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) static void LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) { - char *base = NULL; + char *base = NULL; - HnswNeighborTuple ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); - int neighborCount = (element->level + 2) * m; + HnswNeighborTuple ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); + int neighborCount = (element->level + 2) * m; - Assert(HnswIsNeighborTuple(ntup)); + Assert(HnswIsNeighborTuple(ntup)); - HnswInitNeighbors(base, element, m, NULL); + HnswInitNeighbors(base, element, m, NULL); - /* Ensure expected neighbors */ - if (ntup->count != neighborCount) - return; + /* Ensure expected neighbors */ + if (ntup->count != neighborCount) + return; - for (int i = 0; i < neighborCount; i++) - { - HnswElement e; - int level; - HnswCandidate *hc; - ItemPointer indextid; - HnswNeighborArray *neighbors; + for (int i = 0; i < neighborCount; i++) + { + HnswElement e; + int level; + HnswCandidate *hc; + ItemPointer indextid; + HnswNeighborArray *neighbors; - indextid = &ntup->indextids[i]; + indextid = &ntup->indextids[i]; - if (!ItemPointerIsValid(indextid)) - continue; + if (!ItemPointerIsValid(indextid)) + continue; - e = HnswInitElementFromBlock(ItemPointerGetBlockNumber(indextid), ItemPointerGetOffsetNumber(indextid)); + e = HnswInitElementFromBlock(ItemPointerGetBlockNumber(indextid), ItemPointerGetOffsetNumber(indextid)); - /* Calculate level based on offset */ - level = element->level - i / m; - if (level < 0) - level = 0; + /* Calculate level based on offset */ + level = element->level - i / m; + if (level < 0) + level = 0; - neighbors = HnswGetNeighbors(base, element, level); - hc = &neighbors->items[neighbors->length++]; - HnswPtrStore(base, hc->element, e); - } + neighbors = HnswGetNeighbors(base, element, level); + hc = &neighbors->items[neighbors->length++]; + HnswPtrStore(base, hc->element, e); + } } /* @@ -608,16 +608,16 @@ LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) void HnswLoadNeighbors(HnswElement element, Relation index, int m) { - Buffer buf; - Page page; + Buffer buf; + Page page; - buf = ReadBuffer(index, element->neighborPage); - LockBuffer(buf, BUFFER_LOCK_SHARE); - page = BufferGetPage(buf); + buf = ReadBuffer(index, element->neighborPage); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); - LoadNeighborsFromPage(element, index, page, m); + LoadNeighborsFromPage(element, index, page, m); - UnlockReleaseBuffer(buf); + UnlockReleaseBuffer(buf); } /* @@ -626,31 +626,31 @@ HnswLoadNeighbors(HnswElement element, Relation index, int m) void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec) { - element->level = etup->level; - element->deleted = etup->deleted; - element->neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); - element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - element->heaptidsLength = 0; - - if (loadHeaptids) - { - for (int i = 0; i < HNSW_HEAPTIDS; i++) - { - /* Can stop at first invalid */ - if (!ItemPointerIsValid(&etup->heaptids[i])) - break; - - HnswAddHeapTid(element, &etup->heaptids[i]); - } - } - - if (loadVec) - { - char *base = NULL; - Datum value = datumCopy(PointerGetDatum(&etup->data), false, -1); - - HnswPtrStore(base, element->value, DatumGetPointer(value)); - } + element->level = etup->level; + element->deleted = etup->deleted; + element->neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); + element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); + element->heaptidsLength = 0; + + if (loadHeaptids) + { + for (int i = 0; i < HNSW_HEAPTIDS; i++) + { + /* Can stop at first invalid */ + if (!ItemPointerIsValid(&etup->heaptids[i])) + break; + + HnswAddHeapTid(element, &etup->heaptids[i]); + } + } + + if (loadVec) + { + char *base = NULL; + Datum value = datumCopy(PointerGetDatum(&etup->data), false, -1); + + HnswPtrStore(base, element->value, DatumGetPointer(value)); + } } /* @@ -705,10 +705,10 @@ HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, static float GetCandidateDistance(char *base, HnswCandidate * hc, Datum q, FmgrInfo *procinfo, Oid collation) { - HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); - Datum value = HnswGetValue(base, hce); + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + Datum value = HnswGetValue(base, hce); - return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, q, value)); + return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, q, value)); } /* @@ -739,13 +739,13 @@ HnswEntryCandidate(char *base, HnswElement entryPoint, Datum q, Relation index, static int CompareNearestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) - return 1; + if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) + return 1; - if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) - return -1; + if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) + return -1; - return 0; + return 0; } /* @@ -754,13 +754,13 @@ CompareNearestCandidates(const pairingheap_node *a, const pairingheap_node *b, v static int CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) - return -1; + if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) + return -1; - if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) - return 1; + if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) + return 1; - return 0; + return 0; } /* @@ -769,10 +769,10 @@ CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b, static HnswPairingHeapNode * CreatePairingHeapNode(HnswCandidate * c) { - HnswPairingHeapNode *node = (HnswPairingHeapNode *)palloc(sizeof(HnswPairingHeapNode)); + HnswPairingHeapNode *node = (HnswPairingHeapNode *)palloc(sizeof(HnswPairingHeapNode)); - node->inner = c; - return node; + node->inner = c; + return node; } /* @@ -781,12 +781,12 @@ CreatePairingHeapNode(HnswCandidate * c) static inline void InitVisited(char *base, visited_hash * v, Relation index, int ef, int m) { - if (index != NULL) - v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL); - else if (base != NULL) - v->offsets = offsethash_create(CurrentMemoryContext, ef * m * 2, NULL); - else - v->pointers = pointerhash_create(CurrentMemoryContext, ef * m * 2, NULL); + if (index != NULL) + v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL); + else if (base != NULL) + v->offsets = offsethash_create(CurrentMemoryContext, ef * m * 2, NULL); + else + v->pointers = pointerhash_create(CurrentMemoryContext, ef * m * 2, NULL); } /* @@ -795,34 +795,34 @@ InitVisited(char *base, visited_hash * v, Relation index, int ef, int m) static inline void AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, bool *found) { - if (index != NULL) - { - HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); - ItemPointerData indextid; - - ItemPointerSet(&indextid, element->blkno, element->offno); - tidhash_insert(v->tids, indextid, found); - } - else if (base != NULL) - { + if (index != NULL) + { + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + ItemPointerData indextid; + + ItemPointerSet(&indextid, element->blkno, element->offno); + tidhash_insert(v->tids, indextid, found); + } + else if (base != NULL) + { #if PG_VERSION_NUM >= 130000 - HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); - offsethash_insert_hash(v->offsets, HnswPtrOffset(hc->element), element->hash, found); + offsethash_insert_hash(v->offsets, HnswPtrOffset(hc->element), element->hash, found); #else - offsethash_insert(v->offsets, HnswPtrOffset(hc->element), found); + offsethash_insert(v->offsets, HnswPtrOffset(hc->element), found); #endif - } - else - { + } + else + { #if PG_VERSION_NUM >= 130000 - HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); + HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); - pointerhash_insert_hash(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), element->hash, found); + pointerhash_insert_hash(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), element->hash, found); #else - pointerhash_insert(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), found); + pointerhash_insert(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), found); #endif - } + } } /* @@ -831,16 +831,16 @@ AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, b static inline bool CountElement(char *base, HnswElement skipElement, HnswCandidate * hc) { - HnswElement e; + HnswElement e; - if (skipElement == NULL) - return true; + if (skipElement == NULL) + return true; - /* Ensure does not access heaptidsLength during in-memory build */ - pg_memory_barrier(); + /* Ensure does not access heaptidsLength during in-memory build */ + pg_memory_barrier(); - e = (HnswElement)HnswPtrAccess(base, hc->element); - return e->heaptidsLength != 0; + e = (HnswElement)HnswPtrAccess(base, hc->element); + return e->heaptidsLength != 0; } /* @@ -986,28 +986,28 @@ static int #if PG_VERSION_NUM >= 130000 CompareCandidateDistances(const ListCell *a, const ListCell *b) { - HnswCandidate *hca = (HnswCandidate *)lfirst(a); - HnswCandidate *hcb = (HnswCandidate *)lfirst(b); + HnswCandidate *hca = (HnswCandidate *)lfirst(a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(b); #else CompareCandidateDistances(const void *a, const void *b) { - HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); - HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); + HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); #endif - if (hca->distance < hcb->distance) - return 1; + if (hca->distance < hcb->distance) + return 1; - if (hca->distance > hcb->distance) - return -1; + if (hca->distance > hcb->distance) + return -1; - if (HnswPtrPointer(hca->element) < HnswPtrPointer(hcb->element)) - return 1; + if (HnswPtrPointer(hca->element) < HnswPtrPointer(hcb->element)) + return 1; - if (HnswPtrPointer(hca->element) > HnswPtrPointer(hcb->element)) - return -1; + if (HnswPtrPointer(hca->element) > HnswPtrPointer(hcb->element)) + return -1; - return 0; + return 0; } /* @@ -1017,28 +1017,28 @@ static int #if PG_VERSION_NUM >= 130000 CompareCandidateDistancesOffset(const ListCell *a, const ListCell *b) { - HnswCandidate *hca = (HnswCandidate *)lfirst(a); - HnswCandidate *hcb = (HnswCandidate *)lfirst(b); + HnswCandidate *hca = (HnswCandidate *)lfirst(a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(b); #else CompareCandidateDistancesOffset(const void *a, const void *b) { - HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); - HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); + HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); #endif - if (hca->distance < hcb->distance) - return 1; + if (hca->distance < hcb->distance) + return 1; - if (hca->distance > hcb->distance) - return -1; + if (hca->distance > hcb->distance) + return -1; - if (HnswPtrOffset(hca->element) < HnswPtrOffset(hcb->element)) - return 1; + if (HnswPtrOffset(hca->element) < HnswPtrOffset(hcb->element)) + return 1; - if (HnswPtrOffset(hca->element) > HnswPtrOffset(hcb->element)) - return -1; + if (HnswPtrOffset(hca->element) > HnswPtrOffset(hcb->element)) + return -1; - return 0; + return 0; } /* @@ -1047,10 +1047,10 @@ CompareCandidateDistancesOffset(const void *a, const void *b) static float HnswGetDistance(char *base, HnswElement a, HnswElement b, FmgrInfo *procinfo, Oid collation) { - Datum aValue = HnswGetValue(base, a); - Datum bValue = HnswGetValue(base, b); + Datum aValue = HnswGetValue(base, a); + Datum bValue = HnswGetValue(base, b); - return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, aValue, bValue)); + return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, aValue, bValue)); } /* @@ -1059,20 +1059,20 @@ HnswGetDistance(char *base, HnswElement a, HnswElement b, FmgrInfo *procinfo, Oi static bool CheckElementCloser(char *base, HnswCandidate * e, List *r, FmgrInfo *procinfo, Oid collation) { - HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); - ListCell *lc2; + HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); + ListCell *lc2; - foreach(lc2, r) - { - HnswCandidate *ri = (HnswCandidate *)lfirst(lc2); - HnswElement riElement = (HnswElement)HnswPtrAccess(base, ri->element); - float distance = HnswGetDistance(base, eElement, riElement, procinfo, collation); + foreach(lc2, r) + { + HnswCandidate *ri = (HnswCandidate *)lfirst(lc2); + HnswElement riElement = (HnswElement)HnswPtrAccess(base, ri->element); + float distance = HnswGetDistance(base, eElement, riElement, procinfo, collation); - if (distance <= e->distance) - return false; - } + if (distance <= e->distance) + return false; + } - return true; + return true; } /* @@ -1195,11 +1195,11 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col static void AddConnections(char *base, HnswElement element, List *neighbors, int lc) { - ListCell *lc2; - HnswNeighborArray *a = HnswGetNeighbors(base, element, lc); + ListCell *lc2; + HnswNeighborArray *a = HnswGetNeighbors(base, element, lc); - foreach(lc2, neighbors) - a->items[a->length++] = *((HnswCandidate *) lfirst(lc2)); + foreach(lc2, neighbors) + a->items[a->length++] = *((HnswCandidate *) lfirst(lc2)); } /* @@ -1208,81 +1208,81 @@ AddConnections(char *base, HnswElement element, List *neighbors, int lc) void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation) { - HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); - HnswNeighborArray *currentNeighbors = HnswGetNeighbors(base, hce, lc); - HnswCandidate hc2; - - HnswPtrStore(base, hc2.element, element); - hc2.distance = hc->distance; - - if (currentNeighbors->length < lm) - { - currentNeighbors->items[currentNeighbors->length++] = hc2; - - /* Track update */ - if (updateIdx != NULL) - *updateIdx = -2; - } - else - { - /* Shrink connections */ - HnswCandidate *pruned = NULL; - - /* Load elements on insert */ - if (index != NULL) - { - Datum q = HnswGetValue(base, hce); - - for (int i = 0; i < currentNeighbors->length; i++) - { - HnswCandidate *hc3 = ¤tNeighbors->items[i]; - HnswElement hc3Element = (HnswElement)HnswPtrAccess(base, hc3->element); - - if (HnswPtrIsNull(base, hc3Element->value)) - HnswLoadElement(hc3Element, &hc3->distance, &q, index, procinfo, collation, true, NULL); - else - hc3->distance = GetCandidateDistance(base, hc3, q, procinfo, collation); - - /* Prune element if being deleted */ - if (hc3Element->heaptidsLength == 0) - { - pruned = ¤tNeighbors->items[i]; - break; - } - } - } - - if (pruned == NULL) - { - List *c = NIL; - - /* Add candidates */ - for (int i = 0; i < currentNeighbors->length; i++) - c = lappend(c, ¤tNeighbors->items[i]); - c = lappend(c, &hc2); - - SelectNeighbors(base, c, lm, lc, procinfo, collation, hce, &hc2, &pruned, true); - - /* Should not happen */ - if (pruned == NULL) - return; - } - - /* Find and replace the pruned element */ - for (int i = 0; i < currentNeighbors->length; i++) - { - if (HnswPtrEqual(base, currentNeighbors->items[i].element, pruned->element)) - { - currentNeighbors->items[i] = hc2; - - /* Track update */ - if (updateIdx != NULL) - *updateIdx = i; - - break; - } - } - } + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + HnswNeighborArray *currentNeighbors = HnswGetNeighbors(base, hce, lc); + HnswCandidate hc2; + + HnswPtrStore(base, hc2.element, element); + hc2.distance = hc->distance; + + if (currentNeighbors->length < lm) + { + currentNeighbors->items[currentNeighbors->length++] = hc2; + + /* Track update */ + if (updateIdx != NULL) + *updateIdx = -2; + } + else + { + /* Shrink connections */ + HnswCandidate *pruned = NULL; + + /* Load elements on insert */ + if (index != NULL) + { + Datum q = HnswGetValue(base, hce); + + for (int i = 0; i < currentNeighbors->length; i++) + { + HnswCandidate *hc3 = ¤tNeighbors->items[i]; + HnswElement hc3Element = (HnswElement)HnswPtrAccess(base, hc3->element); + + if (HnswPtrIsNull(base, hc3Element->value)) + HnswLoadElement(hc3Element, &hc3->distance, &q, index, procinfo, collation, true, NULL); + else + hc3->distance = GetCandidateDistance(base, hc3, q, procinfo, collation); + + /* Prune element if being deleted */ + if (hc3Element->heaptidsLength == 0) + { + pruned = ¤tNeighbors->items[i]; + break; + } + } + } + + if (pruned == NULL) + { + List *c = NIL; + + /* Add candidates */ + for (int i = 0; i < currentNeighbors->length; i++) + c = lappend(c, ¤tNeighbors->items[i]); + c = lappend(c, &hc2); + + SelectNeighbors(base, c, lm, lc, procinfo, collation, hce, &hc2, &pruned, true); + + /* Should not happen */ + if (pruned == NULL) + return; + } + + /* Find and replace the pruned element */ + for (int i = 0; i < currentNeighbors->length; i++) + { + if (HnswPtrEqual(base, currentNeighbors->items[i].element, pruned->element)) + { + currentNeighbors->items[i] = hc2; + + /* Track update */ + if (updateIdx != NULL) + *updateIdx = i; + + break; + } + } + } } /* @@ -1291,26 +1291,26 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm static List * RemoveElements(char *base, List *w, HnswElement skipElement) { - ListCell *lc2; - List *w2 = NIL; + ListCell *lc2; + List *w2 = NIL; - /* Ensure does not access heaptidsLength during in-memory build */ - pg_memory_barrier(); + /* Ensure does not access heaptidsLength during in-memory build */ + pg_memory_barrier(); - foreach(lc2, w) - { - HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); - HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); + foreach(lc2, w) + { + HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); + HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); - /* Skip self for vacuuming update */ - if (skipElement != NULL && hce->blkno == skipElement->blkno && hce->offno == skipElement->offno) - continue; + /* Skip self for vacuuming update */ + if (skipElement != NULL && hce->blkno == skipElement->blkno && hce->offno == skipElement->offno) + continue; - if (hce->heaptidsLength != 0) - w2 = lappend(w2, hc); - } + if (hce->heaptidsLength != 0) + w2 = lappend(w2, hc); + } - return w2; + return w2; } #if PG_VERSION_NUM >= 130000 @@ -1320,14 +1320,14 @@ RemoveElements(char *base, List *w, HnswElement skipElement) static void PrecomputeHash(char *base, HnswElement element) { - HnswElementPtr ptr; + HnswElementPtr ptr; - HnswPtrStore(base, ptr, element); + HnswPtrStore(base, ptr, element); - if (base == NULL) - element->hash = hash_pointer((uintptr_t) HnswPtrPointer(ptr)); - else - element->hash = hash_offset(HnswPtrOffset(ptr)); + if (base == NULL) + element->hash = hash_pointer((uintptr_t) HnswPtrPointer(ptr)); + else + element->hash = hash_offset(HnswPtrOffset(ptr)); } #endif @@ -1337,77 +1337,77 @@ PrecomputeHash(char *base, HnswElement element) void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing) { - List *ep; - List *w; - int level = element->level; - int entryLevel; - Datum q = HnswGetValue(base, element); - HnswElement skipElement = existing ? element : NULL; + List *ep; + List *w; + int level = element->level; + int entryLevel; + Datum q = HnswGetValue(base, element); + HnswElement skipElement = existing ? element : NULL; #if PG_VERSION_NUM >= 130000 - /* Precompute hash */ - if (index == NULL) - PrecomputeHash(base, element); + /* Precompute hash */ + if (index == NULL) + PrecomputeHash(base, element); #endif - /* No neighbors if no entry point */ - if (entryPoint == NULL) - return; - - /* Get entry point and level */ - ep = list_make1(HnswEntryCandidate(base, entryPoint, q, index, procinfo, collation, true)); - entryLevel = entryPoint->level; - - /* 1st phase: greedy search to insert level */ - for (int lc = entryLevel; lc >= level + 1; lc--) - { - w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, true, skipElement); - ep = w; - } - - if (level > entryLevel) - level = entryLevel; - - /* Add one for existing element */ - if (existing) - efConstruction++; - - /* 2nd phase */ - for (int lc = level; lc >= 0; lc--) - { - int lm = HnswGetLayerM(m, lc); - List *neighbors; - List *lw; - - w = HnswSearchLayer(base, q, ep, efConstruction, lc, index, procinfo, collation, m, true, skipElement); - - /* Elements being deleted or skipped can help with search */ - /* but should be removed before selecting neighbors */ - if (index != NULL) - lw = RemoveElements(base, w, skipElement); - else - lw = w; - - /* - * Candidates are sorted, but not deterministically. Could set - * sortCandidates to true for in-memory builds to enable closer - * caching, but there does not seem to be a difference in performance. - */ - neighbors = SelectNeighbors(base, lw, lm, lc, procinfo, collation, element, NULL, NULL, false); - - AddConnections(base, element, neighbors, lc); - - ep = w; - } + /* No neighbors if no entry point */ + if (entryPoint == NULL) + return; + + /* Get entry point and level */ + ep = list_make1(HnswEntryCandidate(base, entryPoint, q, index, procinfo, collation, true)); + entryLevel = entryPoint->level; + + /* 1st phase: greedy search to insert level */ + for (int lc = entryLevel; lc >= level + 1; lc--) + { + w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, true, skipElement); + ep = w; + } + + if (level > entryLevel) + level = entryLevel; + + /* Add one for existing element */ + if (existing) + efConstruction++; + + /* 2nd phase */ + for (int lc = level; lc >= 0; lc--) + { + int lm = HnswGetLayerM(m, lc); + List *neighbors; + List *lw; + + w = HnswSearchLayer(base, q, ep, efConstruction, lc, index, procinfo, collation, m, true, skipElement); + + /* Elements being deleted or skipped can help with search */ + /* but should be removed before selecting neighbors */ + if (index != NULL) + lw = RemoveElements(base, w, skipElement); + else + lw = w; + + /* + * Candidates are sorted, but not deterministically. Could set + * sortCandidates to true for in-memory builds to enable closer + * caching, but there does not seem to be a difference in performance. + */ + neighbors = SelectNeighbors(base, lw, lm, lc, procinfo, collation, element, NULL, NULL, false); + + AddConnections(base, element, neighbors, lc); + + ep = w; + } } static void SparsevecCheckValue(Pointer v) { - SparseVector *vec = (SparseVector *) v; + SparseVector *vec = (SparseVector *) v; - if (vec->nnz > HNSW_MAX_NNZ) - elog(ERROR, "sparsevec cannot have more than %d non-zero elements for hnsw index", HNSW_MAX_NNZ); + if (vec->nnz > HNSW_MAX_NNZ) + elog(ERROR, "sparsevec cannot have more than %d non-zero elements for hnsw index", HNSW_MAX_NNZ); } /* @@ -1416,57 +1416,57 @@ SparsevecCheckValue(Pointer v) const HnswTypeInfo * HnswGetTypeInfo(Relation index) { - FmgrInfo *procinfo = HnswOptionalProcInfo(index, HNSW_TYPE_INFO_PROC); - - if (procinfo == NULL) - { - static const HnswTypeInfo typeInfo = { - .maxDimensions = HNSW_MAX_DIM, - .normalize = l2_normalize, - .checkValue = NULL - }; - - return (&typeInfo); - } - else - return (const HnswTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); + FmgrInfo *procinfo = HnswOptionalProcInfo(index, HNSW_TYPE_INFO_PROC); + + if (procinfo == NULL) + { + static const HnswTypeInfo typeInfo = { + .maxDimensions = HNSW_MAX_DIM, + .normalize = l2_normalize, + .checkValue = NULL + }; + + return (&typeInfo); + } + else + return (const HnswTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_halfvec_support); Datum hnsw_halfvec_support(PG_FUNCTION_ARGS) { - static const HnswTypeInfo typeInfo = { - .maxDimensions = HNSW_MAX_DIM * 2, - .normalize = halfvec_l2_normalize, - .checkValue = NULL - }; + static const HnswTypeInfo typeInfo = { + .maxDimensions = HNSW_MAX_DIM * 2, + .normalize = halfvec_l2_normalize, + .checkValue = NULL + }; - PG_RETURN_POINTER(&typeInfo); + PG_RETURN_POINTER(&typeInfo); }; PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_bit_support); Datum hnsw_bit_support(PG_FUNCTION_ARGS) { - static const HnswTypeInfo typeInfo = { - .maxDimensions = HNSW_MAX_DIM * 32, - .normalize = NULL, - .checkValue = NULL - }; + static const HnswTypeInfo typeInfo = { + .maxDimensions = HNSW_MAX_DIM * 32, + .normalize = NULL, + .checkValue = NULL + }; - PG_RETURN_POINTER(&typeInfo); + PG_RETURN_POINTER(&typeInfo); }; PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_sparsevec_support); Datum hnsw_sparsevec_support(PG_FUNCTION_ARGS) { - static const HnswTypeInfo typeInfo = { - .maxDimensions = SPARSEVEC_MAX_DIM, - .normalize = sparsevec_l2_normalize, - .checkValue = SparsevecCheckValue - }; + static const HnswTypeInfo typeInfo = { + .maxDimensions = SPARSEVEC_MAX_DIM, + .normalize = sparsevec_l2_normalize, + .checkValue = SparsevecCheckValue + }; - PG_RETURN_POINTER(&typeInfo); + PG_RETURN_POINTER(&typeInfo); }; diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp index d9e5f0574f..d6bf541a27 100644 --- a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -15,7 +15,7 @@ static bool DeletedContains(tidhash_hash * deleted, ItemPointer indextid) { - return tidhash_lookup(deleted, *indextid) != NULL; + return tidhash_lookup(deleted, *indextid) != NULL; } /* @@ -26,109 +26,109 @@ DeletedContains(tidhash_hash * deleted, ItemPointer indextid) static void RemoveHeapTids(HnswVacuumState * vacuumstate) { - BlockNumber blkno = HNSW_HEAD_BLKNO; - HnswElement highestPoint = &vacuumstate->highestPoint; - Relation index = vacuumstate->index; - BufferAccessStrategy bas = vacuumstate->bas; - HnswElement entryPoint = HnswGetEntryPoint(vacuumstate->index); - IndexBulkDeleteResult *stats = vacuumstate->stats; - - /* Store separately since highestPoint.level is uint8 */ - int highestLevel = -1; - - /* Initialize highest point */ - highestPoint->blkno = InvalidBlockNumber; - highestPoint->offno = InvalidOffsetNumber; - - while (BlockNumberIsValid(blkno)) - { - Buffer buf; - Page page; - GenericXLogState *state; - OffsetNumber offno; - OffsetNumber maxoffno; - bool updated = false; - - vacuum_delay_point(); - - buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - maxoffno = PageGetMaxOffsetNumber(page); - - /* Iterate over nodes */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); - int idx = 0; - bool itemUpdated = false; - - /* Skip neighbor tuples */ - if (!HnswIsElementTuple(etup)) - continue; - - if (ItemPointerIsValid(&etup->heaptids[0])) - { - for (int i = 0; i < HNSW_HEAPTIDS; i++) - { - /* Stop at first unused */ - if (!ItemPointerIsValid(&etup->heaptids[i])) - break; - - if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, InvalidBktId)) - { - itemUpdated = true; - stats->tuples_removed++; - } - else - { - /* Move to front of list */ - etup->heaptids[idx++] = etup->heaptids[i]; - stats->num_index_tuples++; - } - } - - if (itemUpdated) - { - /* Mark rest as invalid */ - for (int i = idx; i < HNSW_HEAPTIDS; i++) - ItemPointerSetInvalid(&etup->heaptids[i]); - - updated = true; - } - } - - if (!ItemPointerIsValid(&etup->heaptids[0])) - { - ItemPointerData ip; - bool found; - - /* Add to deleted list */ - ItemPointerSet(&ip, blkno, offno); - - tidhash_insert(vacuumstate->deleted, ip, &found); - Assert(!found); - } - else if (etup->level > highestLevel && !(entryPoint != NULL && blkno == entryPoint->blkno && offno == entryPoint->offno)) - { - /* Keep track of highest non-entry point */ - highestPoint->blkno = blkno; - highestPoint->offno = offno; - highestPoint->level = etup->level; - highestLevel = etup->level; - } - } - - blkno = HnswPageGetOpaque(page)->nextblkno; - - if (updated) - GenericXLogFinish(state); - else - GenericXLogAbort(state); - - UnlockReleaseBuffer(buf); - } + BlockNumber blkno = HNSW_HEAD_BLKNO; + HnswElement highestPoint = &vacuumstate->highestPoint; + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + HnswElement entryPoint = HnswGetEntryPoint(vacuumstate->index); + IndexBulkDeleteResult *stats = vacuumstate->stats; + + /* Store separately since highestPoint.level is uint8 */ + int highestLevel = -1; + + /* Initialize highest point */ + highestPoint->blkno = InvalidBlockNumber; + highestPoint->offno = InvalidOffsetNumber; + + while (BlockNumberIsValid(blkno)) + { + Buffer buf; + Page page; + GenericXLogState *state; + OffsetNumber offno; + OffsetNumber maxoffno; + bool updated = false; + + vacuum_delay_point(); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + maxoffno = PageGetMaxOffsetNumber(page); + + /* Iterate over nodes */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + int idx = 0; + bool itemUpdated = false; + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + if (ItemPointerIsValid(&etup->heaptids[0])) + { + for (int i = 0; i < HNSW_HEAPTIDS; i++) + { + /* Stop at first unused */ + if (!ItemPointerIsValid(&etup->heaptids[i])) + break; + + if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, InvalidBktId)) + { + itemUpdated = true; + stats->tuples_removed++; + } + else + { + /* Move to front of list */ + etup->heaptids[idx++] = etup->heaptids[i]; + stats->num_index_tuples++; + } + } + + if (itemUpdated) + { + /* Mark rest as invalid */ + for (int i = idx; i < HNSW_HEAPTIDS; i++) + ItemPointerSetInvalid(&etup->heaptids[i]); + + updated = true; + } + } + + if (!ItemPointerIsValid(&etup->heaptids[0])) + { + ItemPointerData ip; + bool found; + + /* Add to deleted list */ + ItemPointerSet(&ip, blkno, offno); + + tidhash_insert(vacuumstate->deleted, ip, &found); + Assert(!found); + } + else if (etup->level > highestLevel && !(entryPoint != NULL && blkno == entryPoint->blkno && offno == entryPoint->offno)) + { + /* Keep track of highest non-entry point */ + highestPoint->blkno = blkno; + highestPoint->offno = offno; + highestPoint->level = etup->level; + highestLevel = etup->level; + } + } + + blkno = HnswPageGetOpaque(page)->nextblkno; + + if (updated) + GenericXLogFinish(state); + else + GenericXLogAbort(state); + + UnlockReleaseBuffer(buf); + } } /* @@ -137,44 +137,44 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) static bool NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) { - Relation index = vacuumstate->index; - BufferAccessStrategy bas = vacuumstate->bas; - Buffer buf; - Page page; - HnswNeighborTuple ntup; - bool needsUpdated = false; - - buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); - LockBuffer(buf, BUFFER_LOCK_SHARE); - page = BufferGetPage(buf); - ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); - - Assert(HnswIsNeighborTuple(ntup)); - - /* Check neighbors */ - for (int i = 0; i < ntup->count; i++) - { - ItemPointer indextid = &ntup->indextids[i]; - - if (!ItemPointerIsValid(indextid)) - continue; - - /* Check if in deleted list */ - if (DeletedContains(vacuumstate->deleted, indextid)) - { - needsUpdated = true; - break; - } - } - - /* Also update if layer 0 is not full */ - /* This could indicate too many candidates being deleted during insert */ - if (!needsUpdated) - needsUpdated = !ItemPointerIsValid(&ntup->indextids[ntup->count - 1]); - - UnlockReleaseBuffer(buf); - - return needsUpdated; + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + Buffer buf; + Page page; + HnswNeighborTuple ntup; + bool needsUpdated = false; + + buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); + + Assert(HnswIsNeighborTuple(ntup)); + + /* Check neighbors */ + for (int i = 0; i < ntup->count; i++) + { + ItemPointer indextid = &ntup->indextids[i]; + + if (!ItemPointerIsValid(indextid)) + continue; + + /* Check if in deleted list */ + if (DeletedContains(vacuumstate->deleted, indextid)) + { + needsUpdated = true; + break; + } + } + + /* Also update if layer 0 is not full */ + /* This could indicate too many candidates being deleted during insert */ + if (!needsUpdated) + needsUpdated = !ItemPointerIsValid(&ntup->indextids[ntup->count - 1]); + + UnlockReleaseBuffer(buf); + + return needsUpdated; } /* @@ -183,53 +183,53 @@ NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) static void RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswElement entryPoint) { - Relation index = vacuumstate->index; - Buffer buf; - Page page; - GenericXLogState *state; - int m = vacuumstate->m; - int efConstruction = vacuumstate->efConstruction; - FmgrInfo *procinfo = vacuumstate->procinfo; - Oid collation = vacuumstate->collation; - BufferAccessStrategy bas = vacuumstate->bas; - HnswNeighborTuple ntup = vacuumstate->ntup; - Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); - char *base = NULL; - - /* Skip if element is entry point */ - if (entryPoint != NULL && element->blkno == entryPoint->blkno && element->offno == entryPoint->offno) - return; - - /* Init fields */ - HnswInitNeighbors(base, element, m, NULL); - element->heaptidsLength = 0; - - /* Find neighbors for element, skipping itself */ - HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, true); - - /* Zero memory for each element */ - MemSet(ntup, 0, HNSW_TUPLE_ALLOC_SIZE); - - /* Update neighbor tuple */ - /* Do this before getting page to minimize locking */ - HnswSetNeighborTuple(base, ntup, element, m); - - /* Get neighbor page */ - buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - - /* Overwrite tuple */ - if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) - elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); - - /* Commit */ - GenericXLogFinish(state); - UnlockReleaseBuffer(buf); - - /* Update neighbors */ - HnswUpdateNeighborsOnDisk(index, procinfo, collation, element, m, true, false); + Relation index = vacuumstate->index; + Buffer buf; + Page page; + GenericXLogState *state; + int m = vacuumstate->m; + int efConstruction = vacuumstate->efConstruction; + FmgrInfo *procinfo = vacuumstate->procinfo; + Oid collation = vacuumstate->collation; + BufferAccessStrategy bas = vacuumstate->bas; + HnswNeighborTuple ntup = vacuumstate->ntup; + Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); + char *base = NULL; + + /* Skip if element is entry point */ + if (entryPoint != NULL && element->blkno == entryPoint->blkno && element->offno == entryPoint->offno) + return; + + /* Init fields */ + HnswInitNeighbors(base, element, m, NULL); + element->heaptidsLength = 0; + + /* Find neighbors for element, skipping itself */ + HnswFindElementNeighbors(base, element, entryPoint, index, procinfo, collation, m, efConstruction, true); + + /* Zero memory for each element */ + MemSet(ntup, 0, HNSW_TUPLE_ALLOC_SIZE); + + /* Update neighbor tuple */ + /* Do this before getting page to minimize locking */ + HnswSetNeighborTuple(base, ntup, element, m); + + /* Get neighbor page */ + buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + + /* Overwrite tuple */ + if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + /* Commit */ + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); + + /* Update neighbors */ + HnswUpdateNeighborsOnDisk(index, procinfo, collation, element, m, true, false); } /* @@ -238,81 +238,81 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme static void RepairGraphEntryPoint(HnswVacuumState * vacuumstate) { - Relation index = vacuumstate->index; - HnswElement highestPoint = &vacuumstate->highestPoint; - HnswElement entryPoint; - MemoryContext oldCtx = MemoryContextSwitchTo(vacuumstate->tmpCtx); - - if (!BlockNumberIsValid(highestPoint->blkno)) - highestPoint = NULL; - - /* - * Repair graph for highest non-entry point. Highest point may be outdated - * due to inserts that happen during and after RemoveHeapTids. - */ - if (highestPoint != NULL) - { - /* Get a shared lock */ - LockPage(index, HNSW_UPDATE_LOCK, ShareLock); - - /* Load element */ - HnswLoadElement(highestPoint, NULL, NULL, index, vacuumstate->procinfo, vacuumstate->collation, true, NULL); - - /* Repair if needed */ - if (NeedsUpdated(vacuumstate, highestPoint)) - RepairGraphElement(vacuumstate, highestPoint, HnswGetEntryPoint(index)); - - /* Release lock */ - UnlockPage(index, HNSW_UPDATE_LOCK, ShareLock); - } - - /* Prevent concurrent inserts when possibly updating entry point */ - LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); - - /* Get latest entry point */ - entryPoint = HnswGetEntryPoint(index); - - if (entryPoint != NULL) - { - ItemPointerData epData; - - ItemPointerSet(&epData, entryPoint->blkno, entryPoint->offno); - - if (DeletedContains(vacuumstate->deleted, &epData)) - { - /* - * Replace the entry point with the highest point. If highest - * point is outdated and empty, the entry point will be empty - * until an element is repaired. - */ - HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_ALWAYS, highestPoint, InvalidBlockNumber, MAIN_FORKNUM, false); - } - else - { - /* - * Repair the entry point with the highest point. If highest point - * is outdated, this can remove connections at higher levels in - * the graph until they are repaired, but this should be fine. - */ - HnswLoadElement(entryPoint, NULL, NULL, index, vacuumstate->procinfo, vacuumstate->collation, true, NULL); - - if (NeedsUpdated(vacuumstate, entryPoint)) - { - /* Reset neighbors from previous update */ - if (highestPoint != NULL) - HnswPtrStore((char *) NULL, highestPoint->neighbors, (HnswNeighborArrayPtr *) NULL); - - RepairGraphElement(vacuumstate, entryPoint, highestPoint); - } - } - } - - /* Release lock */ - UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); - - /* Reset memory context */ - MemoryContextSwitchTo(oldCtx); - MemoryContextReset(vacuumstate->tmpCtx); + Relation index = vacuumstate->index; + HnswElement highestPoint = &vacuumstate->highestPoint; + HnswElement entryPoint; + MemoryContext oldCtx = MemoryContextSwitchTo(vacuumstate->tmpCtx); + + if (!BlockNumberIsValid(highestPoint->blkno)) + highestPoint = NULL; + + /* + * Repair graph for highest non-entry point. Highest point may be outdated + * due to inserts that happen during and after RemoveHeapTids. + */ + if (highestPoint != NULL) + { + /* Get a shared lock */ + LockPage(index, HNSW_UPDATE_LOCK, ShareLock); + + /* Load element */ + HnswLoadElement(highestPoint, NULL, NULL, index, vacuumstate->procinfo, vacuumstate->collation, true, NULL); + + /* Repair if needed */ + if (NeedsUpdated(vacuumstate, highestPoint)) + RepairGraphElement(vacuumstate, highestPoint, HnswGetEntryPoint(index)); + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, ShareLock); + } + + /* Prevent concurrent inserts when possibly updating entry point */ + LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + + /* Get latest entry point */ + entryPoint = HnswGetEntryPoint(index); + + if (entryPoint != NULL) + { + ItemPointerData epData; + + ItemPointerSet(&epData, entryPoint->blkno, entryPoint->offno); + + if (DeletedContains(vacuumstate->deleted, &epData)) + { + /* + * Replace the entry point with the highest point. If highest + * point is outdated and empty, the entry point will be empty + * until an element is repaired. + */ + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_ALWAYS, highestPoint, InvalidBlockNumber, MAIN_FORKNUM, false); + } + else + { + /* + * Repair the entry point with the highest point. If highest point + * is outdated, this can remove connections at higher levels in + * the graph until they are repaired, but this should be fine. + */ + HnswLoadElement(entryPoint, NULL, NULL, index, vacuumstate->procinfo, vacuumstate->collation, true, NULL); + + if (NeedsUpdated(vacuumstate, entryPoint)) + { + /* Reset neighbors from previous update */ + if (highestPoint != NULL) + HnswPtrStore((char *) NULL, highestPoint->neighbors, (HnswNeighborArrayPtr *) NULL); + + RepairGraphElement(vacuumstate, entryPoint, highestPoint); + } + } + } + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(vacuumstate->tmpCtx); } /* @@ -321,113 +321,113 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) static void RepairGraph(HnswVacuumState * vacuumstate) { - Relation index = vacuumstate->index; - BufferAccessStrategy bas = vacuumstate->bas; - BlockNumber blkno = HNSW_HEAD_BLKNO; - - /* - * Wait for inserts to complete. Inserts before this point may have - * neighbors about to be deleted. Inserts after this point will not. - */ - LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); - UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); - - /* Repair entry point first */ - RepairGraphEntryPoint(vacuumstate); - - while (BlockNumberIsValid(blkno)) - { - Buffer buf; - Page page; - OffsetNumber offno; - OffsetNumber maxoffno; - List *elements = NIL; - ListCell *lc2; - MemoryContext oldCtx; - - vacuum_delay_point(); - - oldCtx = MemoryContextSwitchTo(vacuumstate->tmpCtx); - - buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); - LockBuffer(buf, BUFFER_LOCK_SHARE); - page = BufferGetPage(buf); - maxoffno = PageGetMaxOffsetNumber(page); - - /* Load items into memory to minimize locking */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); - HnswElement element; - - /* Skip neighbor tuples */ - if (!HnswIsElementTuple(etup)) - continue; - - /* Skip updating neighbors if being deleted */ - if (!ItemPointerIsValid(&etup->heaptids[0])) - continue; - - /* Create an element */ - element = HnswInitElementFromBlock(blkno, offno); - HnswLoadElementFromTuple(element, etup, false, true); - - elements = lappend(elements, element); - } - - blkno = HnswPageGetOpaque(page)->nextblkno; - - UnlockReleaseBuffer(buf); - - /* Update neighbor pages */ - foreach(lc2, elements) - { - HnswElement element = (HnswElement) lfirst(lc2); - HnswElement entryPoint; - LOCKMODE lockmode = ShareLock; - - /* Check if any neighbors point to deleted values */ - if (!NeedsUpdated(vacuumstate, element)) - continue; - - /* Get a shared lock */ - LockPage(index, HNSW_UPDATE_LOCK, lockmode); - - /* Refresh entry point for each element */ - entryPoint = HnswGetEntryPoint(index); - - /* Prevent concurrent inserts when likely updating entry point */ - if (entryPoint == NULL || element->level > entryPoint->level) - { - /* Release shared lock */ - UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); - - /* Get exclusive lock */ - lockmode = ExclusiveLock; - LockPage(index, HNSW_UPDATE_LOCK, lockmode); - - /* Get latest entry point after lock is acquired */ - entryPoint = HnswGetEntryPoint(index); - } - - /* Repair connections */ - RepairGraphElement(vacuumstate, element, entryPoint); - - /* - * Update metapage if needed. Should only happen if entry point - * was replaced and highest point was outdated. - */ - if (entryPoint == NULL || element->level > entryPoint->level) - HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM, false); - - /* Release lock */ - UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); - } - - /* Reset memory context */ - MemoryContextSwitchTo(oldCtx); - MemoryContextReset(vacuumstate->tmpCtx); - } + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + BlockNumber blkno = HNSW_HEAD_BLKNO; + + /* + * Wait for inserts to complete. Inserts before this point may have + * neighbors about to be deleted. Inserts after this point will not. + */ + LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock); + + /* Repair entry point first */ + RepairGraphEntryPoint(vacuumstate); + + while (BlockNumberIsValid(blkno)) + { + Buffer buf; + Page page; + OffsetNumber offno; + OffsetNumber maxoffno; + List *elements = NIL; + ListCell *lc2; + MemoryContext oldCtx; + + vacuum_delay_point(); + + oldCtx = MemoryContextSwitchTo(vacuumstate->tmpCtx); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + maxoffno = PageGetMaxOffsetNumber(page); + + /* Load items into memory to minimize locking */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswElement element; + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + /* Skip updating neighbors if being deleted */ + if (!ItemPointerIsValid(&etup->heaptids[0])) + continue; + + /* Create an element */ + element = HnswInitElementFromBlock(blkno, offno); + HnswLoadElementFromTuple(element, etup, false, true); + + elements = lappend(elements, element); + } + + blkno = HnswPageGetOpaque(page)->nextblkno; + + UnlockReleaseBuffer(buf); + + /* Update neighbor pages */ + foreach(lc2, elements) + { + HnswElement element = (HnswElement) lfirst(lc2); + HnswElement entryPoint; + LOCKMODE lockmode = ShareLock; + + /* Check if any neighbors point to deleted values */ + if (!NeedsUpdated(vacuumstate, element)) + continue; + + /* Get a shared lock */ + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Refresh entry point for each element */ + entryPoint = HnswGetEntryPoint(index); + + /* Prevent concurrent inserts when likely updating entry point */ + if (entryPoint == NULL || element->level > entryPoint->level) + { + /* Release shared lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get exclusive lock */ + lockmode = ExclusiveLock; + LockPage(index, HNSW_UPDATE_LOCK, lockmode); + + /* Get latest entry point after lock is acquired */ + entryPoint = HnswGetEntryPoint(index); + } + + /* Repair connections */ + RepairGraphElement(vacuumstate, element, entryPoint); + + /* + * Update metapage if needed. Should only happen if entry point + * was replaced and highest point was outdated. + */ + if (entryPoint == NULL || element->level > entryPoint->level) + HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM, false); + + /* Release lock */ + UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); + } + + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(vacuumstate->tmpCtx); + } } /* @@ -436,124 +436,124 @@ RepairGraph(HnswVacuumState * vacuumstate) static void MarkDeleted(HnswVacuumState * vacuumstate) { - BlockNumber blkno = HNSW_HEAD_BLKNO; - BlockNumber insertPage = InvalidBlockNumber; - Relation index = vacuumstate->index; - BufferAccessStrategy bas = vacuumstate->bas; - - /* - * Wait for index scans to complete. Scans before this point may contain - * tuples about to be deleted. Scans after this point will not, since the - * graph has been repaired. - */ - LockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); - UnlockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); - - while (BlockNumberIsValid(blkno)) - { - Buffer buf; - Page page; - GenericXLogState *state; - OffsetNumber offno; - OffsetNumber maxoffno; - - vacuum_delay_point(); - - buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); - - /* - * ambulkdelete cannot delete entries from pages that are pinned by - * other backends - * - * https://www.postgresql.org/docs/current/index-locking.html - */ - LockBufferForCleanup(buf); - - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - maxoffno = PageGetMaxOffsetNumber(page); - - /* Update element and neighbors together */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); - HnswNeighborTuple ntup; - Buffer nbuf; - Page npage; - BlockNumber neighborPage; - OffsetNumber neighborOffno; - - /* Skip neighbor tuples */ - if (!HnswIsElementTuple(etup)) - continue; - - /* Skip deleted tuples */ - if (etup->deleted) - { - /* Set to first free page */ - if (!BlockNumberIsValid(insertPage)) - insertPage = blkno; - - continue; - } - - /* Skip live tuples */ - if (ItemPointerIsValid(&etup->heaptids[0])) - continue; - - /* Get neighbor page */ - neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); - neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - - if (neighborPage == blkno) - { - nbuf = buf; - npage = page; - } - else - { - nbuf = ReadBufferExtended(index, MAIN_FORKNUM, neighborPage, RBM_NORMAL, bas); - LockBuffer(nbuf, BUFFER_LOCK_EXCLUSIVE); - npage = GenericXLogRegisterBuffer(state, nbuf, 0); - } - - ntup = (HnswNeighborTuple) PageGetItem(npage, PageGetItemId(npage, neighborOffno)); - - /* Overwrite element */ - etup->deleted = 1; - MemSet(&etup->data, 0, VARSIZE_ANY(&etup->data)); - - /* Overwrite neighbors */ - for (int i = 0; i < ntup->count; i++) - ItemPointerSetInvalid(&ntup->indextids[i]); - - /* - * We modified the tuples in place, no need to call - * page_index_tuple_overwrite - */ - - /* Commit */ - GenericXLogFinish(state); - if (nbuf != buf) - UnlockReleaseBuffer(nbuf); - - /* Set to first free page */ - if (!BlockNumberIsValid(insertPage)) - insertPage = blkno; - - /* Prepare new xlog */ - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - } - - blkno = HnswPageGetOpaque(page)->nextblkno; - - GenericXLogAbort(state); - UnlockReleaseBuffer(buf); - } - - /* Update insert page last, after everything has been marked as deleted */ - HnswUpdateMetaPage(index, 0, NULL, insertPage, MAIN_FORKNUM, false); + BlockNumber blkno = HNSW_HEAD_BLKNO; + BlockNumber insertPage = InvalidBlockNumber; + Relation index = vacuumstate->index; + BufferAccessStrategy bas = vacuumstate->bas; + + /* + * Wait for index scans to complete. Scans before this point may contain + * tuples about to be deleted. Scans after this point will not, since the + * graph has been repaired. + */ + LockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); + UnlockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); + + while (BlockNumberIsValid(blkno)) + { + Buffer buf; + Page page; + GenericXLogState *state; + OffsetNumber offno; + OffsetNumber maxoffno; + + vacuum_delay_point(); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, blkno, RBM_NORMAL, bas); + + /* + * ambulkdelete cannot delete entries from pages that are pinned by + * other backends + * + * https://www.postgresql.org/docs/current/index-locking.html + */ + LockBufferForCleanup(buf); + + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + maxoffno = PageGetMaxOffsetNumber(page); + + /* Update element and neighbors together */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswNeighborTuple ntup; + Buffer nbuf; + Page npage; + BlockNumber neighborPage; + OffsetNumber neighborOffno; + + /* Skip neighbor tuples */ + if (!HnswIsElementTuple(etup)) + continue; + + /* Skip deleted tuples */ + if (etup->deleted) + { + /* Set to first free page */ + if (!BlockNumberIsValid(insertPage)) + insertPage = blkno; + + continue; + } + + /* Skip live tuples */ + if (ItemPointerIsValid(&etup->heaptids[0])) + continue; + + /* Get neighbor page */ + neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); + neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); + + if (neighborPage == blkno) + { + nbuf = buf; + npage = page; + } + else + { + nbuf = ReadBufferExtended(index, MAIN_FORKNUM, neighborPage, RBM_NORMAL, bas); + LockBuffer(nbuf, BUFFER_LOCK_EXCLUSIVE); + npage = GenericXLogRegisterBuffer(state, nbuf, 0); + } + + ntup = (HnswNeighborTuple) PageGetItem(npage, PageGetItemId(npage, neighborOffno)); + + /* Overwrite element */ + etup->deleted = 1; + MemSet(&etup->data, 0, VARSIZE_ANY(&etup->data)); + + /* Overwrite neighbors */ + for (int i = 0; i < ntup->count; i++) + ItemPointerSetInvalid(&ntup->indextids[i]); + + /* + * We modified the tuples in place, no need to call + * page_index_tuple_overwrite + */ + + /* Commit */ + GenericXLogFinish(state); + if (nbuf != buf) + UnlockReleaseBuffer(nbuf); + + /* Set to first free page */ + if (!BlockNumberIsValid(insertPage)) + insertPage = blkno; + + /* Prepare new xlog */ + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + } + + blkno = HnswPageGetOpaque(page)->nextblkno; + + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + } + + /* Update insert page last, after everything has been marked as deleted */ + HnswUpdateMetaPage(index, 0, NULL, insertPage, MAIN_FORKNUM, false); } /* @@ -562,29 +562,29 @@ MarkDeleted(HnswVacuumState * vacuumstate) static void InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) { - Relation index = info->index; - - if (stats == NULL) - stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); - - vacuumstate->index = index; - vacuumstate->stats = stats; - vacuumstate->callback = callback; - vacuumstate->callback_state = callback_state; - vacuumstate->efConstruction = HnswGetEfConstruction(index); - vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD); - vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); - vacuumstate->collation = index->rd_indcollation[0]; - vacuumstate->ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); - vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, - "Hnsw vacuum temporary context", - ALLOCSET_DEFAULT_SIZES); - - /* Get m from metapage */ - HnswGetMetaPageInfo(index, &vacuumstate->m, NULL); - - /* Create hash table */ - vacuumstate->deleted = tidhash_create(CurrentMemoryContext, 256, NULL); + Relation index = info->index; + + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + + vacuumstate->index = index; + vacuumstate->stats = stats; + vacuumstate->callback = callback; + vacuumstate->callback_state = callback_state; + vacuumstate->efConstruction = HnswGetEfConstruction(index); + vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD); + vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); + vacuumstate->collation = index->rd_indcollation[0]; + vacuumstate->ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); + vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, + "Hnsw vacuum temporary context", + ALLOCSET_DEFAULT_SIZES); + + /* Get m from metapage */ + HnswGetMetaPageInfo(index, &vacuumstate->m, NULL); + + /* Create hash table */ + vacuumstate->deleted = tidhash_create(CurrentMemoryContext, 256, NULL); } /* @@ -593,10 +593,10 @@ InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkD static void FreeVacuumState(HnswVacuumState * vacuumstate) { - tidhash_destroy(vacuumstate->deleted); - FreeAccessStrategy(vacuumstate->bas); - pfree(vacuumstate->ntup); - MemoryContextDelete(vacuumstate->tmpCtx); + tidhash_destroy(vacuumstate->deleted); + FreeAccessStrategy(vacuumstate->bas); + pfree(vacuumstate->ntup); + MemoryContextDelete(vacuumstate->tmpCtx); } /* @@ -604,24 +604,24 @@ FreeVacuumState(HnswVacuumState * vacuumstate) */ IndexBulkDeleteResult * hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) + IndexBulkDeleteCallback callback, void *callback_state) { - HnswVacuumState vacuumstate; + HnswVacuumState vacuumstate; - InitVacuumState(&vacuumstate, info, stats, callback, callback_state); + InitVacuumState(&vacuumstate, info, stats, callback, callback_state); - /* Pass 1: Remove heap TIDs */ - RemoveHeapTids(&vacuumstate); + /* Pass 1: Remove heap TIDs */ + RemoveHeapTids(&vacuumstate); - /* Pass 2: Repair graph */ - RepairGraph(&vacuumstate); + /* Pass 2: Repair graph */ + RepairGraph(&vacuumstate); - /* Pass 3: Mark as deleted */ - MarkDeleted(&vacuumstate); + /* Pass 3: Mark as deleted */ + MarkDeleted(&vacuumstate); - FreeVacuumState(&vacuumstate); + FreeVacuumState(&vacuumstate); - return vacuumstate.stats; + return vacuumstate.stats; } /* @@ -630,17 +630,17 @@ hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteResult * hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { - Relation rel = info->index; + Relation rel = info->index; - if (info->analyze_only) - return stats; + if (info->analyze_only) + return stats; - /* stats is NULL if ambulkdelete not called */ - /* OK to return NULL if index not changed */ - if (stats == NULL) - return NULL; + /* stats is NULL if ambulkdelete not called */ + /* OK to return NULL if index not changed */ + if (stats == NULL) + return NULL; - stats->num_pages = RelationGetNumberOfBlocks(rel); + stats->num_pages = RelationGetNumberOfBlocks(rel); - return stats; + return stats; } diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index b28bd73f33..dffaa2719d 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -134,61 +134,61 @@ SampleRows(IvfflatBuildState *buildstate) static void AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState * buildstate) { - double distance; - double minDistance = DBL_MAX; - int closestCenter = 0; - VectorArray centers = buildstate->centers; - TupleTableSlot *slot = buildstate->slot; - - /* Detoast once for all calls */ - Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); - - /* Normalize if needed */ - if (buildstate->normprocinfo != NULL) - { - if (!IvfflatCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) - return; - - value = IvfflatNormValue(buildstate->typeInfo, buildstate->collation, value); - } - - /* Find the list that minimizes the distance */ - for (int i = 0; i < centers->length; i++) - { - distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, value, PointerGetDatum(VectorArrayGet(centers, i)))); - - if (distance < minDistance) - { - minDistance = distance; - closestCenter = i; - } - } + double distance; + double minDistance = DBL_MAX; + int closestCenter = 0; + VectorArray centers = buildstate->centers; + TupleTableSlot *slot = buildstate->slot; + + /* Detoast once for all calls */ + Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Normalize if needed */ + if (buildstate->normprocinfo != NULL) + { + if (!IvfflatCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) + return; + + value = IvfflatNormValue(buildstate->typeInfo, buildstate->collation, value); + } + + /* Find the list that minimizes the distance */ + for (int i = 0; i < centers->length; i++) + { + distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, value, PointerGetDatum(VectorArrayGet(centers, i)))); + + if (distance < minDistance) + { + minDistance = distance; + closestCenter = i; + } + } #ifdef IVFFLAT_KMEANS_DEBUG - buildstate->inertia += minDistance; - buildstate->listSums[closestCenter] += minDistance; - buildstate->listCounts[closestCenter]++; + buildstate->inertia += minDistance; + buildstate->listSums[closestCenter] += minDistance; + buildstate->listCounts[closestCenter]++; #endif - /* Create a virtual tuple */ - ExecClearTuple(slot); - slot->tts_values[0] = Int32GetDatum(closestCenter); - slot->tts_isnull[0] = false; - slot->tts_values[1] = PointerGetDatum(tid); - slot->tts_isnull[1] = false; - slot->tts_values[2] = value; - slot->tts_isnull[2] = false; - ExecStoreVirtualTuple(slot); - - /* - * Add tuple to sort - * - * tuplesort_puttupleslot comment: Input data is always copied; the caller - * need not save it. - */ - tuplesort_puttupleslot(buildstate->sortstate, slot); - - buildstate->indtuples++; + /* Create a virtual tuple */ + ExecClearTuple(slot); + slot->tts_values[0] = Int32GetDatum(closestCenter); + slot->tts_isnull[0] = false; + slot->tts_values[1] = PointerGetDatum(tid); + slot->tts_isnull[1] = false; + slot->tts_values[2] = value; + slot->tts_isnull[2] = false; + ExecStoreVirtualTuple(slot); + + /* + * Add tuple to sort + * + * tuplesort_puttupleslot comment: Input data is always copied; the caller + * need not save it. + */ + tuplesort_puttupleslot(buildstate->sortstate, slot); + + buildstate->indtuples++; } /* @@ -196,28 +196,28 @@ AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState */ static void BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, - const bool *isnull, bool tupleIsAlive, void *state) + const bool *isnull, bool tupleIsAlive, void *state) { - IvfflatBuildState *buildstate = (IvfflatBuildState *) state; - MemoryContext oldCtx; + IvfflatBuildState *buildstate = (IvfflatBuildState *) state; + MemoryContext oldCtx; #if PG_VERSION_NUM < 130000 - ItemPointer tid = &hup->t_self; + ItemPointer tid = &hup->t_self; #endif - /* Skip nulls */ - if (isnull[0]) - return; + /* Skip nulls */ + if (isnull[0]) + return; - /* Use memory context since detoast can allocate */ - oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); + /* Use memory context since detoast can allocate */ + oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); - /* Add tuple to sort */ - AddTupleToSort(index, tid, values, buildstate); + /* Add tuple to sort */ + AddTupleToSort(index, tid, values, buildstate); - /* Reset memory context */ - MemoryContextSwitchTo(oldCtx); - MemoryContextReset(buildstate->tmpCtx); + /* Reset memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(buildstate->tmpCtx); } /* @@ -226,20 +226,20 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, static inline void GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, IndexTuple *itup, int *list) { - Datum value; - bool isnull; - - if (tuplesort_gettupleslot(sortstate, true, slot, NULL)) - { - *list = DatumGetInt32(heap_slot_getattr(slot, 1, &isnull)); - value = heap_slot_getattr(slot, 3, &isnull); - - /* Form the index tuple */ - *itup = index_form_tuple(tupdesc, &value, &isnull); - (*itup)->t_tid = *((ItemPointer) DatumGetPointer(heap_slot_getattr(slot, 2, &isnull))); - } - else - *list = -1; + Datum value; + bool isnull; + + if (tuplesort_gettupleslot(sortstate, true, slot, NULL)) + { + *list = DatumGetInt32(heap_slot_getattr(slot, 1, &isnull)); + value = heap_slot_getattr(slot, 3, &isnull); + + /* Form the index tuple */ + *itup = index_form_tuple(tupdesc, &value, &isnull); + (*itup)->t_tid = *((ItemPointer) DatumGetPointer(heap_slot_getattr(slot, 2, &isnull))); + } + else + *list = -1; } /* @@ -248,59 +248,59 @@ GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, static void InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) { - int list; - IndexTuple itup = NULL; /* silence compiler warning */ - int64 inserted = 0; + int list; + IndexTuple itup = NULL; /* silence compiler warning */ + int64 inserted = 0; - TupleTableSlot *slot = MakeSingleTupleTableSlot(buildstate->tupdesc); - TupleDesc tupdesc = RelationGetDescr(index); + TupleTableSlot *slot = MakeSingleTupleTableSlot(buildstate->tupdesc); + TupleDesc tupdesc = RelationGetDescr(index); - GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); + GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); - for (int i = 0; i < buildstate->centers->length; i++) - { - Buffer buf; - Page page; - GenericXLogState *state; - BlockNumber startPage; - BlockNumber insertPage; + for (int i = 0; i < buildstate->centers->length; i++) + { + Buffer buf; + Page page; + GenericXLogState *state; + BlockNumber startPage; + BlockNumber insertPage; - /* Can take a while, so ensure we can interrupt */ - /* Needs to be called when no buffer locks are held */ - CHECK_FOR_INTERRUPTS(); + /* Can take a while, so ensure we can interrupt */ + /* Needs to be called when no buffer locks are held */ + CHECK_FOR_INTERRUPTS(); - buf = IvfflatNewBuffer(index, forkNum); - IvfflatInitRegisterPage(index, &buf, &page, &state); + buf = IvfflatNewBuffer(index, forkNum); + IvfflatInitRegisterPage(index, &buf, &page, &state); - startPage = BufferGetBlockNumber(buf); + startPage = BufferGetBlockNumber(buf); - /* Get all tuples for list */ - while (list == i) - { - /* Check for free space */ - Size itemsz = MAXALIGN(IndexTupleSize(itup)); + /* Get all tuples for list */ + while (list == i) + { + /* Check for free space */ + Size itemsz = MAXALIGN(IndexTupleSize(itup)); - if (PageGetFreeSpace(page) < itemsz) - IvfflatAppendPage(index, &buf, &page, &state, forkNum); + if (PageGetFreeSpace(page) < itemsz) + IvfflatAppendPage(index, &buf, &page, &state, forkNum); - /* Add the item */ - if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) - elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + /* Add the item */ + if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); - pfree(itup); + pfree(itup); - UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++inserted); + UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++inserted); - GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); - } + GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); + } - insertPage = BufferGetBlockNumber(buf); + insertPage = BufferGetBlockNumber(buf); - IvfflatCommitBuffer(buf, state); + IvfflatCommitBuffer(buf, state); - /* Set the start and insert pages */ - IvfflatUpdateList(index, buildstate->listInfo[i], insertPage, InvalidBlockNumber, startPage, forkNum); - } + /* Set the start and insert pages */ + IvfflatUpdateList(index, buildstate->listInfo[i], insertPage, InvalidBlockNumber, startPage, forkNum); + } } /* @@ -309,59 +309,59 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) static void InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, IndexInfo *indexInfo) { - buildstate->heap = heap; - buildstate->index = index; - buildstate->indexInfo = indexInfo; - buildstate->typeInfo = IvfflatGetTypeInfo(index); + buildstate->heap = heap; + buildstate->index = index; + buildstate->indexInfo = indexInfo; + buildstate->typeInfo = IvfflatGetTypeInfo(index); - buildstate->lists = IvfflatGetLists(index); - buildstate->dimensions = TupleDescAttr(index->rd_att, 0)->atttypmod; + buildstate->lists = IvfflatGetLists(index); + buildstate->dimensions = TupleDescAttr(index->rd_att, 0)->atttypmod; - /* Disallow varbit since require fixed dimensions */ - if (TupleDescAttr(index->rd_att, 0)->atttypid == VARBITOID) - elog(ERROR, "type not supported for ivfflat index"); + /* Disallow varbit since require fixed dimensions */ + if (TupleDescAttr(index->rd_att, 0)->atttypid == VARBITOID) + elog(ERROR, "type not supported for ivfflat index"); - /* Require column to have dimensions to be indexed */ - if (buildstate->dimensions < 0) - elog(ERROR, "column does not have dimensions"); + /* Require column to have dimensions to be indexed */ + if (buildstate->dimensions < 0) + elog(ERROR, "column does not have dimensions"); - if (buildstate->dimensions > buildstate->typeInfo->maxDimensions) - elog(ERROR, "column cannot have more than %d dimensions for ivfflat index", buildstate->typeInfo->maxDimensions); + if (buildstate->dimensions > buildstate->typeInfo->maxDimensions) + elog(ERROR, "column cannot have more than %d dimensions for ivfflat index", buildstate->typeInfo->maxDimensions); - buildstate->reltuples = 0; - buildstate->indtuples = 0; + buildstate->reltuples = 0; + buildstate->indtuples = 0; - /* Get support functions */ - buildstate->procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC); - buildstate->normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); - buildstate->kmeansnormprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); - buildstate->collation = index->rd_indcollation[0]; + /* Get support functions */ + buildstate->procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC); + buildstate->normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + buildstate->kmeansnormprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); + buildstate->collation = index->rd_indcollation[0]; - /* Require more than one dimension for spherical k-means */ - if (buildstate->kmeansnormprocinfo != NULL && buildstate->dimensions == 1) - elog(ERROR, "dimensions must be greater than one for this opclass"); + /* Require more than one dimension for spherical k-means */ + if (buildstate->kmeansnormprocinfo != NULL && buildstate->dimensions == 1) + elog(ERROR, "dimensions must be greater than one for this opclass"); - /* Create tuple description for sorting */ - buildstate->tupdesc = CreateTemplateTupleDesc(3, false); - TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 1, "list", INT4OID, -1, 0); - TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 2, "tid", TIDOID, -1, 0); - TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 3, "vector", RelationGetDescr(index)->attrs[0].atttypid, -1, 0); + /* Create tuple description for sorting */ + buildstate->tupdesc = CreateTemplateTupleDesc(3, false); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 1, "list", INT4OID, -1, 0); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 2, "tid", TIDOID, -1, 0); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 3, "vector", RelationGetDescr(index)->attrs[0].atttypid, -1, 0); - buildstate->slot = MakeSingleTupleTableSlot(buildstate->tupdesc); + buildstate->slot = MakeSingleTupleTableSlot(buildstate->tupdesc); - buildstate->centers = VectorArrayInit(buildstate->lists, buildstate->dimensions, buildstate->typeInfo->itemSize(buildstate->dimensions)); - buildstate->listInfo = (ListInfo *)palloc(sizeof(ListInfo) * buildstate->lists); + buildstate->centers = VectorArrayInit(buildstate->lists, buildstate->dimensions, buildstate->typeInfo->itemSize(buildstate->dimensions)); + buildstate->listInfo = (ListInfo *)palloc(sizeof(ListInfo) * buildstate->lists); - buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat build temporary context", - ALLOCSET_DEFAULT_SIZES); + buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat build temporary context", + ALLOCSET_DEFAULT_SIZES); #ifdef IVFFLAT_KMEANS_DEBUG - buildstate->inertia = 0; - buildstate->listSums = palloc0(sizeof(double) * buildstate->lists); - buildstate->listCounts = palloc0(sizeof(int) * buildstate->lists); + buildstate->inertia = 0; + buildstate->listSums = palloc0(sizeof(double) * buildstate->lists); + buildstate->listCounts = palloc0(sizeof(int) * buildstate->lists); #endif - buildstate->ivfleader = NULL; + buildstate->ivfleader = NULL; } /* @@ -370,15 +370,15 @@ InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, In static void FreeBuildState(IvfflatBuildState * buildstate) { - VectorArrayFree(buildstate->centers); - pfree(buildstate->listInfo); + VectorArrayFree(buildstate->centers); + pfree(buildstate->listInfo); #ifdef IVFFLAT_KMEANS_DEBUG - pfree(buildstate->listSums); - pfree(buildstate->listCounts); + pfree(buildstate->listSums); + pfree(buildstate->listCounts); #endif - MemoryContextDelete(buildstate->tmpCtx); + MemoryContextDelete(buildstate->tmpCtx); } /* @@ -428,24 +428,24 @@ ComputeCenters(IvfflatBuildState *buildstate) static void CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) { - Buffer buf; - Page page; - GenericXLogState *state; - IvfflatMetaPage metap; - - buf = IvfflatNewBuffer(index, forkNum); - IvfflatInitRegisterPage(index, &buf, &page, &state); - - /* Set metapage data */ - metap = IvfflatPageGetMeta(page); - metap->magicNumber = IVFFLAT_MAGIC_NUMBER; - metap->version = IVFFLAT_VERSION; - metap->dimensions = dimensions; - metap->lists = lists; - ((PageHeader) page)->pd_lower = - ((char *) metap + sizeof(IvfflatMetaPageData)) - (char *) page; - - IvfflatCommitBuffer(buf, state); + Buffer buf; + Page page; + GenericXLogState *state; + IvfflatMetaPage metap; + + buf = IvfflatNewBuffer(index, forkNum); + IvfflatInitRegisterPage(index, &buf, &page, &state); + + /* Set metapage data */ + metap = IvfflatPageGetMeta(page); + metap->magicNumber = IVFFLAT_MAGIC_NUMBER; + metap->version = IVFFLAT_VERSION; + metap->dimensions = dimensions; + metap->lists = lists; + ((PageHeader) page)->pd_lower = + ((char *) metap + sizeof(IvfflatMetaPageData)) - (char *) page; + + IvfflatCommitBuffer(buf, state); } /* @@ -453,49 +453,49 @@ CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) */ static void CreateListPages(Relation index, VectorArray centers, int dimensions, - int lists, ForkNumber forkNum, ListInfo * *listInfo) + int lists, ForkNumber forkNum, ListInfo * *listInfo) { - Buffer buf; - Page page; - GenericXLogState *state; - Size listSize; - IvfflatList list; - - listSize = MAXALIGN(IVFFLAT_LIST_SIZE(centers->itemsize)); - list = (IvfflatList)palloc0(listSize); - - buf = IvfflatNewBuffer(index, forkNum); - IvfflatInitRegisterPage(index, &buf, &page, &state); - - for (int i = 0; i < lists; i++) - { - OffsetNumber offno; - - /* Zero memory for each list */ - MemSet(list, 0, listSize); - - /* Load list */ - list->startPage = InvalidBlockNumber; - list->insertPage = InvalidBlockNumber; - memcpy(&list->center, VectorArrayGet(centers, i), VARSIZE_ANY(VectorArrayGet(centers, i))); - - /* Ensure free space */ - if (PageGetFreeSpace(page) < listSize) - IvfflatAppendPage(index, &buf, &page, &state, forkNum); - - /* Add the item */ - offno = PageAddItem(page, (Item) list, listSize, InvalidOffsetNumber, false, false); - if (offno == InvalidOffsetNumber) - elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); - - /* Save location info */ - (*listInfo)[i].blkno = BufferGetBlockNumber(buf); - (*listInfo)[i].offno = offno; - } + Buffer buf; + Page page; + GenericXLogState *state; + Size listSize; + IvfflatList list; + + listSize = MAXALIGN(IVFFLAT_LIST_SIZE(centers->itemsize)); + list = (IvfflatList)palloc0(listSize); + + buf = IvfflatNewBuffer(index, forkNum); + IvfflatInitRegisterPage(index, &buf, &page, &state); + + for (int i = 0; i < lists; i++) + { + OffsetNumber offno; + + /* Zero memory for each list */ + MemSet(list, 0, listSize); + + /* Load list */ + list->startPage = InvalidBlockNumber; + list->insertPage = InvalidBlockNumber; + memcpy(&list->center, VectorArrayGet(centers, i), VARSIZE_ANY(VectorArrayGet(centers, i))); + + /* Ensure free space */ + if (PageGetFreeSpace(page) < listSize) + IvfflatAppendPage(index, &buf, &page, &state, forkNum); + + /* Add the item */ + offno = PageAddItem(page, (Item) list, listSize, InvalidOffsetNumber, false, false); + if (offno == InvalidOffsetNumber) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + /* Save location info */ + (*listInfo)[i].blkno = BufferGetBlockNumber(buf); + (*listInfo)[i].offno = offno; + } - IvfflatCommitBuffer(buf, state); + IvfflatCommitBuffer(buf, state); - pfree(list); + pfree(list); } #ifdef IVFFLAT_KMEANS_DEBUG @@ -505,41 +505,41 @@ CreateListPages(Relation index, VectorArray centers, int dimensions, static void PrintKmeansMetrics(IvfflatBuildState * buildstate) { - elog(INFO, "inertia: %.3e", buildstate->inertia); - - /* Calculate Davies-Bouldin index */ - if (buildstate->lists > 1) - { - double db = 0.0; - - /* Calculate average distance */ - for (int i = 0; i < buildstate->lists; i++) - { - if (buildstate->listCounts[i] > 0) - buildstate->listSums[i] /= buildstate->listCounts[i]; - } - - for (int i = 0; i < buildstate->lists; i++) - { - double max = 0.0; - double distance; - - for (int j = 0; j < buildstate->lists; j++) - { - if (j == i) - continue; - - distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, PointerGetDatum(VectorArrayGet(buildstate->centers, i)), PointerGetDatum(VectorArrayGet(buildstate->centers, j)))); - distance = (buildstate->listSums[i] + buildstate->listSums[j]) / distance; - - if (distance > max) - max = distance; - } - db += max; - } - db /= buildstate->lists; - elog(INFO, "davies-bouldin: %.3f", db); - } + elog(INFO, "inertia: %.3e", buildstate->inertia); + + /* Calculate Davies-Bouldin index */ + if (buildstate->lists > 1) + { + double db = 0.0; + + /* Calculate average distance */ + for (int i = 0; i < buildstate->lists; i++) + { + if (buildstate->listCounts[i] > 0) + buildstate->listSums[i] /= buildstate->listCounts[i]; + } + + for (int i = 0; i < buildstate->lists; i++) + { + double max = 0.0; + double distance; + + for (int j = 0; j < buildstate->lists; j++) + { + if (j == i) + continue; + + distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, PointerGetDatum(VectorArrayGet(buildstate->centers, i)), PointerGetDatum(VectorArrayGet(buildstate->centers, j)))); + distance = (buildstate->listSums[i] + buildstate->listSums[j]) / distance; + + if (distance > max) + max = distance; + } + db += max; + } + db /= buildstate->lists; + elog(INFO, "davies-bouldin: %.3f", db); + } } #endif @@ -549,24 +549,24 @@ PrintKmeansMetrics(IvfflatBuildState * buildstate) static double ParallelHeapScan(IvfflatBuildState * buildstate) { - IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; - double reltuples; + IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; + double reltuples; - BgworkerListWaitFinish(&buildstate->ivfleader->nparticipanttuplesorts); - pg_memory_barrier(); + BgworkerListWaitFinish(&buildstate->ivfleader->nparticipanttuplesorts); + pg_memory_barrier(); - /*all done, update to the actual number of participants*/ - if (ivfshared->sharedsort != NULL) { - ivfshared->sharedsort->actualParticipants = buildstate->ivfleader->nparticipanttuplesorts; - } + /*all done, update to the actual number of participants*/ + if (ivfshared->sharedsort != NULL) { + ivfshared->sharedsort->actualParticipants = buildstate->ivfleader->nparticipanttuplesorts; + } - buildstate->indtuples = ivfshared->indtuples; - reltuples = ivfshared->reltuples; + buildstate->indtuples = ivfshared->indtuples; + reltuples = ivfshared->reltuples; #ifdef IVFFLAT_KMEANS_DEBUG - buildstate->inertia = ivfshared->inertia; + buildstate->inertia = ivfshared->inertia; #endif - return reltuples; + return reltuples; } /* @@ -575,56 +575,56 @@ ParallelHeapScan(IvfflatBuildState * buildstate) static void IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, Vector *ivfcenters) { - SortCoordinate coordinate; - IvfflatBuildState buildstate; - TableScanDesc scan; - double reltuples; - IndexInfo *indexInfo; - - /* Sort options, which must match AssignTuples */ - AttrNumber attNums[] = {1}; - Oid sortOperators[] = {INT4LTOID}; - Oid sortCollations[] = {InvalidOid}; - bool nullsFirstFlags[] = {false}; - - /* Initialize local tuplesort coordination state */ - coordinate = (SortCoordinate)palloc0(sizeof(SortCoordinateData)); - coordinate->isWorker = true; - coordinate->nParticipants = -1; - coordinate->sharedsort = ivfshared->sharedsort; - - int sortmem = ivfshared->workmem / ivfshared->scantuplesortstates; - - /* Join parallel scan */ - indexInfo = BuildIndexInfo(ivfspool->index); - indexInfo->ii_Concurrent = false; - InitBuildState(&buildstate, ivfspool->heap, ivfspool->index, indexInfo); - memcpy(buildstate.centers->items, ivfcenters, VECTOR_SIZE(buildstate.centers->dim) * buildstate.centers->maxlen); - buildstate.centers->length = buildstate.centers->maxlen; - ivfspool->sortstate = tuplesort_begin_heap(buildstate.tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, sortmem, false, 0, 0, 1, coordinate); - buildstate.sortstate = ivfspool->sortstate; - - scan = tableam_scan_begin_parallel(ivfspool->heap, &ivfshared->heapdesc); - reltuples = tableam_index_build_scan(ivfspool->heap, ivfspool->index, indexInfo, - true, BuildCallback, (void *) &buildstate, scan); - - /* Execute this worker's part of the sort */ - tuplesort_performsort(ivfspool->sortstate); - - /* Record statistics */ - SpinLockAcquire(&ivfshared->mutex); - ivfshared->nparticipantsdone++; - ivfshared->reltuples += reltuples; - ivfshared->indtuples += buildstate.indtuples; + SortCoordinate coordinate; + IvfflatBuildState buildstate; + TableScanDesc scan; + double reltuples; + IndexInfo *indexInfo; + + /* Sort options, which must match AssignTuples */ + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {INT4LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; + + /* Initialize local tuplesort coordination state */ + coordinate = (SortCoordinate)palloc0(sizeof(SortCoordinateData)); + coordinate->isWorker = true; + coordinate->nParticipants = -1; + coordinate->sharedsort = ivfshared->sharedsort; + + int sortmem = ivfshared->workmem / ivfshared->scantuplesortstates; + + /* Join parallel scan */ + indexInfo = BuildIndexInfo(ivfspool->index); + indexInfo->ii_Concurrent = false; + InitBuildState(&buildstate, ivfspool->heap, ivfspool->index, indexInfo); + memcpy(buildstate.centers->items, ivfcenters, VECTOR_SIZE(buildstate.centers->dim) * buildstate.centers->maxlen); + buildstate.centers->length = buildstate.centers->maxlen; + ivfspool->sortstate = tuplesort_begin_heap(buildstate.tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, sortmem, false, 0, 0, 1, coordinate); + buildstate.sortstate = ivfspool->sortstate; + + scan = tableam_scan_begin_parallel(ivfspool->heap, &ivfshared->heapdesc); + reltuples = tableam_index_build_scan(ivfspool->heap, ivfspool->index, indexInfo, + true, BuildCallback, (void *) &buildstate, scan); + + /* Execute this worker's part of the sort */ + tuplesort_performsort(ivfspool->sortstate); + + /* Record statistics */ + SpinLockAcquire(&ivfshared->mutex); + ivfshared->nparticipantsdone++; + ivfshared->reltuples += reltuples; + ivfshared->indtuples += buildstate.indtuples; #ifdef IVFFLAT_KMEANS_DEBUG - ivfshared->inertia += buildstate.inertia; + ivfshared->inertia += buildstate.inertia; #endif - SpinLockRelease(&ivfshared->mutex); + SpinLockRelease(&ivfshared->mutex); - /* We can end tuplesorts immediately */ - tuplesort_end(ivfspool->sortstate); + /* We can end tuplesorts immediately */ + tuplesort_end(ivfspool->sortstate); - FreeBuildState(&buildstate); + FreeBuildState(&buildstate); } /* @@ -633,27 +633,27 @@ IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, V void IvfflatParallelBuildMain(const BgWorkerContext *bwc) { - IvfflatSpool *ivfspool; - IvfflatShared *ivfshared; - Relation heapRel; - Relation indexRel; + IvfflatSpool *ivfspool; + IvfflatShared *ivfshared; + Relation heapRel; + Relation indexRel; - ivfshared = (IvfflatShared*)bwc->bgshared; + ivfshared = (IvfflatShared*)bwc->bgshared; - /* Open relations within worker */ - heapRel = heap_open(ivfshared->heaprelid, NoLock); - indexRel = index_open(ivfshared->indexrelid, NoLock); + /* Open relations within worker */ + heapRel = heap_open(ivfshared->heaprelid, NoLock); + indexRel = index_open(ivfshared->indexrelid, NoLock); - /* Initialize worker's own spool */ - ivfspool = (IvfflatSpool *) palloc0(sizeof(IvfflatSpool)); - ivfspool->heap = heapRel; - ivfspool->index = indexRel; + /* Initialize worker's own spool */ + ivfspool = (IvfflatSpool *) palloc0(sizeof(IvfflatSpool)); + ivfspool->heap = heapRel; + ivfspool->index = indexRel; - IvfflatParallelScanAndSort(ivfspool, ivfshared, ivfshared->ivfcenters); + IvfflatParallelScanAndSort(ivfspool, ivfshared, ivfshared->ivfcenters); - /* Close relations within worker */ - index_close(indexRel, NoLock); - heap_close(heapRel, NoLock); + /* Close relations within worker */ + index_close(indexRel, NoLock); + heap_close(heapRel, NoLock); } /* @@ -662,54 +662,54 @@ IvfflatParallelBuildMain(const BgWorkerContext *bwc) static void IvfflatParallelCleanup(const BgWorkerContext *bwc) { - IvfflatShared *ivfshared = (IvfflatShared*)bwc->bgshared; + IvfflatShared *ivfshared = (IvfflatShared*)bwc->bgshared; - /* delete shared fileset */ - Assert(ivfshared->sharedsort); - SharedFileSetDeleteAll(&ivfshared->sharedsort->fileset); - pfree_ext(ivfshared->sharedsort); + /* delete shared fileset */ + Assert(ivfshared->sharedsort); + SharedFileSetDeleteAll(&ivfshared->sharedsort->fileset); + pfree_ext(ivfshared->sharedsort); } static IvfflatShared* IvfflatParallelInitshared(IvfflatBuildState * buildstate, int workmem, int scantuplesortstates) { - IvfflatShared *ivfshared; - Sharedsort *sharedsort; - Size estsort; - Size estcenters; - char *ivfcenters; + IvfflatShared *ivfshared; + Sharedsort *sharedsort; + Size estsort; + Size estcenters; + char *ivfcenters; - /* Store shared build state, for which we reserved space */ - ivfshared = (IvfflatShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(IvfflatShared)); + /* Store shared build state, for which we reserved space */ + ivfshared = (IvfflatShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(IvfflatShared)); /* Initialize immutable state */ - ivfshared->heaprelid = RelationGetRelid(buildstate->heap); - ivfshared->indexrelid = RelationGetRelid(buildstate->index); - ivfshared->scantuplesortstates = scantuplesortstates; - SpinLockInit(&ivfshared->mutex); - - /* Initialize mutable state */ - ivfshared->nparticipantsdone = 0; - ivfshared->reltuples = 0; - ivfshared->indtuples = 0; - ivfshared->workmem = workmem; + ivfshared->heaprelid = RelationGetRelid(buildstate->heap); + ivfshared->indexrelid = RelationGetRelid(buildstate->index); + ivfshared->scantuplesortstates = scantuplesortstates; + SpinLockInit(&ivfshared->mutex); + + /* Initialize mutable state */ + ivfshared->nparticipantsdone = 0; + ivfshared->reltuples = 0; + ivfshared->indtuples = 0; + ivfshared->workmem = workmem; #ifdef IVFFLAT_KMEANS_DEBUG - ivfshared->inertia = 0; + ivfshared->inertia = 0; #endif - HeapParallelscanInitialize(&ivfshared->heapdesc, buildstate->heap); + HeapParallelscanInitialize(&ivfshared->heapdesc, buildstate->heap); - /* Store shared tuplesort-private state, for which we reserved space */ - estsort = tuplesort_estimate_shared(scantuplesortstates); - sharedsort = (Sharedsort *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estsort); - tuplesort_initialize_shared(sharedsort, scantuplesortstates); - ivfshared->sharedsort = sharedsort; + /* Store shared tuplesort-private state, for which we reserved space */ + estsort = tuplesort_estimate_shared(scantuplesortstates); + sharedsort = (Sharedsort *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estsort); + tuplesort_initialize_shared(sharedsort, scantuplesortstates); + ivfshared->sharedsort = sharedsort; - estcenters = VECTOR_SIZE(buildstate->dimensions) * buildstate->lists; - ivfcenters = (char *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estcenters); - memcpy(ivfcenters, buildstate->centers->items, estcenters); - ivfshared->ivfcenters = (Vector*)ivfcenters; + estcenters = VECTOR_SIZE(buildstate->dimensions) * buildstate->lists; + ivfcenters = (char *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estcenters); + memcpy(ivfcenters, buildstate->centers->items, estcenters); + ivfshared->ivfcenters = (Vector*)ivfcenters; - return ivfshared; + return ivfshared; } /* @@ -718,52 +718,52 @@ IvfflatParallelInitshared(IvfflatBuildState * buildstate, int workmem, int scant static void IvfflatBeginParallel(IvfflatBuildState * buildstate, int request, int workmem) { - IvfflatShared *ivfshared; - IvfflatLeader *ivfleader = (IvfflatLeader *) palloc0(sizeof(IvfflatLeader)); + IvfflatShared *ivfshared; + IvfflatLeader *ivfleader = (IvfflatLeader *) palloc0(sizeof(IvfflatLeader)); - Assert(request > 0); - ivfshared = IvfflatParallelInitshared(buildstate, workmem, request); + Assert(request > 0); + ivfshared = IvfflatParallelInitshared(buildstate, workmem, request); - /* Launch workers, saving status for leader/caller */ - ivfleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, ivfshared, IvfflatParallelBuildMain, IvfflatParallelCleanup); + /* Launch workers, saving status for leader/caller */ + ivfleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, ivfshared, IvfflatParallelBuildMain, IvfflatParallelCleanup); - /* If no workers were successfully launched, back out (do serial build) */ - if (ivfleader->nparticipanttuplesorts == 0) - { - pfree_ext(ivfshared); - pfree_ext(ivfleader); - return; - } + /* If no workers were successfully launched, back out (do serial build) */ + if (ivfleader->nparticipanttuplesorts == 0) + { + pfree_ext(ivfshared); + pfree_ext(ivfleader); + return; + } - /* Log participants */ - ereport(DEBUG1, (errmsg("using %d parallel workers", ivfleader->nparticipanttuplesorts))); + /* Log participants */ + ereport(DEBUG1, (errmsg("using %d parallel workers", ivfleader->nparticipanttuplesorts))); - ivfleader->ivfshared = ivfshared; - /* Save leader state now that it's clear build will be parallel */ - buildstate->ivfleader = ivfleader; + ivfleader->ivfshared = ivfshared; + /* Save leader state now that it's clear build will be parallel */ + buildstate->ivfleader = ivfleader; } static double AssignTupleUtility(IvfflatBuildState * buildstate) { - Relation heap = buildstate->heap; - Relation index = buildstate->index; - IndexInfo *indexInfo = buildstate->indexInfo; - double reltuples = 0; + Relation heap = buildstate->heap; + Relation index = buildstate->index; + IndexInfo *indexInfo = buildstate->indexInfo; + double reltuples = 0; - /* Fill spool using either serial or parallel heap scan */ - if (!buildstate->ivfleader) { + /* Fill spool using either serial or parallel heap scan */ + if (!buildstate->ivfleader) { serial_build: - reltuples = tableam_index_build_scan(heap, index, indexInfo, true, BuildCallback, (void*)buildstate, NULL); - } else { - reltuples = ParallelHeapScan(buildstate); - IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; - int nruns = ivfshared->sharedsort->actualParticipants; - if (nruns == 0) { - /* failed to startup any bgworker, retry to do serial build */ - goto serial_build; - } - } - return reltuples; + reltuples = tableam_index_build_scan(heap, index, indexInfo, true, BuildCallback, (void*)buildstate, NULL); + } else { + reltuples = ParallelHeapScan(buildstate); + IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; + int nruns = ivfshared->sharedsort->actualParticipants; + if (nruns == 0) { + /* failed to startup any bgworker, retry to do serial build */ + goto serial_build; + } + } + return reltuples; } /* @@ -771,7 +771,7 @@ serial_build: */ void IvfflatEndParallel() { - BgworkerListSyncQuit(); + BgworkerListSyncQuit(); } /* @@ -780,53 +780,53 @@ void IvfflatEndParallel() static void AssignTuples(IvfflatBuildState * buildstate) { - SortCoordinate coordinate = NULL; - int parallel_workers = 0; - IndexInfo *indexInfo = buildstate->indexInfo; - UtilityDesc *desc = &indexInfo->ii_desc; - int workmem; - - /* Sort options, which must match IvfflatParallelScanAndSort */ - AttrNumber attNums[] = {1}; - Oid sortOperators[] = {INT4LTOID}; - Oid sortCollations[] = {InvalidOid}; - bool nullsFirstFlags[] = {false}; - - workmem = (desc->query_mem[0] > 0) ? (desc->query_mem[0] - SIMPLE_THRESHOLD) : - u_sess->attr.attr_memory.maintenance_work_mem; - - /* Calculate parallel workers */ - if (buildstate->heap != NULL) - parallel_workers = PlanCreateIndexWorkers(buildstate->heap, indexInfo); - - /* Attempt to launch parallel worker scan when required */ - if (parallel_workers > 0) { - Assert(!indexInfo->ii_Concurrent); - IvfflatBeginParallel(buildstate, parallel_workers,workmem); - } - - /* Set up coordination state if at least one worker launched */ - if (buildstate->ivfleader) - { - coordinate = (SortCoordinate) palloc0(sizeof(SortCoordinateData)); - coordinate->isWorker = false; - coordinate->nParticipants = buildstate->ivfleader->nparticipanttuplesorts; - coordinate->sharedsort = buildstate->ivfleader->ivfshared->sharedsort; - } - - /* Begin serial/leader tuplesort */ - buildstate->sortstate = tuplesort_begin_heap(buildstate->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, - u_sess->attr.attr_memory.maintenance_work_mem, false, 0, 0, 1, coordinate); - - /* Add tuples to sort */ - if (buildstate->heap != NULL) - { - buildstate->reltuples = AssignTupleUtility(buildstate); + SortCoordinate coordinate = NULL; + int parallel_workers = 0; + IndexInfo *indexInfo = buildstate->indexInfo; + UtilityDesc *desc = &indexInfo->ii_desc; + int workmem; + + /* Sort options, which must match IvfflatParallelScanAndSort */ + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {INT4LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; + + workmem = (desc->query_mem[0] > 0) ? (desc->query_mem[0] - SIMPLE_THRESHOLD) : + u_sess->attr.attr_memory.maintenance_work_mem; + + /* Calculate parallel workers */ + if (buildstate->heap != NULL) + parallel_workers = PlanCreateIndexWorkers(buildstate->heap, indexInfo); + + /* Attempt to launch parallel worker scan when required */ + if (parallel_workers > 0) { + Assert(!indexInfo->ii_Concurrent); + IvfflatBeginParallel(buildstate, parallel_workers,workmem); + } + + /* Set up coordination state if at least one worker launched */ + if (buildstate->ivfleader) + { + coordinate = (SortCoordinate) palloc0(sizeof(SortCoordinateData)); + coordinate->isWorker = false; + coordinate->nParticipants = buildstate->ivfleader->nparticipanttuplesorts; + coordinate->sharedsort = buildstate->ivfleader->ivfshared->sharedsort; + } + + /* Begin serial/leader tuplesort */ + buildstate->sortstate = tuplesort_begin_heap(buildstate->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, + u_sess->attr.attr_memory.maintenance_work_mem, false, 0, 0, 1, coordinate); + + /* Add tuples to sort */ + if (buildstate->heap != NULL) + { + buildstate->reltuples = AssignTupleUtility(buildstate); #ifdef IVFFLAT_KMEANS_DEBUG - PrintKmeansMetrics(buildstate); + PrintKmeansMetrics(buildstate); #endif - } + } } /* @@ -835,21 +835,21 @@ AssignTuples(IvfflatBuildState * buildstate) static void CreateEntryPages(IvfflatBuildState * buildstate, ForkNumber forkNum) { - /* Assign */ - IvfflatBench("assign tuples", AssignTuples(buildstate)); + /* Assign */ + IvfflatBench("assign tuples", AssignTuples(buildstate)); - /* Sort */ - IvfflatBench("sort tuples", tuplesort_performsort(buildstate->sortstate)); + /* Sort */ + IvfflatBench("sort tuples", tuplesort_performsort(buildstate->sortstate)); - /* Load */ - IvfflatBench("load tuples", InsertTuples(buildstate->index, buildstate, forkNum)); + /* Load */ + IvfflatBench("load tuples", InsertTuples(buildstate->index, buildstate, forkNum)); - /* End sort */ - tuplesort_end(buildstate->sortstate); + /* End sort */ + tuplesort_end(buildstate->sortstate); - /* End parallel build */ - if (buildstate->ivfleader) - IvfflatEndParallel(); + /* End parallel build */ + if (buildstate->ivfleader) + IvfflatEndParallel(); } /* @@ -857,22 +857,22 @@ CreateEntryPages(IvfflatBuildState * buildstate, ForkNumber forkNum) */ static void BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, - IvfflatBuildState * buildstate, ForkNumber forkNum) + IvfflatBuildState * buildstate, ForkNumber forkNum) { - InitBuildState(buildstate, heap, index, indexInfo); + InitBuildState(buildstate, heap, index, indexInfo); - ComputeCenters(buildstate); + ComputeCenters(buildstate); - /* Create pages */ - CreateMetaPage(index, buildstate->dimensions, buildstate->lists, forkNum); - CreateListPages(index, buildstate->centers, buildstate->dimensions, buildstate->lists, forkNum, &buildstate->listInfo); - CreateEntryPages(buildstate, forkNum); + /* Create pages */ + CreateMetaPage(index, buildstate->dimensions, buildstate->lists, forkNum); + CreateListPages(index, buildstate->centers, buildstate->dimensions, buildstate->lists, forkNum, &buildstate->listInfo); + CreateEntryPages(buildstate, forkNum); - /* Write WAL for initialization fork since GenericXLog functions do not */ - if (forkNum == INIT_FORKNUM) - log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); + /* Write WAL for initialization fork since GenericXLog functions do not */ + if (forkNum == INIT_FORKNUM) + log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); - FreeBuildState(buildstate); + FreeBuildState(buildstate); } /* @@ -881,16 +881,16 @@ BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, IndexBuildResult * ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) { - IndexBuildResult *result; - IvfflatBuildState buildstate; + IndexBuildResult *result; + IvfflatBuildState buildstate; - BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); + BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); - result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); - result->heap_tuples = buildstate.reltuples; - result->index_tuples = buildstate.indtuples; + result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + result->heap_tuples = buildstate.reltuples; + result->index_tuples = buildstate.indtuples; - return result; + return result; } /* @@ -899,8 +899,8 @@ ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) void ivfflatbuildempty_internal(Relation index) { - IndexInfo *indexInfo = BuildIndexInfo(index); - IvfflatBuildState buildstate; + IndexInfo *indexInfo = BuildIndexInfo(index); + IvfflatBuildState buildstate; - BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); + BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); } diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index 41c2e8f59b..caf57ceae8 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -19,13 +19,13 @@ static THR_LOCAL bool IvfflatNeedInitialization = true; void IvfflatInit(void) { - ivfflat_relopt_kind = add_reloption_kind(); - add_int_reloption(ivfflat_relopt_kind, "lists", "Number of inverted lists", - IVFFLAT_DEFAULT_LISTS, IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS + ivfflat_relopt_kind = add_reloption_kind(); + add_int_reloption(ivfflat_relopt_kind, "lists", "Number of inverted lists", + IVFFLAT_DEFAULT_LISTS, IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS #if PG_VERSION_NUM >= 130000 - ,AccessExclusiveLock + ,AccessExclusiveLock #endif - ); + ); } /* @@ -117,8 +117,8 @@ ivfflatoptions_internal(Datum reloptions, bool validate) #if PG_VERSION_NUM >= 130000 return (bytea *) build_reloptions(reloptions, validate, ivfflat_relopt_kind, - sizeof(IvfflatOptions), - tab, lengthof(tab)); + sizeof(IvfflatOptions), + tab, lengthof(tab)); #else relopt_value *options; int numoptions; @@ -144,7 +144,7 @@ ivfflatoptions_internal(Datum reloptions, bool validate) static bool ivfflatvalidate_internal(Oid opclassoid) { - return true; + return true; } /* @@ -156,210 +156,210 @@ PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflathandler); Datum ivfflathandler(PG_FUNCTION_ARGS) { - IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); + IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); - amroutine->amstrategies = 0; - amroutine->amsupport = 5; + amroutine->amstrategies = 0; + amroutine->amsupport = 5; #if PG_VERSION_NUM >= 130000 - amroutine->amoptsprocnum = 0; + amroutine->amoptsprocnum = 0; #endif - amroutine->amcanorder = false; - amroutine->amcanorderbyop = true; - amroutine->amcanbackward = false; /* can change direction mid-scan */ - amroutine->amcanunique = false; - amroutine->amcanmulticol = false; - amroutine->amoptionalkey = true; - amroutine->amsearcharray = false; - amroutine->amsearchnulls = false; - amroutine->amstorage = false; - amroutine->amclusterable = false; - amroutine->ampredlocks = false; - amroutine->amcanparallel = false; - amroutine->amcaninclude = false; + amroutine->amcanorder = false; + amroutine->amcanorderbyop = true; + amroutine->amcanbackward = false; /* can change direction mid-scan */ + amroutine->amcanunique = false; + amroutine->amcanmulticol = false; + amroutine->amoptionalkey = true; + amroutine->amsearcharray = false; + amroutine->amsearchnulls = false; + amroutine->amstorage = false; + amroutine->amclusterable = false; + amroutine->ampredlocks = false; + amroutine->amcanparallel = false; + amroutine->amcaninclude = false; #if PG_VERSION_NUM >= 130000 - amroutine->amusemaintenanceworkmem = false; /* not used during VACUUM */ - amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL; + amroutine->amusemaintenanceworkmem = false; /* not used during VACUUM */ + amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL; #endif - amroutine->amkeytype = InvalidOid; - - /* Interface functions */ - errno_t rc; - rc = strcpy_s(amroutine->ambuildfuncname, NAMEDATALEN, "ivfflatbuild"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->ambuildemptyfuncname, NAMEDATALEN, "ivfflatbuildempty"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->aminsertfuncname, NAMEDATALEN, "ivfflatinsert"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->ambulkdeletefuncname, NAMEDATALEN, "ivfflatbulkdelete"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->amvacuumcleanupfuncname, NAMEDATALEN, "ivfflatvacuumcleanup"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->amcostestimatefuncname, NAMEDATALEN, "ivfflatcostestimate"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->amoptionsfuncname, NAMEDATALEN, "ivfflatoptions"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->amvalidatefuncname, NAMEDATALEN, "ivfflatvalidate"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->ambeginscanfuncname, NAMEDATALEN, "ivfflatbeginscan"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->amrescanfuncname, NAMEDATALEN, "ivfflatrescan"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->amgettuplefuncname, NAMEDATALEN, "ivfflatgettuple"); - securec_check(rc, "\0", "\0"); - rc = strcpy_s(amroutine->amendscanfuncname, NAMEDATALEN, "ivfflatendscan"); - securec_check(rc, "\0", "\0"); - - PG_RETURN_POINTER(amroutine); + amroutine->amkeytype = InvalidOid; + + /* Interface functions */ + errno_t rc; + rc = strcpy_s(amroutine->ambuildfuncname, NAMEDATALEN, "ivfflatbuild"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambuildemptyfuncname, NAMEDATALEN, "ivfflatbuildempty"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->aminsertfuncname, NAMEDATALEN, "ivfflatinsert"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambulkdeletefuncname, NAMEDATALEN, "ivfflatbulkdelete"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amvacuumcleanupfuncname, NAMEDATALEN, "ivfflatvacuumcleanup"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amcostestimatefuncname, NAMEDATALEN, "ivfflatcostestimate"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amoptionsfuncname, NAMEDATALEN, "ivfflatoptions"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amvalidatefuncname, NAMEDATALEN, "ivfflatvalidate"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->ambeginscanfuncname, NAMEDATALEN, "ivfflatbeginscan"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amrescanfuncname, NAMEDATALEN, "ivfflatrescan"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amgettuplefuncname, NAMEDATALEN, "ivfflatgettuple"); + securec_check(rc, "\0", "\0"); + rc = strcpy_s(amroutine->amendscanfuncname, NAMEDATALEN, "ivfflatendscan"); + securec_check(rc, "\0", "\0"); + + PG_RETURN_POINTER(amroutine); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbuild); Datum ivfflatbuild(PG_FUNCTION_ARGS) { - Relation heap = (Relation)PG_GETARG_POINTER(0); - Relation index = (Relation)PG_GETARG_POINTER(1); - IndexInfo *indexinfo = (IndexInfo *)PG_GETARG_POINTER(2); - IndexBuildResult *result = ivfflatbuild_internal(heap, index, indexinfo); + Relation heap = (Relation)PG_GETARG_POINTER(0); + Relation index = (Relation)PG_GETARG_POINTER(1); + IndexInfo *indexinfo = (IndexInfo *)PG_GETARG_POINTER(2); + IndexBuildResult *result = ivfflatbuild_internal(heap, index, indexinfo); - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbuildempty); Datum ivfflatbuildempty(PG_FUNCTION_ARGS) { - Relation index = (Relation)PG_GETARG_POINTER(0); - ivfflatbuildempty_internal(index); + Relation index = (Relation)PG_GETARG_POINTER(0); + ivfflatbuildempty_internal(index); - PG_RETURN_VOID(); + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatinsert); Datum ivfflatinsert(PG_FUNCTION_ARGS) { - Relation rel = (Relation)PG_GETARG_POINTER(0); - Datum * values = (Datum *)PG_GETARG_POINTER(1); - bool *isnull = (bool *)PG_GETARG_POINTER(2); - ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); - Relation heaprel = (Relation)PG_GETARG_POINTER(4); - IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); - bool result = ivfflatinsert_internal(rel, values, isnull, ht_ctid, heaprel, checkunique); - - PG_RETURN_BOOL(result); + Relation rel = (Relation)PG_GETARG_POINTER(0); + Datum * values = (Datum *)PG_GETARG_POINTER(1); + bool *isnull = (bool *)PG_GETARG_POINTER(2); + ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); + Relation heaprel = (Relation)PG_GETARG_POINTER(4); + IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); + bool result = ivfflatinsert_internal(rel, values, isnull, ht_ctid, heaprel, checkunique); + + PG_RETURN_BOOL(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbulkdelete); Datum ivfflatbulkdelete(PG_FUNCTION_ARGS) { - IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); - IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); - IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); - void *callback_state = (void *)PG_GETARG_POINTER(3); - stats = ivfflatbulkdelete_internal(info, stats, callback, callback_state); + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); + void *callback_state = (void *)PG_GETARG_POINTER(3); + stats = ivfflatbulkdelete_internal(info, stats, callback, callback_state); - PG_RETURN_POINTER(stats); + PG_RETURN_POINTER(stats); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatvacuumcleanup); Datum ivfflatvacuumcleanup(PG_FUNCTION_ARGS) { - IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); - IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); - stats = ivfflatvacuumcleanup_internal(info, stats); + IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); + IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); + stats = ivfflatvacuumcleanup_internal(info, stats); - PG_RETURN_POINTER(stats); + PG_RETURN_POINTER(stats); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatcostestimate); Datum ivfflatcostestimate(PG_FUNCTION_ARGS) { - PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); - IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); - double loopcount = (double)PG_GETARG_FLOAT8(2); - Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); - Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); - Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); - double *correlation = (double *)PG_GETARG_POINTER(6); - ivfflatcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); - - PG_RETURN_VOID(); + PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); + IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); + double loopcount = (double)PG_GETARG_FLOAT8(2); + Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); + Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); + Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); + double *correlation = (double *)PG_GETARG_POINTER(6); + ivfflatcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); + + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatoptions); Datum ivfflatoptions(PG_FUNCTION_ARGS) { - Datum reloptions = PG_GETARG_DATUM(0); - bool validate = PG_GETARG_BOOL(1); - bytea *result = ivfflatoptions_internal(reloptions, validate); + Datum reloptions = PG_GETARG_DATUM(0); + bool validate = PG_GETARG_BOOL(1); + bytea *result = ivfflatoptions_internal(reloptions, validate); - if (NULL != result) - PG_RETURN_BYTEA_P(result); + if (NULL != result) + PG_RETURN_BYTEA_P(result); - PG_RETURN_NULL(); + PG_RETURN_NULL(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatvalidate); Datum ivfflatvalidate(PG_FUNCTION_ARGS) { - Oid opclassoid = PG_GETARG_OID(0); - bool result = ivfflatvalidate_internal(opclassoid); + Oid opclassoid = PG_GETARG_OID(0); + bool result = ivfflatvalidate_internal(opclassoid); - PG_RETURN_BOOL(result); + PG_RETURN_BOOL(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbeginscan); Datum ivfflatbeginscan(PG_FUNCTION_ARGS) { - Relation rel = (Relation)PG_GETARG_POINTER(0); - int nkeys = PG_GETARG_INT32(1); - int norderbys = PG_GETARG_INT32(2); - IndexScanDesc scan = ivfflatbeginscan_internal(rel, nkeys, norderbys); + Relation rel = (Relation)PG_GETARG_POINTER(0); + int nkeys = PG_GETARG_INT32(1); + int norderbys = PG_GETARG_INT32(2); + IndexScanDesc scan = ivfflatbeginscan_internal(rel, nkeys, norderbys); - PG_RETURN_POINTER(scan); + PG_RETURN_POINTER(scan); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatrescan); Datum ivfflatrescan(PG_FUNCTION_ARGS) { - IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); - ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); - int nkeys = PG_GETARG_INT32(2); - ScanKey orderbys = (ScanKey)PG_GETARG_POINTER(3); - int norderbys = PG_GETARG_INT32(4); - ivfflatrescan_internal(scan, scankey, nkeys, orderbys, norderbys); - - PG_RETURN_VOID(); + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); + int nkeys = PG_GETARG_INT32(2); + ScanKey orderbys = (ScanKey)PG_GETARG_POINTER(3); + int norderbys = PG_GETARG_INT32(4); + ivfflatrescan_internal(scan, scankey, nkeys, orderbys, norderbys); + + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatgettuple); Datum ivfflatgettuple(PG_FUNCTION_ARGS) { - IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); - ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); - if (NULL == scan) - ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function ivfflatgettuple"))); + if (NULL == scan) + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function ivfflatgettuple"))); - bool result = ivfflatgettuple_internal(scan, direction); + bool result = ivfflatgettuple_internal(scan, direction); - PG_RETURN_BOOL(result); + PG_RETURN_BOOL(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatendscan); Datum ivfflatendscan(PG_FUNCTION_ARGS) { - IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); - ivfflatendscan_internal(scan); + IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); + ivfflatendscan_internal(scan); - PG_RETURN_VOID(); + PG_RETURN_VOID(); } diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp index aa53fc013d..68afddbb87 100644 --- a/src/gausskernel/storage/access/datavec/ivfinsert.cpp +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -14,51 +14,51 @@ static void FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo * listInfo) { - double minDistance = DBL_MAX; - BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; - FmgrInfo *procinfo; - Oid collation; - - /* Avoid compiler warning */ - listInfo->blkno = nextblkno; - listInfo->offno = FirstOffsetNumber; - - procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC); - collation = index->rd_indcollation[0]; - - /* Search all list pages */ - while (BlockNumberIsValid(nextblkno)) - { - Buffer cbuf; - Page cpage; - OffsetNumber maxoffno; - - cbuf = ReadBuffer(index, nextblkno); - LockBuffer(cbuf, BUFFER_LOCK_SHARE); - cpage = BufferGetPage(cbuf); - maxoffno = PageGetMaxOffsetNumber(cpage); - - for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - IvfflatList list; - double distance; - - list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); - distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, values[0], PointerGetDatum(&list->center))); - - if (distance < minDistance || !BlockNumberIsValid(*insertPage)) - { - *insertPage = list->insertPage; - listInfo->blkno = nextblkno; - listInfo->offno = offno; - minDistance = distance; - } - } - - nextblkno = IvfflatPageGetOpaque(cpage)->nextblkno; - - UnlockReleaseBuffer(cbuf); - } + double minDistance = DBL_MAX; + BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; + FmgrInfo *procinfo; + Oid collation; + + /* Avoid compiler warning */ + listInfo->blkno = nextblkno; + listInfo->offno = FirstOffsetNumber; + + procinfo = index_getprocinfo(index, 1, IVFFLAT_DISTANCE_PROC); + collation = index->rd_indcollation[0]; + + /* Search all list pages */ + while (BlockNumberIsValid(nextblkno)) + { + Buffer cbuf; + Page cpage; + OffsetNumber maxoffno; + + cbuf = ReadBuffer(index, nextblkno); + LockBuffer(cbuf, BUFFER_LOCK_SHARE); + cpage = BufferGetPage(cbuf); + maxoffno = PageGetMaxOffsetNumber(cpage); + + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IvfflatList list; + double distance; + + list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); + distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, values[0], PointerGetDatum(&list->center))); + + if (distance < minDistance || !BlockNumberIsValid(*insertPage)) + { + *insertPage = list->insertPage; + listInfo->blkno = nextblkno; + listInfo->offno = offno; + minDistance = distance; + } + } + + nextblkno = IvfflatPageGetOpaque(cpage)->nextblkno; + + UnlockReleaseBuffer(cbuf); + } } /* @@ -67,112 +67,112 @@ FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo static void InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heapRel) { - const IvfflatTypeInfo *typeInfo = IvfflatGetTypeInfo(index); - IndexTuple itup; - Datum value; - FmgrInfo *normprocinfo; - Buffer buf; - Page page; - GenericXLogState *state; - Size itemsz; - BlockNumber insertPage = InvalidBlockNumber; - ListInfo listInfo; - BlockNumber originalInsertPage; - - /* Detoast once for all calls */ - value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); - - /* Normalize if needed */ - normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); - if (normprocinfo != NULL) - { - Oid collation = index->rd_indcollation[0]; - - if (!IvfflatCheckNorm(normprocinfo, collation, value)) - return; - - value = IvfflatNormValue(typeInfo, collation, value); - } - - /* Ensure index is valid */ - IvfflatGetMetaPageInfo(index, NULL, NULL); - - /* Find the insert page - sets the page and list info */ - FindInsertPage(index, values, &insertPage, &listInfo); - Assert(BlockNumberIsValid(insertPage)); - originalInsertPage = insertPage; - - /* Form tuple */ - itup = index_form_tuple(RelationGetDescr(index), &value, isnull); - itup->t_tid = *heap_tid; - - /* Get tuple size */ - itemsz = MAXALIGN(IndexTupleSize(itup)); - Assert(itemsz <= BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)) - sizeof(ItemIdData)); - - /* Find a page to insert the item */ - for (;;) - { - buf = ReadBuffer(index, insertPage); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - - if (PageGetFreeSpace(page) >= itemsz) - break; - - insertPage = IvfflatPageGetOpaque(page)->nextblkno; - - if (BlockNumberIsValid(insertPage)) - { - /* Move to next page */ - GenericXLogAbort(state); - UnlockReleaseBuffer(buf); - } - else - { - Buffer newbuf; - Page newpage; - - /* Add a new page */ - LockRelationForExtension(index, ExclusiveLock); - newbuf = IvfflatNewBuffer(index, MAIN_FORKNUM); - UnlockRelationForExtension(index, ExclusiveLock); - - /* Init new page */ - newpage = GenericXLogRegisterBuffer(state, newbuf, GENERIC_XLOG_FULL_IMAGE); - IvfflatInitPage(newbuf, newpage); - - /* Update insert page */ - insertPage = BufferGetBlockNumber(newbuf); - - /* Update previous buffer */ - IvfflatPageGetOpaque(page)->nextblkno = insertPage; - - /* Commit */ - GenericXLogFinish(state); - - /* Unlock previous buffer */ - UnlockReleaseBuffer(buf); - - /* Prepare new buffer */ - state = GenericXLogStart(index); - buf = newbuf; - page = GenericXLogRegisterBuffer(state, buf, 0); - break; - } - } - - /* Add to next offset */ - if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) - elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); - - IvfflatCommitBuffer(buf, state); - - /* Update the insert page */ - if (insertPage != originalInsertPage) - IvfflatUpdateList(index, listInfo, insertPage, originalInsertPage, InvalidBlockNumber, MAIN_FORKNUM); + const IvfflatTypeInfo *typeInfo = IvfflatGetTypeInfo(index); + IndexTuple itup; + Datum value; + FmgrInfo *normprocinfo; + Buffer buf; + Page page; + GenericXLogState *state; + Size itemsz; + BlockNumber insertPage = InvalidBlockNumber; + ListInfo listInfo; + BlockNumber originalInsertPage; + + /* Detoast once for all calls */ + value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + + /* Normalize if needed */ + normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + if (normprocinfo != NULL) + { + Oid collation = index->rd_indcollation[0]; + + if (!IvfflatCheckNorm(normprocinfo, collation, value)) + return; + + value = IvfflatNormValue(typeInfo, collation, value); + } + + /* Ensure index is valid */ + IvfflatGetMetaPageInfo(index, NULL, NULL); + + /* Find the insert page - sets the page and list info */ + FindInsertPage(index, values, &insertPage, &listInfo); + Assert(BlockNumberIsValid(insertPage)); + originalInsertPage = insertPage; + + /* Form tuple */ + itup = index_form_tuple(RelationGetDescr(index), &value, isnull); + itup->t_tid = *heap_tid; + + /* Get tuple size */ + itemsz = MAXALIGN(IndexTupleSize(itup)); + Assert(itemsz <= BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)) - sizeof(ItemIdData)); + + /* Find a page to insert the item */ + for (;;) + { + buf = ReadBuffer(index, insertPage); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + + if (PageGetFreeSpace(page) >= itemsz) + break; + + insertPage = IvfflatPageGetOpaque(page)->nextblkno; + + if (BlockNumberIsValid(insertPage)) + { + /* Move to next page */ + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + } + else + { + Buffer newbuf; + Page newpage; + + /* Add a new page */ + LockRelationForExtension(index, ExclusiveLock); + newbuf = IvfflatNewBuffer(index, MAIN_FORKNUM); + UnlockRelationForExtension(index, ExclusiveLock); + + /* Init new page */ + newpage = GenericXLogRegisterBuffer(state, newbuf, GENERIC_XLOG_FULL_IMAGE); + IvfflatInitPage(newbuf, newpage); + + /* Update insert page */ + insertPage = BufferGetBlockNumber(newbuf); + + /* Update previous buffer */ + IvfflatPageGetOpaque(page)->nextblkno = insertPage; + + /* Commit */ + GenericXLogFinish(state); + + /* Unlock previous buffer */ + UnlockReleaseBuffer(buf); + + /* Prepare new buffer */ + state = GenericXLogStart(index); + buf = newbuf; + page = GenericXLogRegisterBuffer(state, buf, 0); + break; + } + } + + /* Add to next offset */ + if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) + elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); + + IvfflatCommitBuffer(buf, state); + + /* Update the insert page */ + if (insertPage != originalInsertPage) + IvfflatUpdateList(index, listInfo, insertPage, originalInsertPage, InvalidBlockNumber, MAIN_FORKNUM); } /* @@ -181,28 +181,28 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ bool ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique) { - MemoryContext oldCtx; - MemoryContext insertCtx; - - /* Skip nulls */ - if (isnull[0]) - return false; - - /* - * Use memory context since detoast, IvfflatNormValue, and - * index_form_tuple can allocate - */ - insertCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat insert temporary context", - ALLOCSET_DEFAULT_SIZES); - oldCtx = MemoryContextSwitchTo(insertCtx); - - /* Insert tuple */ - InsertTuple(index, values, isnull, heap_tid, heap); - - /* Delete memory context */ - MemoryContextSwitchTo(oldCtx); - MemoryContextDelete(insertCtx); - - return false; + MemoryContext oldCtx; + MemoryContext insertCtx; + + /* Skip nulls */ + if (isnull[0]) + return false; + + /* + * Use memory context since detoast, IvfflatNormValue, and + * index_form_tuple can allocate + */ + insertCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat insert temporary context", + ALLOCSET_DEFAULT_SIZES); + oldCtx = MemoryContextSwitchTo(insertCtx); + + /* Insert tuple */ + InsertTuple(index, values, isnull, heap_tid, heap); + + /* Delete memory context */ + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(insertCtx); + + return false; } diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index f196b80599..6eec852195 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -21,71 +21,71 @@ static void InitCenters(Relation index, VectorArray samples, VectorArray centers, float *lowerBound) { - FmgrInfo *procinfo; - Oid collation; - int64 j; - float *weight = (float *)palloc(samples->length * sizeof(float)); - int numCenters = centers->maxlen; - int numSamples = samples->length; + FmgrInfo *procinfo; + Oid collation; + int64 j; + float *weight = (float *)palloc(samples->length * sizeof(float)); + int numCenters = centers->maxlen; + int numSamples = samples->length; - procinfo = index_getprocinfo(index, 1, IVFFLAT_KMEANS_DISTANCE_PROC); - collation = index->rd_indcollation[0]; + procinfo = index_getprocinfo(index, 1, IVFFLAT_KMEANS_DISTANCE_PROC); + collation = index->rd_indcollation[0]; - /* Choose an initial center uniformly at random */ - VectorArraySet(centers, 0, VectorArrayGet(samples, RandomInt() % samples->length)); - centers->length++; + /* Choose an initial center uniformly at random */ + VectorArraySet(centers, 0, VectorArrayGet(samples, RandomInt() % samples->length)); + centers->length++; - for (j = 0; j < numSamples; j++) - weight[j] = FLT_MAX; + for (j = 0; j < numSamples; j++) + weight[j] = FLT_MAX; - for (int i = 0; i < numCenters; i++) - { - double sum; - double choice; + for (int i = 0; i < numCenters; i++) + { + double sum; + double choice; - CHECK_FOR_INTERRUPTS(); + CHECK_FOR_INTERRUPTS(); - sum = 0.0; + sum = 0.0; - for (j = 0; j < numSamples; j++) - { - Datum vec = PointerGetDatum(VectorArrayGet(samples, j)); - double distance; + for (j = 0; j < numSamples; j++) + { + Datum vec = PointerGetDatum(VectorArrayGet(samples, j)); + double distance; - /* Only need to compute distance for new center */ - /* TODO Use triangle inequality to reduce distance calculations */ - distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, i)))); + /* Only need to compute distance for new center */ + /* TODO Use triangle inequality to reduce distance calculations */ + distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, i)))); - /* Set lower bound */ - lowerBound[j * numCenters + i] = distance; + /* Set lower bound */ + lowerBound[j * numCenters + i] = distance; - /* Use distance squared for weighted probability distribution */ - distance *= distance; + /* Use distance squared for weighted probability distribution */ + distance *= distance; - if (distance < weight[j]) - weight[j] = distance; + if (distance < weight[j]) + weight[j] = distance; - sum += weight[j]; - } + sum += weight[j]; + } - /* Only compute lower bound on last iteration */ - if (i + 1 == numCenters) - break; + /* Only compute lower bound on last iteration */ + if (i + 1 == numCenters) + break; - /* Choose new center using weighted probability distribution. */ - choice = sum * RandomDouble(); - for (j = 0; j < numSamples - 1; j++) - { - choice -= weight[j]; - if (choice <= 0) - break; - } + /* Choose new center using weighted probability distribution. */ + choice = sum * RandomDouble(); + for (j = 0; j < numSamples - 1; j++) + { + choice -= weight[j]; + if (choice <= 0) + break; + } - VectorArraySet(centers, i + 1, VectorArrayGet(samples, j)); - centers->length++; - } + VectorArraySet(centers, i + 1, VectorArrayGet(samples, j)); + centers->length++; + } - pfree(weight); + pfree(weight); } /* @@ -94,26 +94,26 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low static void NormCenters(const IvfflatTypeInfo * typeInfo, Oid collation, VectorArray centers) { - MemoryContext normCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat norm temporary context", - ALLOCSET_DEFAULT_SIZES); - MemoryContext oldCtx = MemoryContextSwitchTo(normCtx); - - for (int j = 0; j < centers->length; j++) - { - Datum center = PointerGetDatum(VectorArrayGet(centers, j)); - Datum newCenter = IvfflatNormValue(typeInfo, collation, center); - Size size = VARSIZE_ANY(DatumGetPointer(newCenter)); - - if (size > centers->itemsize) - elog(ERROR, "safety check failed"); - - memcpy(DatumGetPointer(center), DatumGetPointer(newCenter), size); - MemoryContextReset(normCtx); - } - - MemoryContextSwitchTo(oldCtx); - MemoryContextDelete(normCtx); + MemoryContext normCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat norm temporary context", + ALLOCSET_DEFAULT_SIZES); + MemoryContext oldCtx = MemoryContextSwitchTo(normCtx); + + for (int j = 0; j < centers->length; j++) + { + Datum center = PointerGetDatum(VectorArrayGet(centers, j)); + Datum newCenter = IvfflatNormValue(typeInfo, collation, center); + Size size = VARSIZE_ANY(DatumGetPointer(newCenter)); + + if (size > centers->itemsize) + elog(ERROR, "safety check failed"); + + memcpy(DatumGetPointer(center), DatumGetPointer(newCenter), size); + MemoryContextReset(normCtx); + } + + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(normCtx); } /* @@ -122,26 +122,26 @@ NormCenters(const IvfflatTypeInfo * typeInfo, Oid collation, VectorArray centers static void RandomCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - int dimensions = centers->dim; - FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); - Oid collation = index->rd_indcollation[0]; - float *x = (float *) palloc(sizeof(float) * dimensions); + int dimensions = centers->dim; + FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); + Oid collation = index->rd_indcollation[0]; + float *x = (float *) palloc(sizeof(float) * dimensions); - /* Fill with random data */ - while (centers->length < centers->maxlen) - { - Pointer center = VectorArrayGet(centers, centers->length); + /* Fill with random data */ + while (centers->length < centers->maxlen) + { + Pointer center = VectorArrayGet(centers, centers->length); - for (int i = 0; i < dimensions; i++) - x[i] = (float) RandomDouble(); + for (int i = 0; i < dimensions; i++) + x[i] = (float) RandomDouble(); - typeInfo->updateCenter(center, dimensions, x); + typeInfo->updateCenter(center, dimensions, x); - centers->length++; - } + centers->length++; + } - if (normprocinfo != NULL) - NormCenters(typeInfo, collation, centers); + if (normprocinfo != NULL) + NormCenters(typeInfo, collation, centers); } #ifdef IVFFLAT_MEMORY @@ -152,12 +152,12 @@ static void ShowMemoryUsage(MemoryContext context, Size estimatedSize) { #if PG_VERSION_NUM >= 130000 - elog(INFO, "total memory: %zu MB", - MemoryContextMemAllocated(context, true) / (1024 * 1024)); + elog(INFO, "total memory: %zu MB", + MemoryContextMemAllocated(context, true) / (1024 * 1024)); #else - MemoryContextStats(context); + MemoryContextStats(context); #endif - elog(INFO, "estimated memory: %zu MB", estimatedSize / (1024 * 1024)); + elog(INFO, "estimated memory: %zu MB", estimatedSize / (1024 * 1024)); } #endif @@ -167,12 +167,12 @@ ShowMemoryUsage(MemoryContext context, Size estimatedSize) static void SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTypeInfo * typeInfo) { - for (int j = 0; j < samples->length; j++) - { - float *x = agg + ((int64) closestCenters[j] * samples->dim); + for (int j = 0; j < samples->length; j++) + { + float *x = agg + ((int64) closestCenters[j] * samples->dim); - typeInfo->sumCenter(VectorArrayGet(samples, j), x); - } + typeInfo->sumCenter(VectorArrayGet(samples, j), x); + } } /* @@ -181,12 +181,12 @@ SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTy static void UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - for (int j = 0; j < centers->length; j++) - { - float *x = agg + ((int64) j * centers->dim); + for (int j = 0; j < centers->length; j++) + { + float *x = agg + ((int64) j * centers->dim); - typeInfo->updateCenter(VectorArrayGet(centers, j), centers->dim, x); - } + typeInfo->updateCenter(VectorArrayGet(centers, j), centers->dim, x); + } } /* @@ -195,60 +195,60 @@ UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo) static void ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *centerCounts, int *closestCenters, FmgrInfo *normprocinfo, Oid collation, const IvfflatTypeInfo * typeInfo) { - int dimensions = newCenters->dim; - int numCenters = newCenters->length; - int numSamples = samples->length; - - /* Reset sum and count */ - for (int j = 0; j < numCenters; j++) - { - float *x = agg + ((int64) j * dimensions); - - for (int k = 0; k < dimensions; k++) - x[k] = 0.0; - - centerCounts[j] = 0; - } - - /* Increment sum of closest center */ - SumCenters(samples, agg, closestCenters, typeInfo); - - /* Increment count of closest center */ - for (int j = 0; j < numSamples; j++) - centerCounts[closestCenters[j]] += 1; - - /* Divide sum by count */ - for (int j = 0; j < numCenters; j++) - { - float *x = agg + ((int64) j * dimensions); - - if (centerCounts[j] > 0) - { - /* Double avoids overflow, but requires more memory */ - /* TODO Update bounds */ - for (int k = 0; k < dimensions; k++) - { - if (isinf(x[k])) - x[k] = x[k] > 0 ? FLT_MAX : -FLT_MAX; - } - - for (int k = 0; k < dimensions; k++) - x[k] /= centerCounts[j]; - } - else - { - /* TODO Handle empty centers properly */ - for (int k = 0; k < dimensions; k++) - x[k] = RandomDouble(); - } - } - - /* Set new centers */ - UpdateCenters(agg, newCenters, typeInfo); - - /* Normalize if needed */ - if (normprocinfo != NULL) - NormCenters(typeInfo, collation, newCenters); + int dimensions = newCenters->dim; + int numCenters = newCenters->length; + int numSamples = samples->length; + + /* Reset sum and count */ + for (int j = 0; j < numCenters; j++) + { + float *x = agg + ((int64) j * dimensions); + + for (int k = 0; k < dimensions; k++) + x[k] = 0.0; + + centerCounts[j] = 0; + } + + /* Increment sum of closest center */ + SumCenters(samples, agg, closestCenters, typeInfo); + + /* Increment count of closest center */ + for (int j = 0; j < numSamples; j++) + centerCounts[closestCenters[j]] += 1; + + /* Divide sum by count */ + for (int j = 0; j < numCenters; j++) + { + float *x = agg + ((int64) j * dimensions); + + if (centerCounts[j] > 0) + { + /* Double avoids overflow, but requires more memory */ + /* TODO Update bounds */ + for (int k = 0; k < dimensions; k++) + { + if (isinf(x[k])) + x[k] = x[k] > 0 ? FLT_MAX : -FLT_MAX; + } + + for (int k = 0; k < dimensions; k++) + x[k] /= centerCounts[j]; + } + else + { + /* TODO Handle empty centers properly */ + for (int k = 0; k < dimensions; k++) + x[k] = RandomDouble(); + } + } + + /* Set new centers */ + UpdateCenters(agg, newCenters, typeInfo); + + /* Normalize if needed */ + if (normprocinfo != NULL) + NormCenters(typeInfo, collation, newCenters); } /* @@ -262,239 +262,239 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int * static void ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - Oid collation; - int dimensions = centers->dim; - int numCenters = centers->maxlen; - int numSamples = samples->length; - VectorArray newCenters; - float *agg; - int *centerCounts; - int *closestCenters; - float *lowerBound; - float *upperBound; - float *s; - float *halfcdist; - float *newcdist; - - /* Calculate allocation sizes */ - Size samplesSize = VECTOR_ARRAY_SIZE(samples->maxlen, samples->itemsize); - Size centersSize = VECTOR_ARRAY_SIZE(centers->maxlen, centers->itemsize); - Size newCentersSize = VECTOR_ARRAY_SIZE(numCenters, centers->itemsize); - Size aggSize = sizeof(float) * (int64) numCenters * dimensions; - Size centerCountsSize = sizeof(int) * numCenters; - Size closestCentersSize = sizeof(int) * numSamples; - Size lowerBoundSize = sizeof(float) * numSamples * numCenters; - Size upperBoundSize = sizeof(float) * numSamples; - Size sSize = sizeof(float) * numCenters; - Size halfcdistSize = sizeof(float) * numCenters * numCenters; - Size newcdistSize = sizeof(float) * numCenters; - - /* Calculate total size */ - Size totalSize = samplesSize + centersSize + newCentersSize + aggSize + centerCountsSize + closestCentersSize + lowerBoundSize + upperBoundSize + sSize + halfcdistSize + newcdistSize; - - /* Check memory requirements */ - /* Add one to error message to ceil */ - if (totalSize > (Size) u_sess->attr.attr_memory.maintenance_work_mem * 1024L) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("memory required is %zu MB, maintenance_work_mem is %d MB", - totalSize / (1024 * 1024) + 1, u_sess->attr.attr_memory.maintenance_work_mem / 1024))); - - /* Ensure indexing does not overflow */ - if (numCenters * numCenters > INT_MAX) - elog(ERROR, "Indexing overflow detected. Please report a bug."); - - /* Set support functions */ - procinfo = index_getprocinfo(index, 1, IVFFLAT_KMEANS_DISTANCE_PROC); - normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); - collation = index->rd_indcollation[0]; - - /* Allocate space */ - /* Use float instead of double to save memory */ - agg = (float *)palloc(aggSize); - centerCounts = (int *)palloc(centerCountsSize); - closestCenters = (int *)palloc(closestCentersSize); + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + int dimensions = centers->dim; + int numCenters = centers->maxlen; + int numSamples = samples->length; + VectorArray newCenters; + float *agg; + int *centerCounts; + int *closestCenters; + float *lowerBound; + float *upperBound; + float *s; + float *halfcdist; + float *newcdist; + + /* Calculate allocation sizes */ + Size samplesSize = VECTOR_ARRAY_SIZE(samples->maxlen, samples->itemsize); + Size centersSize = VECTOR_ARRAY_SIZE(centers->maxlen, centers->itemsize); + Size newCentersSize = VECTOR_ARRAY_SIZE(numCenters, centers->itemsize); + Size aggSize = sizeof(float) * (int64) numCenters * dimensions; + Size centerCountsSize = sizeof(int) * numCenters; + Size closestCentersSize = sizeof(int) * numSamples; + Size lowerBoundSize = sizeof(float) * numSamples * numCenters; + Size upperBoundSize = sizeof(float) * numSamples; + Size sSize = sizeof(float) * numCenters; + Size halfcdistSize = sizeof(float) * numCenters * numCenters; + Size newcdistSize = sizeof(float) * numCenters; + + /* Calculate total size */ + Size totalSize = samplesSize + centersSize + newCentersSize + aggSize + centerCountsSize + closestCentersSize + lowerBoundSize + upperBoundSize + sSize + halfcdistSize + newcdistSize; + + /* Check memory requirements */ + /* Add one to error message to ceil */ + if (totalSize > (Size) u_sess->attr.attr_memory.maintenance_work_mem * 1024L) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("memory required is %zu MB, maintenance_work_mem is %d MB", + totalSize / (1024 * 1024) + 1, u_sess->attr.attr_memory.maintenance_work_mem / 1024))); + + /* Ensure indexing does not overflow */ + if (numCenters * numCenters > INT_MAX) + elog(ERROR, "Indexing overflow detected. Please report a bug."); + + /* Set support functions */ + procinfo = index_getprocinfo(index, 1, IVFFLAT_KMEANS_DISTANCE_PROC); + normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); + collation = index->rd_indcollation[0]; + + /* Allocate space */ + /* Use float instead of double to save memory */ + agg = (float *)palloc(aggSize); + centerCounts = (int *)palloc(centerCountsSize); + closestCenters = (int *)palloc(closestCentersSize); lowerBound = (float *)MemoryContextAllocExtended(CurrentMemoryContext, lowerBoundSize, MCXT_ALLOC_HUGE); - upperBound = (float *)palloc(upperBoundSize); - s = (float *)palloc(sSize); - halfcdist = (float *)palloc_extended(halfcdistSize, MCXT_ALLOC_HUGE); - newcdist = (float *)palloc(newcdistSize); + upperBound = (float *)palloc(upperBoundSize); + s = (float *)palloc(sSize); + halfcdist = (float *)palloc_extended(halfcdistSize, MCXT_ALLOC_HUGE); + newcdist = (float *)palloc(newcdistSize); - /* Initialize new centers */ - newCenters = VectorArrayInit(numCenters, dimensions, centers->itemsize); - newCenters->length = numCenters; + /* Initialize new centers */ + newCenters = VectorArrayInit(numCenters, dimensions, centers->itemsize); + newCenters->length = numCenters; #ifdef IVFFLAT_MEMORY - ShowMemoryUsage(MemoryContextGetParent(CurrentMemoryContext)); + ShowMemoryUsage(MemoryContextGetParent(CurrentMemoryContext)); #endif - /* Pick initial centers */ - InitCenters(index, samples, centers, lowerBound); + /* Pick initial centers */ + InitCenters(index, samples, centers, lowerBound); - /* Assign each x to its closest initial center c(x) = argmin d(x,c) */ - for (int64 j = 0; j < numSamples; j++) - { - float minDistance = FLT_MAX; - int closestCenter = 0; + /* Assign each x to its closest initial center c(x) = argmin d(x,c) */ + for (int64 j = 0; j < numSamples; j++) + { + float minDistance = FLT_MAX; + int closestCenter = 0; - /* Find closest center */ - for (int64 k = 0; k < numCenters; k++) - { - /* TODO Use Lemma 1 in k-means++ initialization */ - float distance = lowerBound[j * numCenters + k]; - - if (distance < minDistance) - { - minDistance = distance; - closestCenter = k; - } - } + /* Find closest center */ + for (int64 k = 0; k < numCenters; k++) + { + /* TODO Use Lemma 1 in k-means++ initialization */ + float distance = lowerBound[j * numCenters + k]; + + if (distance < minDistance) + { + minDistance = distance; + closestCenter = k; + } + } - upperBound[j] = minDistance; - closestCenters[j] = closestCenter; - } + upperBound[j] = minDistance; + closestCenters[j] = closestCenter; + } - /* Give 500 iterations to converge */ - for (int iteration = 0; iteration < 500; iteration++) - { - int changes = 0; - bool rjreset; - - /* Can take a while, so ensure we can interrupt */ - CHECK_FOR_INTERRUPTS(); - - /* Step 1: For all centers, compute distance */ - for (int64 j = 0; j < numCenters; j++) - { - Datum vec = PointerGetDatum(VectorArrayGet(centers, j)); + /* Give 500 iterations to converge */ + for (int iteration = 0; iteration < 500; iteration++) + { + int changes = 0; + bool rjreset; + + /* Can take a while, so ensure we can interrupt */ + CHECK_FOR_INTERRUPTS(); + + /* Step 1: For all centers, compute distance */ + for (int64 j = 0; j < numCenters; j++) + { + Datum vec = PointerGetDatum(VectorArrayGet(centers, j)); - for (int64 k = j + 1; k < numCenters; k++) - { - float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); - - halfcdist[j * numCenters + k] = distance; - halfcdist[k * numCenters + j] = distance; - } - } + for (int64 k = j + 1; k < numCenters; k++) + { + float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + + halfcdist[j * numCenters + k] = distance; + halfcdist[k * numCenters + j] = distance; + } + } - /* For all centers c, compute s(c) */ - for (int64 j = 0; j < numCenters; j++) - { - float minDistance = FLT_MAX; + /* For all centers c, compute s(c) */ + for (int64 j = 0; j < numCenters; j++) + { + float minDistance = FLT_MAX; - for (int64 k = 0; k < numCenters; k++) - { - float distance; + for (int64 k = 0; k < numCenters; k++) + { + float distance; - if (j == k) - continue; - - distance = halfcdist[j * numCenters + k]; - if (distance < minDistance) - minDistance = distance; - } - - s[j] = minDistance; - } - - rjreset = iteration != 0; - - for (int64 j = 0; j < numSamples; j++) - { - bool rj; - - /* Step 2: Identify all points x such that u(x) <= s(c(x)) */ - if (upperBound[j] <= s[closestCenters[j]]) - continue; - - rj = rjreset; - - for (int64 k = 0; k < numCenters; k++) - { - Datum vec; - float dxcx; - - /* Step 3: For all remaining points x and centers c */ - if (k == closestCenters[j]) - continue; - - if (upperBound[j] <= lowerBound[j * numCenters + k]) - continue; - - if (upperBound[j] <= halfcdist[closestCenters[j] * numCenters + k]) - continue; - - vec = PointerGetDatum(VectorArrayGet(samples, j)); - - /* Step 3a */ - if (rj) - { - dxcx = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j])))); - - /* d(x,c(x)) computed, which is a form of d(x,c) */ - lowerBound[j * numCenters + closestCenters[j]] = dxcx; - upperBound[j] = dxcx; - - rj = false; - } - else - dxcx = upperBound[j]; - - /* Step 3b */ - if (dxcx > lowerBound[j * numCenters + k] || dxcx > halfcdist[closestCenters[j] * numCenters + k]) - { - float dxc = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); - - /* d(x,c) calculated */ - lowerBound[j * numCenters + k] = dxc; + if (j == k) + continue; + + distance = halfcdist[j * numCenters + k]; + if (distance < minDistance) + minDistance = distance; + } + + s[j] = minDistance; + } + + rjreset = iteration != 0; + + for (int64 j = 0; j < numSamples; j++) + { + bool rj; + + /* Step 2: Identify all points x such that u(x) <= s(c(x)) */ + if (upperBound[j] <= s[closestCenters[j]]) + continue; + + rj = rjreset; + + for (int64 k = 0; k < numCenters; k++) + { + Datum vec; + float dxcx; + + /* Step 3: For all remaining points x and centers c */ + if (k == closestCenters[j]) + continue; + + if (upperBound[j] <= lowerBound[j * numCenters + k]) + continue; + + if (upperBound[j] <= halfcdist[closestCenters[j] * numCenters + k]) + continue; + + vec = PointerGetDatum(VectorArrayGet(samples, j)); + + /* Step 3a */ + if (rj) + { + dxcx = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j])))); + + /* d(x,c(x)) computed, which is a form of d(x,c) */ + lowerBound[j * numCenters + closestCenters[j]] = dxcx; + upperBound[j] = dxcx; + + rj = false; + } + else + dxcx = upperBound[j]; + + /* Step 3b */ + if (dxcx > lowerBound[j * numCenters + k] || dxcx > halfcdist[closestCenters[j] * numCenters + k]) + { + float dxc = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + + /* d(x,c) calculated */ + lowerBound[j * numCenters + k] = dxc; - if (dxc < dxcx) - { - closestCenters[j] = k; + if (dxc < dxcx) + { + closestCenters[j] = k; - /* c(x) changed */ - upperBound[j] = dxc; + /* c(x) changed */ + upperBound[j] = dxc; - changes++; - } - } - } - } + changes++; + } + } + } + } - /* Step 4: For each center c, let m(c) be mean of all points assigned */ - ComputeNewCenters(samples, agg, newCenters, centerCounts, closestCenters, normprocinfo, collation, typeInfo); + /* Step 4: For each center c, let m(c) be mean of all points assigned */ + ComputeNewCenters(samples, agg, newCenters, centerCounts, closestCenters, normprocinfo, collation, typeInfo); - /* Step 5 */ - for (int j = 0; j < numCenters; j++) - newcdist[j] = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), PointerGetDatum(VectorArrayGet(newCenters, j)))); + /* Step 5 */ + for (int j = 0; j < numCenters; j++) + newcdist[j] = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), PointerGetDatum(VectorArrayGet(newCenters, j)))); - for (int64 j = 0; j < numSamples; j++) - { - for (int64 k = 0; k < numCenters; k++) - { - float distance = lowerBound[j * numCenters + k] - newcdist[k]; + for (int64 j = 0; j < numSamples; j++) + { + for (int64 k = 0; k < numCenters; k++) + { + float distance = lowerBound[j * numCenters + k] - newcdist[k]; - if (distance < 0) - distance = 0; + if (distance < 0) + distance = 0; - lowerBound[j * numCenters + k] = distance; - } - } + lowerBound[j * numCenters + k] = distance; + } + } - /* Step 6 */ - /* We reset r(x) before Step 3 in the next iteration */ - for (int j = 0; j < numSamples; j++) - upperBound[j] += newcdist[closestCenters[j]]; + /* Step 6 */ + /* We reset r(x) before Step 3 in the next iteration */ + for (int j = 0; j < numSamples; j++) + upperBound[j] += newcdist[closestCenters[j]]; - /* Step 7 */ - for (int j = 0; j < numCenters; j++) - VectorArraySet(centers, j, VectorArrayGet(newCenters, j)); + /* Step 7 */ + for (int j = 0; j < numCenters; j++) + VectorArraySet(centers, j, VectorArrayGet(newCenters, j)); - if (changes == 0 && iteration != 0) - break; - } + if (changes == 0 && iteration != 0) + break; + } } /* @@ -503,25 +503,25 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff static void CheckElements(VectorArray centers, const IvfflatTypeInfo * typeInfo) { - float *scratch = (float *)palloc(sizeof(float) * centers->dim); + float *scratch = (float *)palloc(sizeof(float) * centers->dim); - for (int i = 0; i < centers->length; i++) - { - for (int j = 0; j < centers->dim; j++) - scratch[j] = 0; + for (int i = 0; i < centers->length; i++) + { + for (int j = 0; j < centers->dim; j++) + scratch[j] = 0; - /* /fp:fast may not propagate NaN with MSVC, but that's alright */ - typeInfo->sumCenter(VectorArrayGet(centers, i), scratch); + /* /fp:fast may not propagate NaN with MSVC, but that's alright */ + typeInfo->sumCenter(VectorArrayGet(centers, i), scratch); - for (int j = 0; j < centers->dim; j++) - { - if (isnan(scratch[j])) - elog(ERROR, "NaN detected. Please report a bug."); + for (int j = 0; j < centers->dim; j++) + { + if (isnan(scratch[j])) + elog(ERROR, "NaN detected. Please report a bug."); - if (isinf(scratch[j])) - elog(ERROR, "Infinite value detected. Please report a bug."); - } - } + if (isinf(scratch[j])) + elog(ERROR, "Infinite value detected. Please report a bug."); + } + } } /* @@ -530,20 +530,20 @@ CheckElements(VectorArray centers, const IvfflatTypeInfo * typeInfo) static void CheckNorms(VectorArray centers, Relation index) { - /* Check NORM_PROC instead of KMEANS_NORM_PROC */ - FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); - Oid collation = index->rd_indcollation[0]; + /* Check NORM_PROC instead of KMEANS_NORM_PROC */ + FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + Oid collation = index->rd_indcollation[0]; - if (normprocinfo == NULL) - return; + if (normprocinfo == NULL) + return; - for (int i = 0; i < centers->length; i++) - { - double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); + for (int i = 0; i < centers->length; i++) + { + double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); - if (norm == 0) - elog(ERROR, "Zero norm detected. Please report a bug."); - } + if (norm == 0) + elog(ERROR, "Zero norm detected. Please report a bug."); + } } /* @@ -552,11 +552,11 @@ CheckNorms(VectorArray centers, Relation index) static void CheckCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - if (centers->length != centers->maxlen) - elog(ERROR, "Not enough centers. Please report a bug."); + if (centers->length != centers->maxlen) + elog(ERROR, "Not enough centers. Please report a bug."); - CheckElements(centers, typeInfo); - CheckNorms(centers, index); + CheckElements(centers, typeInfo); + CheckNorms(centers, index); } /* @@ -566,18 +566,18 @@ CheckCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeIn void IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - MemoryContext kmeansCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat kmeans temporary context", - ALLOCSET_DEFAULT_SIZES); - MemoryContext oldCtx = MemoryContextSwitchTo(kmeansCtx); + MemoryContext kmeansCtx = AllocSetContextCreate(CurrentMemoryContext, + "Ivfflat kmeans temporary context", + ALLOCSET_DEFAULT_SIZES); + MemoryContext oldCtx = MemoryContextSwitchTo(kmeansCtx); - if (samples->length == 0) - RandomCenters(index, centers, typeInfo); - else - ElkanKmeans(index, samples, centers, typeInfo); + if (samples->length == 0) + RandomCenters(index, centers, typeInfo); + else + ElkanKmeans(index, samples, centers, typeInfo); - CheckCenters(index, centers, typeInfo); + CheckCenters(index, centers, typeInfo); - MemoryContextSwitchTo(oldCtx); - MemoryContextDelete(kmeansCtx); + MemoryContextSwitchTo(oldCtx); + MemoryContextDelete(kmeansCtx); } diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index 1ce26c5d78..5da810a286 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -15,13 +15,13 @@ static int CompareLists(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const IvfflatScanList *) a)->distance > ((const IvfflatScanList *) b)->distance) - return 1; + if (((const IvfflatScanList *) a)->distance > ((const IvfflatScanList *) b)->distance) + return 1; - if (((const IvfflatScanList *) a)->distance < ((const IvfflatScanList *) b)->distance) - return -1; + if (((const IvfflatScanList *) a)->distance < ((const IvfflatScanList *) b)->distance) + return -1; - return 0; + return 0; } /* @@ -30,69 +30,69 @@ CompareLists(const pairingheap_node *a, const pairingheap_node *b, void *arg) static void GetScanLists(IndexScanDesc scan, Datum value) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; - BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; - int listCount = 0; - double maxDistance = DBL_MAX; - - /* Search all list pages */ - while (BlockNumberIsValid(nextblkno)) - { - Buffer cbuf; - Page cpage; - OffsetNumber maxoffno; - - cbuf = ReadBuffer(scan->indexRelation, nextblkno); - LockBuffer(cbuf, BUFFER_LOCK_SHARE); - cpage = BufferGetPage(cbuf); - - maxoffno = PageGetMaxOffsetNumber(cpage); - - for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); - double distance; - - /* Use procinfo from the index instead of scan key for performance */ - distance = DatumGetFloat8(so->distfunc(so->procinfo, so->collation, PointerGetDatum(&list->center), value)); - - if (listCount < so->probes) - { - IvfflatScanList *scanlist; - - scanlist = &so->lists[listCount]; - scanlist->startPage = list->startPage; - scanlist->distance = distance; - listCount++; - - /* Add to heap */ - pairingheap_add(so->listQueue, &scanlist->ph_node); - - /* Calculate max distance */ - if (listCount == so->probes) - maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; - } - else if (distance < maxDistance) - { - IvfflatScanList *scanlist; - - /* Remove */ - scanlist = (IvfflatScanList *) pairingheap_remove_first(so->listQueue); - - /* Reuse */ - scanlist->startPage = list->startPage; - scanlist->distance = distance; - pairingheap_add(so->listQueue, &scanlist->ph_node); - - /* Update max distance */ - maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; - } - } - - nextblkno = IvfflatPageGetOpaque(cpage)->nextblkno; - - UnlockReleaseBuffer(cbuf); - } + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; + int listCount = 0; + double maxDistance = DBL_MAX; + + /* Search all list pages */ + while (BlockNumberIsValid(nextblkno)) + { + Buffer cbuf; + Page cpage; + OffsetNumber maxoffno; + + cbuf = ReadBuffer(scan->indexRelation, nextblkno); + LockBuffer(cbuf, BUFFER_LOCK_SHARE); + cpage = BufferGetPage(cbuf); + + maxoffno = PageGetMaxOffsetNumber(cpage); + + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); + double distance; + + /* Use procinfo from the index instead of scan key for performance */ + distance = DatumGetFloat8(so->distfunc(so->procinfo, so->collation, PointerGetDatum(&list->center), value)); + + if (listCount < so->probes) + { + IvfflatScanList *scanlist; + + scanlist = &so->lists[listCount]; + scanlist->startPage = list->startPage; + scanlist->distance = distance; + listCount++; + + /* Add to heap */ + pairingheap_add(so->listQueue, &scanlist->ph_node); + + /* Calculate max distance */ + if (listCount == so->probes) + maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; + } + else if (distance < maxDistance) + { + IvfflatScanList *scanlist; + + /* Remove */ + scanlist = (IvfflatScanList *) pairingheap_remove_first(so->listQueue); + + /* Reuse */ + scanlist->startPage = list->startPage; + scanlist->distance = distance; + pairingheap_add(so->listQueue, &scanlist->ph_node); + + /* Update max distance */ + maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; + } + } + + nextblkno = IvfflatPageGetOpaque(cpage)->nextblkno; + + UnlockReleaseBuffer(cbuf); + } } /* @@ -101,78 +101,78 @@ GetScanLists(IndexScanDesc scan, Datum value) static void GetScanItems(IndexScanDesc scan, Datum value) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; - TupleDesc tupdesc = RelationGetDescr(scan->indexRelation); - double tuples = 0; - TupleTableSlot *slot = MakeSingleTupleTableSlot(so->tupdesc); - - /* - * Reuse same set of shared buffers for scan - * - * See postgres/src/backend/storage/buffer/README for description - */ - BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); - - /* Search closest probes lists */ - while (!pairingheap_is_empty(so->listQueue)) - { - BlockNumber searchPage = ((IvfflatScanList *) pairingheap_remove_first(so->listQueue))->startPage; - - /* Search all entry pages for list */ - while (BlockNumberIsValid(searchPage)) - { - Buffer buf; - Page page; - OffsetNumber maxoffno; - - buf = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas); - LockBuffer(buf, BUFFER_LOCK_SHARE); - page = BufferGetPage(buf); - maxoffno = PageGetMaxOffsetNumber(page); - - for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - IndexTuple itup; - Datum datum; - bool isnull; - ItemId itemid = PageGetItemId(page, offno); - - itup = (IndexTuple) PageGetItem(page, itemid); - datum = index_getattr(itup, 1, tupdesc, &isnull); - - /* - * Add virtual tuple - * - * Use procinfo from the index instead of scan key for - * performance - */ - ExecClearTuple(slot); - slot->tts_values[0] = so->distfunc(so->procinfo, so->collation, datum, value); - slot->tts_isnull[0] = false; - slot->tts_values[1] = PointerGetDatum(&itup->t_tid); - slot->tts_isnull[1] = false; - ExecStoreVirtualTuple(slot); - - tuplesort_puttupleslot(so->sortstate, slot); - - tuples++; - } - - searchPage = IvfflatPageGetOpaque(page)->nextblkno; - - UnlockReleaseBuffer(buf); - } - } - - FreeAccessStrategy(bas); - - if (tuples < 100) - ereport(DEBUG1, - (errmsg("index scan found few tuples"), - errdetail("Index may have been created with little data."), - errhint("Recreate the index and possibly decrease lists."))); - - tuplesort_performsort(so->sortstate); + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + TupleDesc tupdesc = RelationGetDescr(scan->indexRelation); + double tuples = 0; + TupleTableSlot *slot = MakeSingleTupleTableSlot(so->tupdesc); + + /* + * Reuse same set of shared buffers for scan + * + * See postgres/src/backend/storage/buffer/README for description + */ + BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); + + /* Search closest probes lists */ + while (!pairingheap_is_empty(so->listQueue)) + { + BlockNumber searchPage = ((IvfflatScanList *) pairingheap_remove_first(so->listQueue))->startPage; + + /* Search all entry pages for list */ + while (BlockNumberIsValid(searchPage)) + { + Buffer buf; + Page page; + OffsetNumber maxoffno; + + buf = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + maxoffno = PageGetMaxOffsetNumber(page); + + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IndexTuple itup; + Datum datum; + bool isnull; + ItemId itemid = PageGetItemId(page, offno); + + itup = (IndexTuple) PageGetItem(page, itemid); + datum = index_getattr(itup, 1, tupdesc, &isnull); + + /* + * Add virtual tuple + * + * Use procinfo from the index instead of scan key for + * performance + */ + ExecClearTuple(slot); + slot->tts_values[0] = so->distfunc(so->procinfo, so->collation, datum, value); + slot->tts_isnull[0] = false; + slot->tts_values[1] = PointerGetDatum(&itup->t_tid); + slot->tts_isnull[1] = false; + ExecStoreVirtualTuple(slot); + + tuplesort_puttupleslot(so->sortstate, slot); + + tuples++; + } + + searchPage = IvfflatPageGetOpaque(page)->nextblkno; + + UnlockReleaseBuffer(buf); + } + } + + FreeAccessStrategy(bas); + + if (tuples < 100) + ereport(DEBUG1, + (errmsg("index scan found few tuples"), + errdetail("Index may have been created with little data."), + errhint("Recreate the index and possibly decrease lists."))); + + tuplesort_performsort(so->sortstate); } /* @@ -181,7 +181,7 @@ GetScanItems(IndexScanDesc scan, Datum value) static Datum ZeroDistance(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) { - return Float8GetDatum(0.0); + return Float8GetDatum(0.0); } /* @@ -190,29 +190,29 @@ ZeroDistance(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) static Datum GetScanValue(IndexScanDesc scan) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; - Datum value; - - if (scan->orderByData->sk_flags & SK_ISNULL) - { - value = PointerGetDatum(NULL); - so->distfunc = ZeroDistance; - } - else - { - value = scan->orderByData->sk_argument; - so->distfunc = FunctionCall2Coll; - - /* Value should not be compressed or toasted */ - Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); - Assert(!VARATT_IS_EXTENDED(DatumGetPointer(value))); - - /* Normalize if needed */ - if (so->normprocinfo != NULL) - value = IvfflatNormValue(so->typeInfo, so->collation, value); - } - - return value; + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + Datum value; + + if (scan->orderByData->sk_flags & SK_ISNULL) + { + value = PointerGetDatum(NULL); + so->distfunc = ZeroDistance; + } + else + { + value = scan->orderByData->sk_argument; + so->distfunc = FunctionCall2Coll; + + /* Value should not be compressed or toasted */ + Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); + Assert(!VARATT_IS_EXTENDED(DatumGetPointer(value))); + + /* Normalize if needed */ + if (so->normprocinfo != NULL) + value = IvfflatNormValue(so->typeInfo, so->collation, value); + } + + return value; } /* @@ -278,21 +278,21 @@ ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; #if PG_VERSION_NUM >= 130000 - if (!so->first) - tuplesort_reset(so->sortstate); + if (!so->first) + tuplesort_reset(so->sortstate); #endif - so->first = true; - pairingheap_reset(so->listQueue); + so->first = true; + pairingheap_reset(so->listQueue); - if (keys && scan->numberOfKeys > 0) - memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData)); + if (keys && scan->numberOfKeys > 0) + memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData)); - if (orderbys && scan->numberOfOrderBys > 0) - memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); + if (orderbys && scan->numberOfOrderBys > 0) + memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); } /* @@ -301,50 +301,50 @@ ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orde bool ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; - - /* - * Index can be used to scan backward, but Postgres doesn't support - * backward scan on operators - */ - Assert(ScanDirectionIsForward(dir)); - - if (so->first) - { - Datum value; - - /* Count index scan for stats */ - pgstat_count_index_scan(scan->indexRelation); - - /* Safety check */ - if (scan->orderByData == NULL) - elog(ERROR, "cannot scan ivfflat index without order"); - - /* Requires MVCC-compliant snapshot as not able to pin during sorting */ - /* https://www.postgresql.org/docs/current/index-locking.html */ - if (!IsMVCCSnapshot(scan->xs_snapshot)) - elog(ERROR, "non-MVCC snapshots are not supported with ivfflat"); - - value = GetScanValue(scan); - IvfflatBench("GetScanLists", GetScanLists(scan, value)); - IvfflatBench("GetScanItems", GetScanItems(scan, value)); - so->first = false; - - /* Clean up if we allocated a new value */ - if (value != scan->orderByData->sk_argument) - pfree(DatumGetPointer(value)); - } - - if (tuplesort_gettupleslot(so->sortstate, true, so->slot, NULL)) - { - ItemPointer heaptid = (ItemPointer) DatumGetPointer(heap_slot_getattr(so->slot, 2, &so->isnull)); - - scan->xs_ctup.t_self = *heaptid; - scan->xs_recheck = false; - return true; - } - - return false; + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + + /* + * Index can be used to scan backward, but Postgres doesn't support + * backward scan on operators + */ + Assert(ScanDirectionIsForward(dir)); + + if (so->first) + { + Datum value; + + /* Count index scan for stats */ + pgstat_count_index_scan(scan->indexRelation); + + /* Safety check */ + if (scan->orderByData == NULL) + elog(ERROR, "cannot scan ivfflat index without order"); + + /* Requires MVCC-compliant snapshot as not able to pin during sorting */ + /* https://www.postgresql.org/docs/current/index-locking.html */ + if (!IsMVCCSnapshot(scan->xs_snapshot)) + elog(ERROR, "non-MVCC snapshots are not supported with ivfflat"); + + value = GetScanValue(scan); + IvfflatBench("GetScanLists", GetScanLists(scan, value)); + IvfflatBench("GetScanItems", GetScanItems(scan, value)); + so->first = false; + + /* Clean up if we allocated a new value */ + if (value != scan->orderByData->sk_argument) + pfree(DatumGetPointer(value)); + } + + if (tuplesort_gettupleslot(so->sortstate, true, so->slot, NULL)) + { + ItemPointer heaptid = (ItemPointer) DatumGetPointer(heap_slot_getattr(so->slot, 2, &so->isnull)); + + scan->xs_ctup.t_self = *heaptid; + scan->xs_recheck = false; + return true; + } + + return false; } /* @@ -353,11 +353,11 @@ ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) void ivfflatendscan_internal(IndexScanDesc scan) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; - pairingheap_free(so->listQueue); - tuplesort_end(so->sortstate); + pairingheap_free(so->listQueue); + tuplesort_end(so->sortstate); - pfree(so); - scan->opaque = NULL; + pfree(so); + scan->opaque = NULL; } diff --git a/src/gausskernel/storage/access/datavec/ivfutils.cpp b/src/gausskernel/storage/access/datavec/ivfutils.cpp index 3e6659f30b..d1dd3f0275 100644 --- a/src/gausskernel/storage/access/datavec/ivfutils.cpp +++ b/src/gausskernel/storage/access/datavec/ivfutils.cpp @@ -15,17 +15,17 @@ VectorArray VectorArrayInit(int maxlen, int dimensions, Size itemsize) { - VectorArray res = (VectorArray)palloc(sizeof(VectorArrayData)); + VectorArray res = (VectorArray)palloc(sizeof(VectorArrayData)); - /* Ensure items are aligned to prevent UB */ - itemsize = MAXALIGN(itemsize); + /* Ensure items are aligned to prevent UB */ + itemsize = MAXALIGN(itemsize); - res->length = 0; - res->maxlen = maxlen; - res->dim = dimensions; - res->itemsize = itemsize; - res->items = (char *)palloc_extended(maxlen * itemsize, MCXT_ALLOC_ZERO | MCXT_ALLOC_HUGE); - return res; + res->length = 0; + res->maxlen = maxlen; + res->dim = dimensions; + res->itemsize = itemsize; + res->items = (char *)palloc_extended(maxlen * itemsize, MCXT_ALLOC_ZERO | MCXT_ALLOC_HUGE); + return res; } /* @@ -34,8 +34,8 @@ VectorArrayInit(int maxlen, int dimensions, Size itemsize) void VectorArrayFree(VectorArray arr) { - pfree(arr->items); - pfree(arr); + pfree(arr->items); + pfree(arr); } /* @@ -44,12 +44,12 @@ VectorArrayFree(VectorArray arr) int IvfflatGetLists(Relation index) { - IvfflatOptions *opts = (IvfflatOptions *) index->rd_options; + IvfflatOptions *opts = (IvfflatOptions *) index->rd_options; - if (opts) - return opts->lists; + if (opts) + return opts->lists; - return IVFFLAT_DEFAULT_LISTS; + return IVFFLAT_DEFAULT_LISTS; } /* @@ -58,10 +58,10 @@ IvfflatGetLists(Relation index) FmgrInfo * IvfflatOptionalProcInfo(Relation index, uint16 procnum) { - if (!OidIsValid(index_getprocid(index, 1, procnum))) - return NULL; + if (!OidIsValid(index_getprocid(index, 1, procnum))) + return NULL; - return index_getprocinfo(index, 1, procnum); + return index_getprocinfo(index, 1, procnum); } /* @@ -70,7 +70,7 @@ IvfflatOptionalProcInfo(Relation index, uint16 procnum) Datum IvfflatNormValue(const IvfflatTypeInfo * typeInfo, Oid collation, Datum value) { - return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); + return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); } /* @@ -79,7 +79,7 @@ IvfflatNormValue(const IvfflatTypeInfo * typeInfo, Oid collation, Datum value) bool IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) { - return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; + return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; } /* @@ -88,10 +88,10 @@ IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum) { - Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); + Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - return buf; + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + return buf; } /* @@ -100,9 +100,9 @@ IvfflatNewBuffer(Relation index, ForkNumber forkNum) void IvfflatInitPage(Buffer buf, Page page) { - PageInit(page, BufferGetPageSize(buf), sizeof(IvfflatPageOpaqueData)); - IvfflatPageGetOpaque(page)->nextblkno = InvalidBlockNumber; - IvfflatPageGetOpaque(page)->page_id = IVFFLAT_PAGE_ID; + PageInit(page, BufferGetPageSize(buf), sizeof(IvfflatPageOpaqueData)); + IvfflatPageGetOpaque(page)->nextblkno = InvalidBlockNumber; + IvfflatPageGetOpaque(page)->page_id = IVFFLAT_PAGE_ID; } /* @@ -111,9 +111,9 @@ IvfflatInitPage(Buffer buf, Page page) void IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state) { - *state = GenericXLogStart(index); - *page = GenericXLogRegisterBuffer(*state, *buf, GENERIC_XLOG_FULL_IMAGE); - IvfflatInitPage(*buf, *page); + *state = GenericXLogStart(index); + *page = GenericXLogRegisterBuffer(*state, *buf, GENERIC_XLOG_FULL_IMAGE); + IvfflatInitPage(*buf, *page); } /* @@ -122,8 +122,8 @@ IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogStat void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state) { - GenericXLogFinish(state); - UnlockReleaseBuffer(buf); + GenericXLogFinish(state); + UnlockReleaseBuffer(buf); } /* @@ -134,25 +134,25 @@ IvfflatCommitBuffer(Buffer buf, GenericXLogState *state) void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum) { - /* Get new buffer */ - Buffer newbuf = IvfflatNewBuffer(index, forkNum); - Page newpage = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); + /* Get new buffer */ + Buffer newbuf = IvfflatNewBuffer(index, forkNum); + Page newpage = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); - /* Update the previous buffer */ - IvfflatPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); + /* Update the previous buffer */ + IvfflatPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); - /* Init new page */ - IvfflatInitPage(newbuf, newpage); + /* Init new page */ + IvfflatInitPage(newbuf, newpage); - /* Commit */ - GenericXLogFinish(*state); + /* Commit */ + GenericXLogFinish(*state); - /* Unlock */ - UnlockReleaseBuffer(*buf); + /* Unlock */ + UnlockReleaseBuffer(*buf); - *state = GenericXLogStart(index); - *page = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); - *buf = newbuf; + *state = GenericXLogStart(index); + *page = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); + *buf = newbuf; } /* @@ -161,25 +161,25 @@ IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **st void IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) { - Buffer buf; - Page page; - IvfflatMetaPage metap; + Buffer buf; + Page page; + IvfflatMetaPage metap; - buf = ReadBuffer(index, IVFFLAT_METAPAGE_BLKNO); - LockBuffer(buf, BUFFER_LOCK_SHARE); - page = BufferGetPage(buf); - metap = IvfflatPageGetMeta(page); + buf = ReadBuffer(index, IVFFLAT_METAPAGE_BLKNO); + LockBuffer(buf, BUFFER_LOCK_SHARE); + page = BufferGetPage(buf); + metap = IvfflatPageGetMeta(page); - if (unlikely(metap->magicNumber != IVFFLAT_MAGIC_NUMBER)) - elog(ERROR, "ivfflat index is not valid"); + if (unlikely(metap->magicNumber != IVFFLAT_MAGIC_NUMBER)) + elog(ERROR, "ivfflat index is not valid"); - if (lists != NULL) - *lists = metap->lists; + if (lists != NULL) + *lists = metap->lists; - if (dimensions != NULL) - *dimensions = metap->dimensions; + if (dimensions != NULL) + *dimensions = metap->dimensions; - UnlockReleaseBuffer(buf); + UnlockReleaseBuffer(buf); } /* @@ -187,131 +187,131 @@ IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) */ void IvfflatUpdateList(Relation index, ListInfo listInfo, - BlockNumber insertPage, BlockNumber originalInsertPage, - BlockNumber startPage, ForkNumber forkNum) + BlockNumber insertPage, BlockNumber originalInsertPage, + BlockNumber startPage, ForkNumber forkNum) { - Buffer buf; - Page page; - GenericXLogState *state; - IvfflatList list; - bool changed = false; - - buf = ReadBufferExtended(index, forkNum, listInfo.blkno, RBM_NORMAL, NULL); - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - list = (IvfflatList) PageGetItem(page, PageGetItemId(page, listInfo.offno)); - - if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage) - { - /* Skip update if insert page is lower than original insert page */ - /* This is needed to prevent insert from overwriting vacuum */ - if (!BlockNumberIsValid(originalInsertPage) || insertPage >= originalInsertPage) - { - list->insertPage = insertPage; - changed = true; - } - } - - if (BlockNumberIsValid(startPage) && startPage != list->startPage) - { - list->startPage = startPage; - changed = true; - } - - /* Only commit if changed */ - if (changed) - IvfflatCommitBuffer(buf, state); - else - { - GenericXLogAbort(state); - UnlockReleaseBuffer(buf); - } + Buffer buf; + Page page; + GenericXLogState *state; + IvfflatList list; + bool changed = false; + + buf = ReadBufferExtended(index, forkNum, listInfo.blkno, RBM_NORMAL, NULL); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + list = (IvfflatList) PageGetItem(page, PageGetItemId(page, listInfo.offno)); + + if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage) + { + /* Skip update if insert page is lower than original insert page */ + /* This is needed to prevent insert from overwriting vacuum */ + if (!BlockNumberIsValid(originalInsertPage) || insertPage >= originalInsertPage) + { + list->insertPage = insertPage; + changed = true; + } + } + + if (BlockNumberIsValid(startPage) && startPage != list->startPage) + { + list->startPage = startPage; + changed = true; + } + + /* Only commit if changed */ + if (changed) + IvfflatCommitBuffer(buf, state); + else + { + GenericXLogAbort(state); + UnlockReleaseBuffer(buf); + } } static Size VectorItemSize(int dimensions) { - return VECTOR_SIZE(dimensions); + return VECTOR_SIZE(dimensions); } static Size HalfvecItemSize(int dimensions) { - return HALFVEC_SIZE(dimensions); + return HALFVEC_SIZE(dimensions); } static Size BitItemSize(int dimensions) { - return VARBITTOTALLEN(dimensions); + return VARBITTOTALLEN(dimensions); } static void VectorUpdateCenter(Pointer v, int dimensions, float *x) { - Vector *vec = (Vector *) v; + Vector *vec = (Vector *) v; - SET_VARSIZE(vec, VECTOR_SIZE(dimensions)); - vec->dim = dimensions; + SET_VARSIZE(vec, VECTOR_SIZE(dimensions)); + vec->dim = dimensions; - for (int k = 0; k < dimensions; k++) - vec->x[k] = x[k]; + for (int k = 0; k < dimensions; k++) + vec->x[k] = x[k]; } static void HalfvecUpdateCenter(Pointer v, int dimensions, float *x) { - HalfVector *vec = (HalfVector *) v; + HalfVector *vec = (HalfVector *) v; - SET_VARSIZE(vec, HALFVEC_SIZE(dimensions)); - vec->dim = dimensions; + SET_VARSIZE(vec, HALFVEC_SIZE(dimensions)); + vec->dim = dimensions; - for (int k = 0; k < dimensions; k++) - vec->x[k] = Float4ToHalfUnchecked(x[k]); + for (int k = 0; k < dimensions; k++) + vec->x[k] = Float4ToHalfUnchecked(x[k]); } static void BitUpdateCenter(Pointer v, int dimensions, float *x) { - VarBit *vec = (VarBit *) v; - unsigned char *nx = VARBITS(vec); + VarBit *vec = (VarBit *) v; + unsigned char *nx = VARBITS(vec); - SET_VARSIZE(vec, VARBITTOTALLEN(dimensions)); - VARBITLEN(vec) = dimensions; + SET_VARSIZE(vec, VARBITTOTALLEN(dimensions)); + VARBITLEN(vec) = dimensions; - for (uint32 k = 0; k < VARBITBYTES(vec); k++) - nx[k] = 0; + for (uint32 k = 0; k < VARBITBYTES(vec); k++) + nx[k] = 0; - for (int k = 0; k < dimensions; k++) - nx[k / 8] |= (x[k] > 0.5 ? 1 : 0) << (7 - (k % 8)); + for (int k = 0; k < dimensions; k++) + nx[k / 8] |= (x[k] > 0.5 ? 1 : 0) << (7 - (k % 8)); } static void VectorSumCenter(Pointer v, float *x) { - Vector *vec = (Vector *) v; + Vector *vec = (Vector *) v; - for (int k = 0; k < vec->dim; k++) - x[k] += vec->x[k]; + for (int k = 0; k < vec->dim; k++) + x[k] += vec->x[k]; } static void HalfvecSumCenter(Pointer v, float *x) { - HalfVector *vec = (HalfVector *) v; + HalfVector *vec = (HalfVector *) v; - for (int k = 0; k < vec->dim; k++) - x[k] += HalfToFloat4(vec->x[k]); + for (int k = 0; k < vec->dim; k++) + x[k] += HalfToFloat4(vec->x[k]); } static void BitSumCenter(Pointer v, float *x) { - VarBit *vec = (VarBit *) v; + VarBit *vec = (VarBit *) v; - for (int k = 0; k < VARBITLEN(vec); k++) - x[k] += (float) (((VARBITS(vec)[k / 8]) >> (7 - (k % 8))) & 0x01); + for (int k = 0; k < VARBITLEN(vec); k++) + x[k] += (float) (((VARBITS(vec)[k / 8]) >> (7 - (k % 8))) & 0x01); } /* @@ -320,50 +320,50 @@ BitSumCenter(Pointer v, float *x) const IvfflatTypeInfo * IvfflatGetTypeInfo(Relation index) { - FmgrInfo *procinfo = IvfflatOptionalProcInfo(index, IVFFLAT_TYPE_INFO_PROC); - - if (procinfo == NULL) - { - static const IvfflatTypeInfo typeInfo = { - .maxDimensions = IVFFLAT_MAX_DIM, - .normalize = l2_normalize, - .itemSize = VectorItemSize, - .updateCenter = VectorUpdateCenter, - .sumCenter = VectorSumCenter - }; - - return (&typeInfo); - } - else - return (const IvfflatTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); + FmgrInfo *procinfo = IvfflatOptionalProcInfo(index, IVFFLAT_TYPE_INFO_PROC); + + if (procinfo == NULL) + { + static const IvfflatTypeInfo typeInfo = { + .maxDimensions = IVFFLAT_MAX_DIM, + .normalize = l2_normalize, + .itemSize = VectorItemSize, + .updateCenter = VectorUpdateCenter, + .sumCenter = VectorSumCenter + }; + + return (&typeInfo); + } + else + return (const IvfflatTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflat_halfvec_support); Datum ivfflat_halfvec_support(PG_FUNCTION_ARGS) { - static const IvfflatTypeInfo typeInfo = { - .maxDimensions = IVFFLAT_MAX_DIM * 2, - .normalize = halfvec_l2_normalize, - .itemSize = HalfvecItemSize, - .updateCenter = HalfvecUpdateCenter, - .sumCenter = HalfvecSumCenter - }; - - PG_RETURN_POINTER(&typeInfo); + static const IvfflatTypeInfo typeInfo = { + .maxDimensions = IVFFLAT_MAX_DIM * 2, + .normalize = halfvec_l2_normalize, + .itemSize = HalfvecItemSize, + .updateCenter = HalfvecUpdateCenter, + .sumCenter = HalfvecSumCenter + }; + + PG_RETURN_POINTER(&typeInfo); }; PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflat_bit_support); Datum ivfflat_bit_support(PG_FUNCTION_ARGS) { - static const IvfflatTypeInfo typeInfo = { - .maxDimensions = IVFFLAT_MAX_DIM * 32, - .normalize = NULL, - .itemSize = BitItemSize, - .updateCenter = BitUpdateCenter, - .sumCenter = BitSumCenter - }; - - PG_RETURN_POINTER(&typeInfo); + static const IvfflatTypeInfo typeInfo = { + .maxDimensions = IVFFLAT_MAX_DIM * 32, + .normalize = NULL, + .itemSize = BitItemSize, + .updateCenter = BitUpdateCenter, + .sumCenter = BitSumCenter + }; + + PG_RETURN_POINTER(&typeInfo); }; diff --git a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp index 2950915681..335502bc60 100644 --- a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp @@ -10,129 +10,129 @@ */ IndexBulkDeleteResult * ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) + IndexBulkDeleteCallback callback, void *callback_state) { - Relation index = info->index; - BlockNumber blkno = IVFFLAT_HEAD_BLKNO; - BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); - - if (stats == NULL) - stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); - - /* Iterate over list pages */ - while (BlockNumberIsValid(blkno)) - { - Buffer cbuf; - Page cpage; - OffsetNumber coffno; - OffsetNumber cmaxoffno; - BlockNumber startPages[MaxOffsetNumber]; - ListInfo listInfo; - - cbuf = ReadBuffer(index, blkno); - LockBuffer(cbuf, BUFFER_LOCK_SHARE); - cpage = BufferGetPage(cbuf); - - cmaxoffno = PageGetMaxOffsetNumber(cpage); - - /* Iterate over lists */ - for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) - { - IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, coffno)); - - startPages[coffno - FirstOffsetNumber] = list->startPage; - } - - listInfo.blkno = blkno; - blkno = IvfflatPageGetOpaque(cpage)->nextblkno; - - UnlockReleaseBuffer(cbuf); - - for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) - { - BlockNumber searchPage = startPages[coffno - FirstOffsetNumber]; - BlockNumber insertPage = InvalidBlockNumber; - - /* Iterate over entry pages */ - while (BlockNumberIsValid(searchPage)) - { - Buffer buf; - Page page; - GenericXLogState *state; - OffsetNumber offno; - OffsetNumber maxoffno; - OffsetNumber deletable[MaxOffsetNumber]; - int ndeletable; - - vacuum_delay_point(); - - buf = ReadBufferExtended(index, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas); - - /* - * ambulkdelete cannot delete entries from pages that are - * pinned by other backends - * - * https://www.postgresql.org/docs/current/index-locking.html - */ - LockBufferForCleanup(buf); - - state = GenericXLogStart(index); - page = GenericXLogRegisterBuffer(state, buf, 0); - - maxoffno = PageGetMaxOffsetNumber(page); - ndeletable = 0; - - /* Find deleted tuples */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offno)); - ItemPointer htup = &(itup->t_tid); - - if (callback(htup, callback_state, InvalidOid, InvalidBktId)) - { - deletable[ndeletable++] = offno; - stats->tuples_removed++; - } - else - stats->num_index_tuples++; - } - - /* Set to first free page */ - /* Must be set before searchPage is updated */ - if (!BlockNumberIsValid(insertPage) && ndeletable > 0) - insertPage = searchPage; - - searchPage = IvfflatPageGetOpaque(page)->nextblkno; - - if (ndeletable > 0) - { - /* Delete tuples */ - PageIndexMultiDelete(page, deletable, ndeletable); - GenericXLogFinish(state); - } - else - GenericXLogAbort(state); - - UnlockReleaseBuffer(buf); - } - - /* - * Update after all tuples deleted. - * - * We don't add or delete items from lists pages, so offset won't - * change. - */ - if (BlockNumberIsValid(insertPage)) - { - listInfo.offno = coffno; - IvfflatUpdateList(index, listInfo, insertPage, InvalidBlockNumber, InvalidBlockNumber, MAIN_FORKNUM); - } - } - } - - FreeAccessStrategy(bas); - - return stats; + Relation index = info->index; + BlockNumber blkno = IVFFLAT_HEAD_BLKNO; + BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); + + if (stats == NULL) + stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + + /* Iterate over list pages */ + while (BlockNumberIsValid(blkno)) + { + Buffer cbuf; + Page cpage; + OffsetNumber coffno; + OffsetNumber cmaxoffno; + BlockNumber startPages[MaxOffsetNumber]; + ListInfo listInfo; + + cbuf = ReadBuffer(index, blkno); + LockBuffer(cbuf, BUFFER_LOCK_SHARE); + cpage = BufferGetPage(cbuf); + + cmaxoffno = PageGetMaxOffsetNumber(cpage); + + /* Iterate over lists */ + for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) + { + IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, coffno)); + + startPages[coffno - FirstOffsetNumber] = list->startPage; + } + + listInfo.blkno = blkno; + blkno = IvfflatPageGetOpaque(cpage)->nextblkno; + + UnlockReleaseBuffer(cbuf); + + for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) + { + BlockNumber searchPage = startPages[coffno - FirstOffsetNumber]; + BlockNumber insertPage = InvalidBlockNumber; + + /* Iterate over entry pages */ + while (BlockNumberIsValid(searchPage)) + { + Buffer buf; + Page page; + GenericXLogState *state; + OffsetNumber offno; + OffsetNumber maxoffno; + OffsetNumber deletable[MaxOffsetNumber]; + int ndeletable; + + vacuum_delay_point(); + + buf = ReadBufferExtended(index, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas); + + /* + * ambulkdelete cannot delete entries from pages that are + * pinned by other backends + * + * https://www.postgresql.org/docs/current/index-locking.html + */ + LockBufferForCleanup(buf); + + state = GenericXLogStart(index); + page = GenericXLogRegisterBuffer(state, buf, 0); + + maxoffno = PageGetMaxOffsetNumber(page); + ndeletable = 0; + + /* Find deleted tuples */ + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) + { + IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offno)); + ItemPointer htup = &(itup->t_tid); + + if (callback(htup, callback_state, InvalidOid, InvalidBktId)) + { + deletable[ndeletable++] = offno; + stats->tuples_removed++; + } + else + stats->num_index_tuples++; + } + + /* Set to first free page */ + /* Must be set before searchPage is updated */ + if (!BlockNumberIsValid(insertPage) && ndeletable > 0) + insertPage = searchPage; + + searchPage = IvfflatPageGetOpaque(page)->nextblkno; + + if (ndeletable > 0) + { + /* Delete tuples */ + PageIndexMultiDelete(page, deletable, ndeletable); + GenericXLogFinish(state); + } + else + GenericXLogAbort(state); + + UnlockReleaseBuffer(buf); + } + + /* + * Update after all tuples deleted. + * + * We don't add or delete items from lists pages, so offset won't + * change. + */ + if (BlockNumberIsValid(insertPage)) + { + listInfo.offno = coffno; + IvfflatUpdateList(index, listInfo, insertPage, InvalidBlockNumber, InvalidBlockNumber, MAIN_FORKNUM); + } + } + } + + FreeAccessStrategy(bas); + + return stats; } /* @@ -141,17 +141,17 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteResult * ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { - Relation rel = info->index; + Relation rel = info->index; - if (info->analyze_only) - return stats; + if (info->analyze_only) + return stats; - /* stats is NULL if ambulkdelete not called */ - /* OK to return NULL if index not changed */ - if (stats == NULL) - return NULL; + /* stats is NULL if ambulkdelete not called */ + /* OK to return NULL if index not changed */ + if (stats == NULL) + return NULL; - stats->num_pages = RelationGetNumberOfBlocks(rel); + stats->num_pages = RelationGetNumberOfBlocks(rel); - return stats; + return stats; } diff --git a/src/include/access/datavec/halfutils.h b/src/include/access/datavec/halfutils.h index 6e9d53a66e..906a8157c1 100644 --- a/src/include/access/datavec/halfutils.h +++ b/src/include/access/datavec/halfutils.h @@ -24,9 +24,9 @@ static inline bool HalfIsNan(half num) { #ifdef FLT16_SUPPORT - return isnan(num); + return isnan(num); #else - return (num & 0x7C00) == 0x7C00 && (num & 0x7FFF) != 0x7C00; + return (num & 0x7C00) == 0x7C00 && (num & 0x7FFF) != 0x7C00; #endif } @@ -37,9 +37,9 @@ static inline bool HalfIsInf(half num) { #ifdef FLT16_SUPPORT - return isinf(num); + return isinf(num); #else - return (num & 0x7FFF) == 0x7C00; + return (num & 0x7FFF) == 0x7C00; #endif } @@ -50,9 +50,9 @@ static inline bool HalfIsZero(half num) { #ifdef FLT16_SUPPORT - return num == 0; + return num == 0; #else - return (num & 0x7FFF) == 0x0000; + return (num & 0x7FFF) == 0x0000; #endif } @@ -63,80 +63,80 @@ static inline float HalfToFloat4(half num) { #if defined(F16C_SUPPORT) - return _cvtsh_ss(num); + return _cvtsh_ss(num); #elif defined(FLT16_SUPPORT) - return (float) num; + return (float) num; #else - union - { - float f; - uint32 i; - } swapfloat; - - union - { - half h; - uint16 i; - } swaphalf; - - uint16 bin; - uint32 exponent; - uint32 mantissa; - uint32 result; - - swaphalf.h = num; - bin = swaphalf.i; - exponent = (bin & 0x7C00) >> 10; - mantissa = bin & 0x03FF; - - /* Sign */ - result = (bin & 0x8000) << 16; - - if (unlikely(exponent == 31)) - { - if (mantissa == 0) - { - /* Infinite */ - result |= 0x7F800000; - } - else - { - /* NaN */ - result |= 0x7FC00000; - } - } - else if (unlikely(exponent == 0)) - { - /* Subnormal */ - if (mantissa != 0) - { - exponent = -14; - - for (int i = 0; i < 10; i++) - { - mantissa <<= 1; - exponent -= 1; - - if ((mantissa >> 10) % 2 == 1) - { - mantissa &= 0x03ff; - break; - } - } - - result |= (exponent + 127) << 23; - } - } - else - { - /* Normal */ - result |= (exponent - 15 + 127) << 23; - } - - result |= mantissa << 13; - - swapfloat.i = result; - return swapfloat.f; + union + { + float f; + uint32 i; + } swapfloat; + + union + { + half h; + uint16 i; + } swaphalf; + + uint16 bin; + uint32 exponent; + uint32 mantissa; + uint32 result; + + swaphalf.h = num; + bin = swaphalf.i; + exponent = (bin & 0x7C00) >> 10; + mantissa = bin & 0x03FF; + + /* Sign */ + result = (bin & 0x8000) << 16; + + if (unlikely(exponent == 31)) + { + if (mantissa == 0) + { + /* Infinite */ + result |= 0x7F800000; + } + else + { + /* NaN */ + result |= 0x7FC00000; + } + } + else if (unlikely(exponent == 0)) + { + /* Subnormal */ + if (mantissa != 0) + { + exponent = -14; + + for (int i = 0; i < 10; i++) + { + mantissa <<= 1; + exponent -= 1; + + if ((mantissa >> 10) % 2 == 1) + { + mantissa &= 0x03ff; + break; + } + } + + result |= (exponent + 127) << 23; + } + } + else + { + /* Normal */ + result |= (exponent - 15 + 127) << 23; + } + + result |= mantissa << 13; + + swapfloat.i = result; + return swapfloat.f; #endif } @@ -147,94 +147,94 @@ static inline half Float4ToHalfUnchecked(float num) { #if defined(F16C_SUPPORT) - return _cvtss_sh(num, 0); + return _cvtss_sh(num, 0); #elif defined(FLT16_SUPPORT) - return num; + return num; #else - union - { - float f; - uint32 i; - } swapfloat; - - union - { - half h; - uint16 i; - } swaphalf; - - uint32 bin; - int exponent; - int mantissa; - uint16 result; - - swapfloat.f = num; - bin = swapfloat.i; - exponent = (bin & 0x7F800000) >> 23; - mantissa = bin & 0x007FFFFF; - - /* Sign */ - result = (bin & 0x80000000) >> 16; - - if (isinf(num)) - { - /* Infinite */ - result |= 0x7C00; - } - else if (isnan(num)) - { - /* NaN */ - result |= 0x7E00; - result |= mantissa >> 13; - } - else if (exponent > 98) - { - int m; - int gr; - int s; - - exponent -= 127; - s = mantissa & 0x00000FFF; - - /* Subnormal */ - if (exponent < -14) - { - int diff = -exponent - 14; - - mantissa >>= diff; - mantissa += 1 << (23 - diff); - s |= mantissa & 0x00000FFF; - } - - m = mantissa >> 13; - - /* Round */ - gr = (mantissa >> 12) % 4; - if (gr == 3 || (gr == 1 && s != 0)) - m += 1; - - if (m == 1024) - { - m = 0; - exponent += 1; - } - - if (exponent > 15) - { - /* Infinite */ - result |= 0x7C00; - } - else - { - if (exponent >= -14) - result |= (exponent + 15) << 10; - - result |= m; - } - } - - swaphalf.i = result; - return swaphalf.h; + union + { + float f; + uint32 i; + } swapfloat; + + union + { + half h; + uint16 i; + } swaphalf; + + uint32 bin; + int exponent; + int mantissa; + uint16 result; + + swapfloat.f = num; + bin = swapfloat.i; + exponent = (bin & 0x7F800000) >> 23; + mantissa = bin & 0x007FFFFF; + + /* Sign */ + result = (bin & 0x80000000) >> 16; + + if (isinf(num)) + { + /* Infinite */ + result |= 0x7C00; + } + else if (isnan(num)) + { + /* NaN */ + result |= 0x7E00; + result |= mantissa >> 13; + } + else if (exponent > 98) + { + int m; + int gr; + int s; + + exponent -= 127; + s = mantissa & 0x00000FFF; + + /* Subnormal */ + if (exponent < -14) + { + int diff = -exponent - 14; + + mantissa >>= diff; + mantissa += 1 << (23 - diff); + s |= mantissa & 0x00000FFF; + } + + m = mantissa >> 13; + + /* Round */ + gr = (mantissa >> 12) % 4; + if (gr == 3 || (gr == 1 && s != 0)) + m += 1; + + if (m == 1024) + { + m = 0; + exponent += 1; + } + + if (exponent > 15) + { + /* Infinite */ + result |= 0x7C00; + } + else + { + if (exponent >= -14) + result |= (exponent + 15) << 10; + + result |= m; + } + } + + swaphalf.i = result; + return swaphalf.h; #endif } @@ -244,20 +244,20 @@ Float4ToHalfUnchecked(float num) static inline half Float4ToHalf(float num) { - half result = Float4ToHalfUnchecked(num); + half result = Float4ToHalfUnchecked(num); - if (unlikely(HalfIsInf(result)) && !isinf(num)) - { - char *buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); + if (unlikely(HalfIsInf(result)) && !isinf(num)) + { + char *buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); - float_to_shortest_decimal_buf(num, buf); + float_to_shortest_decimal_buf(num, buf); - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type halfvec", buf))); - } + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type halfvec", buf))); + } - return result; + return result; } #endif diff --git a/src/include/access/datavec/halfvec.h b/src/include/access/datavec/halfvec.h index c46a34f248..eadefb5627 100644 --- a/src/include/access/datavec/halfvec.h +++ b/src/include/access/datavec/halfvec.h @@ -61,10 +61,10 @@ typedef struct HalfVector { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int16 dim; /* number of dimensions */ - int16 unused; /* reserved for future use, always zero */ - half x[FLEXIBLE_ARRAY_MEMBER]; + int32 vl_len_; /* varlena header (do not touch directly!) */ + int16 dim; /* number of dimensions */ + int16 unused; /* reserved for future use, always zero */ + half x[FLEXIBLE_ARRAY_MEMBER]; } HalfVector; HalfVector *InitHalfVector(int dim); diff --git a/src/include/access/datavec/hnsw.h b/src/include/access/datavec/hnsw.h index ff1f2fc449..642a983787 100644 --- a/src/include/access/datavec/hnsw.h +++ b/src/include/access/datavec/hnsw.h @@ -113,8 +113,8 @@ \ if (len == 0) { \ list = NIL; \ - return list; \ - } \ + return list; \ + } \ i = 0; \ list_arr = (ListCell **)palloc(sizeof(ListCell *) * len); \ foreach(cell, list) \ @@ -227,8 +227,8 @@ relptr_store_eval(char *base, char *val) #endif #define HnswPtrDeclare(type, relptrtype, ptrtype) \ - relptr_declare(type, relptrtype); \ - typedef union { type *ptr; relptrtype relptr; } ptrtype; + relptr_declare(type, relptrtype); \ + typedef union { type *ptr; relptrtype relptr; } ptrtype; /* Pointers that can be absolute or relative */ /* Use char for HnswDatumPtr so works with Pointer */ @@ -239,42 +239,42 @@ HnswPtrDeclare(char, DatumRelptr, HnswDatumPtr); struct HnswElementData { - HnswElementPtr next; - ItemPointerData heaptids[HNSW_HEAPTIDS]; - uint8 heaptidsLength; - uint8 level; - uint8 deleted; - uint32 hash; - HnswNeighborsPtr neighbors; - BlockNumber blkno; - OffsetNumber offno; - OffsetNumber neighborOffno; - BlockNumber neighborPage; - HnswDatumPtr value; + HnswElementPtr next; + ItemPointerData heaptids[HNSW_HEAPTIDS]; + uint8 heaptidsLength; + uint8 level; + uint8 deleted; + uint32 hash; + HnswNeighborsPtr neighbors; + BlockNumber blkno; + OffsetNumber offno; + OffsetNumber neighborOffno; + BlockNumber neighborPage; + HnswDatumPtr value; uint8 *pqcodes; - LWLock lock; + LWLock lock; }; typedef HnswElementData * HnswElement; typedef struct HnswCandidate { - HnswElementPtr element; - float distance; - bool closer; + HnswElementPtr element; + float distance; + bool closer; } HnswCandidate; struct HnswNeighborArray { - int length; - bool closerSet; - HnswCandidate items[FLEXIBLE_ARRAY_MEMBER]; + int length; + bool closerSet; + HnswCandidate items[FLEXIBLE_ARRAY_MEMBER]; }; typedef struct HnswPairingHeapNode { - pairingheap_node ph_node; - HnswCandidate *inner; + pairingheap_node ph_node; + HnswCandidate *inner; } HnswPairingHeapNode; /* HNSW index options */ @@ -291,61 +291,61 @@ typedef struct HnswOptions typedef struct HnswGraph { - /* Graph state */ - slock_t lock; - HnswElementPtr head; - double indtuples; - - /* Entry state */ - LWLock entryLock; - LWLock entryWaitLock; - HnswElementPtr entryPoint; - - /* Allocations state */ - LWLock allocatorLock; - long memoryUsed; - long memoryTotal; - - /* Flushed state */ - LWLock flushLock; - bool flushed; + /* Graph state */ + slock_t lock; + HnswElementPtr head; + double indtuples; + + /* Entry state */ + LWLock entryLock; + LWLock entryWaitLock; + HnswElementPtr entryPoint; + + /* Allocations state */ + LWLock allocatorLock; + long memoryUsed; + long memoryTotal; + + /* Flushed state */ + LWLock flushLock; + bool flushed; } HnswGraph; typedef struct HnswShared { - /* Immutable state */ - Oid heaprelid; - Oid indexrelid; + /* Immutable state */ + Oid heaprelid; + Oid indexrelid; - /* Mutex for mutable state */ - slock_t mutex; + /* Mutex for mutable state */ + slock_t mutex; - /* Mutable state */ - int nparticipantsdone; - double reltuples; - HnswGraph graphData; + /* Mutable state */ + int nparticipantsdone; + double reltuples; + HnswGraph graphData; - char *hnswarea; - ParallelHeapScanDescData heapdesc; + char *hnswarea; + ParallelHeapScanDescData heapdesc; } HnswShared; typedef struct HnswLeader { - int nparticipanttuplesorts; - HnswShared *hnswshared; + int nparticipanttuplesorts; + HnswShared *hnswshared; } HnswLeader; typedef struct HnswAllocator { - void *(*alloc) (Size size, void *state); - void *state; + void *(*alloc) (Size size, void *state); + void *state; } HnswAllocator; typedef struct HnswTypeInfo { - int maxDimensions; - Datum (*normalize) (PG_FUNCTION_ARGS); - void (*checkValue) (Pointer v); + int maxDimensions; + Datum (*normalize) (PG_FUNCTION_ARGS); + void (*checkValue) (Pointer v); } HnswTypeInfo; typedef struct HnswBuildState @@ -401,15 +401,15 @@ typedef struct HnswBuildState typedef struct HnswMetaPageData { - uint32 magicNumber; - uint32 version; - uint32 dimensions; - uint16 m; - uint16 efConstruction; - BlockNumber entryBlkno; - OffsetNumber entryOffno; - int16 entryLevel; - BlockNumber insertPage; + uint32 magicNumber; + uint32 version; + uint32 dimensions; + uint16 m; + uint16 efConstruction; + BlockNumber entryBlkno; + OffsetNumber entryOffno; + int16 entryLevel; + BlockNumber insertPage; } HnswMetaPageData; typedef HnswMetaPageData * HnswMetaPage; @@ -469,25 +469,25 @@ typedef HnswElementTupleData * HnswElementTuple; typedef struct HnswNeighborTupleData { - uint8 type; - uint8 unused; - uint16 count; - ItemPointerData indextids[FLEXIBLE_ARRAY_MEMBER]; + uint8 type; + uint8 unused; + uint16 count; + ItemPointerData indextids[FLEXIBLE_ARRAY_MEMBER]; } HnswNeighborTupleData; typedef HnswNeighborTupleData * HnswNeighborTuple; typedef struct HnswScanOpaqueData { - const HnswTypeInfo *typeInfo; - bool first; - List *w; - MemoryContext tmpCtx; + const HnswTypeInfo *typeInfo; + bool first; + List *w; + MemoryContext tmpCtx; - /* Support functions */ - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - Oid collation; + /* Support functions */ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; /* used in ustore only */ VectorScanData vs; @@ -497,28 +497,28 @@ typedef HnswScanOpaqueData * HnswScanOpaque; typedef struct HnswVacuumState { - /* Info */ - Relation index; - IndexBulkDeleteResult *stats; - IndexBulkDeleteCallback callback; - void *callback_state; - - /* Settings */ - int m; - int efConstruction; - - /* Support functions */ - FmgrInfo *procinfo; - Oid collation; - - /* Variables */ - struct tidhash_hash *deleted; - BufferAccessStrategy bas; - HnswNeighborTuple ntup; - HnswElementData highestPoint; - - /* Memory */ - MemoryContext tmpCtx; + /* Info */ + Relation index; + IndexBulkDeleteResult *stats; + IndexBulkDeleteCallback callback; + void *callback_state; + + /* Settings */ + int m; + int efConstruction; + + /* Support functions */ + FmgrInfo *procinfo; + Oid collation; + + /* Variables */ + struct tidhash_hash *deleted; + BufferAccessStrategy bas; + HnswNeighborTuple ntup; + HnswElementData highestPoint; + + /* Memory */ + MemoryContext tmpCtx; } HnswVacuumState; /* Methods */ @@ -592,18 +592,18 @@ bool hnswdelete_internal(Relation index, Datum* values, const bool* isnull, Item static inline HnswNeighborArray * HnswGetNeighbors(char *base, HnswElement element, int lc) { - HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *)HnswPtrAccess(base, element->neighbors); + HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *)HnswPtrAccess(base, element->neighbors); - Assert(element->level >= lc); + Assert(element->level >= lc); - return (HnswNeighborArray *)HnswPtrAccess(base, neighborList[lc]); + return (HnswNeighborArray *)HnswPtrAccess(base, neighborList[lc]); } /* Hash tables */ typedef struct TidHashEntry { - ItemPointerData tid; - char status; + ItemPointerData tid; + char status; } TidHashEntry; #define SH_PREFIX tidhash @@ -615,8 +615,8 @@ typedef struct TidHashEntry typedef struct PointerHashEntry { - uintptr_t ptr; - char status; + uintptr_t ptr; + char status; } PointerHashEntry; #define SH_PREFIX pointerhash @@ -628,8 +628,8 @@ typedef struct PointerHashEntry typedef struct OffsetHashEntry { - Size offset; - char status; + Size offset; + char status; } OffsetHashEntry; #define SH_PREFIX offsethash diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h index 492524971d..af0dfe578c 100644 --- a/src/include/access/datavec/ivfflat.h +++ b/src/include/access/datavec/ivfflat.h @@ -58,15 +58,15 @@ #ifdef IVFFLAT_BENCH #define IvfflatBench(name, code) \ - do { \ - instr_time start; \ - instr_time duration; \ - INSTR_TIME_SET_CURRENT(start); \ - (code); \ - INSTR_TIME_SET_CURRENT(duration); \ - INSTR_TIME_SUBTRACT(duration, start); \ - elog(INFO, "%s: %.3f ms", name, INSTR_TIME_GET_MILLISEC(duration)); \ - } while (0) + do { \ + instr_time start; \ + instr_time duration; \ + INSTR_TIME_SET_CURRENT(start); \ + (code); \ + INSTR_TIME_SET_CURRENT(duration); \ + INSTR_TIME_SUBTRACT(duration, start); \ + elog(INFO, "%s: %.3f ms", name, INSTR_TIME_GET_MILLISEC(duration)); \ + } while (0) #else #define IvfflatBench(name, code) (code) #endif @@ -81,186 +81,186 @@ typedef struct VectorArrayData { - int length; - int maxlen; - int dim; - Size itemsize; - char *items; + int length; + int maxlen; + int dim; + Size itemsize; + char *items; } VectorArrayData; typedef VectorArrayData * VectorArray; typedef struct ListInfo { - BlockNumber blkno; - OffsetNumber offno; + BlockNumber blkno; + OffsetNumber offno; } ListInfo; /* IVFFlat index options */ typedef struct IvfflatOptions { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int lists; /* number of lists */ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int lists; /* number of lists */ } IvfflatOptions; typedef struct IvfflatSpool { - Tuplesortstate *sortstate; - Relation heap; - Relation index; + Tuplesortstate *sortstate; + Relation heap; + Relation index; } IvfflatSpool; typedef struct IvfflatShared { - /* Immutable state */ - Oid heaprelid; - Oid indexrelid; - int scantuplesortstates; + /* Immutable state */ + Oid heaprelid; + Oid indexrelid; + int scantuplesortstates; - /* Mutex for mutable state */ - slock_t mutex; + /* Mutex for mutable state */ + slock_t mutex; - /* Mutable state */ - int nparticipantsdone; - double reltuples; - double indtuples; + /* Mutable state */ + int nparticipantsdone; + double reltuples; + double indtuples; - Sharedsort *sharedsort; - Vector *ivfcenters; - int workmem; + Sharedsort *sharedsort; + Vector *ivfcenters; + int workmem; #ifdef IVFFLAT_KMEANS_DEBUG - double inertia; + double inertia; #endif ParallelHeapScanDescData heapdesc; // must come last } IvfflatShared; #define ParallelTableScanFromIvfflatShared(shared) \ - (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(IvfflatShared))) + (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(IvfflatShared))) typedef struct IvfflatLeader { - int nparticipanttuplesorts; - IvfflatShared *ivfshared; + int nparticipanttuplesorts; + IvfflatShared *ivfshared; } IvfflatLeader; typedef struct IvfflatTypeInfo { - int maxDimensions; - Datum (*normalize) (PG_FUNCTION_ARGS); - Size (*itemSize) (int dimensions); - void (*updateCenter) (Pointer v, int dimensions, float *x); - void (*sumCenter) (Pointer v, float *x); + int maxDimensions; + Datum (*normalize) (PG_FUNCTION_ARGS); + Size (*itemSize) (int dimensions); + void (*updateCenter) (Pointer v, int dimensions, float *x); + void (*sumCenter) (Pointer v, float *x); } IvfflatTypeInfo; typedef struct IvfflatBuildState { - /* Info */ - Relation heap; - Relation index; - IndexInfo *indexInfo; - const IvfflatTypeInfo *typeInfo; - - /* Settings */ - int dimensions; - int lists; - - /* Statistics */ - double indtuples; - double reltuples; - - /* Support functions */ - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - FmgrInfo *kmeansnormprocinfo; - Oid collation; - - /* Variables */ - VectorArray samples; - VectorArray centers; - ListInfo *listInfo; + /* Info */ + Relation heap; + Relation index; + IndexInfo *indexInfo; + const IvfflatTypeInfo *typeInfo; + + /* Settings */ + int dimensions; + int lists; + + /* Statistics */ + double indtuples; + double reltuples; + + /* Support functions */ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + FmgrInfo *kmeansnormprocinfo; + Oid collation; + + /* Variables */ + VectorArray samples; + VectorArray centers; + ListInfo *listInfo; #ifdef IVFFLAT_KMEANS_DEBUG - double inertia; - double *listSums; - int *listCounts; + double inertia; + double *listSums; + int *listCounts; #endif - /* Sampling */ - BlockSamplerData bs; + /* Sampling */ + BlockSamplerData bs; double rstate; - int rowstoskip; + int rowstoskip; - /* Sorting */ - Tuplesortstate *sortstate; - TupleDesc tupdesc; - TupleTableSlot *slot; + /* Sorting */ + Tuplesortstate *sortstate; + TupleDesc tupdesc; + TupleTableSlot *slot; - /* Memory */ - MemoryContext tmpCtx; + /* Memory */ + MemoryContext tmpCtx; - /* Parallel builds */ - IvfflatLeader *ivfleader; + /* Parallel builds */ + IvfflatLeader *ivfleader; } IvfflatBuildState; typedef struct IvfflatMetaPageData { - uint32 magicNumber; - uint32 version; - uint16 dimensions; - uint16 lists; + uint32 magicNumber; + uint32 version; + uint16 dimensions; + uint16 lists; } IvfflatMetaPageData; typedef IvfflatMetaPageData * IvfflatMetaPage; typedef struct IvfflatPageOpaqueData { - BlockNumber nextblkno; - uint16 unused; - uint16 page_id; /* for identification of IVFFlat indexes */ + BlockNumber nextblkno; + uint16 unused; + uint16 page_id; /* for identification of IVFFlat indexes */ } IvfflatPageOpaqueData; typedef IvfflatPageOpaqueData * IvfflatPageOpaque; typedef struct IvfflatListData { - BlockNumber startPage; - BlockNumber insertPage; - Vector center; + BlockNumber startPage; + BlockNumber insertPage; + Vector center; } IvfflatListData; typedef IvfflatListData * IvfflatList; typedef struct IvfflatScanList { - pairingheap_node ph_node; - BlockNumber startPage; - double distance; + pairingheap_node ph_node; + BlockNumber startPage; + double distance; } IvfflatScanList; typedef struct IvfflatScanOpaqueData { - const IvfflatTypeInfo *typeInfo; - int probes; - int dimensions; - bool first; - - /* Sorting */ - Tuplesortstate *sortstate; - TupleDesc tupdesc; - TupleTableSlot *slot; - bool isnull; - - /* Support functions */ - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - Oid collation; - Datum (*distfunc) (FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2); - - /* Lists */ - pairingheap *listQueue; - IvfflatScanList lists[FLEXIBLE_ARRAY_MEMBER]; /* must come last */ + const IvfflatTypeInfo *typeInfo; + int probes; + int dimensions; + bool first; + + /* Sorting */ + Tuplesortstate *sortstate; + TupleDesc tupdesc; + TupleTableSlot *slot; + bool isnull; + + /* Support functions */ + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + Datum (*distfunc) (FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2); + + /* Lists */ + pairingheap *listQueue; + IvfflatScanList lists[FLEXIBLE_ARRAY_MEMBER]; /* must come last */ } IvfflatScanOpaqueData; typedef IvfflatScanOpaqueData * IvfflatScanOpaque; @@ -272,13 +272,13 @@ typedef IvfflatScanOpaqueData * IvfflatScanOpaque; static inline Pointer VectorArrayGet(VectorArray arr, int offset) { - return ((char *) arr->items) + (offset * arr->itemsize); + return ((char *) arr->items) + (offset * arr->itemsize); } static inline void VectorArraySet(VectorArray arr, int offset, Pointer val) { - memcpy(VectorArrayGet(arr, offset), val, VARSIZE_ANY(val)); + memcpy(VectorArrayGet(arr, offset), val, VARSIZE_ANY(val)); } /* Methods */ diff --git a/src/include/access/datavec/pg_prng.h b/src/include/access/datavec/pg_prng.h index e201b95686..dcdc1875fd 100644 --- a/src/include/access/datavec/pg_prng.h +++ b/src/include/access/datavec/pg_prng.h @@ -18,8 +18,8 @@ */ typedef struct pg_prng_state { - uint64 s0, - s1; + uint64 s0, + s1; } pg_prng_state; /* @@ -44,8 +44,8 @@ extern bool pg_prng_seed_check(pg_prng_state *state); * pg_strong_random.c and thence OpenSSL. */ #define pg_prng_strong_seed(state) \ - (pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \ - pg_prng_seed_check(state) : false) + (pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \ + pg_prng_seed_check(state) : false) extern uint64 pg_prng_uint64(pg_prng_state *state); extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax); diff --git a/src/include/access/datavec/ryu_common.h b/src/include/access/datavec/ryu_common.h index 69aa7ac125..0dbe1b1d73 100644 --- a/src/include/access/datavec/ryu_common.h +++ b/src/include/access/datavec/ryu_common.h @@ -70,81 +70,81 @@ static const char DIGIT_TABLE[200] = { static inline uint32 pow5bits(const int32 e) { - /* - * This approximation works up to the point that the multiplication - * overflows at e = 3529. - * - * If the multiplication were done in 64 bits, it would fail at 5^4004 - * which is just greater than 2^9297. - */ - Assert(e >= 0); - Assert(e <= 3528); - return ((((uint32) e) * 1217359) >> 19) + 1; + /* + * This approximation works up to the point that the multiplication + * overflows at e = 3529. + * + * If the multiplication were done in 64 bits, it would fail at 5^4004 + * which is just greater than 2^9297. + */ + Assert(e >= 0); + Assert(e <= 3528); + return ((((uint32) e) * 1217359) >> 19) + 1; } /* Returns floor(log_10(2^e)). */ static inline int32 log10Pow2(const int32 e) { - /* - * The first value this approximation fails for is 2^1651 which is just - * greater than 10^297. - */ - Assert(e >= 0); - Assert(e <= 1650); - return (int32) ((((uint32) e) * 78913) >> 18); + /* + * The first value this approximation fails for is 2^1651 which is just + * greater than 10^297. + */ + Assert(e >= 0); + Assert(e <= 1650); + return (int32) ((((uint32) e) * 78913) >> 18); } /* Returns floor(log_10(5^e)). */ static inline int32 log10Pow5(const int32 e) { - /* - * The first value this approximation fails for is 5^2621 which is just - * greater than 10^1832. - */ - Assert(e >= 0); - Assert(e <= 2620); - return (int32) ((((uint32) e) * 732923) >> 20); + /* + * The first value this approximation fails for is 5^2621 which is just + * greater than 10^1832. + */ + Assert(e >= 0); + Assert(e <= 2620); + return (int32) ((((uint32) e) * 732923) >> 20); } static inline int copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) { - if (mantissa) - { - memcpy(result, "NaN", 3); - return 3; - } - if (sign) - { - result[0] = '-'; - } - if (exponent) - { - memcpy(result + sign, "Infinity", 8); - return sign + 8; - } - result[sign] = '0'; - return sign + 1; + if (mantissa) + { + memcpy(result, "NaN", 3); + return 3; + } + if (sign) + { + result[0] = '-'; + } + if (exponent) + { + memcpy(result + sign, "Infinity", 8); + return sign + 8; + } + result[sign] = '0'; + return sign + 1; } static inline uint32 float_to_bits(const float f) { - uint32 bits = 0; + uint32 bits = 0; - memcpy(&bits, &f, sizeof(float)); - return bits; + memcpy(&bits, &f, sizeof(float)); + return bits; } static inline uint64 double_to_bits(const double d) { - uint64 bits = 0; + uint64 bits = 0; - memcpy(&bits, &d, sizeof(double)); - return bits; + memcpy(&bits, &d, sizeof(double)); + return bits; } #endif /* RYU_COMMON_H */ diff --git a/src/include/access/datavec/sampling.h b/src/include/access/datavec/sampling.h index 13934f4083..5f3772fb5f 100644 --- a/src/include/access/datavec/sampling.h +++ b/src/include/access/datavec/sampling.h @@ -7,7 +7,7 @@ /* Random generator for sampling code */ extern void sampler_random_init_state(uint32 seed, - pg_prng_state *randstate); + pg_prng_state *randstate); extern double sampler_random_fract(pg_prng_state *randstate); /* Block sampling methods */ @@ -15,17 +15,17 @@ extern double sampler_random_fract(pg_prng_state *randstate); /* Data structure for Algorithm S from Knuth 3.4.2 */ typedef struct { - BlockNumber N; /* number of blocks, known in advance */ - uint32 n; /* desired sample size */ - BlockNumber t; /* current block number */ - uint32 m; /* blocks selected so far */ - pg_prng_state randstate; /* random generator state */ + BlockNumber N; /* number of blocks, known in advance */ + uint32 n; /* desired sample size */ + BlockNumber t; /* current block number */ + uint32 m; /* blocks selected so far */ + pg_prng_state randstate; /* random generator state */ } BlockSamplerData2; typedef BlockSamplerData2 *BlockSampler2; extern BlockNumber BlockSampler_Init2(BlockSampler2 bs, BlockNumber nblocks, - int samplesize, uint32 randseed); + int samplesize, uint32 randseed); extern bool BlockSampler_HasMore2(BlockSampler2 bs); extern BlockNumber BlockSampler_Next2(BlockSampler2 bs); @@ -33,8 +33,8 @@ extern BlockNumber BlockSampler_Next2(BlockSampler2 bs); typedef struct { - double W; - pg_prng_state randstate; /* random generator state */ + double W; + pg_prng_state randstate; /* random generator state */ } ReservoirStateData; typedef ReservoirStateData *ReservoirState; diff --git a/src/include/access/datavec/sparsevec.h b/src/include/access/datavec/sparsevec.h index 1fcf4e2522..6809e8d4d2 100644 --- a/src/include/access/datavec/sparsevec.h +++ b/src/include/access/datavec/sparsevec.h @@ -41,11 +41,11 @@ Datum sparsevec_to_halfvec(PG_FUNCTION_ARGS); typedef struct SparseVector { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int32 dim; /* number of dimensions */ - int32 nnz; /* number of non-zero elements */ - int32 unused; /* reserved for future use, always zero */ - int32 indices[FLEXIBLE_ARRAY_MEMBER]; + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 dim; /* number of dimensions */ + int32 nnz; /* number of non-zero elements */ + int32 unused; /* reserved for future use, always zero */ + int32 indices[FLEXIBLE_ARRAY_MEMBER]; } SparseVector; /* Use functions instead of macros to avoid double evaluation */ @@ -53,13 +53,13 @@ typedef struct SparseVector static inline Size SPARSEVEC_SIZE(int nnz) { - return offsetof(SparseVector, indices) + (nnz * sizeof(int32)) + (nnz * sizeof(float)); + return offsetof(SparseVector, indices) + (nnz * sizeof(int32)) + (nnz * sizeof(float)); } static inline float * SPARSEVEC_VALUES(SparseVector * x) { - return (float *) (((char *) x) + offsetof(SparseVector, indices) + (x->nnz * sizeof(int32))); + return (float *) (((char *) x) + offsetof(SparseVector, indices) + (x->nnz * sizeof(int32))); } SparseVector *InitSparseVector(int dim, int nnz); diff --git a/src/include/access/datavec/vector.h b/src/include/access/datavec/vector.h index 6fce5cb71c..fc9ff17530 100644 --- a/src/include/access/datavec/vector.h +++ b/src/include/access/datavec/vector.h @@ -12,10 +12,10 @@ typedef struct Vector { - int32 vl_len_; /* varlena header (do not touch directly!) */ - int16 dim; /* number of dimensions */ - int16 unused; /* reserved for future use, always zero */ - float x[FLEXIBLE_ARRAY_MEMBER]; + int32 vl_len_; /* varlena header (do not touch directly!) */ + int16 dim; /* number of dimensions */ + int16 unused; /* reserved for future use, always zero */ + float x[FLEXIBLE_ARRAY_MEMBER]; } Vector; Vector *InitVector(int dim); -- Gitee From 9b850fd0c331ab1c11937f16b8bb48cac325de50 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Fri, 1 Nov 2024 15:56:49 +0800 Subject: [PATCH 08/67] clean code --- .../storage/access/datavec/Makefile | 2 +- .../storage/access/datavec/bitutils.cpp | 47 ++- .../storage/access/datavec/hnsw.cpp | 13 +- .../storage/access/datavec/hnswbuild.cpp | 116 ++++---- .../storage/access/datavec/hnswinsert.cpp | 125 ++++---- .../storage/access/datavec/hnswscan.cpp | 23 +- .../storage/access/datavec/hnswutils.cpp | 273 ++++++++---------- .../storage/access/datavec/hnswvacuum.cpp | 149 ++++------ .../storage/access/datavec/ivfbuild.cpp | 121 ++++---- .../storage/access/datavec/ivfflat.cpp | 12 +- .../storage/access/datavec/ivfinsert.cpp | 44 ++- .../storage/access/datavec/ivfkmeans.cpp | 232 +++++++-------- .../storage/access/datavec/ivfscan.cpp | 85 +++--- .../storage/access/datavec/ivfutils.cpp | 46 ++- .../storage/access/datavec/ivfvacuum.cpp | 45 ++- .../storage/access/datavec/vecindex.cpp | 25 +- 16 files changed, 580 insertions(+), 778 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/Makefile b/src/gausskernel/storage/access/datavec/Makefile index 4fcedca437..c6c1736f66 100644 --- a/src/gausskernel/storage/access/datavec/Makefile +++ b/src/gausskernel/storage/access/datavec/Makefile @@ -11,6 +11,6 @@ ifneq "$(MAKECMDGOALS)" "clean" endif OBJS = bitutils.o hnsw.o hnswbuild.o hnswdelete.o hnswinsert.o hnswscan.o hnswutils.o hnswvacuum.o \ - ivfbuild.o ivfflat.o ivfinsert.o ivfkmeans.o ivfscan.o ivfutils.o ivfvacuum.o vecindex.o + ivfbuild.o ivfflat.o ivfinsert.o ivfkmeans.o ivfscan.o ivfutils.o ivfvacuum.o vecindex.o include $(top_srcdir)/src/gausskernel/common.mk diff --git a/src/gausskernel/storage/access/datavec/bitutils.cpp b/src/gausskernel/storage/access/datavec/bitutils.cpp index 36f43929cc..c2f59152fa 100644 --- a/src/gausskernel/storage/access/datavec/bitutils.cpp +++ b/src/gausskernel/storage/access/datavec/bitutils.cpp @@ -1,7 +1,7 @@ #include "postgres.h" #include "access/datavec/bitvec.h" -#include "access/datavec/halfvec.h" /* for USE_DISPATCH and USE_TARGET_CLONES */ +#include "access/datavec/halfvec.h" /* for USE_DISPATCH and USE_TARGET_CLONES */ #include "port/pg_bitutils.h" #if defined(USE_DISPATCH) @@ -43,8 +43,8 @@ BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui #ifdef popcount64 for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) { - uint64 axs; - uint64 bxs; + uint64 axs; + uint64 bxs; /* Ensure aligned */ memcpy(&axs, ax, sizeof(uint64)); @@ -67,12 +67,11 @@ BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui TARGET_AVX512_POPCOUNT static uint64 BitHammingDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance) { - __m512i dist = _mm512_setzero_si512(); + __m512i dist = _mm512_setzero_si512(); - for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) - { - __m512i axs = _mm512_loadu_si512((const __m512i *) ax); - __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) { + __m512i axs = _mm512_loadu_si512((const __m512i *) ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); dist = _mm512_add_epi64(dist, _mm512_popcnt_epi64(_mm512_xor_si512(axs, bxs))); @@ -90,10 +89,9 @@ BIT_TARGET_CLONES static double BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) { #ifdef popcount64 - for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) - { - uint64 axs; - uint64 bxs; + for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) { + uint64 axs; + uint64 bxs; /* Ensure aligned */ memcpy(&axs, ax, sizeof(uint64)); @@ -108,8 +106,7 @@ BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui } #endif - for (uint32 i = 0; i < bytes; i++) - { + for (uint32 i = 0; i < bytes; i++) { ab += pg_number_of_ones[ax[i] & bx[i]]; aa += pg_number_of_ones[ax[i]]; bb += pg_number_of_ones[bx[i]]; @@ -125,14 +122,13 @@ BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui TARGET_AVX512_POPCOUNT static double BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) { - __m512i abx = _mm512_setzero_si512(); - __m512i aax = _mm512_setzero_si512(); - __m512i bbx = _mm512_setzero_si512(); + __m512i abx = _mm512_setzero_si512(); + __m512i aax = _mm512_setzero_si512(); + __m512i bbx = _mm512_setzero_si512(); - for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) - { - __m512i axs = _mm512_loadu_si512((const __m512i *) ax); - __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) { + __m512i axs = _mm512_loadu_si512((const __m512i *) ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); abx = _mm512_add_epi64(abx, _mm512_popcnt_epi64(_mm512_and_si512(axs, bxs))); aax = _mm512_add_epi64(aax, _mm512_popcnt_epi64(axs)); @@ -151,9 +147,9 @@ BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char #endif #ifdef BIT_DISPATCH -#define CPU_FEATURE_OSXSAVE (1 << 27) /* F1 ECX */ -#define CPU_FEATURE_AVX512F (1 << 16) /* F7,0 EBX */ -#define CPU_FEATURE_AVX512VPOPCNTDQ (1 << 14) /* F7,0 ECX */ +#define CPU_FEATURE_OSXSAVE (1 << 27) /* F1 ECX */ +#define CPU_FEATURE_AVX512F (1 << 16) /* F7,0 EBX */ +#define CPU_FEATURE_AVX512VPOPCNTDQ (1 << 14) /* F7,0 ECX */ #ifdef _MSC_VER #define TARGET_XSAVE @@ -206,8 +202,7 @@ BitvecInit(void) BitJaccardDistance = BitJaccardDistanceDefault; #ifdef BIT_DISPATCH - if (SupportsAvx512Popcount()) - { + if (SupportsAvx512Popcount()) { BitHammingDistance = BitHammingDistanceAvx512Popcount; BitJaccardDistance = BitJaccardDistanceAvx512Popcount; } diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp index cd860a37bb..29d2827df0 100644 --- a/src/gausskernel/storage/access/datavec/hnsw.cpp +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -11,7 +11,7 @@ #include "utils/guc.h" #include "utils/selfuncs.h" -int hnsw_lock_tranche_id; +int hnsw_lock_tranche_id; static relopt_kind hnsw_relopt_kind; static THR_LOCAL bool HnswNeedInitialization = true; @@ -42,13 +42,12 @@ hnswcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, Selectivity *indexSelectivity, double *indexCorrelation) { GenericCosts costs; - int m; - int entryLevel; - Relation index; + int m; + int entryLevel; + Relation index; /* Never use index without order */ - if (path->indexorderbys == NULL) - { + if (path->indexorderbys == NULL) { *indexStartupCost = DBL_MAX; *indexTotalCost = DBL_MAX; *indexSelectivity = 0; @@ -268,7 +267,7 @@ hnswcostestimate(PG_FUNCTION_ARGS) double *correlation = (double *)PG_GETARG_POINTER(6); hnswcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); - PG_RETURN_VOID(); + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswoptions); diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp index 2203f38006..e1547b65e0 100644 --- a/src/gausskernel/storage/access/datavec/hnswbuild.cpp +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -67,9 +67,9 @@ #include "utils/wait_event.h" #endif -#define PARALLEL_KEY_HNSW_SHARED UINT64CONST(0xA000000000000001) -#define PARALLEL_KEY_HNSW_AREA UINT64CONST(0xA000000000000002) -#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000003) +#define PARALLEL_KEY_HNSW_SHARED UINT64CONST(0xA000000000000001) +#define PARALLEL_KEY_HNSW_AREA UINT64CONST(0xA000000000000002) +#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000003) #define PROGRESS_CREATEIDX_TUPLES_DONE 0 #if PG_VERSION_NUM < 130000 @@ -180,7 +180,7 @@ static void HnswBuildAppendPage(Relation index, Buffer *buf, Page *page, ForkNumber forkNum) { /* Add a new page */ - Buffer newbuf = HnswNewBuffer(index, forkNum); + Buffer newbuf = HnswNewBuffer(index, forkNum); /* Update previous page */ HnswPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); @@ -330,22 +330,21 @@ CreateGraphPages(HnswBuildState * buildstate) static void WriteNeighborTuples(HnswBuildState * buildstate) { - Relation index = buildstate->index; - ForkNumber forkNum = buildstate->forkNum; - int m = buildstate->m; + Relation index = buildstate->index; + ForkNumber forkNum = buildstate->forkNum; + int m = buildstate->m; HnswElementPtr iter = buildstate->graph->head; - char *base = buildstate->hnswarea; + char *base = buildstate->hnswarea; HnswNeighborTuple ntup; /* Allocate once */ ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); - while (!HnswPtrIsNull(base, iter)) - { + while (!HnswPtrIsNull(base, iter)) { HnswElement element = (HnswElement)HnswPtrAccess(base, iter); - Buffer buf; - Page page; - Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); + Buffer buf; + Page page; + Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); /* Update iterator */ iter = element->next; @@ -400,8 +399,7 @@ AddDuplicateInMemory(HnswElement element, HnswElement dup) { LWLockAcquire(&dup->lock, LW_EXCLUSIVE); - if (dup->heaptidsLength == HNSW_HEAPTIDS) - { + if (dup->heaptidsLength == HNSW_HEAPTIDS) { LWLockRelease(&dup->lock); return false; } @@ -420,13 +418,12 @@ static bool FindDuplicateInMemory(char *base, HnswElement element) { HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); - Datum value = HnswGetValue(base, element); + Datum value = HnswGetValue(base, element); - for (int i = 0; i < neighbors->length; i++) - { + for (int i = 0; i < neighbors->length; i++) { HnswCandidate *neighbor = &neighbors->items[i]; HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); - Datum neighborValue = HnswGetValue(base, neighborElement); + Datum neighborValue = HnswGetValue(base, neighborElement); /* Exit early since ordered by distance */ if (!datumIsEqual(value, neighborValue, false, -1)) @@ -458,13 +455,11 @@ AddElementInMemory(char *base, HnswGraph * graph, HnswElement element) static void UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswElement e, int m) { - for (int lc = e->level; lc >= 0; lc--) - { - int lm = HnswGetLayerM(m, lc); + for (int lc = e->level; lc >= 0; lc--) { + int lm = HnswGetLayerM(m, lc); HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); - for (int i = 0; i < neighbors->length; i++) - { + for (int i = 0; i < neighbors->length; i++) { HnswCandidate *hc = &neighbors->items[i]; HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); @@ -485,8 +480,8 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme static void UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, HnswBuildState * buildstate) { - HnswGraph *graph = buildstate->graph; - char *base = buildstate->hnswarea; + HnswGraph *graph = buildstate->graph; + char *base = buildstate->hnswarea; /* Look for duplicate */ if (FindDuplicateInMemory(base, element)) @@ -509,15 +504,15 @@ UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int static void InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) { - FmgrInfo *procinfo = buildstate->procinfo; - Oid collation = buildstate->collation; - HnswGraph *graph = buildstate->graph; + FmgrInfo *procinfo = buildstate->procinfo; + Oid collation = buildstate->collation; + HnswGraph *graph = buildstate->graph; HnswElement entryPoint; - LWLock *entryLock = &graph->entryLock; - LWLock *entryWaitLock = &graph->entryWaitLock; - int efConstruction = buildstate->efConstruction; - int m = buildstate->m; - char *base = buildstate->hnswarea; + LWLock *entryLock = &graph->entryLock; + LWLock *entryWaitLock = &graph->entryWaitLock; + int efConstruction = buildstate->efConstruction; + int m = buildstate->m; + char *base = buildstate->hnswarea; /* Wait if another process needs exclusive lock on entry lock */ LWLockAcquire(entryWaitLock, LW_EXCLUSIVE); @@ -528,8 +523,7 @@ InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); /* Prevent concurrent inserts when likely updating entry point */ - if (entryPoint == NULL || element->level > entryPoint->level) - { + if (entryPoint == NULL || element->level > entryPoint->level) { /* Release shared lock */ LWLockRelease(entryLock); @@ -558,25 +552,24 @@ InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) static bool InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heaptid, HnswBuildState * buildstate) { - const HnswTypeInfo *typeInfo = buildstate->typeInfo; - HnswGraph *graph = buildstate->graph; + const HnswTypeInfo *typeInfo = buildstate->typeInfo; + HnswGraph *graph = buildstate->graph; HnswElement element; HnswAllocator *allocator = &buildstate->allocator; - Size valueSize; - Pointer valuePtr; - LWLock *flushLock = &graph->flushLock; - char *base = buildstate->hnswarea; + Size valueSize; + Pointer valuePtr; + LWLock *flushLock = &graph->flushLock; + char *base = buildstate->hnswarea; /* Detoast once for all calls */ - Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); /* Check value */ if (typeInfo->checkValue != NULL) typeInfo->checkValue(DatumGetPointer(value)); /* Normalize if needed */ - if (buildstate->normprocinfo != NULL) - { + if (buildstate->normprocinfo != NULL) { if (!HnswCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) return false; @@ -590,8 +583,7 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heapt LWLockAcquire(flushLock, LW_SHARED); /* Are we in the on-disk phase? */ - if (graph->flushed) - { + if (graph->flushed) { LWLockRelease(flushLock); return HnswInsertTupleOnDisk(index, value, values, isnull, heaptid, true); @@ -607,15 +599,13 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heapt * Check that we have enough memory available for the new element now that * we have the allocator lock, and flush pages if needed. */ - if (graph->memoryUsed >= graph->memoryTotal) - { + if (graph->memoryUsed >= graph->memoryTotal) { LWLockRelease(&graph->allocatorLock); LWLockRelease(flushLock); LWLockAcquire(flushLock, LW_EXCLUSIVE); - if (!graph->flushed) - { + if (!graph->flushed) { ereport(NOTICE, (errmsg("hnsw graph no longer fits into maintenance_work_mem after " INT64_FORMAT " tuples", (int64) graph->indtuples), errdetail("Building will take significantly more time."), @@ -664,7 +654,7 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, const bool *isnull, bool tupleIsAlive, void *state) { HnswBuildState *buildstate = (HnswBuildState *) state; - HnswGraph *graph = buildstate->graph; + HnswGraph *graph = buildstate->graph; MemoryContext oldCtx; #if PG_VERSION_NUM < 130000 @@ -679,8 +669,7 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); /* Insert tuple */ - if (InsertTuple(index, values, isnull, tid, buildstate)) - { + if (InsertTuple(index, values, isnull, tid, buildstate)) { /* Update progress */ SpinLockAcquire(&graph->lock); UpdateProgress(PROGRESS_CREATEIDX_TUPLES_DONE, ++graph->indtuples); @@ -728,7 +717,7 @@ static void * HnswMemoryContextAlloc(Size size, void *state) { HnswBuildState *buildstate = (HnswBuildState *) state; - void *chunk = MemoryContextAlloc(buildstate->graphCtx, size); + void *chunk = MemoryContextAlloc(buildstate->graphCtx, size); #if PG_VERSION_NUM >= 130000 buildstate->graphData.memoryUsed = MemoryContextMemAllocated(buildstate->graphCtx, false); @@ -857,7 +846,7 @@ HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared * hnsw { HnswBuildState buildstate; TableScanDesc scan; - double reltuples; + double reltuples; IndexInfo *indexInfo; /* Join parallel scan */ @@ -886,9 +875,9 @@ void HnswParallelBuildMain(const BgWorkerContext *bwc) { HnswShared *hnswshared; - char *hnswarea; - Relation heapRel; - Relation indexRel; + char *hnswarea; + Relation heapRel; + Relation indexRel; /* Look up shared state */ hnswshared = (HnswShared*)bwc->bgshared; @@ -920,9 +909,9 @@ static HnswShared* HnswParallelInitshared(HnswBuildState * buildstate) { HnswShared *hnswshared; - char *hnswarea; - Size esthnswarea; - Size estother; + char *hnswarea; + Size esthnswarea; + Size estother; /* Store shared build state, for which we reserved space */ hnswshared = (HnswShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(HnswShared)); @@ -977,8 +966,7 @@ HnswBeginParallel(HnswBuildState * buildstate, int request) hnswleader->hnswshared = hnswshared; /* If no workers were successfully launched, back out (do serial build) */ - if (hnswleader->nparticipanttuplesorts == 0) - { + if (hnswleader->nparticipanttuplesorts == 0) { HnswEndParallel(); return; } diff --git a/src/gausskernel/storage/access/datavec/hnswinsert.cpp b/src/gausskernel/storage/access/datavec/hnswinsert.cpp index bf23fb30bd..bf787056dd 100644 --- a/src/gausskernel/storage/access/datavec/hnswinsert.cpp +++ b/src/gausskernel/storage/access/datavec/hnswinsert.cpp @@ -16,8 +16,8 @@ static BlockNumber GetInsertPage(Relation index) { - Buffer buf; - Page page; + Buffer buf; + Page page; HnswMetaPage metap; BlockNumber insertPage; @@ -42,31 +42,26 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size OffsetNumber offno; OffsetNumber maxoffno = PageGetMaxOffsetNumber(page); - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); /* Skip neighbor tuples */ if (!HnswIsElementTuple(etup)) continue; - if (etup->deleted) - { + if (etup->deleted) { BlockNumber elementPage = BufferGetBlockNumber(buf); BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - ItemId itemid; + ItemId itemid; if (!BlockNumberIsValid(*newInsertPage)) *newInsertPage = elementPage; - if (neighborPage == elementPage) - { + if (neighborPage == elementPage) { *nbuf = buf; *npage = page; - } - else - { + } else { *nbuf = ReadBuffer(index, neighborPage); LockBuffer(*nbuf, BUFFER_LOCK_EXCLUSIVE); @@ -77,13 +72,11 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size itemid = PageGetItemId(*npage, neighborOffno); /* Check for space on neighbor tuple page */ - if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize) - { + if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize) { *freeOffno = offno; *freeNeighborOffno = neighborOffno; return true; - } - else if (*nbuf != buf) + } else if (*nbuf != buf) UnlockReleaseBuffer(*nbuf); } } @@ -337,8 +330,7 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B static bool ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) { - for (int i = 0; i < lm; i++) - { + for (int i = 0; i < lm; i++) { ItemPointer indextid = &ntup->indextids[startIdx + i]; if (!ItemPointerIsValid(indextid)) @@ -357,22 +349,20 @@ ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) void HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting, bool building) { - char *base = NULL; + char *base = NULL; - for (int lc = e->level; lc >= 0; lc--) - { - int lm = HnswGetLayerM(m, lc); + for (int lc = e->level; lc >= 0; lc--) { + int lm = HnswGetLayerM(m, lc); HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); - for (int i = 0; i < neighbors->length; i++) - { + for (int i = 0; i < neighbors->length; i++) { HnswCandidate *hc = &neighbors->items[i]; - Buffer buf; - Page page; + Buffer buf; + Page page; GenericXLogState *state; HnswNeighborTuple ntup; - int idx = -1; - int startIdx; + int idx = -1; + int startIdx; HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, hc->element); OffsetNumber offno = neighborElement->neighborOffno; @@ -397,13 +387,10 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns /* Register page */ buf = ReadBuffer(index, neighborElement->neighborPage); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - if (building) - { + if (building) { state = NULL; page = BufferGetPage(buf); - } - else - { + } else { state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); } @@ -417,25 +404,20 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns /* Check for existing connection */ if (checkExisting && ConnectionExists(e, ntup, startIdx, lm)) idx = -1; - else if (idx == -2) - { + else if (idx == -2) { /* Find free offset if still exists */ /* TODO Retry updating connections if not */ - for (int j = 0; j < lm; j++) - { - if (!ItemPointerIsValid(&ntup->indextids[startIdx + j])) - { + for (int j = 0; j < lm; j++) { + if (!ItemPointerIsValid(&ntup->indextids[startIdx + j])) { idx = startIdx + j; break; } } - } - else + } else idx += startIdx; /* Make robust to issues */ - if (idx >= 0 && idx < ntup->count) - { + if (idx >= 0 && idx < ntup->count) { ItemPointer indextid = &ntup->indextids[idx]; /* Update neighbor on the buffer */ @@ -446,8 +428,7 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns MarkBufferDirty(buf); else GenericXLogFinish(state); - } - else if (!building) + } else if (!building) GenericXLogAbort(state); UnlockReleaseBuffer(buf); @@ -461,37 +442,32 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns static bool AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool building) { - Buffer buf; - Page page; + Buffer buf; + Page page; GenericXLogState *state; HnswElementTuple etup; - int i; + int i; /* Read page */ buf = ReadBuffer(index, dup->blkno); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - if (building) - { + if (building) { state = NULL; page = BufferGetPage(buf); - } - else - { + } else { state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); } /* Find space */ etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, dup->offno)); - for (i = 0; i < HNSW_HEAPTIDS; i++) - { + for (i = 0; i < HNSW_HEAPTIDS; i++) { if (!ItemPointerIsValid(&etup->heaptids[i])) break; } /* Either being deleted or we lost our chance to another backend */ - if (i == 0 || i == HNSW_HEAPTIDS) - { + if (i == 0 || i == HNSW_HEAPTIDS) { if (!building) GenericXLogAbort(state); UnlockReleaseBuffer(buf); @@ -517,15 +493,14 @@ AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool bu static bool FindDuplicateOnDisk(Relation index, HnswElement element, bool building) { - char *base = NULL; + char *base = NULL; HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); - Datum value = HnswGetValue(base, element); + Datum value = HnswGetValue(base, element); - for (int i = 0; i < neighbors->length; i++) - { + for (int i = 0; i < neighbors->length; i++) { HnswCandidate *neighbor = &neighbors->items[i]; HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); - Datum neighborValue = HnswGetValue(base, neighborElement); + Datum neighborValue = HnswGetValue(base, neighborElement); /* Exit early since ordered by distance */ if (!datumIsEqual(value, neighborValue, false, -1)) @@ -573,12 +548,12 @@ HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *is { HnswElement entryPoint; HnswElement element; - int m; - int efConstruction = HnswGetEfConstruction(index); - FmgrInfo *procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); - Oid collation = index->rd_indcollation[0]; - LOCKMODE lockmode = ShareLock; - char *base = NULL; + int m; + int efConstruction = HnswGetEfConstruction(index); + FmgrInfo *procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); + Oid collation = index->rd_indcollation[0]; + LOCKMODE lockmode = ShareLock; + char *base = NULL; /* * Get a shared lock. This allows vacuum to ensure no in-flight inserts @@ -595,8 +570,7 @@ HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *is HnswPtrStore(base, element->value, DatumGetPointer(value)); /* Prevent concurrent inserts when likely updating entry point */ - if (entryPoint == NULL || element->level > entryPoint->level) - { + if (entryPoint == NULL || element->level > entryPoint->level) { /* Release shared lock */ UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); @@ -626,10 +600,10 @@ HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *is static void HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid) { - Datum value; - const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index); - FmgrInfo *normprocinfo; - Oid collation = index->rd_indcollation[0]; + Datum value; + const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index); + FmgrInfo *normprocinfo; + Oid collation = index->rd_indcollation[0]; /* Detoast once for all calls */ value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); @@ -640,8 +614,7 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti /* Normalize if needed */ normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); - if (normprocinfo != NULL) - { + if (normprocinfo != NULL) { if (!HnswCheckNorm(normprocinfo, collation, value)) return; diff --git a/src/gausskernel/storage/access/datavec/hnswscan.cpp b/src/gausskernel/storage/access/datavec/hnswscan.cpp index c8962028d1..c702a9c2ac 100644 --- a/src/gausskernel/storage/access/datavec/hnswscan.cpp +++ b/src/gausskernel/storage/access/datavec/hnswscan.cpp @@ -14,14 +14,14 @@ static List * GetScanItems(IndexScanDesc scan, Datum q) { HnswScanOpaque so = (HnswScanOpaque) scan->opaque; - Relation index = scan->indexRelation; - FmgrInfo *procinfo = so->procinfo; - Oid collation = so->collation; - List *ep; - List *w; - int m; + Relation index = scan->indexRelation; + FmgrInfo *procinfo = so->procinfo; + Oid collation = so->collation; + List *ep; + List *w; + int m; HnswElement entryPoint; - char *base = NULL; + char *base = NULL; /* Get m and entry point */ HnswGetMetaPageInfo(index, &m, &entryPoint); @@ -47,12 +47,11 @@ static Datum GetScanValue(IndexScanDesc scan) { HnswScanOpaque so = (HnswScanOpaque) scan->opaque; - Datum value; + Datum value; if (scan->orderByData->sk_flags & SK_ISNULL) value = PointerGetDatum(NULL); - else - { + else { value = scan->orderByData->sk_argument; /* Value should not be compressed or toasted */ @@ -137,7 +136,7 @@ hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir) Assert(ScanDirectionIsForward(dir)); if (so->first) { - Datum value; + Datum value; /* Count index scan for stats */ pgstat_count_index_scan(scan->indexRelation); @@ -173,7 +172,7 @@ hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir) } while (list_length(so->w) > 0) { - char *base = NULL; + char *base = NULL; HnswCandidate *hc = (HnswCandidate *)linitial(so->w); HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); ItemPointer heaptid; diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index 043725e153..f3786e8a2b 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -23,7 +23,7 @@ static inline uint64 murmurhash64(uint64 data) { - uint64 h = data; + uint64 h = data; h ^= h >> 33; h *= 0xff51afd7ed558ccd; @@ -41,9 +41,9 @@ hash_tid(ItemPointerData tid) { union { - uint64 i; + uint64 i; ItemPointerData tid; - } x; + } x; /* Initialize unused bytes */ x.i = 0; @@ -54,13 +54,13 @@ hash_tid(ItemPointerData tid) #define VALGRIND_MAKE_MEM_DEFINED(addr, size) do {} while (0) -#define SH_PREFIX tidhash -#define SH_ELEMENT_TYPE TidHashEntry -#define SH_KEY_TYPE ItemPointerData -#define SH_KEY tid -#define SH_HASH_KEY(tb, key) hash_tid(key) -#define SH_EQUAL(tb, a, b) ItemPointerEquals(&a, &b) -#define SH_SCOPE extern +#define SH_PREFIX tidhash +#define SH_ELEMENT_TYPE TidHashEntry +#define SH_KEY_TYPE ItemPointerData +#define SH_KEY tid +#define SH_HASH_KEY(tb, key) hash_tid(key) +#define SH_EQUAL(tb, a, b) ItemPointerEquals(&a, &b) +#define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" @@ -75,13 +75,13 @@ hash_pointer(uintptr_t ptr) #endif } -#define SH_PREFIX pointerhash -#define SH_ELEMENT_TYPE PointerHashEntry -#define SH_KEY_TYPE uintptr_t -#define SH_KEY ptr -#define SH_HASH_KEY(tb, key) hash_pointer(key) -#define SH_EQUAL(tb, a, b) (a == b) -#define SH_SCOPE extern +#define SH_PREFIX pointerhash +#define SH_ELEMENT_TYPE PointerHashEntry +#define SH_KEY_TYPE uintptr_t +#define SH_KEY ptr +#define SH_HASH_KEY(tb, key) hash_pointer(key) +#define SH_EQUAL(tb, a, b) (a == b) +#define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" @@ -96,13 +96,13 @@ hash_offset(Size offset) #endif } -#define SH_PREFIX offsethash -#define SH_ELEMENT_TYPE OffsetHashEntry -#define SH_KEY_TYPE Size -#define SH_KEY offset -#define SH_HASH_KEY(tb, key) hash_offset(key) -#define SH_EQUAL(tb, a, b) (a == b) -#define SH_SCOPE extern +#define SH_PREFIX offsethash +#define SH_ELEMENT_TYPE OffsetHashEntry +#define SH_KEY_TYPE Size +#define SH_KEY offset +#define SH_HASH_KEY(tb, key) hash_offset(key) +#define SH_EQUAL(tb, a, b) (a == b) +#define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" @@ -111,7 +111,7 @@ typedef union pointerhash_hash *pointers; offsethash_hash *offsets; tidhash_hash *tids; -} visited_hash; +} visited_hash; /* * Get the max number of connections in an upper layer for each element in the index @@ -223,7 +223,7 @@ HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) Buffer HnswNewBuffer(Relation index, ForkNumber forkNum) { - Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); + Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); return buf; @@ -260,7 +260,7 @@ HnswInitNeighborArray(int lm, HnswAllocator * allocator) void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * allocator) { - int level = element->level; + int level = element->level; HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *) HnswAlloc(allocator, sizeof(HnswNeighborArrayPtr) * (level + 1)); HnswPtrStore(base, element->neighbors, neighborList); @@ -289,7 +289,7 @@ HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, { HnswElement element = (HnswElement)HnswAlloc(allocator, sizeof(HnswElementData)); - int level = (int) (-log(RandomDouble()) * ml); + int level = (int) (-log(RandomDouble()) * ml); /* Cap level */ if (level > maxLevel) @@ -324,7 +324,7 @@ HnswElement HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno) { HnswElement element = (HnswElement)palloc(sizeof(HnswElementData)); - char *base = NULL; + char *base = NULL; element->blkno = blkno; element->offno = offno; @@ -339,8 +339,8 @@ HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno) void HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint) { - Buffer buf; - Page page; + Buffer buf; + Page page; HnswMetaPage metap; buf = ReadBuffer(index, HNSW_METAPAGE_BLKNO); @@ -354,14 +354,11 @@ HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint) if (m != NULL) *m = metap->m; - if (entryPoint != NULL) - { - if (BlockNumberIsValid(metap->entryBlkno)) - { + if (entryPoint != NULL) { + if (BlockNumberIsValid(metap->entryBlkno)) { *entryPoint = HnswInitElementFromBlock(metap->entryBlkno, metap->entryOffno); (*entryPoint)->level = metap->entryLevel; - } - else + } else *entryPoint = NULL; } @@ -389,16 +386,12 @@ HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, Block { HnswMetaPage metap = HnswPageGetMeta(page); - if (updateEntry) - { - if (entryPoint == NULL) - { + if (updateEntry) { + if (entryPoint == NULL) { metap->entryBlkno = InvalidBlockNumber; metap->entryOffno = InvalidOffsetNumber; metap->entryLevel = -1; - } - else if (entryPoint->level > metap->entryLevel || updateEntry == HNSW_UPDATE_ENTRY_ALWAYS) - { + } else if (entryPoint->level > metap->entryLevel || updateEntry == HNSW_UPDATE_ENTRY_ALWAYS) { metap->entryBlkno = entryPoint->blkno; metap->entryOffno = entryPoint->offno; metap->entryLevel = entryPoint->level; @@ -445,19 +438,16 @@ HnswUpdateAppendMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum, bool building) { - Buffer buf; - Page page; + Buffer buf; + Page page; GenericXLogState *state; buf = ReadBufferExtended(index, forkNum, HNSW_METAPAGE_BLKNO, RBM_NORMAL, NULL); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - if (building) - { + if (building) { state = NULL; page = BufferGetPage(buf); - } - else - { + } else { state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); } @@ -508,13 +498,12 @@ HnswUpdateAppendMetaPage(Relation index, int updateEntry, HnswElement entryPoint void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) { - Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); + Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); etup->type = HNSW_ELEMENT_TUPLE_TYPE; etup->level = element->level; etup->deleted = 0; - for (int i = 0; i < HNSW_HEAPTIDS; i++) - { + for (int i = 0; i < HNSW_HEAPTIDS; i++) { if (i < element->heaptidsLength) etup->heaptids[i] = element->heaptids[i]; else @@ -529,27 +518,23 @@ HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) { - int idx = 0; + int idx = 0; ntup->type = HNSW_NEIGHBOR_TUPLE_TYPE; - for (int lc = e->level; lc >= 0; lc--) - { + for (int lc = e->level; lc >= 0; lc--) { HnswNeighborArray *neighbors = HnswGetNeighbors(base, e, lc); - int lm = HnswGetLayerM(m, lc); + int lm = HnswGetLayerM(m, lc); - for (int i = 0; i < lm; i++) - { + for (int i = 0; i < lm; i++) { ItemPointer indextid = &ntup->indextids[idx++]; - if (i < neighbors->length) - { + if (i < neighbors->length) { HnswCandidate *hc = &neighbors->items[i]; HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); ItemPointerSet(indextid, hce->blkno, hce->offno); - } - else + } else ItemPointerSetInvalid(indextid); } } @@ -563,10 +548,10 @@ HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) static void LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) { - char *base = NULL; + char *base = NULL; HnswNeighborTuple ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); - int neighborCount = (element->level + 2) * m; + int neighborCount = (element->level + 2) * m; Assert(HnswIsNeighborTuple(ntup)); @@ -576,10 +561,9 @@ LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) if (ntup->count != neighborCount) return; - for (int i = 0; i < neighborCount; i++) - { + for (int i = 0; i < neighborCount; i++) { HnswElement e; - int level; + int level; HnswCandidate *hc; ItemPointer indextid; HnswNeighborArray *neighbors; @@ -608,8 +592,8 @@ LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) void HnswLoadNeighbors(HnswElement element, Relation index, int m) { - Buffer buf; - Page page; + Buffer buf; + Page page; buf = ReadBuffer(index, element->neighborPage); LockBuffer(buf, BUFFER_LOCK_SHARE); @@ -632,10 +616,8 @@ HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHe element->neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); element->heaptidsLength = 0; - if (loadHeaptids) - { - for (int i = 0; i < HNSW_HEAPTIDS; i++) - { + if (loadHeaptids) { + for (int i = 0; i < HNSW_HEAPTIDS; i++) { /* Can stop at first invalid */ if (!ItemPointerIsValid(&etup->heaptids[i])) break; @@ -644,10 +626,9 @@ HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHe } } - if (loadVec) - { - char *base = NULL; - Datum value = datumCopy(PointerGetDatum(&etup->data), false, -1); + if (loadVec) { + char *base = NULL; + Datum value = datumCopy(PointerGetDatum(&etup->data), false, -1); HnswPtrStore(base, element->value, DatumGetPointer(value)); } @@ -706,7 +687,7 @@ static float GetCandidateDistance(char *base, HnswCandidate * hc, Datum q, FmgrInfo *procinfo, Oid collation) { HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); - Datum value = HnswGetValue(base, hce); + Datum value = HnswGetValue(base, hce); return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, q, value)); } @@ -795,16 +776,13 @@ InitVisited(char *base, visited_hash * v, Relation index, int ef, int m) static inline void AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, bool *found) { - if (index != NULL) - { + if (index != NULL) { HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); ItemPointerData indextid; ItemPointerSet(&indextid, element->blkno, element->offno); tidhash_insert(v->tids, indextid, found); - } - else if (base != NULL) - { + } else if (base != NULL) { #if PG_VERSION_NUM >= 130000 HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); @@ -812,9 +790,7 @@ AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, b #else offsethash_insert(v->offsets, HnswPtrOffset(hc->element), found); #endif - } - else - { + } else { #if PG_VERSION_NUM >= 130000 HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); @@ -850,14 +826,14 @@ List * HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *procinfo, Oid collation, int m, bool inserting, HnswElement skipElement, IndexScanDesc scan) { - List *w = NIL; + List *w = NIL; pairingheap *C = pairingheap_allocate(CompareNearestCandidates, NULL); pairingheap *W = pairingheap_allocate(CompareFurthestCandidates, NULL); - int wlen = 0; + int wlen = 0; visited_hash v; - ListCell *lc2; + ListCell *lc2; HnswNeighborArray *neighborhoodData = NULL; - Size neighborhoodSize; + Size neighborhoodSize; bool isVisible = true; InitVisited(base, &v, index, ef, m); @@ -871,7 +847,7 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F /* Add entry points to v, C, and W */ foreach(lc2, ep) { HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); - bool found; + bool found; AddToVisited(base, &v, hc, index, &found); @@ -914,14 +890,14 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F for (int i = 0; i < neighborhood->length; i++) { HnswCandidate *e = &neighborhood->items[i]; - bool visited; + bool visited; AddToVisited(base, &v, e, index, &visited); if (!visited) { - float eDistance; + float eDistance; HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); - bool alwaysAdd = wlen < ef; + bool alwaysAdd = wlen < ef; f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner; @@ -1047,8 +1023,8 @@ CompareCandidateDistancesOffset(const void *a, const void *b) static float HnswGetDistance(char *base, HnswElement a, HnswElement b, FmgrInfo *procinfo, Oid collation) { - Datum aValue = HnswGetValue(base, a); - Datum bValue = HnswGetValue(base, b); + Datum aValue = HnswGetValue(base, a); + Datum bValue = HnswGetValue(base, b); return DatumGetFloat8(FunctionCall2Coll(procinfo, collation, aValue, bValue)); } @@ -1060,13 +1036,12 @@ static bool CheckElementCloser(char *base, HnswCandidate * e, List *r, FmgrInfo *procinfo, Oid collation) { HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); - ListCell *lc2; + ListCell *lc2; - foreach(lc2, r) - { + foreach(lc2, r) { HnswCandidate *ri = (HnswCandidate *)lfirst(lc2); HnswElement riElement = (HnswElement)HnswPtrAccess(base, ri->element); - float distance = HnswGetDistance(base, eElement, riElement, procinfo, collation); + float distance = HnswGetDistance(base, eElement, riElement, procinfo, collation); if (distance <= e->distance) return false; @@ -1081,15 +1056,15 @@ CheckElementCloser(char *base, HnswCandidate * e, List *r, FmgrInfo *procinfo, O static List * SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid collation, HnswElement e2, HnswCandidate * newCandidate, HnswCandidate * *pruned, bool sortCandidates) { - List *r = NIL; - List *w = list_copy(c); + List *r = NIL; + List *w = list_copy(c); HnswCandidate **wd; - int wdlen = 0; - int wdoff = 0; + int wdlen = 0; + int wdoff = 0; HnswNeighborArray *neighbors = HnswGetNeighbors(base, e2, lc); - bool mustCalculate = !neighbors->closerSet; - List *added = NIL; - bool removedAny = false; + bool mustCalculate = !neighbors->closerSet; + List *added = NIL; + bool removedAny = false; if (list_length(w) <= lm) return w; @@ -1097,8 +1072,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col wd = (HnswCandidate **)palloc(sizeof(HnswCandidate *) * list_length(w)); /* Ensure order of candidates is deterministic for closer caching */ - if (sortCandidates) - { + if (sortCandidates) { if (base == NULL) { list_sort(w, CompareCandidateDistances); } @@ -1133,8 +1107,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col if (!e->closer) { removedAny = true; } - } - else { + } else { /* * If we have removed any candidates from closer, a candidate * that was not closer earlier might now be. @@ -1146,9 +1119,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col } } } - } - else if (e == newCandidate) - { + } else if (e == newCandidate) { e->closer = CheckElementCloser(base, e, r, procinfo, collation); if (e->closer) { added = lappend(added, e); @@ -1180,8 +1151,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col if (pruned != NULL) { if (wdoff < wdlen) { *pruned = wd[wdoff]; - } - else { + } else { *pruned = (HnswCandidate *)linitial(w); } } @@ -1195,7 +1165,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col static void AddConnections(char *base, HnswElement element, List *neighbors, int lc) { - ListCell *lc2; + ListCell *lc2; HnswNeighborArray *a = HnswGetNeighbors(base, element, lc); foreach(lc2, neighbors) @@ -1215,26 +1185,21 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm HnswPtrStore(base, hc2.element, element); hc2.distance = hc->distance; - if (currentNeighbors->length < lm) - { + if (currentNeighbors->length < lm) { currentNeighbors->items[currentNeighbors->length++] = hc2; /* Track update */ if (updateIdx != NULL) *updateIdx = -2; - } - else - { + } else { /* Shrink connections */ HnswCandidate *pruned = NULL; /* Load elements on insert */ - if (index != NULL) - { - Datum q = HnswGetValue(base, hce); + if (index != NULL) { + Datum q = HnswGetValue(base, hce); - for (int i = 0; i < currentNeighbors->length; i++) - { + for (int i = 0; i < currentNeighbors->length; i++) { HnswCandidate *hc3 = ¤tNeighbors->items[i]; HnswElement hc3Element = (HnswElement)HnswPtrAccess(base, hc3->element); @@ -1244,17 +1209,15 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm hc3->distance = GetCandidateDistance(base, hc3, q, procinfo, collation); /* Prune element if being deleted */ - if (hc3Element->heaptidsLength == 0) - { + if (hc3Element->heaptidsLength == 0) { pruned = ¤tNeighbors->items[i]; break; } } } - if (pruned == NULL) - { - List *c = NIL; + if (pruned == NULL) { + List *c = NIL; /* Add candidates */ for (int i = 0; i < currentNeighbors->length; i++) @@ -1269,10 +1232,8 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm } /* Find and replace the pruned element */ - for (int i = 0; i < currentNeighbors->length; i++) - { - if (HnswPtrEqual(base, currentNeighbors->items[i].element, pruned->element)) - { + for (int i = 0; i < currentNeighbors->length; i++) { + if (HnswPtrEqual(base, currentNeighbors->items[i].element, pruned->element)) { currentNeighbors->items[i] = hc2; /* Track update */ @@ -1291,14 +1252,13 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm static List * RemoveElements(char *base, List *w, HnswElement skipElement) { - ListCell *lc2; - List *w2 = NIL; + ListCell *lc2; + List *w2 = NIL; /* Ensure does not access heaptidsLength during in-memory build */ pg_memory_barrier(); - foreach(lc2, w) - { + foreach(lc2, w) { HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); @@ -1337,11 +1297,11 @@ PrecomputeHash(char *base, HnswElement element) void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing) { - List *ep; - List *w; - int level = element->level; - int entryLevel; - Datum q = HnswGetValue(base, element); + List *ep; + List *w; + int level = element->level; + int entryLevel; + Datum q = HnswGetValue(base, element); HnswElement skipElement = existing ? element : NULL; #if PG_VERSION_NUM >= 130000 @@ -1359,8 +1319,7 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint entryLevel = entryPoint->level; /* 1st phase: greedy search to insert level */ - for (int lc = entryLevel; lc >= level + 1; lc--) - { + for (int lc = entryLevel; lc >= level + 1; lc--) { w = HnswSearchLayer(base, q, ep, 1, lc, index, procinfo, collation, m, true, skipElement); ep = w; } @@ -1373,11 +1332,10 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint efConstruction++; /* 2nd phase */ - for (int lc = level; lc >= 0; lc--) - { - int lm = HnswGetLayerM(m, lc); - List *neighbors; - List *lw; + for (int lc = level; lc >= 0; lc--) { + int lm = HnswGetLayerM(m, lc); + List *neighbors; + List *lw; w = HnswSearchLayer(base, q, ep, efConstruction, lc, index, procinfo, collation, m, true, skipElement); @@ -1413,13 +1371,12 @@ SparsevecCheckValue(Pointer v) /* * Get type info */ -const HnswTypeInfo * +const HnswTypeInfo * HnswGetTypeInfo(Relation index) { - FmgrInfo *procinfo = HnswOptionalProcInfo(index, HNSW_TYPE_INFO_PROC); + FmgrInfo *procinfo = HnswOptionalProcInfo(index, HNSW_TYPE_INFO_PROC); - if (procinfo == NULL) - { + if (procinfo == NULL) { static const HnswTypeInfo typeInfo = { .maxDimensions = HNSW_MAX_DIM, .normalize = l2_normalize, diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp index d6bf541a27..de9558961f 100644 --- a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -28,26 +28,25 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) { BlockNumber blkno = HNSW_HEAD_BLKNO; HnswElement highestPoint = &vacuumstate->highestPoint; - Relation index = vacuumstate->index; + Relation index = vacuumstate->index; BufferAccessStrategy bas = vacuumstate->bas; HnswElement entryPoint = HnswGetEntryPoint(vacuumstate->index); IndexBulkDeleteResult *stats = vacuumstate->stats; /* Store separately since highestPoint.level is uint8 */ - int highestLevel = -1; + int highestLevel = -1; /* Initialize highest point */ highestPoint->blkno = InvalidBlockNumber; highestPoint->offno = InvalidOffsetNumber; - while (BlockNumberIsValid(blkno)) - { - Buffer buf; - Page page; + while (BlockNumberIsValid(blkno)) { + Buffer buf; + Page page; GenericXLogState *state; OffsetNumber offno; OffsetNumber maxoffno; - bool updated = false; + bool updated = false; vacuum_delay_point(); @@ -58,39 +57,32 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) maxoffno = PageGetMaxOffsetNumber(page); /* Iterate over nodes */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); - int idx = 0; - bool itemUpdated = false; + int idx = 0; + bool itemUpdated = false; /* Skip neighbor tuples */ if (!HnswIsElementTuple(etup)) continue; - if (ItemPointerIsValid(&etup->heaptids[0])) - { - for (int i = 0; i < HNSW_HEAPTIDS; i++) - { + if (ItemPointerIsValid(&etup->heaptids[0])) { + for (int i = 0; i < HNSW_HEAPTIDS; i++) { /* Stop at first unused */ if (!ItemPointerIsValid(&etup->heaptids[i])) break; - if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, InvalidBktId)) - { + if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, InvalidBktId)) { itemUpdated = true; stats->tuples_removed++; - } - else - { + } else { /* Move to front of list */ etup->heaptids[idx++] = etup->heaptids[i]; stats->num_index_tuples++; } } - if (itemUpdated) - { + if (itemUpdated) { /* Mark rest as invalid */ for (int i = idx; i < HNSW_HEAPTIDS; i++) ItemPointerSetInvalid(&etup->heaptids[i]); @@ -99,19 +91,16 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) } } - if (!ItemPointerIsValid(&etup->heaptids[0])) - { + if (!ItemPointerIsValid(&etup->heaptids[0])) { ItemPointerData ip; - bool found; + bool found; /* Add to deleted list */ ItemPointerSet(&ip, blkno, offno); tidhash_insert(vacuumstate->deleted, ip, &found); Assert(!found); - } - else if (etup->level > highestLevel && !(entryPoint != NULL && blkno == entryPoint->blkno && offno == entryPoint->offno)) - { + } else if (etup->level > highestLevel && !(entryPoint != NULL && blkno == entryPoint->blkno && offno == entryPoint->offno)) { /* Keep track of highest non-entry point */ highestPoint->blkno = blkno; highestPoint->offno = offno; @@ -137,12 +126,12 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) static bool NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) { - Relation index = vacuumstate->index; + Relation index = vacuumstate->index; BufferAccessStrategy bas = vacuumstate->bas; - Buffer buf; - Page page; + Buffer buf; + Page page; HnswNeighborTuple ntup; - bool needsUpdated = false; + bool needsUpdated = false; buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); LockBuffer(buf, BUFFER_LOCK_SHARE); @@ -152,16 +141,14 @@ NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) Assert(HnswIsNeighborTuple(ntup)); /* Check neighbors */ - for (int i = 0; i < ntup->count; i++) - { + for (int i = 0; i < ntup->count; i++) { ItemPointer indextid = &ntup->indextids[i]; if (!ItemPointerIsValid(indextid)) continue; /* Check if in deleted list */ - if (DeletedContains(vacuumstate->deleted, indextid)) - { + if (DeletedContains(vacuumstate->deleted, indextid)) { needsUpdated = true; break; } @@ -183,18 +170,18 @@ NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) static void RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswElement entryPoint) { - Relation index = vacuumstate->index; - Buffer buf; - Page page; + Relation index = vacuumstate->index; + Buffer buf; + Page page; GenericXLogState *state; - int m = vacuumstate->m; - int efConstruction = vacuumstate->efConstruction; - FmgrInfo *procinfo = vacuumstate->procinfo; - Oid collation = vacuumstate->collation; + int m = vacuumstate->m; + int efConstruction = vacuumstate->efConstruction; + FmgrInfo *procinfo = vacuumstate->procinfo; + Oid collation = vacuumstate->collation; BufferAccessStrategy bas = vacuumstate->bas; HnswNeighborTuple ntup = vacuumstate->ntup; - Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); - char *base = NULL; + Size ntupSize = HNSW_NEIGHBOR_TUPLE_SIZE(element->level, m); + char *base = NULL; /* Skip if element is entry point */ if (entryPoint != NULL && element->blkno == entryPoint->blkno && element->offno == entryPoint->offno) @@ -238,7 +225,7 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme static void RepairGraphEntryPoint(HnswVacuumState * vacuumstate) { - Relation index = vacuumstate->index; + Relation index = vacuumstate->index; HnswElement highestPoint = &vacuumstate->highestPoint; HnswElement entryPoint; MemoryContext oldCtx = MemoryContextSwitchTo(vacuumstate->tmpCtx); @@ -250,8 +237,7 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) * Repair graph for highest non-entry point. Highest point may be outdated * due to inserts that happen during and after RemoveHeapTids. */ - if (highestPoint != NULL) - { + if (highestPoint != NULL) { /* Get a shared lock */ LockPage(index, HNSW_UPDATE_LOCK, ShareLock); @@ -272,23 +258,19 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) /* Get latest entry point */ entryPoint = HnswGetEntryPoint(index); - if (entryPoint != NULL) - { + if (entryPoint != NULL) { ItemPointerData epData; ItemPointerSet(&epData, entryPoint->blkno, entryPoint->offno); - if (DeletedContains(vacuumstate->deleted, &epData)) - { + if (DeletedContains(vacuumstate->deleted, &epData)) { /* * Replace the entry point with the highest point. If highest * point is outdated and empty, the entry point will be empty * until an element is repaired. */ HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_ALWAYS, highestPoint, InvalidBlockNumber, MAIN_FORKNUM, false); - } - else - { + } else { /* * Repair the entry point with the highest point. If highest point * is outdated, this can remove connections at higher levels in @@ -296,8 +278,7 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) */ HnswLoadElement(entryPoint, NULL, NULL, index, vacuumstate->procinfo, vacuumstate->collation, true, NULL); - if (NeedsUpdated(vacuumstate, entryPoint)) - { + if (NeedsUpdated(vacuumstate, entryPoint)) { /* Reset neighbors from previous update */ if (highestPoint != NULL) HnswPtrStore((char *) NULL, highestPoint->neighbors, (HnswNeighborArrayPtr *) NULL); @@ -321,7 +302,7 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) static void RepairGraph(HnswVacuumState * vacuumstate) { - Relation index = vacuumstate->index; + Relation index = vacuumstate->index; BufferAccessStrategy bas = vacuumstate->bas; BlockNumber blkno = HNSW_HEAD_BLKNO; @@ -335,14 +316,13 @@ RepairGraph(HnswVacuumState * vacuumstate) /* Repair entry point first */ RepairGraphEntryPoint(vacuumstate); - while (BlockNumberIsValid(blkno)) - { - Buffer buf; - Page page; + while (BlockNumberIsValid(blkno)) { + Buffer buf; + Page page; OffsetNumber offno; OffsetNumber maxoffno; - List *elements = NIL; - ListCell *lc2; + List *elements = NIL; + ListCell *lc2; MemoryContext oldCtx; vacuum_delay_point(); @@ -355,8 +335,7 @@ RepairGraph(HnswVacuumState * vacuumstate) maxoffno = PageGetMaxOffsetNumber(page); /* Load items into memory to minimize locking */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); HnswElement element; @@ -380,11 +359,10 @@ RepairGraph(HnswVacuumState * vacuumstate) UnlockReleaseBuffer(buf); /* Update neighbor pages */ - foreach(lc2, elements) - { + foreach(lc2, elements) { HnswElement element = (HnswElement) lfirst(lc2); HnswElement entryPoint; - LOCKMODE lockmode = ShareLock; + LOCKMODE lockmode = ShareLock; /* Check if any neighbors point to deleted values */ if (!NeedsUpdated(vacuumstate, element)) @@ -397,8 +375,7 @@ RepairGraph(HnswVacuumState * vacuumstate) entryPoint = HnswGetEntryPoint(index); /* Prevent concurrent inserts when likely updating entry point */ - if (entryPoint == NULL || element->level > entryPoint->level) - { + if (entryPoint == NULL || element->level > entryPoint->level) { /* Release shared lock */ UnlockPage(index, HNSW_UPDATE_LOCK, lockmode); @@ -438,7 +415,7 @@ MarkDeleted(HnswVacuumState * vacuumstate) { BlockNumber blkno = HNSW_HEAD_BLKNO; BlockNumber insertPage = InvalidBlockNumber; - Relation index = vacuumstate->index; + Relation index = vacuumstate->index; BufferAccessStrategy bas = vacuumstate->bas; /* @@ -449,10 +426,9 @@ MarkDeleted(HnswVacuumState * vacuumstate) LockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); UnlockPage(index, HNSW_SCAN_LOCK, ExclusiveLock); - while (BlockNumberIsValid(blkno)) - { - Buffer buf; - Page page; + while (BlockNumberIsValid(blkno)) { + Buffer buf; + Page page; GenericXLogState *state; OffsetNumber offno; OffsetNumber maxoffno; @@ -474,12 +450,11 @@ MarkDeleted(HnswVacuumState * vacuumstate) maxoffno = PageGetMaxOffsetNumber(page); /* Update element and neighbors together */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); HnswNeighborTuple ntup; - Buffer nbuf; - Page npage; + Buffer nbuf; + Page npage; BlockNumber neighborPage; OffsetNumber neighborOffno; @@ -488,8 +463,7 @@ MarkDeleted(HnswVacuumState * vacuumstate) continue; /* Skip deleted tuples */ - if (etup->deleted) - { + if (etup->deleted) { /* Set to first free page */ if (!BlockNumberIsValid(insertPage)) insertPage = blkno; @@ -505,13 +479,10 @@ MarkDeleted(HnswVacuumState * vacuumstate) neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - if (neighborPage == blkno) - { + if (neighborPage == blkno) { nbuf = buf; npage = page; - } - else - { + } else { nbuf = ReadBufferExtended(index, MAIN_FORKNUM, neighborPage, RBM_NORMAL, bas); LockBuffer(nbuf, BUFFER_LOCK_EXCLUSIVE); npage = GenericXLogRegisterBuffer(state, nbuf, 0); @@ -562,7 +533,7 @@ MarkDeleted(HnswVacuumState * vacuumstate) static void InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) { - Relation index = info->index; + Relation index = info->index; if (stats == NULL) stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); @@ -630,7 +601,7 @@ hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteResult * hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { - Relation rel = info->index; + Relation rel = info->index; if (info->analyze_only) return stats; diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index dffaa2719d..7db0050482 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -33,10 +33,10 @@ #include "utils/wait_event.h" #endif -#define PARALLEL_KEY_IVFFLAT_SHARED UINT64CONST(0xA000000000000001) -#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xA000000000000002) -#define PARALLEL_KEY_IVFFLAT_CENTERS UINT64CONST(0xA000000000000003) -#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000004) +#define PARALLEL_KEY_IVFFLAT_SHARED UINT64CONST(0xA000000000000001) +#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xA000000000000002) +#define PARALLEL_KEY_IVFFLAT_CENTERS UINT64CONST(0xA000000000000003) +#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000004) /* * Add sample @@ -134,18 +134,17 @@ SampleRows(IvfflatBuildState *buildstate) static void AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState * buildstate) { - double distance; - double minDistance = DBL_MAX; - int closestCenter = 0; + double distance; + double minDistance = DBL_MAX; + int closestCenter = 0; VectorArray centers = buildstate->centers; TupleTableSlot *slot = buildstate->slot; /* Detoast once for all calls */ - Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); + Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); /* Normalize if needed */ - if (buildstate->normprocinfo != NULL) - { + if (buildstate->normprocinfo != NULL) { if (!IvfflatCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) return; @@ -153,12 +152,10 @@ AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState } /* Find the list that minimizes the distance */ - for (int i = 0; i < centers->length; i++) - { + for (int i = 0; i < centers->length; i++) { distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, value, PointerGetDatum(VectorArrayGet(centers, i)))); - if (distance < minDistance) - { + if (distance < minDistance) { minDistance = distance; closestCenter = i; } @@ -226,19 +223,17 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, static inline void GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, IndexTuple *itup, int *list) { - Datum value; - bool isnull; + Datum value; + bool isnull; - if (tuplesort_gettupleslot(sortstate, true, slot, NULL)) - { + if (tuplesort_gettupleslot(sortstate, true, slot, NULL)) { *list = DatumGetInt32(heap_slot_getattr(slot, 1, &isnull)); value = heap_slot_getattr(slot, 3, &isnull); /* Form the index tuple */ *itup = index_form_tuple(tupdesc, &value, &isnull); (*itup)->t_tid = *((ItemPointer) DatumGetPointer(heap_slot_getattr(slot, 2, &isnull))); - } - else + } else *list = -1; } @@ -248,19 +243,18 @@ GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, static void InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) { - int list; - IndexTuple itup = NULL; /* silence compiler warning */ - int64 inserted = 0; + int list; + IndexTuple itup = NULL; /* silence compiler warning */ + int64 inserted = 0; TupleTableSlot *slot = MakeSingleTupleTableSlot(buildstate->tupdesc); - TupleDesc tupdesc = RelationGetDescr(index); + TupleDesc tupdesc = RelationGetDescr(index); GetNextTuple(buildstate->sortstate, tupdesc, slot, &itup, &list); - for (int i = 0; i < buildstate->centers->length; i++) - { - Buffer buf; - Page page; + for (int i = 0; i < buildstate->centers->length; i++) { + Buffer buf; + Page page; GenericXLogState *state; BlockNumber startPage; BlockNumber insertPage; @@ -275,10 +269,9 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) startPage = BufferGetBlockNumber(buf); /* Get all tuples for list */ - while (list == i) - { + while (list == i) { /* Check for free space */ - Size itemsz = MAXALIGN(IndexTupleSize(itup)); + Size itemsz = MAXALIGN(IndexTupleSize(itup)); if (PageGetFreeSpace(page) < itemsz) IvfflatAppendPage(index, &buf, &page, &state, forkNum); @@ -428,8 +421,8 @@ ComputeCenters(IvfflatBuildState *buildstate) static void CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) { - Buffer buf; - Page page; + Buffer buf; + Page page; GenericXLogState *state; IvfflatMetaPage metap; @@ -455,10 +448,10 @@ static void CreateListPages(Relation index, VectorArray centers, int dimensions, int lists, ForkNumber forkNum, ListInfo * *listInfo) { - Buffer buf; - Page page; + Buffer buf; + Page page; GenericXLogState *state; - Size listSize; + Size listSize; IvfflatList list; listSize = MAXALIGN(IVFFLAT_LIST_SIZE(centers->itemsize)); @@ -467,8 +460,7 @@ CreateListPages(Relation index, VectorArray centers, int dimensions, buf = IvfflatNewBuffer(index, forkNum); IvfflatInitRegisterPage(index, &buf, &page, &state); - for (int i = 0; i < lists; i++) - { + for (int i = 0; i < lists; i++) { OffsetNumber offno; /* Zero memory for each list */ @@ -508,24 +500,20 @@ PrintKmeansMetrics(IvfflatBuildState * buildstate) elog(INFO, "inertia: %.3e", buildstate->inertia); /* Calculate Davies-Bouldin index */ - if (buildstate->lists > 1) - { - double db = 0.0; + if (buildstate->lists > 1) { + double db = 0.0; /* Calculate average distance */ - for (int i = 0; i < buildstate->lists; i++) - { + for (int i = 0; i < buildstate->lists; i++) { if (buildstate->listCounts[i] > 0) buildstate->listSums[i] /= buildstate->listCounts[i]; } - for (int i = 0; i < buildstate->lists; i++) - { - double max = 0.0; - double distance; + for (int i = 0; i < buildstate->lists; i++) { + double max = 0.0; + double distance; - for (int j = 0; j < buildstate->lists; j++) - { + for (int j = 0; j < buildstate->lists; j++) { if (j == i) continue; @@ -578,14 +566,14 @@ IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, V SortCoordinate coordinate; IvfflatBuildState buildstate; TableScanDesc scan; - double reltuples; - IndexInfo *indexInfo; + double reltuples; + IndexInfo *indexInfo; /* Sort options, which must match AssignTuples */ - AttrNumber attNums[] = {1}; - Oid sortOperators[] = {INT4LTOID}; - Oid sortCollations[] = {InvalidOid}; - bool nullsFirstFlags[] = {false}; + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {INT4LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; /* Initialize local tuplesort coordination state */ coordinate = (SortCoordinate)palloc0(sizeof(SortCoordinateData)); @@ -635,8 +623,8 @@ IvfflatParallelBuildMain(const BgWorkerContext *bwc) { IvfflatSpool *ivfspool; IvfflatShared *ivfshared; - Relation heapRel; - Relation indexRel; + Relation heapRel; + Relation indexRel; ivfshared = (IvfflatShared*)bwc->bgshared; @@ -728,8 +716,7 @@ IvfflatBeginParallel(IvfflatBuildState * buildstate, int request, int workmem) ivfleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, ivfshared, IvfflatParallelBuildMain, IvfflatParallelCleanup); /* If no workers were successfully launched, back out (do serial build) */ - if (ivfleader->nparticipanttuplesorts == 0) - { + if (ivfleader->nparticipanttuplesorts == 0) { pfree_ext(ivfshared); pfree_ext(ivfleader); return; @@ -787,10 +774,10 @@ AssignTuples(IvfflatBuildState * buildstate) int workmem; /* Sort options, which must match IvfflatParallelScanAndSort */ - AttrNumber attNums[] = {1}; - Oid sortOperators[] = {INT4LTOID}; - Oid sortCollations[] = {InvalidOid}; - bool nullsFirstFlags[] = {false}; + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {INT4LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; workmem = (desc->query_mem[0] > 0) ? (desc->query_mem[0] - SIMPLE_THRESHOLD) : u_sess->attr.attr_memory.maintenance_work_mem; @@ -806,8 +793,7 @@ AssignTuples(IvfflatBuildState * buildstate) } /* Set up coordination state if at least one worker launched */ - if (buildstate->ivfleader) - { + if (buildstate->ivfleader) { coordinate = (SortCoordinate) palloc0(sizeof(SortCoordinateData)); coordinate->isWorker = false; coordinate->nParticipants = buildstate->ivfleader->nparticipanttuplesorts; @@ -819,8 +805,7 @@ AssignTuples(IvfflatBuildState * buildstate) u_sess->attr.attr_memory.maintenance_work_mem, false, 0, 0, 1, coordinate); /* Add tuples to sort */ - if (buildstate->heap != NULL) - { + if (buildstate->heap != NULL) { buildstate->reltuples = AssignTupleUtility(buildstate); #ifdef IVFFLAT_KMEANS_DEBUG @@ -899,7 +884,7 @@ ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) void ivfflatbuildempty_internal(Relation index) { - IndexInfo *indexInfo = BuildIndexInfo(index); + IndexInfo *indexInfo = BuildIndexInfo(index); IvfflatBuildState buildstate; BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index caf57ceae8..009350b462 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -37,11 +37,11 @@ ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_cou Selectivity *indexSelectivity, double *indexCorrelation) { GenericCosts costs; - int lists; - double ratio; - double spc_seq_page_cost; - Relation index; - double half = 0.5; + int lists; + double ratio; + double spc_seq_page_cost; + Relation index; + double half = 0.5; /* Never use index without order */ if (path->indexorderbys == NULL) { @@ -165,7 +165,7 @@ ivfflathandler(PG_FUNCTION_ARGS) #endif amroutine->amcanorder = false; amroutine->amcanorderbyop = true; - amroutine->amcanbackward = false; /* can change direction mid-scan */ + amroutine->amcanbackward = false; /* can change direction mid-scan */ amroutine->amcanunique = false; amroutine->amcanmulticol = false; amroutine->amoptionalkey = true; diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp index 68afddbb87..0e201b4ae8 100644 --- a/src/gausskernel/storage/access/datavec/ivfinsert.cpp +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -14,10 +14,10 @@ static void FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo * listInfo) { - double minDistance = DBL_MAX; + double minDistance = DBL_MAX; BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; - FmgrInfo *procinfo; - Oid collation; + FmgrInfo *procinfo; + Oid collation; /* Avoid compiler warning */ listInfo->blkno = nextblkno; @@ -29,8 +29,8 @@ FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo /* Search all list pages */ while (BlockNumberIsValid(nextblkno)) { - Buffer cbuf; - Page cpage; + Buffer cbuf; + Page cpage; OffsetNumber maxoffno; cbuf = ReadBuffer(index, nextblkno); @@ -41,7 +41,7 @@ FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { IvfflatList list; - double distance; + double distance; list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, values[0], PointerGetDatum(&list->center))); @@ -67,16 +67,16 @@ FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo static void InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heapRel) { - const IvfflatTypeInfo *typeInfo = IvfflatGetTypeInfo(index); - IndexTuple itup; - Datum value; - FmgrInfo *normprocinfo; - Buffer buf; - Page page; + const IvfflatTypeInfo *typeInfo = IvfflatGetTypeInfo(index); + IndexTuple itup; + Datum value; + FmgrInfo *normprocinfo; + Buffer buf; + Page page; GenericXLogState *state; - Size itemsz; + Size itemsz; BlockNumber insertPage = InvalidBlockNumber; - ListInfo listInfo; + ListInfo listInfo; BlockNumber originalInsertPage; /* Detoast once for all calls */ @@ -86,7 +86,7 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); if (normprocinfo != NULL) { - Oid collation = index->rd_indcollation[0]; + Oid collation = index->rd_indcollation[0]; if (!IvfflatCheckNorm(normprocinfo, collation, value)) return; @@ -111,8 +111,7 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ Assert(itemsz <= BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)) - sizeof(ItemIdData)); /* Find a page to insert the item */ - for (;;) - { + for (;;) { buf = ReadBuffer(index, insertPage); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); @@ -124,16 +123,13 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ insertPage = IvfflatPageGetOpaque(page)->nextblkno; - if (BlockNumberIsValid(insertPage)) - { + if (BlockNumberIsValid(insertPage)) { /* Move to next page */ GenericXLogAbort(state); UnlockReleaseBuffer(buf); - } - else - { - Buffer newbuf; - Page newpage; + } else { + Buffer newbuf; + Page newpage; /* Add a new page */ LockRelationForExtension(index, ExclusiveLock); diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index 6eec852195..cbeaea1aeb 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -21,12 +21,12 @@ static void InitCenters(Relation index, VectorArray samples, VectorArray centers, float *lowerBound) { - FmgrInfo *procinfo; - Oid collation; - int64 j; - float *weight = (float *)palloc(samples->length * sizeof(float)); - int numCenters = centers->maxlen; - int numSamples = samples->length; + FmgrInfo *procinfo; + Oid collation; + int64 j; + float *weight = (float *)palloc(samples->length * sizeof(float)); + int numCenters = centers->maxlen; + int numSamples = samples->length; procinfo = index_getprocinfo(index, 1, IVFFLAT_KMEANS_DISTANCE_PROC); collation = index->rd_indcollation[0]; @@ -38,19 +38,17 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low for (j = 0; j < numSamples; j++) weight[j] = FLT_MAX; - for (int i = 0; i < numCenters; i++) - { - double sum; - double choice; + for (int i = 0; i < numCenters; i++) { + double sum; + double choice; CHECK_FOR_INTERRUPTS(); sum = 0.0; - for (j = 0; j < numSamples; j++) - { - Datum vec = PointerGetDatum(VectorArrayGet(samples, j)); - double distance; + for (j = 0; j < numSamples; j++) { + Datum vec = PointerGetDatum(VectorArrayGet(samples, j)); + double distance; /* Only need to compute distance for new center */ /* TODO Use triangle inequality to reduce distance calculations */ @@ -74,8 +72,7 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low /* Choose new center using weighted probability distribution. */ choice = sum * RandomDouble(); - for (j = 0; j < numSamples - 1; j++) - { + for (j = 0; j < numSamples - 1; j++) { choice -= weight[j]; if (choice <= 0) break; @@ -99,11 +96,10 @@ NormCenters(const IvfflatTypeInfo * typeInfo, Oid collation, VectorArray centers ALLOCSET_DEFAULT_SIZES); MemoryContext oldCtx = MemoryContextSwitchTo(normCtx); - for (int j = 0; j < centers->length; j++) - { - Datum center = PointerGetDatum(VectorArrayGet(centers, j)); - Datum newCenter = IvfflatNormValue(typeInfo, collation, center); - Size size = VARSIZE_ANY(DatumGetPointer(newCenter)); + for (int j = 0; j < centers->length; j++) { + Datum center = PointerGetDatum(VectorArrayGet(centers, j)); + Datum newCenter = IvfflatNormValue(typeInfo, collation, center); + Size size = VARSIZE_ANY(DatumGetPointer(newCenter)); if (size > centers->itemsize) elog(ERROR, "safety check failed"); @@ -122,15 +118,14 @@ NormCenters(const IvfflatTypeInfo * typeInfo, Oid collation, VectorArray centers static void RandomCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - int dimensions = centers->dim; - FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); - Oid collation = index->rd_indcollation[0]; - float *x = (float *) palloc(sizeof(float) * dimensions); + int dimensions = centers->dim; + FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); + Oid collation = index->rd_indcollation[0]; + float *x = (float *) palloc(sizeof(float) * dimensions); /* Fill with random data */ - while (centers->length < centers->maxlen) - { - Pointer center = VectorArrayGet(centers, centers->length); + while (centers->length < centers->maxlen) { + Pointer center = VectorArrayGet(centers, centers->length); for (int i = 0; i < dimensions; i++) x[i] = (float) RandomDouble(); @@ -167,9 +162,8 @@ ShowMemoryUsage(MemoryContext context, Size estimatedSize) static void SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTypeInfo * typeInfo) { - for (int j = 0; j < samples->length; j++) - { - float *x = agg + ((int64) closestCenters[j] * samples->dim); + for (int j = 0; j < samples->length; j++) { + float *x = agg + ((int64) closestCenters[j] * samples->dim); typeInfo->sumCenter(VectorArrayGet(samples, j), x); } @@ -181,9 +175,8 @@ SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTy static void UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - for (int j = 0; j < centers->length; j++) - { - float *x = agg + ((int64) j * centers->dim); + for (int j = 0; j < centers->length; j++) { + float *x = agg + ((int64) j * centers->dim); typeInfo->updateCenter(VectorArrayGet(centers, j), centers->dim, x); } @@ -195,14 +188,13 @@ UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo) static void ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *centerCounts, int *closestCenters, FmgrInfo *normprocinfo, Oid collation, const IvfflatTypeInfo * typeInfo) { - int dimensions = newCenters->dim; - int numCenters = newCenters->length; - int numSamples = samples->length; + int dimensions = newCenters->dim; + int numCenters = newCenters->length; + int numSamples = samples->length; /* Reset sum and count */ - for (int j = 0; j < numCenters; j++) - { - float *x = agg + ((int64) j * dimensions); + for (int j = 0; j < numCenters; j++) { + float *x = agg + ((int64) j * dimensions); for (int k = 0; k < dimensions; k++) x[k] = 0.0; @@ -218,25 +210,20 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int * centerCounts[closestCenters[j]] += 1; /* Divide sum by count */ - for (int j = 0; j < numCenters; j++) - { - float *x = agg + ((int64) j * dimensions); + for (int j = 0; j < numCenters; j++) { + float *x = agg + ((int64) j * dimensions); - if (centerCounts[j] > 0) - { + if (centerCounts[j] > 0) { /* Double avoids overflow, but requires more memory */ /* TODO Update bounds */ - for (int k = 0; k < dimensions; k++) - { + for (int k = 0; k < dimensions; k++) { if (isinf(x[k])) x[k] = x[k] > 0 ? FLT_MAX : -FLT_MAX; } for (int k = 0; k < dimensions; k++) x[k] /= centerCounts[j]; - } - else - { + } else { /* TODO Handle empty centers properly */ for (int k = 0; k < dimensions; k++) x[k] = RandomDouble(); @@ -262,37 +249,37 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int * static void ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo) { - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - Oid collation; - int dimensions = centers->dim; - int numCenters = centers->maxlen; - int numSamples = samples->length; + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + int dimensions = centers->dim; + int numCenters = centers->maxlen; + int numSamples = samples->length; VectorArray newCenters; - float *agg; - int *centerCounts; - int *closestCenters; - float *lowerBound; - float *upperBound; - float *s; - float *halfcdist; - float *newcdist; + float *agg; + int *centerCounts; + int *closestCenters; + float *lowerBound; + float *upperBound; + float *s; + float *halfcdist; + float *newcdist; /* Calculate allocation sizes */ - Size samplesSize = VECTOR_ARRAY_SIZE(samples->maxlen, samples->itemsize); - Size centersSize = VECTOR_ARRAY_SIZE(centers->maxlen, centers->itemsize); - Size newCentersSize = VECTOR_ARRAY_SIZE(numCenters, centers->itemsize); - Size aggSize = sizeof(float) * (int64) numCenters * dimensions; - Size centerCountsSize = sizeof(int) * numCenters; - Size closestCentersSize = sizeof(int) * numSamples; - Size lowerBoundSize = sizeof(float) * numSamples * numCenters; - Size upperBoundSize = sizeof(float) * numSamples; - Size sSize = sizeof(float) * numCenters; - Size halfcdistSize = sizeof(float) * numCenters * numCenters; - Size newcdistSize = sizeof(float) * numCenters; + Size samplesSize = VECTOR_ARRAY_SIZE(samples->maxlen, samples->itemsize); + Size centersSize = VECTOR_ARRAY_SIZE(centers->maxlen, centers->itemsize); + Size newCentersSize = VECTOR_ARRAY_SIZE(numCenters, centers->itemsize); + Size aggSize = sizeof(float) * (int64) numCenters * dimensions; + Size centerCountsSize = sizeof(int) * numCenters; + Size closestCentersSize = sizeof(int) * numSamples; + Size lowerBoundSize = sizeof(float) * numSamples * numCenters; + Size upperBoundSize = sizeof(float) * numSamples; + Size sSize = sizeof(float) * numCenters; + Size halfcdistSize = sizeof(float) * numCenters * numCenters; + Size newcdistSize = sizeof(float) * numCenters; /* Calculate total size */ - Size totalSize = samplesSize + centersSize + newCentersSize + aggSize + centerCountsSize + closestCentersSize + lowerBoundSize + upperBoundSize + sSize + halfcdistSize + newcdistSize; + Size totalSize = samplesSize + centersSize + newCentersSize + aggSize + centerCountsSize + closestCentersSize + lowerBoundSize + upperBoundSize + sSize + halfcdistSize + newcdistSize; /* Check memory requirements */ /* Add one to error message to ceil */ @@ -334,19 +321,16 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff InitCenters(index, samples, centers, lowerBound); /* Assign each x to its closest initial center c(x) = argmin d(x,c) */ - for (int64 j = 0; j < numSamples; j++) - { - float minDistance = FLT_MAX; - int closestCenter = 0; + for (int64 j = 0; j < numSamples; j++) { + float minDistance = FLT_MAX; + int closestCenter = 0; /* Find closest center */ - for (int64 k = 0; k < numCenters; k++) - { + for (int64 k = 0; k < numCenters; k++) { /* TODO Use Lemma 1 in k-means++ initialization */ - float distance = lowerBound[j * numCenters + k]; + float distance = lowerBound[j * numCenters + k]; - if (distance < minDistance) - { + if (distance < minDistance) { minDistance = distance; closestCenter = k; } @@ -357,22 +341,19 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff } /* Give 500 iterations to converge */ - for (int iteration = 0; iteration < 500; iteration++) - { - int changes = 0; - bool rjreset; + for (int iteration = 0; iteration < 500; iteration++) { + int changes = 0; + bool rjreset; /* Can take a while, so ensure we can interrupt */ CHECK_FOR_INTERRUPTS(); /* Step 1: For all centers, compute distance */ - for (int64 j = 0; j < numCenters; j++) - { - Datum vec = PointerGetDatum(VectorArrayGet(centers, j)); + for (int64 j = 0; j < numCenters; j++) { + Datum vec = PointerGetDatum(VectorArrayGet(centers, j)); - for (int64 k = j + 1; k < numCenters; k++) - { - float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + for (int64 k = j + 1; k < numCenters; k++) { + float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); halfcdist[j * numCenters + k] = distance; halfcdist[k * numCenters + j] = distance; @@ -380,13 +361,11 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff } /* For all centers c, compute s(c) */ - for (int64 j = 0; j < numCenters; j++) - { - float minDistance = FLT_MAX; + for (int64 j = 0; j < numCenters; j++) { + float minDistance = FLT_MAX; - for (int64 k = 0; k < numCenters; k++) - { - float distance; + for (int64 k = 0; k < numCenters; k++) { + float distance; if (j == k) continue; @@ -401,9 +380,8 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff rjreset = iteration != 0; - for (int64 j = 0; j < numSamples; j++) - { - bool rj; + for (int64 j = 0; j < numSamples; j++) { + bool rj; /* Step 2: Identify all points x such that u(x) <= s(c(x)) */ if (upperBound[j] <= s[closestCenters[j]]) @@ -411,10 +389,9 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff rj = rjreset; - for (int64 k = 0; k < numCenters; k++) - { - Datum vec; - float dxcx; + for (int64 k = 0; k < numCenters; k++) { + Datum vec; + float dxcx; /* Step 3: For all remaining points x and centers c */ if (k == closestCenters[j]) @@ -429,8 +406,7 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff vec = PointerGetDatum(VectorArrayGet(samples, j)); /* Step 3a */ - if (rj) - { + if (rj) { dxcx = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j])))); /* d(x,c(x)) computed, which is a form of d(x,c) */ @@ -438,20 +414,17 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff upperBound[j] = dxcx; rj = false; - } - else + } else dxcx = upperBound[j]; /* Step 3b */ - if (dxcx > lowerBound[j * numCenters + k] || dxcx > halfcdist[closestCenters[j] * numCenters + k]) - { - float dxc = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + if (dxcx > lowerBound[j * numCenters + k] || dxcx > halfcdist[closestCenters[j] * numCenters + k]) { + float dxc = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); /* d(x,c) calculated */ lowerBound[j * numCenters + k] = dxc; - if (dxc < dxcx) - { + if (dxc < dxcx) { closestCenters[j] = k; /* c(x) changed */ @@ -470,11 +443,9 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff for (int j = 0; j < numCenters; j++) newcdist[j] = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), PointerGetDatum(VectorArrayGet(newCenters, j)))); - for (int64 j = 0; j < numSamples; j++) - { - for (int64 k = 0; k < numCenters; k++) - { - float distance = lowerBound[j * numCenters + k] - newcdist[k]; + for (int64 j = 0; j < numSamples; j++) { + for (int64 k = 0; k < numCenters; k++) { + float distance = lowerBound[j * numCenters + k] - newcdist[k]; if (distance < 0) distance = 0; @@ -503,18 +474,16 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff static void CheckElements(VectorArray centers, const IvfflatTypeInfo * typeInfo) { - float *scratch = (float *)palloc(sizeof(float) * centers->dim); + float *scratch = (float *)palloc(sizeof(float) * centers->dim); - for (int i = 0; i < centers->length; i++) - { + for (int i = 0; i < centers->length; i++) { for (int j = 0; j < centers->dim; j++) scratch[j] = 0; /* /fp:fast may not propagate NaN with MSVC, but that's alright */ typeInfo->sumCenter(VectorArrayGet(centers, i), scratch); - for (int j = 0; j < centers->dim; j++) - { + for (int j = 0; j < centers->dim; j++) { if (isnan(scratch[j])) elog(ERROR, "NaN detected. Please report a bug."); @@ -531,15 +500,14 @@ static void CheckNorms(VectorArray centers, Relation index) { /* Check NORM_PROC instead of KMEANS_NORM_PROC */ - FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); - Oid collation = index->rd_indcollation[0]; + FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); + Oid collation = index->rd_indcollation[0]; if (normprocinfo == NULL) return; - for (int i = 0; i < centers->length; i++) - { - double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); + for (int i = 0; i < centers->length; i++) { + double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); if (norm == 0) elog(ERROR, "Zero norm detected. Please report a bug."); diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index 5da810a286..8499704dc3 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -32,14 +32,13 @@ GetScanLists(IndexScanDesc scan, Datum value) { IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; - int listCount = 0; - double maxDistance = DBL_MAX; + int listCount = 0; + double maxDistance = DBL_MAX; /* Search all list pages */ - while (BlockNumberIsValid(nextblkno)) - { - Buffer cbuf; - Page cpage; + while (BlockNumberIsValid(nextblkno)) { + Buffer cbuf; + Page cpage; OffsetNumber maxoffno; cbuf = ReadBuffer(scan->indexRelation, nextblkno); @@ -48,16 +47,14 @@ GetScanLists(IndexScanDesc scan, Datum value) maxoffno = PageGetMaxOffsetNumber(cpage); - for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); - double distance; + double distance; /* Use procinfo from the index instead of scan key for performance */ distance = DatumGetFloat8(so->distfunc(so->procinfo, so->collation, PointerGetDatum(&list->center), value)); - if (listCount < so->probes) - { + if (listCount < so->probes) { IvfflatScanList *scanlist; scanlist = &so->lists[listCount]; @@ -71,9 +68,7 @@ GetScanLists(IndexScanDesc scan, Datum value) /* Calculate max distance */ if (listCount == so->probes) maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; - } - else if (distance < maxDistance) - { + } else if (distance < maxDistance) { IvfflatScanList *scanlist; /* Remove */ @@ -102,8 +97,8 @@ static void GetScanItems(IndexScanDesc scan, Datum value) { IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; - TupleDesc tupdesc = RelationGetDescr(scan->indexRelation); - double tuples = 0; + TupleDesc tupdesc = RelationGetDescr(scan->indexRelation); + double tuples = 0; TupleTableSlot *slot = MakeSingleTupleTableSlot(so->tupdesc); /* @@ -114,15 +109,13 @@ GetScanItems(IndexScanDesc scan, Datum value) BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); /* Search closest probes lists */ - while (!pairingheap_is_empty(so->listQueue)) - { + while (!pairingheap_is_empty(so->listQueue)) { BlockNumber searchPage = ((IvfflatScanList *) pairingheap_remove_first(so->listQueue))->startPage; /* Search all entry pages for list */ - while (BlockNumberIsValid(searchPage)) - { - Buffer buf; - Page page; + while (BlockNumberIsValid(searchPage)) { + Buffer buf; + Page page; OffsetNumber maxoffno; buf = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas); @@ -130,12 +123,11 @@ GetScanItems(IndexScanDesc scan, Datum value) page = BufferGetPage(buf); maxoffno = PageGetMaxOffsetNumber(page); - for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - IndexTuple itup; - Datum datum; - bool isnull; - ItemId itemid = PageGetItemId(page, offno); + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { + IndexTuple itup; + Datum datum; + bool isnull; + ItemId itemid = PageGetItemId(page, offno); itup = (IndexTuple) PageGetItem(page, itemid); datum = index_getattr(itup, 1, tupdesc, &isnull); @@ -191,15 +183,12 @@ static Datum GetScanValue(IndexScanDesc scan) { IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; - Datum value; + Datum value; - if (scan->orderByData->sk_flags & SK_ISNULL) - { + if (scan->orderByData->sk_flags & SK_ISNULL) { value = PointerGetDatum(NULL); so->distfunc = ZeroDistance; - } - else - { + } else { value = scan->orderByData->sk_argument; so->distfunc = FunctionCall2Coll; @@ -223,16 +212,16 @@ ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) { IndexScanDesc scan; IvfflatScanOpaque so; - int lists; - int dimensions; - AttrNumber attNums[] = {1}; - Oid sortOperators[] = {FLOAT8LTOID}; - Oid sortCollations[] = {InvalidOid}; - bool nullsFirstFlags[] = {false}; - int probes = get_session_context()->ivfflat_probes; - int natts = 2; - int attDistance = 1; - int attHeaptid = 2; + int lists; + int dimensions; + AttrNumber attNums[] = {1}; + Oid sortOperators[] = {FLOAT8LTOID}; + Oid sortCollations[] = {InvalidOid}; + bool nullsFirstFlags[] = {false}; + int probes = get_session_context()->ivfflat_probes; + int natts = 2; + int attDistance = 1; + int attHeaptid = 2; scan = RelationGetIndexScan(index, nkeys, norderbys); @@ -309,9 +298,8 @@ ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) */ Assert(ScanDirectionIsForward(dir)); - if (so->first) - { - Datum value; + if (so->first) { + Datum value; /* Count index scan for stats */ pgstat_count_index_scan(scan->indexRelation); @@ -335,8 +323,7 @@ ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) pfree(DatumGetPointer(value)); } - if (tuplesort_gettupleslot(so->sortstate, true, so->slot, NULL)) - { + if (tuplesort_gettupleslot(so->sortstate, true, so->slot, NULL)) { ItemPointer heaptid = (ItemPointer) DatumGetPointer(heap_slot_getattr(so->slot, 2, &so->isnull)); scan->xs_ctup.t_self = *heaptid; diff --git a/src/gausskernel/storage/access/datavec/ivfutils.cpp b/src/gausskernel/storage/access/datavec/ivfutils.cpp index d1dd3f0275..3adf630c3b 100644 --- a/src/gausskernel/storage/access/datavec/ivfutils.cpp +++ b/src/gausskernel/storage/access/datavec/ivfutils.cpp @@ -88,7 +88,7 @@ IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum) { - Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); + Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); return buf; @@ -135,8 +135,8 @@ void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum) { /* Get new buffer */ - Buffer newbuf = IvfflatNewBuffer(index, forkNum); - Page newpage = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); + Buffer newbuf = IvfflatNewBuffer(index, forkNum); + Page newpage = GenericXLogRegisterBuffer(*state, newbuf, GENERIC_XLOG_FULL_IMAGE); /* Update the previous buffer */ IvfflatPageGetOpaque(*page)->nextblkno = BufferGetBlockNumber(newbuf); @@ -161,8 +161,8 @@ IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **st void IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) { - Buffer buf; - Page page; + Buffer buf; + Page page; IvfflatMetaPage metap; buf = ReadBuffer(index, IVFFLAT_METAPAGE_BLKNO); @@ -190,11 +190,11 @@ IvfflatUpdateList(Relation index, ListInfo listInfo, BlockNumber insertPage, BlockNumber originalInsertPage, BlockNumber startPage, ForkNumber forkNum) { - Buffer buf; - Page page; + Buffer buf; + Page page; GenericXLogState *state; IvfflatList list; - bool changed = false; + bool changed = false; buf = ReadBufferExtended(index, forkNum, listInfo.blkno, RBM_NORMAL, NULL); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); @@ -202,19 +202,16 @@ IvfflatUpdateList(Relation index, ListInfo listInfo, page = GenericXLogRegisterBuffer(state, buf, 0); list = (IvfflatList) PageGetItem(page, PageGetItemId(page, listInfo.offno)); - if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage) - { + if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage) { /* Skip update if insert page is lower than original insert page */ /* This is needed to prevent insert from overwriting vacuum */ - if (!BlockNumberIsValid(originalInsertPage) || insertPage >= originalInsertPage) - { + if (!BlockNumberIsValid(originalInsertPage) || insertPage >= originalInsertPage) { list->insertPage = insertPage; changed = true; } } - if (BlockNumberIsValid(startPage) && startPage != list->startPage) - { + if (BlockNumberIsValid(startPage) && startPage != list->startPage) { list->startPage = startPage; changed = true; } @@ -222,8 +219,7 @@ IvfflatUpdateList(Relation index, ListInfo listInfo, /* Only commit if changed */ if (changed) IvfflatCommitBuffer(buf, state); - else - { + else { GenericXLogAbort(state); UnlockReleaseBuffer(buf); } @@ -250,7 +246,7 @@ BitItemSize(int dimensions) static void VectorUpdateCenter(Pointer v, int dimensions, float *x) { - Vector *vec = (Vector *) v; + Vector *vec = (Vector *) v; SET_VARSIZE(vec, VECTOR_SIZE(dimensions)); vec->dim = dimensions; @@ -274,7 +270,7 @@ HalfvecUpdateCenter(Pointer v, int dimensions, float *x) static void BitUpdateCenter(Pointer v, int dimensions, float *x) { - VarBit *vec = (VarBit *) v; + VarBit *vec = (VarBit *) v; unsigned char *nx = VARBITS(vec); SET_VARSIZE(vec, VARBITTOTALLEN(dimensions)); @@ -290,7 +286,7 @@ BitUpdateCenter(Pointer v, int dimensions, float *x) static void VectorSumCenter(Pointer v, float *x) { - Vector *vec = (Vector *) v; + Vector *vec = (Vector *) v; for (int k = 0; k < vec->dim; k++) x[k] += vec->x[k]; @@ -308,7 +304,7 @@ HalfvecSumCenter(Pointer v, float *x) static void BitSumCenter(Pointer v, float *x) { - VarBit *vec = (VarBit *) v; + VarBit *vec = (VarBit *) v; for (int k = 0; k < VARBITLEN(vec); k++) x[k] += (float) (((VARBITS(vec)[k / 8]) >> (7 - (k % 8))) & 0x01); @@ -317,13 +313,12 @@ BitSumCenter(Pointer v, float *x) /* * Get type info */ -const IvfflatTypeInfo * +const IvfflatTypeInfo * IvfflatGetTypeInfo(Relation index) { - FmgrInfo *procinfo = IvfflatOptionalProcInfo(index, IVFFLAT_TYPE_INFO_PROC); + FmgrInfo *procinfo = IvfflatOptionalProcInfo(index, IVFFLAT_TYPE_INFO_PROC); - if (procinfo == NULL) - { + if (procinfo == NULL) { static const IvfflatTypeInfo typeInfo = { .maxDimensions = IVFFLAT_MAX_DIM, .normalize = l2_normalize, @@ -333,8 +328,7 @@ IvfflatGetTypeInfo(Relation index) }; return (&typeInfo); - } - else + } else return (const IvfflatTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); } diff --git a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp index 335502bc60..6cf9c772de 100644 --- a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp @@ -12,7 +12,7 @@ IndexBulkDeleteResult * ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) { - Relation index = info->index; + Relation index = info->index; BlockNumber blkno = IVFFLAT_HEAD_BLKNO; BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); @@ -22,12 +22,12 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* Iterate over list pages */ while (BlockNumberIsValid(blkno)) { - Buffer cbuf; - Page cpage; + Buffer cbuf; + Page cpage; OffsetNumber coffno; OffsetNumber cmaxoffno; BlockNumber startPages[MaxOffsetNumber]; - ListInfo listInfo; + ListInfo listInfo; cbuf = ReadBuffer(index, blkno); LockBuffer(cbuf, BUFFER_LOCK_SHARE); @@ -36,8 +36,7 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, cmaxoffno = PageGetMaxOffsetNumber(cpage); /* Iterate over lists */ - for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) - { + for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) { IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, coffno)); startPages[coffno - FirstOffsetNumber] = list->startPage; @@ -48,21 +47,19 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, UnlockReleaseBuffer(cbuf); - for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) - { + for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) { BlockNumber searchPage = startPages[coffno - FirstOffsetNumber]; BlockNumber insertPage = InvalidBlockNumber; /* Iterate over entry pages */ - while (BlockNumberIsValid(searchPage)) - { - Buffer buf; - Page page; + while (BlockNumberIsValid(searchPage)) { + Buffer buf; + Page page; GenericXLogState *state; OffsetNumber offno; OffsetNumber maxoffno; OffsetNumber deletable[MaxOffsetNumber]; - int ndeletable; + int ndeletable; vacuum_delay_point(); @@ -83,17 +80,14 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, ndeletable = 0; /* Find deleted tuples */ - for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { - IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offno)); + for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { + IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offno)); ItemPointer htup = &(itup->t_tid); - if (callback(htup, callback_state, InvalidOid, InvalidBktId)) - { + if (callback(htup, callback_state, InvalidOid, InvalidBktId)) { deletable[ndeletable++] = offno; stats->tuples_removed++; - } - else + } else stats->num_index_tuples++; } @@ -104,13 +98,11 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, searchPage = IvfflatPageGetOpaque(page)->nextblkno; - if (ndeletable > 0) - { + if (ndeletable > 0) { /* Delete tuples */ PageIndexMultiDelete(page, deletable, ndeletable); GenericXLogFinish(state); - } - else + } else GenericXLogAbort(state); UnlockReleaseBuffer(buf); @@ -122,8 +114,7 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, * We don't add or delete items from lists pages, so offset won't * change. */ - if (BlockNumberIsValid(insertPage)) - { + if (BlockNumberIsValid(insertPage)) { listInfo.offno = coffno; IvfflatUpdateList(index, listInfo, insertPage, InvalidBlockNumber, InvalidBlockNumber, MAIN_FORKNUM); } @@ -141,7 +132,7 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteResult * ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { - Relation rel = info->index; + Relation rel = info->index; if (info->analyze_only) return stats; diff --git a/src/gausskernel/storage/access/datavec/vecindex.cpp b/src/gausskernel/storage/access/datavec/vecindex.cpp index 539a55c4ea..618cf632d3 100644 --- a/src/gausskernel/storage/access/datavec/vecindex.cpp +++ b/src/gausskernel/storage/access/datavec/vecindex.cpp @@ -46,7 +46,7 @@ bool VecItupGetXminXmax(Page page, OffsetNumber offnum, TransactionId oldest_xmi { ItemId iid = PageGetItemId(page, offnum); HnswElementTuple itup = (HnswElementTuple)PageGetItem(page, iid); - IndexTransInfo* idxXid = (IndexTransInfo*)VecIndexTupleGetXid(itup); + IndexTransInfo *idxXid = (IndexTransInfo *)VecIndexTupleGetXid(itup); bool isDead = false; bool needCheckXmin = true; @@ -185,7 +185,7 @@ static bool VecVisibilityCheckCid(IndexScanDesc scan, IndexTuple itup, bool *nee } /* Step2: Extend when necessary. */ if (newSize != 0) { - vs->lastSelfModifiedItup = (char*)palloc(newSize); + vs->lastSelfModifiedItup = (char *)palloc(newSize); vs->lastSelfModifiedItupBufferSize = newSize; } /* Step3: Save the current IndexTuple. */ @@ -219,7 +219,7 @@ static bool VecXidSatisfiesMVCC(TransactionId xid, bool committed, Snapshot snap } static bool VecVisibilityCheckXid(TransactionId xmin, TransactionId xmax, bool xminCommitted, bool xmaxCommitted, - Snapshot snapshot, Buffer buffer, bool isUpsert) + Snapshot snapshot, Buffer buffer, bool isUpsert) { if (snapshot->satisfies == SNAPSHOT_DIRTY && isUpsert) { bool xmaxVisible = xmaxCommitted || TransactionIdIsCurrentTransactionId(xmax); @@ -230,11 +230,11 @@ static bool VecVisibilityCheckXid(TransactionId xmin, TransactionId xmax, bool x } /* only support MVCC and NOW, ereport used to locate bug */ - if (snapshot->satisfies != SNAPSHOT_VERSION_MVCC && - snapshot->satisfies != SNAPSHOT_MVCC && snapshot->satisfies != SNAPSHOT_NOW) { + if (snapshot->satisfies != SNAPSHOT_VERSION_MVCC && snapshot->satisfies != SNAPSHOT_MVCC && + snapshot->satisfies != SNAPSHOT_NOW) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unsupported snapshot type %u for UBTree index.", snapshot->satisfies), - errhint("This kind of operation may not supported."))); + errmsg("unsupported snapshot type %u for UBTree index.", snapshot->satisfies), + errhint("This kind of operation may not supported."))); } /* handle snapshot MVCC */ @@ -257,13 +257,12 @@ static bool VecVisibilityCheckXid(TransactionId xmin, TransactionId xmax, bool x bool VecVisibilityCheck(IndexScanDesc scan, Page page, OffsetNumber offnum, bool *needRecheck) { - bool needVisibilityCheck = scan->xs_snapshot->satisfies != SNAPSHOT_ANY && - scan->xs_snapshot->satisfies != SNAPSHOT_TOAST; + bool needVisibilityCheck = + scan->xs_snapshot->satisfies != SNAPSHOT_ANY && scan->xs_snapshot->satisfies != SNAPSHOT_TOAST; TransactionId xmin, xmax; bool xminCommitted = false; bool xmaxCommitted = false; - bool isDead = VecItupGetXminXmax(page, offnum, InvalidTransactionId, - &xmin, &xmax, &xminCommitted, &xmaxCommitted, + bool isDead = VecItupGetXminXmax(page, offnum, InvalidTransactionId, &xmin, &xmax, &xminCommitted, &xmaxCommitted, RelationGetNamespace(scan->indexRelation) == PG_TOAST_NAMESPACE); if (needRecheck == NULL) { @@ -284,8 +283,8 @@ bool VecVisibilityCheck(IndexScanDesc scan, Page page, OffsetNumber offnum, bool isVisible = VecVisibilityCheckCid(scan, tuple, needRecheck); /* need check cid */ } else { VectorScanData *vs = VecGetScanData(scan); - isVisible = VecVisibilityCheckXid(xmin, xmax, xminCommitted, xmaxCommitted, - scan->xs_snapshot, vs->buf, scan->isUpsert); + isVisible = VecVisibilityCheckXid(xmin, xmax, xminCommitted, xmaxCommitted, scan->xs_snapshot, vs->buf, + scan->isUpsert); } } -- Gitee From f91f051b63dfad0e1874661b70a59cf7e1d56f73 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Fri, 1 Nov 2024 16:05:06 +0800 Subject: [PATCH 09/67] clean code --- src/common/backend/utils/adt/halfutils.cpp | 191 +++-- src/common/backend/utils/adt/halfvec.cpp | 532 +++++-------- src/common/backend/utils/adt/sparsevec.cpp | 528 +++++-------- src/common/backend/utils/adt/vector.cpp | 848 +++++++++------------ src/include/access/datavec/bitvec.h | 7 +- src/include/access/datavec/halfutils.h | 159 ++-- src/include/access/datavec/halfvec.h | 23 +- src/include/access/datavec/hnsw.h | 530 +++++++------ src/include/access/datavec/ivfflat.h | 314 ++++---- src/include/access/datavec/pg_prng.h | 11 +- src/include/access/datavec/ryu_common.h | 59 +- src/include/access/datavec/sampling.h | 31 +- src/include/access/datavec/sparsevec.h | 29 +- src/include/access/datavec/vecindex.h | 10 +- src/include/access/datavec/vector.h | 29 +- 15 files changed, 1409 insertions(+), 1892 deletions(-) diff --git a/src/common/backend/utils/adt/halfutils.cpp b/src/common/backend/utils/adt/halfutils.cpp index 7da0c3c198..92350ddb90 100644 --- a/src/common/backend/utils/adt/halfutils.cpp +++ b/src/common/backend/utils/adt/halfutils.cpp @@ -15,20 +15,18 @@ #define TARGET_F16C #endif -float (*HalfvecL2SquaredDistance) (int dim, half * ax, half * bx); -float (*HalfvecInnerProduct) (int dim, half * ax, half * bx); -double (*HalfvecCosineSimilarity) (int dim, half * ax, half * bx); -float (*HalfvecL1Distance) (int dim, half * ax, half * bx); +float (*HalfvecL2SquaredDistance)(int dim, half *ax, half *bx); +float (*HalfvecInnerProduct)(int dim, half *ax, half *bx); +double (*HalfvecCosineSimilarity)(int dim, half *ax, half *bx); +float (*HalfvecL1Distance)(int dim, half *ax, half *bx); -static float -HalfvecL2SquaredDistanceDefault(int dim, half * ax, half * bx) +static float HalfvecL2SquaredDistanceDefault(int dim, half *ax, half *bx) { - float distance = 0.0; + float distance = 0.0; /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { - float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); + for (int i = 0; i < dim; i++) { + float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); distance += diff * diff; } @@ -37,22 +35,20 @@ HalfvecL2SquaredDistanceDefault(int dim, half * ax, half * bx) } #ifdef HALFVEC_DISPATCH -TARGET_F16C static float -HalfvecL2SquaredDistanceF16c(int dim, half * ax, half * bx) +TARGET_F16C static float HalfvecL2SquaredDistanceF16c(int dim, half *ax, half *bx) { - float distance; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 dist = _mm256_setzero_ps(); - - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); - __m256 diff = _mm256_sub_ps(axs, bxs); + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); + + for (i = 0; i < count; i += 8) { + __m128i axi = _mm_loadu_si128((__m128i *)(ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *)(bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); + __m256 diff = _mm256_sub_ps(axs, bxs); dist = _mm256_fmadd_ps(diff, diff, dist); } @@ -61,9 +57,8 @@ HalfvecL2SquaredDistanceF16c(int dim, half * ax, half * bx) distance = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; - for (; i < dim; i++) - { - float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); + for (; i < dim; i++) { + float diff = HalfToFloat4(ax[i]) - HalfToFloat4(bx[i]); distance += diff * diff; } @@ -72,10 +67,9 @@ HalfvecL2SquaredDistanceF16c(int dim, half * ax, half * bx) } #endif -static float -HalfvecInnerProductDefault(int dim, half * ax, half * bx) +static float HalfvecInnerProductDefault(int dim, half *ax, half *bx) { - float distance = 0.0; + float distance = 0.0; /* Auto-vectorized */ for (int i = 0; i < dim; i++) @@ -85,21 +79,19 @@ HalfvecInnerProductDefault(int dim, half * ax, half * bx) } #ifdef HALFVEC_DISPATCH -TARGET_F16C static float -HalfvecInnerProductF16c(int dim, half * ax, half * bx) +TARGET_F16C static float HalfvecInnerProductF16c(int dim, half *ax, half *bx) { - float distance; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 dist = _mm256_setzero_ps(); - - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); + + for (i = 0; i < count; i += 8) { + __m128i axi = _mm_loadu_si128((__m128i *)(ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *)(bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); dist = _mm256_fmadd_ps(axs, bxs, dist); } @@ -115,18 +107,16 @@ HalfvecInnerProductF16c(int dim, half * ax, half * bx) } #endif -static double -HalfvecCosineSimilarityDefault(int dim, half * ax, half * bx) +static double HalfvecCosineSimilarityDefault(int dim, half *ax, half *bx) { - float similarity = 0.0; - float norma = 0.0; - float normb = 0.0; + float similarity = 0.0; + float norma = 0.0; + float normb = 0.0; /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { - float axi = HalfToFloat4(ax[i]); - float bxi = HalfToFloat4(bx[i]); + for (int i = 0; i < dim; i++) { + float axi = HalfToFloat4(ax[i]); + float bxi = HalfToFloat4(bx[i]); similarity += axi * bxi; norma += axi * axi; @@ -134,29 +124,27 @@ HalfvecCosineSimilarityDefault(int dim, half * ax, half * bx) } /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double) similarity / sqrt((double) norma * (double) normb); + return (double)similarity / sqrt((double)norma * (double)normb); } #ifdef HALFVEC_DISPATCH -TARGET_F16C static double -HalfvecCosineSimilarityF16c(int dim, half * ax, half * bx) +TARGET_F16C static double HalfvecCosineSimilarityF16c(int dim, half *ax, half *bx) { - float similarity; - float norma; - float normb; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 sim = _mm256_setzero_ps(); - __m256 na = _mm256_setzero_ps(); - __m256 nb = _mm256_setzero_ps(); - - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); + float similarity; + float norma; + float normb; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 sim = _mm256_setzero_ps(); + __m256 na = _mm256_setzero_ps(); + __m256 nb = _mm256_setzero_ps(); + + for (i = 0; i < count; i += 8) { + __m128i axi = _mm_loadu_si128((__m128i *)(ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *)(bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); sim = _mm256_fmadd_ps(axs, bxs, sim); na = _mm256_fmadd_ps(axs, axs, na); @@ -173,10 +161,9 @@ HalfvecCosineSimilarityF16c(int dim, half * ax, half * bx) normb = s[0] + s[1] + s[2] + s[3] + s[4] + s[5] + s[6] + s[7]; /* Auto-vectorized */ - for (; i < dim; i++) - { - float axi = HalfToFloat4(ax[i]); - float bxi = HalfToFloat4(bx[i]); + for (; i < dim; i++) { + float axi = HalfToFloat4(ax[i]); + float bxi = HalfToFloat4(bx[i]); similarity += axi * bxi; norma += axi * axi; @@ -184,14 +171,13 @@ HalfvecCosineSimilarityF16c(int dim, half * ax, half * bx) } /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double) similarity / sqrt((double) norma * (double) normb); + return (double)similarity / sqrt((double)norma * (double)normb); } #endif -static float -HalfvecL1DistanceDefault(int dim, half * ax, half * bx) +static float HalfvecL1DistanceDefault(int dim, half *ax, half *bx) { - float distance = 0.0; + float distance = 0.0; /* Auto-vectorized */ for (int i = 0; i < dim; i++) @@ -202,22 +188,20 @@ HalfvecL1DistanceDefault(int dim, half * ax, half * bx) #ifdef HALFVEC_DISPATCH /* Does not require FMA, but keep logic simple */ -TARGET_F16C static float -HalfvecL1DistanceF16c(int dim, half * ax, half * bx) +TARGET_F16C static float HalfvecL1DistanceF16c(int dim, half *ax, half *bx) { - float distance; - int i; - float s[8]; - int count = (dim / 8) * 8; - __m256 dist = _mm256_setzero_ps(); - __m256 sign = _mm256_set1_ps(-0.0); - - for (i = 0; i < count; i += 8) - { - __m128i axi = _mm_loadu_si128((__m128i *) (ax + i)); - __m128i bxi = _mm_loadu_si128((__m128i *) (bx + i)); - __m256 axs = _mm256_cvtph_ps(axi); - __m256 bxs = _mm256_cvtph_ps(bxi); + float distance; + int i; + float s[8]; + int count = (dim / 8) * 8; + __m256 dist = _mm256_setzero_ps(); + __m256 sign = _mm256_set1_ps(-0.0); + + for (i = 0; i < count; i += 8) { + __m128i axi = _mm_loadu_si128((__m128i *)(ax + i)); + __m128i bxi = _mm_loadu_si128((__m128i *)(bx + i)); + __m256 axs = _mm256_cvtph_ps(axi); + __m256 bxs = _mm256_cvtph_ps(bxi); dist = _mm256_add_ps(dist, _mm256_andnot_ps(sign, _mm256_sub_ps(axs, bxs))); } @@ -234,10 +218,10 @@ HalfvecL1DistanceF16c(int dim, half * ax, half * bx) #endif #ifdef HALFVEC_DISPATCH -#define CPU_FEATURE_FMA (1 << 12) +#define CPU_FEATURE_FMA (1 << 12) #define CPU_FEATURE_OSXSAVE (1 << 27) -#define CPU_FEATURE_AVX (1 << 28) -#define CPU_FEATURE_F16C (1 << 29) +#define CPU_FEATURE_AVX (1 << 28) +#define CPU_FEATURE_F16C (1 << 29) #ifdef _MSC_VER #define TARGET_XSAVE @@ -245,8 +229,7 @@ HalfvecL1DistanceF16c(int dim, half * ax, half * bx) #define TARGET_XSAVE __attribute__((target("xsave"))) #endif -TARGET_XSAVE static bool -SupportsCpuFeature(unsigned int feature) +TARGET_XSAVE static bool SupportsCpuFeature(unsigned int feature) { unsigned int exx[4] = {0, 0, 0, 0}; @@ -269,8 +252,7 @@ SupportsCpuFeature(unsigned int feature) } #endif -void -HalfvecInit(void) +void HalfvecInit(void) { /* * Could skip pointer when single function, but no difference in @@ -282,8 +264,7 @@ HalfvecInit(void) HalfvecL1Distance = HalfvecL1DistanceDefault; #ifdef HALFVEC_DISPATCH - if (SupportsCpuFeature(CPU_FEATURE_AVX | CPU_FEATURE_F16C | CPU_FEATURE_FMA)) - { + if (SupportsCpuFeature(CPU_FEATURE_AVX | CPU_FEATURE_F16C | CPU_FEATURE_FMA)) { HalfvecL2SquaredDistance = HalfvecL2SquaredDistanceF16c; HalfvecInnerProduct = HalfvecInnerProductF16c; HalfvecCosineSimilarity = HalfvecCosineSimilarityF16c; diff --git a/src/common/backend/utils/adt/halfvec.cpp b/src/common/backend/utils/adt/halfvec.cpp index 3c272f26e9..8db9e0b840 100644 --- a/src/common/backend/utils/adt/halfvec.cpp +++ b/src/common/backend/utils/adt/halfvec.cpp @@ -9,7 +9,7 @@ #include "access/datavec/halfvec.h" #include "lib/stringinfo.h" #include "libpq/pqformat.h" -#include "port.h" /* for strtof() */ +#include "port.h" /* for strtof() */ #include "access/datavec/shortest_dec.h" #include "access/datavec/sparsevec.h" #include "utils/array.h" @@ -29,14 +29,12 @@ /* * Get a half from a message buffer */ -static half -pq_getmsghalf(StringInfo msg) +static half pq_getmsghalf(StringInfo msg) { - union - { - half h; - uint16 i; - } swap; + union { + half h; + uint16 i; + } swap; swap.i = pq_getmsgint(msg, 2); return swap.h; @@ -45,14 +43,12 @@ pq_getmsghalf(StringInfo msg) /* * Append a half to a StringInfo buffer */ -static void -pq_sendhalf(StringInfo buf, half h) +static void pq_sendhalf(StringInfo buf, half h) { - union - { - half h; - uint16 i; - } swap; + union { + half h; + uint16 i; + } swap; swap.h = h; pq_sendint16(buf, swap.i); @@ -61,72 +57,57 @@ pq_sendhalf(StringInfo buf, half h) /* * Ensure same dimensions */ -static inline void -CheckDims(HalfVector * a, HalfVector * b) +static inline void CheckDims(HalfVector *a, HalfVector *b) { if (a->dim != b->dim) ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("different halfvec dimensions %d and %d", a->dim, b->dim))); + (errcode(ERRCODE_DATA_EXCEPTION), errmsg("different halfvec dimensions %d and %d", a->dim, b->dim))); } /* * Ensure expected dimensions */ -static inline void -CheckExpectedDim(int32 typmod, int dim) +static inline void CheckExpectedDim(int32 typmod, int dim) { if (typmod != -1 && typmod != dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected %d dimensions, not %d", typmod, dim))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected %d dimensions, not %d", typmod, dim))); } /* * Ensure valid dimensions */ -static inline void -CheckDim(int dim) +static inline void CheckDim(int dim) { if (dim < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("halfvec must have at least 1 dimension"))); if (dim > HALFVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); } /* * Ensure finite element */ -static inline void -CheckElement(half value) +static inline void CheckElement(half value) { if (HalfIsNan(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("NaN not allowed in halfvec"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("NaN not allowed in halfvec"))); if (HalfIsInf(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("infinite value not allowed in halfvec"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("infinite value not allowed in halfvec"))); } /* * Allocate and initialize a new half vector */ -HalfVector * -InitHalfVector(int dim) +HalfVector *InitHalfVector(int dim) { HalfVector *result; - int size; + int size; size = HALFVEC_SIZE(dim); - result = (HalfVector *) palloc0(size); + result = (HalfVector *)palloc0(size); SET_VARSIZE(result, size); result->dim = dim; @@ -136,15 +117,9 @@ InitHalfVector(int dim) /* * Check for whitespace, since array_isspace() is static */ -static inline bool -halfvec_isspace(char ch) +static inline bool halfvec_isspace(char ch) { - if (ch == ' ' || - ch == '\t' || - ch == '\n' || - ch == '\r' || - ch == '\v' || - ch == '\f') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') return true; return false; } @@ -152,32 +127,23 @@ halfvec_isspace(char ch) /* * Check state array */ -static float8 * -CheckStateArray(ArrayType *statearray, const char *caller) +static float8 *CheckStateArray(ArrayType *statearray, const char *caller) { - if (ARR_NDIM(statearray) != 1 || - ARR_DIMS(statearray)[0] < 1 || - ARR_HASNULL(statearray) || + if (ARR_NDIM(statearray) != 1 || ARR_DIMS(statearray)[0] < 1 || ARR_HASNULL(statearray) || ARR_ELEMTYPE(statearray) != FLOAT8OID) elog(ERROR, "%s: expected state array", caller); - return (float8 *) ARR_DATA_PTR(statearray); + return (float8 *)ARR_DATA_PTR(statearray); } #if PG_VERSION_NUM < 120003 -static pg_noinline void -float_overflow_error(void) +static pg_noinline void float_overflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: overflow"))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value out of range: overflow"))); } -static pg_noinline void -float_underflow_error(void) +static pg_noinline void float_underflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: underflow"))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value out of range: underflow"))); } #endif @@ -185,24 +151,22 @@ float_underflow_error(void) * Convert textual representation to internal representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_in); -Datum -halfvec_in(PG_FUNCTION_ARGS) +Datum halfvec_in(PG_FUNCTION_ARGS) { - char *lit = PG_GETARG_CSTRING(0); - int32 typmod = PG_GETARG_INT32(2); - half x[HALFVEC_MAX_DIM]; - int dim = 0; - char *pt = lit; + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + half x[HALFVEC_MAX_DIM]; + int dim = 0; + char *pt = lit; HalfVector *result; while (halfvec_isspace(*pt)) pt++; if (*pt != '[') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit), - errdetail("Vector contents must start with \"[\"."))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit), + errdetail("Vector contents must start with \"[\"."))); pt++; @@ -210,28 +174,23 @@ halfvec_in(PG_FUNCTION_ARGS) pt++; if (*pt == ']') - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("halfvec must have at least 1 dimension"))); - for (;;) - { - float val; - char *stringEnd; + for (;;) { + float val; + char *stringEnd; if (dim == HALFVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); while (halfvec_isspace(*pt)) pt++; /* Check for empty string like float4in */ if (*pt == '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); errno = 0; @@ -239,17 +198,15 @@ halfvec_in(PG_FUNCTION_ARGS) val = strtof(pt, &stringEnd); if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); x[dim] = Float4ToHalfUnchecked(val); /* Check for range error like float4in */ if ((errno == ERANGE && isinf(val)) || (HalfIsInf(x[dim]) && !isinf(val))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt)))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt)))); CheckElement(x[dim]); dim++; @@ -261,15 +218,12 @@ halfvec_in(PG_FUNCTION_ARGS) if (*pt == ',') pt++; - else if (*pt == ']') - { + else if (*pt == ']') { pt++; break; - } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + } else + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); } /* Only whitespace is allowed after the closing brace */ @@ -277,10 +231,9 @@ halfvec_in(PG_FUNCTION_ARGS) pt++; if (*pt != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type halfvec: \"%s\"", lit), - errdetail("Junk after closing right brace."))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type halfvec: \"%s\"", lit), + errdetail("Junk after closing right brace."))); CheckDim(dim); CheckExpectedDim(typmod, dim); @@ -299,13 +252,12 @@ halfvec_in(PG_FUNCTION_ARGS) * Convert internal representation to textual representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_out); -Datum -halfvec_out(PG_FUNCTION_ARGS) +Datum halfvec_out(PG_FUNCTION_ARGS) { HalfVector *vector = PG_GETARG_HALFVEC_P(0); - int dim = vector->dim; - char *buf; - char *ptr; + int dim = vector->dim; + char *buf; + char *ptr; /* * Need: @@ -317,13 +269,12 @@ halfvec_out(PG_FUNCTION_ARGS) * * 3 bytes for [, ], and \0 */ - buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); + buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); ptr = buf; AppendChar(ptr, '['); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { if (i > 0) AppendChar(ptr, ','); @@ -345,29 +296,24 @@ halfvec_out(PG_FUNCTION_ARGS) * Convert type modifier */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_typmod_in); -Datum -halfvec_typmod_in(PG_FUNCTION_ARGS) +Datum halfvec_typmod_in(PG_FUNCTION_ARGS) { - ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); - int32 *tl; - int n; + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; tl = ArrayGetIntegerTypmods(ta, &n); if (n != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid type modifier"))); + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid type modifier"))); if (*tl < 1) ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type halfvec must be at least 1"))); + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dimensions for type halfvec must be at least 1"))); if (*tl > HALFVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type halfvec cannot exceed %d", HALFVEC_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type halfvec cannot exceed %d", HALFVEC_MAX_DIM))); PG_RETURN_INT32(*tl); } @@ -376,14 +322,13 @@ halfvec_typmod_in(PG_FUNCTION_ARGS) * Convert external binary representation to internal representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_recv); -Datum -halfvec_recv(PG_FUNCTION_ARGS) +Datum halfvec_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - int32 typmod = PG_GETARG_INT32(2); + StringInfo buf = (StringInfo)PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); HalfVector *result; - int16 dim; - int16 unused; + int16 dim; + int16 unused; dim = pq_getmsgint(buf, sizeof(int16)); unused = pq_getmsgint(buf, sizeof(int16)); @@ -392,13 +337,10 @@ halfvec_recv(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, dim); if (unused != 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected unused to be 0, not %d", unused))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected unused to be 0, not %d", unused))); result = InitHalfVector(dim); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { result->x[i] = pq_getmsghalf(buf); CheckElement(result->x[i]); } @@ -410,8 +352,7 @@ halfvec_recv(PG_FUNCTION_ARGS) * Convert internal representation to the external binary representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_send); -Datum -halfvec_send(PG_FUNCTION_ARGS) +Datum halfvec_send(PG_FUNCTION_ARGS) { HalfVector *vec = PG_GETARG_HALFVEC_P(0); StringInfoData buf; @@ -430,11 +371,10 @@ halfvec_send(PG_FUNCTION_ARGS) * This is needed to check the type modifier */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec); -Datum -halfvec(PG_FUNCTION_ARGS) +Datum halfvec(PG_FUNCTION_ARGS) { HalfVector *vec = PG_GETARG_HALFVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); + int32 typmod = PG_GETARG_INT32(1); CheckExpectedDim(typmod, vec->dim); @@ -445,27 +385,22 @@ halfvec(PG_FUNCTION_ARGS) * Convert array to half vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(array_to_halfvec); -Datum -array_to_halfvec(PG_FUNCTION_ARGS) +Datum array_to_halfvec(PG_FUNCTION_ARGS) { - ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); - int32 typmod = PG_GETARG_INT32(1); + ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); + int32 typmod = PG_GETARG_INT32(1); HalfVector *result; - int16 typlen; - bool typbyval; - char typalign; - Datum *elemsp; - int nelemsp; + int16 typlen; + bool typbyval; + char typalign; + Datum *elemsp; + int nelemsp; if (ARR_NDIM(array) > 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("array must be 1-D"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("array must be 1-D"))); if (ARR_HASNULL(array) && array_contains_nulls(array)) - ereport(ERROR, - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("array must not contain nulls"))); + ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("array must not contain nulls"))); get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); @@ -475,31 +410,20 @@ array_to_halfvec(PG_FUNCTION_ARGS) result = InitHalfVector(nelemsp); - if (ARR_ELEMTYPE(array) == INT4OID) - { + if (ARR_ELEMTYPE(array) == INT4OID) { for (int i = 0; i < nelemsp; i++) result->x[i] = Float4ToHalf(DatumGetInt32(elemsp[i])); - } - else if (ARR_ELEMTYPE(array) == FLOAT8OID) - { + } else if (ARR_ELEMTYPE(array) == FLOAT8OID) { for (int i = 0; i < nelemsp; i++) result->x[i] = Float4ToHalf(DatumGetFloat8(elemsp[i])); - } - else if (ARR_ELEMTYPE(array) == FLOAT4OID) - { + } else if (ARR_ELEMTYPE(array) == FLOAT4OID) { for (int i = 0; i < nelemsp; i++) result->x[i] = Float4ToHalf(DatumGetFloat4(elemsp[i])); - } - else if (ARR_ELEMTYPE(array) == NUMERICOID) - { + } else if (ARR_ELEMTYPE(array) == NUMERICOID) { for (int i = 0; i < nelemsp; i++) result->x[i] = Float4ToHalf(DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i]))); - } - else - { - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("unsupported array type"))); + } else { + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("unsupported array type"))); } /* @@ -519,14 +443,13 @@ array_to_halfvec(PG_FUNCTION_ARGS) * Convert half vector to float4[] */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_float4); -Datum -halfvec_to_float4(PG_FUNCTION_ARGS) +Datum halfvec_to_float4(PG_FUNCTION_ARGS) { HalfVector *vec = PG_GETARG_HALFVEC_P(0); - Datum *datums; - ArrayType *result; + Datum *datums; + ArrayType *result; - datums = (Datum *) palloc(sizeof(Datum) * vec->dim); + datums = (Datum *)palloc(sizeof(Datum) * vec->dim); for (int i = 0; i < vec->dim; i++) datums[i] = Float4GetDatum(HalfToFloat4(vec->x[i])); @@ -543,11 +466,10 @@ halfvec_to_float4(PG_FUNCTION_ARGS) * Convert vector to half vec */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_halfvec); -Datum -vector_to_halfvec(PG_FUNCTION_ARGS) +Datum vector_to_halfvec(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - int32 typmod = PG_GETARG_INT32(1); + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); HalfVector *result; CheckDim(vec->dim); @@ -565,72 +487,67 @@ vector_to_halfvec(PG_FUNCTION_ARGS) * Get the L2 distance between half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_distance); -Datum -halfvec_l2_distance(PG_FUNCTION_ARGS) +Datum halfvec_l2_distance(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8(sqrt((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x))); + PG_RETURN_FLOAT8(sqrt((double)HalfvecL2SquaredDistance(a->dim, a->x, b->x))); } /* * Get the L2 squared distance between half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_squared_distance); -Datum -halfvec_l2_squared_distance(PG_FUNCTION_ARGS) +Datum halfvec_l2_squared_distance(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) HalfvecL2SquaredDistance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)HalfvecL2SquaredDistance(a->dim, a->x, b->x)); } /* * Get the inner product of two half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_inner_product); -Datum -halfvec_inner_product(PG_FUNCTION_ARGS) +Datum halfvec_inner_product(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) HalfvecInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)HalfvecInnerProduct(a->dim, a->x, b->x)); } /* * Get the negative inner product of two half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_negative_inner_product); -Datum -halfvec_negative_inner_product(PG_FUNCTION_ARGS) +Datum halfvec_negative_inner_product(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) -HalfvecInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)-HalfvecInnerProduct(a->dim, a->x, b->x)); } /* * Get the cosine distance between two half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_cosine_distance); -Datum -halfvec_cosine_distance(PG_FUNCTION_ARGS) +Datum halfvec_cosine_distance(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); - double similarity; + double similarity; CheckDims(a, b); @@ -657,16 +574,15 @@ halfvec_cosine_distance(PG_FUNCTION_ARGS) * Assumes inputs are unit vectors (skips norm) */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_spherical_distance); -Datum -halfvec_spherical_distance(PG_FUNCTION_ARGS) +Datum halfvec_spherical_distance(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); - double distance; + double distance; CheckDims(a, b); - distance = (double) HalfvecInnerProduct(a->dim, a->x, b->x); + distance = (double)HalfvecInnerProduct(a->dim, a->x, b->x); /* Prevent NaN with acos with loss of precision */ if (distance > 1) @@ -681,23 +597,21 @@ halfvec_spherical_distance(PG_FUNCTION_ARGS) * Get the L1 distance between two half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l1_distance); -Datum -halfvec_l1_distance(PG_FUNCTION_ARGS) +Datum halfvec_l1_distance(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) HalfvecL1Distance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)HalfvecL1Distance(a->dim, a->x, b->x)); } /* * Get the dimensions of a half vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_vector_dims); -Datum -halfvec_vector_dims(PG_FUNCTION_ARGS) +Datum halfvec_vector_dims(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); @@ -708,17 +622,15 @@ halfvec_vector_dims(PG_FUNCTION_ARGS) * Get the L2 norm of a half vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_norm); -Datum -halfvec_l2_norm(PG_FUNCTION_ARGS) +Datum halfvec_l2_norm(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); - half *ax = a->x; - double norm = 0.0; + half *ax = a->x; + double norm = 0.0; /* Auto-vectorized */ - for (int i = 0; i < a->dim; i++) - { - double axi = (double) HalfToFloat4(ax[i]); + for (int i = 0; i < a->dim; i++) { + double axi = (double)HalfToFloat4(ax[i]); norm += axi * axi; } @@ -730,33 +642,30 @@ halfvec_l2_norm(PG_FUNCTION_ARGS) * Normalize a half vector with the L2 norm */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_l2_normalize); -Datum -halfvec_l2_normalize(PG_FUNCTION_ARGS) +Datum halfvec_l2_normalize(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); - half *ax = a->x; - double norm = 0; + half *ax = a->x; + double norm = 0; HalfVector *result; - half *rx; + half *rx; result = InitHalfVector(a->dim); rx = result->x; /* Auto-vectorized */ for (int i = 0; i < a->dim; i++) - norm += (double) HalfToFloat4(ax[i]) * (double) HalfToFloat4(ax[i]); + norm += (double)HalfToFloat4(ax[i]) * (double)HalfToFloat4(ax[i]); norm = sqrt(norm); /* Return zero vector for zero norm */ - if (norm > 0) - { + if (norm > 0) { for (int i = 0; i < a->dim; i++) rx[i] = Float4ToHalfUnchecked(HalfToFloat4(ax[i]) / norm); /* Check for overflow */ - for (int i = 0; i < a->dim; i++) - { + for (int i = 0; i < a->dim; i++) { if (HalfIsInf(rx[i])) float_overflow_error(); } @@ -769,15 +678,14 @@ halfvec_l2_normalize(PG_FUNCTION_ARGS) * Add half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_add); -Datum -halfvec_add(PG_FUNCTION_ARGS) +Datum halfvec_add(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); - half *ax = a->x; - half *bx = b->x; + half *ax = a->x; + half *bx = b->x; HalfVector *result; - half *rx; + half *rx; CheckDims(a, b); @@ -785,8 +693,7 @@ halfvec_add(PG_FUNCTION_ARGS) rx = result->x; /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { #ifdef FLT16_SUPPORT rx[i] = ax[i] + bx[i]; #else @@ -795,8 +702,7 @@ halfvec_add(PG_FUNCTION_ARGS) } /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { if (HalfIsInf(rx[i])) float_overflow_error(); } @@ -808,15 +714,14 @@ halfvec_add(PG_FUNCTION_ARGS) * Subtract half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_sub); -Datum -halfvec_sub(PG_FUNCTION_ARGS) +Datum halfvec_sub(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); - half *ax = a->x; - half *bx = b->x; + half *ax = a->x; + half *bx = b->x; HalfVector *result; - half *rx; + half *rx; CheckDims(a, b); @@ -824,8 +729,7 @@ halfvec_sub(PG_FUNCTION_ARGS) rx = result->x; /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { #ifdef FLT16_SUPPORT rx[i] = ax[i] - bx[i]; #else @@ -834,8 +738,7 @@ halfvec_sub(PG_FUNCTION_ARGS) } /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { if (HalfIsInf(rx[i])) float_overflow_error(); } @@ -847,15 +750,14 @@ halfvec_sub(PG_FUNCTION_ARGS) * Multiply half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_mul); -Datum -halfvec_mul(PG_FUNCTION_ARGS) +Datum halfvec_mul(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); - half *ax = a->x; - half *bx = b->x; + half *ax = a->x; + half *bx = b->x; HalfVector *result; - half *rx; + half *rx; CheckDims(a, b); @@ -863,8 +765,7 @@ halfvec_mul(PG_FUNCTION_ARGS) rx = result->x; /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { #ifdef FLT16_SUPPORT rx[i] = ax[i] * bx[i]; #else @@ -873,8 +774,7 @@ halfvec_mul(PG_FUNCTION_ARGS) } /* Check for overflow and underflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { if (HalfIsInf(rx[i])) float_overflow_error(); @@ -889,13 +789,12 @@ halfvec_mul(PG_FUNCTION_ARGS) * Concatenate half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_concat); -Datum -halfvec_concat(PG_FUNCTION_ARGS) +Datum halfvec_concat(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); HalfVector *result; - int dim = a->dim + b->dim; + int dim = a->dim + b->dim; CheckDim(dim); result = InitHalfVector(dim); @@ -913,12 +812,11 @@ halfvec_concat(PG_FUNCTION_ARGS) * Quantize a half vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_binary_quantize); -Datum -halfvec_binary_quantize(PG_FUNCTION_ARGS) +Datum halfvec_binary_quantize(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); - half *ax = a->x; - VarBit *result = InitBitVector(a->dim); + half *ax = a->x; + VarBit *result = InitBitVector(a->dim); unsigned char *rx = VARBITS(result); for (int i = 0; i < a->dim; i++) @@ -931,21 +829,18 @@ halfvec_binary_quantize(PG_FUNCTION_ARGS) * Get a subvector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_subvector); -Datum -halfvec_subvector(PG_FUNCTION_ARGS) +Datum halfvec_subvector(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); - int32 start = PG_GETARG_INT32(1); - int32 count = PG_GETARG_INT32(2); - int32 end; - half *ax = a->x; + int32 start = PG_GETARG_INT32(1); + int32 count = PG_GETARG_INT32(2); + int32 end; + half *ax = a->x; HalfVector *result; - int32 dim; + int32 dim; if (count < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("halfvec must have at least 1 dimension"))); /* * Check if (start + count > a->dim), avoiding integer overflow. a->dim @@ -960,9 +855,7 @@ halfvec_subvector(PG_FUNCTION_ARGS) if (start < 1) start = 1; else if (start > a->dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("halfvec must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("halfvec must have at least 1 dimension"))); dim = end - start; CheckDim(dim); @@ -977,14 +870,12 @@ halfvec_subvector(PG_FUNCTION_ARGS) /* * Internal helper to compare half vectors */ -static int -halfvec_cmp_internal(HalfVector * a, HalfVector * b) +static int halfvec_cmp_internal(HalfVector *a, HalfVector *b) { - int dim = Min(a->dim, b->dim); + int dim = Min(a->dim, b->dim); /* Check values before dimensions to be consistent with Postgres arrays */ - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { if (HalfToFloat4(a->x[i]) < HalfToFloat4(b->x[i])) return -1; @@ -1005,8 +896,7 @@ halfvec_cmp_internal(HalfVector * a, HalfVector * b) * Less than */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_lt); -Datum -halfvec_lt(PG_FUNCTION_ARGS) +Datum halfvec_lt(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); @@ -1018,8 +908,7 @@ halfvec_lt(PG_FUNCTION_ARGS) * Less than or equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_le); -Datum -halfvec_le(PG_FUNCTION_ARGS) +Datum halfvec_le(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); @@ -1031,8 +920,7 @@ halfvec_le(PG_FUNCTION_ARGS) * Equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_eq); -Datum -halfvec_eq(PG_FUNCTION_ARGS) +Datum halfvec_eq(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); @@ -1044,8 +932,7 @@ halfvec_eq(PG_FUNCTION_ARGS) * Not equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ne); -Datum -halfvec_ne(PG_FUNCTION_ARGS) +Datum halfvec_ne(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); @@ -1057,8 +944,7 @@ halfvec_ne(PG_FUNCTION_ARGS) * Greater than or equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_ge); -Datum -halfvec_ge(PG_FUNCTION_ARGS) +Datum halfvec_ge(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); @@ -1070,8 +956,7 @@ halfvec_ge(PG_FUNCTION_ARGS) * Greater than */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_gt); -Datum -halfvec_gt(PG_FUNCTION_ARGS) +Datum halfvec_gt(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); @@ -1083,8 +968,7 @@ halfvec_gt(PG_FUNCTION_ARGS) * Compare half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_cmp); -Datum -halfvec_cmp(PG_FUNCTION_ARGS) +Datum halfvec_cmp(PG_FUNCTION_ARGS) { HalfVector *a = PG_GETARG_HALFVEC_P(0); HalfVector *b = PG_GETARG_HALFVEC_P(1); @@ -1096,18 +980,17 @@ halfvec_cmp(PG_FUNCTION_ARGS) * Accumulate half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_accum); -Datum -halfvec_accum(PG_FUNCTION_ARGS) +Datum halfvec_accum(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); HalfVector *newval = PG_GETARG_HALFVEC_P(1); - float8 *statevalues; - int16 dim; - bool newarr; - float8 n; - Datum *statedatums; - half *x = newval->x; - ArrayType *result; + float8 *statevalues; + int16 dim; + bool newarr; + float8 n; + Datum *statedatums; + half *x = newval->x; + ArrayType *result; /* Check array before using */ statevalues = CheckStateArray(statearray, "halfvec_accum"); @@ -1124,16 +1007,12 @@ halfvec_accum(PG_FUNCTION_ARGS) statedatums = (Datum *)CreateStateDatums(dim); statedatums[0] = Float8GetDatum(n); - if (newarr) - { + if (newarr) { for (int i = 0; i < dim; i++) - statedatums[i + 1] = Float8GetDatum((double) HalfToFloat4(x[i])); - } - else - { - for (int i = 0; i < dim; i++) - { - double v = statevalues[i + 1] + (double) HalfToFloat4(x[i]); + statedatums[i + 1] = Float8GetDatum((double)HalfToFloat4(x[i])); + } else { + for (int i = 0; i < dim; i++) { + double v = statevalues[i + 1] + (double)HalfToFloat4(x[i]); /* Check for overflow */ if (isinf(v)) @@ -1144,9 +1023,7 @@ halfvec_accum(PG_FUNCTION_ARGS) } /* Use float8 array like float4_accum */ - result = construct_array(statedatums, dim + 1, - FLOAT8OID, - sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + result = construct_array(statedatums, dim + 1, FLOAT8OID, sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); pfree(statedatums); @@ -1157,13 +1034,12 @@ halfvec_accum(PG_FUNCTION_ARGS) * Average half vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_avg); -Datum -halfvec_avg(PG_FUNCTION_ARGS) +Datum halfvec_avg(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); - float8 *statevalues; - float8 n; - uint16 dim; + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + float8 *statevalues; + float8 n; + uint16 dim; HalfVector *result; /* Check array before using */ @@ -1178,8 +1054,7 @@ halfvec_avg(PG_FUNCTION_ARGS) dim = STATE_DIMS(statearray); CheckDim(dim); result = InitHalfVector(dim); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { result->x[i] = Float4ToHalf(statevalues[i + 1] / n); CheckElement(result->x[i]); } @@ -1191,14 +1066,13 @@ halfvec_avg(PG_FUNCTION_ARGS) * Convert sparse vector to half vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_to_halfvec); -Datum -sparsevec_to_halfvec(PG_FUNCTION_ARGS) +Datum sparsevec_to_halfvec(PG_FUNCTION_ARGS) { SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); + int32 typmod = PG_GETARG_INT32(1); HalfVector *result; - int dim = svec->dim; - float *values = SPARSEVEC_VALUES(svec); + int dim = svec->dim; + float *values = SPARSEVEC_VALUES(svec); CheckDim(dim); CheckExpectedDim(typmod, dim); diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index 85d8097eef..a35d457580 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -21,132 +21,102 @@ #include "utils/builtins.h" #endif -typedef struct SparseInputElement -{ - int32 index; - float value; -} SparseInputElement; +typedef struct SparseInputElement { + int32 index; + float value; +} SparseInputElement; /* * Ensure same dimensions */ -static inline void -CheckDims(SparseVector * a, SparseVector * b) +static inline void CheckDims(SparseVector *a, SparseVector *b) { if (a->dim != b->dim) ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("different sparsevec dimensions %d and %d", a->dim, b->dim))); + (errcode(ERRCODE_DATA_EXCEPTION), errmsg("different sparsevec dimensions %d and %d", a->dim, b->dim))); } /* * Ensure expected dimensions */ -static inline void -CheckExpectedDim(int32 typmod, int dim) +static inline void CheckExpectedDim(int32 typmod, int dim) { if (typmod != -1 && typmod != dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected %d dimensions, not %d", typmod, dim))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected %d dimensions, not %d", typmod, dim))); } /* * Ensure valid dimensions */ -static inline void -CheckDim(int dim) +static inline void CheckDim(int dim) { if (dim < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("sparsevec must have at least 1 dimension"))); if (dim > SPARSEVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more than %d dimensions", SPARSEVEC_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d dimensions", SPARSEVEC_MAX_DIM))); } /* * Ensure valid nnz */ -static inline void -CheckNnz(int nnz, int dim) +static inline void CheckNnz(int nnz, int dim) { if (nnz < 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec cannot have negative number of elements"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("sparsevec cannot have negative number of elements"))); if (nnz > SPARSEVEC_MAX_NNZ) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); if (nnz > dim) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more elements than dimensions"))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more elements than dimensions"))); } /* * Ensure valid index */ -static inline void -CheckIndex(int32 *indices, int i, int dim) +static inline void CheckIndex(int32 *indices, int i, int dim) { - int32 index = indices[i]; + int32 index = indices[i]; - if (index < 0 || index >= dim) - { - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec index out of bounds"))); + if (index < 0 || index >= dim) { + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("sparsevec index out of bounds"))); } - if (i > 0) - { + if (i > 0) { if (index < indices[i - 1]) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec indices must be in ascending order"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("sparsevec indices must be in ascending order"))); if (index == indices[i - 1]) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("sparsevec indices must not contain duplicates"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("sparsevec indices must not contain duplicates"))); } } /* * Ensure finite element */ -static inline void -CheckElement(float value) +static inline void CheckElement(float value) { if (isnan(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("NaN not allowed in sparsevec"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("NaN not allowed in sparsevec"))); if (isinf(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("infinite value not allowed in sparsevec"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("infinite value not allowed in sparsevec"))); } /* * Allocate and initialize a new sparse vector */ -SparseVector * -InitSparseVector(int dim, int nnz) +SparseVector *InitSparseVector(int dim, int nnz) { SparseVector *result; - int size; + int size; size = SPARSEVEC_SIZE(nnz); - result = (SparseVector *) palloc0(size); + result = (SparseVector *)palloc0(size); SET_VARSIZE(result, size); result->dim = dim; result->nnz = nnz; @@ -157,15 +127,9 @@ InitSparseVector(int dim, int nnz) /* * Check for whitespace, since array_isspace() is static */ -static inline bool -sparsevec_isspace(char ch) +static inline bool sparsevec_isspace(char ch) { - if (ch == ' ' || - ch == '\t' || - ch == '\n' || - ch == '\r' || - ch == '\v' || - ch == '\f') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') return true; return false; } @@ -173,13 +137,12 @@ sparsevec_isspace(char ch) /* * Compare indices */ -static int -CompareIndices(const void *a, const void *b) +static int CompareIndices(const void *a, const void *b) { - if (((SparseInputElement *) a)->index < ((SparseInputElement *) b)->index) + if (((SparseInputElement *)a)->index < ((SparseInputElement *)b)->index) return -1; - if (((SparseInputElement *) a)->index > ((SparseInputElement *) b)->index) + if (((SparseInputElement *)a)->index > ((SparseInputElement *)b)->index) return 1; return 0; @@ -189,23 +152,21 @@ CompareIndices(const void *a, const void *b) * Convert textual representation to internal representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_in); -Datum -sparsevec_in(PG_FUNCTION_ARGS) +Datum sparsevec_in(PG_FUNCTION_ARGS) { - char *lit = PG_GETARG_CSTRING(0); - int32 typmod = PG_GETARG_INT32(2); - long dim; - char *pt = lit; - char *stringEnd; + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + long dim; + char *pt = lit; + char *stringEnd; SparseVector *result; - float *rvalues; + float *rvalues; SparseInputElement *elements; - int maxNnz; - int nnz = 0; + int maxNnz; + int nnz = 0; maxNnz = 1; - while (*pt != '\0') - { + while (*pt != '\0') { if (*pt == ',') maxNnz++; @@ -213,9 +174,8 @@ sparsevec_in(PG_FUNCTION_ARGS) } if (maxNnz > SPARSEVEC_MAX_NNZ) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("sparsevec cannot have more than %d non-zero elements", SPARSEVEC_MAX_NNZ))); elements = (SparseInputElement *)palloc(maxNnz * sizeof(SparseInputElement)); @@ -225,10 +185,9 @@ sparsevec_in(PG_FUNCTION_ARGS) pt++; if (*pt != '{') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), - errdetail("Vector contents must start with \"{\"."))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Vector contents must start with \"{\"."))); pt++; @@ -237,34 +196,29 @@ sparsevec_in(PG_FUNCTION_ARGS) if (*pt == '}') pt++; - else - { - for (;;) - { - long index; - float value; + else { + for (;;) { + long index; + float value; if (nnz == maxNnz) ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("ran out of buffer: \"%s\"", lit))); + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("ran out of buffer: \"%s\"", lit))); while (sparsevec_isspace(*pt)) pt++; /* Check for empty string like float4in */ if (*pt == '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); /* Use similar logic as int2vectorin */ index = strtol(pt, &stringEnd, 10); if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); /* Keep in int range for correct error message later */ if (index > INT_MAX) @@ -278,9 +232,8 @@ sparsevec_in(PG_FUNCTION_ARGS) pt++; if (*pt != ':') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); pt++; @@ -294,21 +247,18 @@ sparsevec_in(PG_FUNCTION_ARGS) value = strtof(pt, &stringEnd); if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); /* Check for range error like float4in */ if (errno == ERANGE && (value == 0 || isinf(value))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type sparsevec", pnstrdup(pt, stringEnd - pt)))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type sparsevec", pnstrdup(pt, stringEnd - pt)))); CheckElement(value); /* Do not store zero values */ - if (value != 0) - { + if (value != 0) { /* Convert 1-based numbering (SQL) to 0-based (C) */ elements[nnz].index = index - 1; elements[nnz].value = value; @@ -322,15 +272,12 @@ sparsevec_in(PG_FUNCTION_ARGS) if (*pt == ',') pt++; - else if (*pt == '}') - { + else if (*pt == '}') { pt++; break; - } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + } else + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); } } @@ -338,10 +285,9 @@ sparsevec_in(PG_FUNCTION_ARGS) pt++; if (*pt != '/') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), - errdetail("Unexpected end of input."))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), + errdetail("Unexpected end of input."))); pt++; @@ -352,9 +298,8 @@ sparsevec_in(PG_FUNCTION_ARGS) dim = strtol(pt, &stringEnd, 10); if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); /* Keep in int range for correct error message later */ if (dim > INT_MAX) @@ -371,8 +316,7 @@ sparsevec_in(PG_FUNCTION_ARGS) if (*pt != '\0') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), - errdetail("Junk after closing."))); + errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), errdetail("Junk after closing."))); CheckDim(dim); CheckExpectedDim(typmod, dim); @@ -381,8 +325,7 @@ sparsevec_in(PG_FUNCTION_ARGS) result = InitSparseVector(dim, nnz); rvalues = SPARSEVEC_VALUES(result); - for (int i = 0; i < nnz; i++) - { + for (int i = 0; i < nnz; i++) { result->indices[i] = elements[i].index; rvalues[i] = elements[i].value; @@ -398,11 +341,11 @@ sparsevec_in(PG_FUNCTION_ARGS) #if PG_VERSION_NUM >= 140000 #define AppendInt(ptr, i) ((ptr) += pg_ltoa((i), (ptr))) #else -#define AppendInt(ptr, i) \ - do { \ - pg_ltoa(i, ptr); \ +#define AppendInt(ptr, i) \ + do { \ + pg_ltoa(i, ptr); \ while (*ptr != '\0') \ - ptr++; \ + ptr++; \ } while (0) #endif @@ -410,13 +353,12 @@ sparsevec_in(PG_FUNCTION_ARGS) * Convert internal representation to textual representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_out); -Datum -sparsevec_out(PG_FUNCTION_ARGS) +Datum sparsevec_out(PG_FUNCTION_ARGS) { SparseVector *sparsevec = PG_GETARG_SPARSEVEC_P(0); - float *values = SPARSEVEC_VALUES(sparsevec); - char *buf; - char *ptr; + float *values = SPARSEVEC_VALUES(sparsevec); + char *buf; + char *ptr; /* * Need: @@ -434,13 +376,12 @@ sparsevec_out(PG_FUNCTION_ARGS) * * 4 bytes for {, }, /, and \0 */ - buf = (char *) palloc((11 + FLOAT_SHORTEST_DECIMAL_LEN) * sparsevec->nnz + 13); + buf = (char *)palloc((11 + FLOAT_SHORTEST_DECIMAL_LEN) * sparsevec->nnz + 13); ptr = buf; AppendChar(ptr, '{'); - for (int i = 0; i < sparsevec->nnz; i++) - { + for (int i = 0; i < sparsevec->nnz; i++) { if (i > 0) AppendChar(ptr, ','); @@ -463,29 +404,24 @@ sparsevec_out(PG_FUNCTION_ARGS) * Convert type modifier */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_typmod_in); -Datum -sparsevec_typmod_in(PG_FUNCTION_ARGS) +Datum sparsevec_typmod_in(PG_FUNCTION_ARGS) { - ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); - int32 *tl; - int n; + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; tl = ArrayGetIntegerTypmods(ta, &n); if (n != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid type modifier"))); + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid type modifier"))); if (*tl < 1) ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type sparsevec must be at least 1"))); + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dimensions for type sparsevec must be at least 1"))); if (*tl > SPARSEVEC_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type sparsevec cannot exceed %d", SPARSEVEC_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type sparsevec cannot exceed %d", SPARSEVEC_MAX_DIM))); PG_RETURN_INT32(*tl); } @@ -494,16 +430,15 @@ sparsevec_typmod_in(PG_FUNCTION_ARGS) * Convert external binary representation to internal representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_recv); -Datum -sparsevec_recv(PG_FUNCTION_ARGS) +Datum sparsevec_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - int32 typmod = PG_GETARG_INT32(2); + StringInfo buf = (StringInfo)PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); SparseVector *result; - int32 dim; - int32 nnz; - int32 unused; - float *values; + int32 dim; + int32 nnz; + int32 unused; + float *values; dim = pq_getmsgint(buf, sizeof(int32)); nnz = pq_getmsgint(buf, sizeof(int32)); @@ -514,29 +449,24 @@ sparsevec_recv(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, dim); if (unused != 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected unused to be 0, not %d", unused))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected unused to be 0, not %d", unused))); result = InitSparseVector(dim, nnz); values = SPARSEVEC_VALUES(result); /* Binary representation uses zero-based numbering for indices */ - for (int i = 0; i < nnz; i++) - { + for (int i = 0; i < nnz; i++) { result->indices[i] = pq_getmsgint(buf, sizeof(int32)); CheckIndex(result->indices, i, dim); } - for (int i = 0; i < nnz; i++) - { + for (int i = 0; i < nnz; i++) { values[i] = pq_getmsgfloat4(buf); CheckElement(values[i]); if (values[i] == 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("binary representation of sparsevec cannot contain zero values"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("binary representation of sparsevec cannot contain zero values"))); } PG_RETURN_POINTER(result); @@ -546,11 +476,10 @@ sparsevec_recv(PG_FUNCTION_ARGS) * Convert internal representation to the external binary representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_send); -Datum -sparsevec_send(PG_FUNCTION_ARGS) +Datum sparsevec_send(PG_FUNCTION_ARGS) { SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - float *values = SPARSEVEC_VALUES(svec); + float *values = SPARSEVEC_VALUES(svec); StringInfoData buf; pq_begintypsend(&buf); @@ -573,11 +502,10 @@ sparsevec_send(PG_FUNCTION_ARGS) * This is needed to check the type modifier */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec); -Datum -sparsevec(PG_FUNCTION_ARGS) +Datum sparsevec(PG_FUNCTION_ARGS) { SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); + int32 typmod = PG_GETARG_INT32(1); CheckExpectedDim(typmod, svec->dim); @@ -588,32 +516,28 @@ sparsevec(PG_FUNCTION_ARGS) * Convert dense vector to sparse vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_sparsevec); -Datum -vector_to_sparsevec(PG_FUNCTION_ARGS) +Datum vector_to_sparsevec(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - int32 typmod = PG_GETARG_INT32(1); + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); SparseVector *result; - int dim = vec->dim; - int nnz = 0; - float *values; - int j = 0; + int dim = vec->dim; + int nnz = 0; + float *values; + int j = 0; CheckDim(dim); CheckExpectedDim(typmod, dim); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { if (vec->x[i] != 0) nnz++; } result = InitSparseVector(dim, nnz); values = SPARSEVEC_VALUES(result); - for (int i = 0; i < dim; i++) - { - if (vec->x[i] != 0) - { + for (int i = 0; i < dim; i++) { + if (vec->x[i] != 0) { /* Safety check */ if (j >= result->nnz) elog(ERROR, "safety check failed"); @@ -631,32 +555,28 @@ vector_to_sparsevec(PG_FUNCTION_ARGS) * Convert half vector to sparse vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_sparsevec); -Datum -halfvec_to_sparsevec(PG_FUNCTION_ARGS) +Datum halfvec_to_sparsevec(PG_FUNCTION_ARGS) { HalfVector *vec = PG_GETARG_HALFVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); + int32 typmod = PG_GETARG_INT32(1); SparseVector *result; - int dim = vec->dim; - int nnz = 0; - float *values; - int j = 0; + int dim = vec->dim; + int nnz = 0; + float *values; + int j = 0; CheckDim(dim); CheckExpectedDim(typmod, dim); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { if (!HalfIsZero(vec->x[i])) nnz++; } result = InitSparseVector(dim, nnz); values = SPARSEVEC_VALUES(result); - for (int i = 0; i < dim; i++) - { - if (!HalfIsZero(vec->x[i])) - { + for (int i = 0; i < dim; i++) { + if (!HalfIsZero(vec->x[i])) { /* Safety check */ if (j >= result->nnz) elog(ERROR, "safety check failed"); @@ -673,30 +593,25 @@ halfvec_to_sparsevec(PG_FUNCTION_ARGS) /* * Get the L2 squared distance between sparse vectors */ -static float -SparsevecL2SquaredDistance(SparseVector * a, SparseVector * b) +static float SparsevecL2SquaredDistance(SparseVector *a, SparseVector *b) { - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float distance = 0.0; - int bpos = 0; + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; - for (int i = 0; i < a->nnz; i++) - { - int ai = a->indices[i]; - int bi = -1; + for (int i = 0; i < a->nnz; i++) { + int ai = a->indices[i]; + int bi = -1; - for (int j = bpos; j < b->nnz; j++) - { + for (int j = bpos; j < b->nnz; j++) { bi = b->indices[j]; - if (ai == bi) - { - float diff = ax[i] - bx[j]; + if (ai == bi) { + float diff = ax[i] - bx[j]; distance += diff * diff; - } - else if (ai > bi) + } else if (ai > bi) distance += bx[j] * bx[j]; /* Update start for next iteration */ @@ -722,15 +637,14 @@ SparsevecL2SquaredDistance(SparseVector * a, SparseVector * b) * Get the L2 distance between sparse vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_distance); -Datum -sparsevec_l2_distance(PG_FUNCTION_ARGS) +Datum sparsevec_l2_distance(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8(sqrt((double) SparsevecL2SquaredDistance(a, b))); + PG_RETURN_FLOAT8(sqrt((double)SparsevecL2SquaredDistance(a, b))); } /* @@ -738,35 +652,31 @@ sparsevec_l2_distance(PG_FUNCTION_ARGS) * This saves a sqrt calculation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_squared_distance); -Datum -sparsevec_l2_squared_distance(PG_FUNCTION_ARGS) +Datum sparsevec_l2_squared_distance(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) SparsevecL2SquaredDistance(a, b)); + PG_RETURN_FLOAT8((double)SparsevecL2SquaredDistance(a, b)); } /* * Get the inner product of two sparse vectors */ -static float -SparsevecInnerProduct(SparseVector * a, SparseVector * b) +static float SparsevecInnerProduct(SparseVector *a, SparseVector *b) { - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float distance = 0.0; - int bpos = 0; + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; - for (int i = 0; i < a->nnz; i++) - { - int ai = a->indices[i]; + for (int i = 0; i < a->nnz; i++) { + int ai = a->indices[i]; - for (int j = bpos; j < b->nnz; j++) - { - int bi = b->indices[j]; + for (int j = bpos; j < b->nnz; j++) { + int bi = b->indices[j]; /* Only update when the same index */ if (ai == bi) @@ -789,46 +699,43 @@ SparsevecInnerProduct(SparseVector * a, SparseVector * b) * Get the inner product of two sparse vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_inner_product); -Datum -sparsevec_inner_product(PG_FUNCTION_ARGS) +Datum sparsevec_inner_product(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) SparsevecInnerProduct(a, b)); + PG_RETURN_FLOAT8((double)SparsevecInnerProduct(a, b)); } /* * Get the negative inner product of two sparse vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_negative_inner_product); -Datum -sparsevec_negative_inner_product(PG_FUNCTION_ARGS) +Datum sparsevec_negative_inner_product(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) -SparsevecInnerProduct(a, b)); + PG_RETURN_FLOAT8((double)-SparsevecInnerProduct(a, b)); } /* * Get the cosine distance between two sparse vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_cosine_distance); -Datum -sparsevec_cosine_distance(PG_FUNCTION_ARGS) +Datum sparsevec_cosine_distance(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float norma = 0.0; - float normb = 0.0; - double similarity; + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float norma = 0.0; + float normb = 0.0; + double similarity; CheckDims(a, b); @@ -843,7 +750,7 @@ sparsevec_cosine_distance(PG_FUNCTION_ARGS) normb += bx[i] * bx[i]; /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - similarity /= sqrt((double) norma * (double) normb); + similarity /= sqrt((double)norma * (double)normb); #ifdef _MSC_VER /* /fp:fast may not propagate NaN */ @@ -864,25 +771,22 @@ sparsevec_cosine_distance(PG_FUNCTION_ARGS) * Get the L1 distance between two sparse vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l1_distance); -Datum -sparsevec_l1_distance(PG_FUNCTION_ARGS) +Datum sparsevec_l1_distance(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - float distance = 0.0; - int bpos = 0; + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + float distance = 0.0; + int bpos = 0; CheckDims(a, b); - for (int i = 0; i < a->nnz; i++) - { - int ai = a->indices[i]; - int bi = -1; + for (int i = 0; i < a->nnz; i++) { + int ai = a->indices[i]; + int bi = -1; - for (int j = bpos; j < b->nnz; j++) - { + for (int j = bpos; j < b->nnz; j++) { bi = b->indices[j]; if (ai == bi) @@ -906,64 +810,57 @@ sparsevec_l1_distance(PG_FUNCTION_ARGS) for (int j = bpos; j < b->nnz; j++) distance += fabsf(bx[j]); - PG_RETURN_FLOAT8((double) distance); + PG_RETURN_FLOAT8((double)distance); } /* * Get the L2 norm of a sparse vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_norm); -Datum -sparsevec_l2_norm(PG_FUNCTION_ARGS) +Datum sparsevec_l2_norm(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - float *ax = SPARSEVEC_VALUES(a); - double norm = 0.0; + float *ax = SPARSEVEC_VALUES(a); + double norm = 0.0; /* Auto-vectorized */ for (int i = 0; i < a->nnz; i++) - norm += (double) ax[i] * (double) ax[i]; + norm += (double)ax[i] * (double)ax[i]; PG_RETURN_FLOAT8(sqrt(norm)); } -static pg_noinline void -float_overflow_error(void) +static pg_noinline void float_overflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: overflow"))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value out of range: overflow"))); } /* * Normalize a sparse vector with the L2 norm */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_l2_normalize); -Datum -sparsevec_l2_normalize(PG_FUNCTION_ARGS) +Datum sparsevec_l2_normalize(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); - float *ax = SPARSEVEC_VALUES(a); - double norm = 0; + float *ax = SPARSEVEC_VALUES(a); + double norm = 0; SparseVector *result; - float *rx; + float *rx; result = InitSparseVector(a->dim, a->nnz); rx = SPARSEVEC_VALUES(result); /* Auto-vectorized */ for (int i = 0; i < a->nnz; i++) - norm += (double) ax[i] * (double) ax[i]; + norm += (double)ax[i] * (double)ax[i]; norm = sqrt(norm); /* Return zero vector for zero norm */ - if (norm > 0) - { - int zeros = 0; + if (norm > 0) { + int zeros = 0; - for (int i = 0; i < a->nnz; i++) - { + for (int i = 0; i < a->nnz; i++) { result->indices[i] = a->indices[i]; rx[i] = ax[i] / norm; @@ -975,14 +872,12 @@ sparsevec_l2_normalize(PG_FUNCTION_ARGS) } /* Allocate a new vector in the unlikely event there are zeros */ - if (zeros > 0) - { + if (zeros > 0) { SparseVector *newResult = InitSparseVector(result->dim, result->nnz - zeros); - float *nx = SPARSEVEC_VALUES(newResult); - int j = 0; + float *nx = SPARSEVEC_VALUES(newResult); + int j = 0; - for (int i = 0; i < result->nnz; i++) - { + for (int i = 0; i < result->nnz; i++) { if (rx[i] == 0) continue; @@ -1007,16 +902,14 @@ sparsevec_l2_normalize(PG_FUNCTION_ARGS) /* * Internal helper to compare sparse vectors */ -static int -sparsevec_cmp_internal(SparseVector * a, SparseVector * b) +static int sparsevec_cmp_internal(SparseVector *a, SparseVector *b) { - float *ax = SPARSEVEC_VALUES(a); - float *bx = SPARSEVEC_VALUES(b); - int nnz = Min(a->nnz, b->nnz); + float *ax = SPARSEVEC_VALUES(a); + float *bx = SPARSEVEC_VALUES(b); + int nnz = Min(a->nnz, b->nnz); /* Check values before dimensions to be consistent with Postgres arrays */ - for (int i = 0; i < nnz; i++) - { + for (int i = 0; i < nnz; i++) { if (a->indices[i] < b->indices[i]) return ax[i] < 0 ? -1 : 1; @@ -1049,8 +942,7 @@ sparsevec_cmp_internal(SparseVector * a, SparseVector * b) * Less than */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_lt); -Datum -sparsevec_lt(PG_FUNCTION_ARGS) +Datum sparsevec_lt(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); @@ -1062,8 +954,7 @@ sparsevec_lt(PG_FUNCTION_ARGS) * Less than or equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_le); -Datum -sparsevec_le(PG_FUNCTION_ARGS) +Datum sparsevec_le(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); @@ -1075,8 +966,7 @@ sparsevec_le(PG_FUNCTION_ARGS) * Equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_eq); -Datum -sparsevec_eq(PG_FUNCTION_ARGS) +Datum sparsevec_eq(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); @@ -1088,8 +978,7 @@ sparsevec_eq(PG_FUNCTION_ARGS) * Not equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_ne); -Datum -sparsevec_ne(PG_FUNCTION_ARGS) +Datum sparsevec_ne(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); @@ -1101,8 +990,7 @@ sparsevec_ne(PG_FUNCTION_ARGS) * Greater than or equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_ge); -Datum -sparsevec_ge(PG_FUNCTION_ARGS) +Datum sparsevec_ge(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); @@ -1114,8 +1002,7 @@ sparsevec_ge(PG_FUNCTION_ARGS) * Greater than */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_gt); -Datum -sparsevec_gt(PG_FUNCTION_ARGS) +Datum sparsevec_gt(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); @@ -1127,8 +1014,7 @@ sparsevec_gt(PG_FUNCTION_ARGS) * Compare sparse vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_cmp); -Datum -sparsevec_cmp(PG_FUNCTION_ARGS) +Datum sparsevec_cmp(PG_FUNCTION_ARGS) { SparseVector *a = PG_GETARG_SPARSEVEC_P(0); SparseVector *b = PG_GETARG_SPARSEVEC_P(1); diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index c9bd66af0c..e3786f1506 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -11,7 +11,7 @@ #include "access/datavec/ivfflat.h" #include "lib/stringinfo.h" #include "libpq/pqformat.h" -#include "port.h" /* for strtof() */ +#include "port.h" /* for strtof() */ #include "access/datavec/shortest_dec.h" #include "access/datavec/sparsevec.h" #include "utils/array.h" @@ -51,35 +51,33 @@ void set_extension_index(uint32 index) datavec_index = index; } -datavec_session_context* get_session_context() +datavec_session_context *get_session_context() { if (u_sess->attr.attr_common.extension_session_vars_array[datavec_index] == NULL) { init_session_vars(); } - return (datavec_session_context*)u_sess->attr.attr_common.extension_session_vars_array[datavec_index]; + return (datavec_session_context *)u_sess->attr.attr_common.extension_session_vars_array[datavec_index]; } void init_session_vars(void) { RepallocSessionVarsArrayIfNecessary(); - datavec_session_context* ctx = (datavec_session_context*)MemoryContextAllocZero(u_sess->self_mem_cxt, - sizeof(datavec_session_context)); + datavec_session_context *ctx = + (datavec_session_context *)MemoryContextAllocZero(u_sess->self_mem_cxt, sizeof(datavec_session_context)); u_sess->attr.attr_common.extension_session_vars_array[datavec_index] = ctx; ctx->hnsw_ef_search = 0; ctx->ivfflat_probes = 0; DefineCustomIntVariable("hnsw.ef_search", "Sets the size of the dynamic candidate list for search", - "Valid range is 1..1000.", &(get_session_context()->hnsw_ef_search), - HNSW_DEFAULT_EF_SEARCH, HNSW_MIN_EF_SEARCH, HNSW_MAX_EF_SEARCH, - PGC_USERSET, 0, NULL, NULL, NULL); + "Valid range is 1..1000.", &(get_session_context()->hnsw_ef_search), HNSW_DEFAULT_EF_SEARCH, + HNSW_MIN_EF_SEARCH, HNSW_MAX_EF_SEARCH, PGC_USERSET, 0, NULL, NULL, NULL); MarkGUCPrefixReserved("hnsw"); - DefineCustomIntVariable("ivfflat.probes", "Sets the number of probes", - "Valid range is 1..lists.", &(get_session_context()->ivfflat_probes), - IVFFLAT_DEFAULT_PROBES, IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS, - PGC_USERSET, 0, NULL, NULL, NULL); + DefineCustomIntVariable("ivfflat.probes", "Sets the number of probes", "Valid range is 1..lists.", + &(get_session_context()->ivfflat_probes), IVFFLAT_DEFAULT_PROBES, IVFFLAT_MIN_LISTS, + IVFFLAT_MAX_LISTS, PGC_USERSET, 0, NULL, NULL, NULL); MarkGUCPrefixReserved("ivfflat"); } @@ -87,72 +85,57 @@ void init_session_vars(void) /* * Ensure same dimensions */ -static inline void -CheckDims(Vector * a, Vector * b) +static inline void CheckDims(Vector *a, Vector *b) { if (a->dim != b->dim) ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("different vector dimensions %d and %d", a->dim, b->dim))); + (errcode(ERRCODE_DATA_EXCEPTION), errmsg("different vector dimensions %d and %d", a->dim, b->dim))); } /* * Ensure expected dimensions */ -static inline void -CheckExpectedDim(int32 typmod, int dim) +static inline void CheckExpectedDim(int32 typmod, int dim) { if (typmod != -1 && typmod != dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected %d dimensions, not %d", typmod, dim))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected %d dimensions, not %d", typmod, dim))); } /* * Ensure valid dimensions */ -static inline void -CheckDim(int dim) +static inline void CheckDim(int dim) { if (dim < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("vector must have at least 1 dimension"))); if (dim > VECTOR_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); } /* * Ensure finite element */ -static inline void -CheckElement(float value) +static inline void CheckElement(float value) { if (isnan(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("NaN not allowed in vector"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("NaN not allowed in vector"))); if (isinf(value)) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("infinite value not allowed in vector"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("infinite value not allowed in vector"))); } /* * Allocate and initialize a new vector */ -Vector * -InitVector(int dim) +Vector *InitVector(int dim) { - Vector *result; - int size; + Vector *result; + int size; size = VECTOR_SIZE(dim); - result = (Vector *) palloc0(size); + result = (Vector *)palloc0(size); SET_VARSIZE(result, size); result->dim = dim; @@ -162,15 +145,9 @@ InitVector(int dim) /* * Check for whitespace, since array_isspace() is static */ -static inline bool -vector_isspace(char ch) +static inline bool vector_isspace(char ch) { - if (ch == ' ' || - ch == '\t' || - ch == '\n' || - ch == '\r' || - ch == '\v' || - ch == '\f') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') return true; return false; } @@ -178,32 +155,23 @@ vector_isspace(char ch) /* * Check state array */ -static float8 * -CheckStateArray(ArrayType *statearray, const char *caller) +static float8 *CheckStateArray(ArrayType *statearray, const char *caller) { - if (ARR_NDIM(statearray) != 1 || - ARR_DIMS(statearray)[0] < 1 || - ARR_HASNULL(statearray) || + if (ARR_NDIM(statearray) != 1 || ARR_DIMS(statearray)[0] < 1 || ARR_HASNULL(statearray) || ARR_ELEMTYPE(statearray) != FLOAT8OID) elog(ERROR, "%s: expected state array", caller); - return (float8 *) ARR_DATA_PTR(statearray); + return (float8 *)ARR_DATA_PTR(statearray); } #if PG_VERSION_NUM < 120003 -static pg_noinline void -float_overflow_error(void) +static pg_noinline void float_overflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: overflow"))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value out of range: overflow"))); } -static pg_noinline void -float_underflow_error(void) +static pg_noinline void float_underflow_error(void) { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value out of range: underflow"))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value out of range: underflow"))); } #endif @@ -211,24 +179,22 @@ float_underflow_error(void) * Convert textual representation to internal representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_in); -Datum -vector_in(PG_FUNCTION_ARGS) +Datum vector_in(PG_FUNCTION_ARGS) { - char *lit = PG_GETARG_CSTRING(0); - int32 typmod = PG_GETARG_INT32(2); - float x[VECTOR_MAX_DIM]; - int dim = 0; - char *pt = lit; - Vector *result; + char *lit = PG_GETARG_CSTRING(0); + int32 typmod = PG_GETARG_INT32(2); + float x[VECTOR_MAX_DIM]; + int dim = 0; + char *pt = lit; + Vector *result; while (vector_isspace(*pt)) pt++; if (*pt != '[') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit), - errdetail("Vector contents must start with \"[\"."))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit), + errdetail("Vector contents must start with \"[\"."))); pt++; @@ -236,28 +202,23 @@ vector_in(PG_FUNCTION_ARGS) pt++; if (*pt == ']') - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("vector must have at least 1 dimension"))); - for (;;) - { - float val; - char *stringEnd; + for (;;) { + float val; + char *stringEnd; if (dim == VECTOR_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); while (vector_isspace(*pt)) pt++; /* Check for empty string like float4in */ if (*pt == '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); errno = 0; @@ -266,15 +227,13 @@ vector_in(PG_FUNCTION_ARGS) val = strtof(pt, &stringEnd); if (stringEnd == pt) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); /* Check for range error like float4in */ if (errno == ERANGE && isinf(val)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type vector", pnstrdup(pt, stringEnd - pt)))); + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type vector", pnstrdup(pt, stringEnd - pt)))); CheckElement(val); x[dim++] = val; @@ -286,15 +245,12 @@ vector_in(PG_FUNCTION_ARGS) if (*pt == ',') pt++; - else if (*pt == ']') - { + else if (*pt == ']') { pt++; break; - } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit))); + } else + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit))); } /* Only whitespace is allowed after the closing brace */ @@ -302,10 +258,9 @@ vector_in(PG_FUNCTION_ARGS) pt++; if (*pt != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type vector: \"%s\"", lit), - errdetail("Junk after closing right brace."))); + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type vector: \"%s\"", lit), + errdetail("Junk after closing right brace."))); CheckDim(dim); CheckExpectedDim(typmod, dim); @@ -324,13 +279,12 @@ vector_in(PG_FUNCTION_ARGS) * Convert internal representation to textual representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_out); -Datum -vector_out(PG_FUNCTION_ARGS) +Datum vector_out(PG_FUNCTION_ARGS) { - Vector *vector = PG_GETARG_VECTOR_P(0); - int dim = vector->dim; - char *buf; - char *ptr; + Vector *vector = PG_GETARG_VECTOR_P(0); + int dim = vector->dim; + char *buf; + char *ptr; /* * Need: @@ -342,13 +296,12 @@ vector_out(PG_FUNCTION_ARGS) * * 3 bytes for [, ], and \0 */ - buf = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); + buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN * dim + 2); ptr = buf; AppendChar(ptr, '['); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { if (i > 0) AppendChar(ptr, ','); @@ -365,10 +318,9 @@ vector_out(PG_FUNCTION_ARGS) /* * Print vector - useful for debugging */ -void -PrintVector(char *msg, Vector * vector) +void PrintVector(char *msg, Vector *vector) { - char *out = DatumGetPointer(DirectFunctionCall1(vector_out, PointerGetDatum(vector))); + char *out = DatumGetPointer(DirectFunctionCall1(vector_out, PointerGetDatum(vector))); elog(INFO, "%s = %s", msg, out); pfree(out); @@ -378,29 +330,24 @@ PrintVector(char *msg, Vector * vector) * Convert type modifier */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_typmod_in); -Datum -vector_typmod_in(PG_FUNCTION_ARGS) +Datum vector_typmod_in(PG_FUNCTION_ARGS) { - ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); - int32 *tl; - int n; + ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); + int32 *tl; + int n; tl = ArrayGetIntegerTypmods(ta, &n); if (n != 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid type modifier"))); + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid type modifier"))); if (*tl < 1) ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type vector must be at least 1"))); + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dimensions for type vector must be at least 1"))); if (*tl > VECTOR_MAX_DIM) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("dimensions for type vector cannot exceed %d", VECTOR_MAX_DIM))); + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("dimensions for type vector cannot exceed %d", VECTOR_MAX_DIM))); PG_RETURN_INT32(*tl); } @@ -409,14 +356,13 @@ vector_typmod_in(PG_FUNCTION_ARGS) * Convert external binary representation to internal representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_recv); -Datum -vector_recv(PG_FUNCTION_ARGS) +Datum vector_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - int32 typmod = PG_GETARG_INT32(2); - Vector *result; - int16 dim; - int16 unused; + StringInfo buf = (StringInfo)PG_GETARG_POINTER(0); + int32 typmod = PG_GETARG_INT32(2); + Vector *result; + int16 dim; + int16 unused; dim = pq_getmsgint(buf, sizeof(int16)); unused = pq_getmsgint(buf, sizeof(int16)); @@ -425,13 +371,10 @@ vector_recv(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, dim); if (unused != 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("expected unused to be 0, not %d", unused))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected unused to be 0, not %d", unused))); result = InitVector(dim); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { result->x[i] = pq_getmsgfloat4(buf); CheckElement(result->x[i]); } @@ -443,10 +386,9 @@ vector_recv(PG_FUNCTION_ARGS) * Convert internal representation to the external binary representation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_send); -Datum -vector_send(PG_FUNCTION_ARGS) +Datum vector_send(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); + Vector *vec = PG_GETARG_VECTOR_P(0); StringInfoData buf; pq_begintypsend(&buf); @@ -463,11 +405,10 @@ vector_send(PG_FUNCTION_ARGS) * This is needed to check the type modifier */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector); -Datum -vector(PG_FUNCTION_ARGS) +Datum vector(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - int32 typmod = PG_GETARG_INT32(1); + Vector *vec = PG_GETARG_VECTOR_P(0); + int32 typmod = PG_GETARG_INT32(1); CheckExpectedDim(typmod, vec->dim); @@ -478,27 +419,22 @@ vector(PG_FUNCTION_ARGS) * Convert array to vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(array_to_vector); -Datum -array_to_vector(PG_FUNCTION_ARGS) +Datum array_to_vector(PG_FUNCTION_ARGS) { - ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); - int32 typmod = PG_GETARG_INT32(1); - Vector *result; - int16 typlen; - bool typbyval; - char typalign; - Datum *elemsp; - int nelemsp; + ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; + int16 typlen; + bool typbyval; + char typalign; + Datum *elemsp; + int nelemsp; if (ARR_NDIM(array) > 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("array must be 1-D"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("array must be 1-D"))); if (ARR_HASNULL(array) && array_contains_nulls(array)) - ereport(ERROR, - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("array must not contain nulls"))); + ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("array must not contain nulls"))); get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); @@ -508,31 +444,20 @@ array_to_vector(PG_FUNCTION_ARGS) result = InitVector(nelemsp); - if (ARR_ELEMTYPE(array) == INT4OID) - { + if (ARR_ELEMTYPE(array) == INT4OID) { for (int i = 0; i < nelemsp; i++) result->x[i] = DatumGetInt32(elemsp[i]); - } - else if (ARR_ELEMTYPE(array) == FLOAT8OID) - { + } else if (ARR_ELEMTYPE(array) == FLOAT8OID) { for (int i = 0; i < nelemsp; i++) result->x[i] = DatumGetFloat8(elemsp[i]); - } - else if (ARR_ELEMTYPE(array) == FLOAT4OID) - { + } else if (ARR_ELEMTYPE(array) == FLOAT4OID) { for (int i = 0; i < nelemsp; i++) result->x[i] = DatumGetFloat4(elemsp[i]); - } - else if (ARR_ELEMTYPE(array) == NUMERICOID) - { + } else if (ARR_ELEMTYPE(array) == NUMERICOID) { for (int i = 0; i < nelemsp; i++) result->x[i] = DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i])); - } - else - { - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("unsupported array type"))); + } else { + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("unsupported array type"))); } /* @@ -552,14 +477,13 @@ array_to_vector(PG_FUNCTION_ARGS) * Convert vector to float4[] */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_to_float4); -Datum -vector_to_float4(PG_FUNCTION_ARGS) +Datum vector_to_float4(PG_FUNCTION_ARGS) { - Vector *vec = PG_GETARG_VECTOR_P(0); - Datum *datums; - ArrayType *result; + Vector *vec = PG_GETARG_VECTOR_P(0); + Datum *datums; + ArrayType *result; - datums = (Datum *) palloc(sizeof(Datum) * vec->dim); + datums = (Datum *)palloc(sizeof(Datum) * vec->dim); for (int i = 0; i < vec->dim; i++) datums[i] = Float4GetDatum(vec->x[i]); @@ -576,12 +500,11 @@ vector_to_float4(PG_FUNCTION_ARGS) * Convert half vector to vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(halfvec_to_vector); -Datum -halfvec_to_vector(PG_FUNCTION_ARGS) +Datum halfvec_to_vector(PG_FUNCTION_ARGS) { HalfVector *vec = PG_GETARG_HALFVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); - Vector *result; + int32 typmod = PG_GETARG_INT32(1); + Vector *result; CheckDim(vec->dim); CheckExpectedDim(typmod, vec->dim); @@ -594,15 +517,13 @@ halfvec_to_vector(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } -VECTOR_TARGET_CLONES static float -VectorL2SquaredDistance(int dim, float *ax, float *bx) +VECTOR_TARGET_CLONES static float VectorL2SquaredDistance(int dim, float *ax, float *bx) { - float distance = 0.0; + float distance = 0.0; /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { - float diff = ax[i] - bx[i]; + for (int i = 0; i < dim; i++) { + float diff = ax[i] - bx[i]; distance += diff * diff; } @@ -614,15 +535,14 @@ VectorL2SquaredDistance(int dim, float *ax, float *bx) * Get the L2 distance between vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(l2_distance); -Datum -l2_distance(PG_FUNCTION_ARGS) +Datum l2_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8(sqrt((double) VectorL2SquaredDistance(a->dim, a->x, b->x))); + PG_RETURN_FLOAT8(sqrt((double)VectorL2SquaredDistance(a->dim, a->x, b->x))); } /* @@ -630,21 +550,19 @@ l2_distance(PG_FUNCTION_ARGS) * This saves a sqrt calculation */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_l2_squared_distance); -Datum -vector_l2_squared_distance(PG_FUNCTION_ARGS) +Datum vector_l2_squared_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) VectorL2SquaredDistance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)VectorL2SquaredDistance(a->dim, a->x, b->x)); } -VECTOR_TARGET_CLONES static float -VectorInnerProduct(int dim, float *ax, float *bx) +VECTOR_TARGET_CLONES static float VectorInnerProduct(int dim, float *ax, float *bx) { - float distance = 0.0; + float distance = 0.0; /* Auto-vectorized */ for (int i = 0; i < dim; i++) @@ -657,61 +575,56 @@ VectorInnerProduct(int dim, float *ax, float *bx) * Get the inner product of two vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(inner_product); -Datum -inner_product(PG_FUNCTION_ARGS) +Datum inner_product(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) VectorInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)VectorInnerProduct(a->dim, a->x, b->x)); } /* * Get the negative inner product of two vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_negative_inner_product); -Datum -vector_negative_inner_product(PG_FUNCTION_ARGS) +Datum vector_negative_inner_product(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) -VectorInnerProduct(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)-VectorInnerProduct(a->dim, a->x, b->x)); } -VECTOR_TARGET_CLONES static double -VectorCosineSimilarity(int dim, float *ax, float *bx) +VECTOR_TARGET_CLONES static double VectorCosineSimilarity(int dim, float *ax, float *bx) { - float similarity = 0.0; - float norma = 0.0; - float normb = 0.0; + float similarity = 0.0; + float norma = 0.0; + float normb = 0.0; /* Auto-vectorized */ - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { similarity += ax[i] * bx[i]; norma += ax[i] * ax[i]; normb += bx[i] * bx[i]; } /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double) similarity / sqrt((double) norma * (double) normb); + return (double)similarity / sqrt((double)norma * (double)normb); } /* * Get the cosine distance between two vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(cosine_distance); -Datum -cosine_distance(PG_FUNCTION_ARGS) +Datum cosine_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - double similarity; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + double similarity; CheckDims(a, b); @@ -738,16 +651,15 @@ cosine_distance(PG_FUNCTION_ARGS) * Assumes inputs are unit vectors (skips norm) */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_spherical_distance); -Datum -vector_spherical_distance(PG_FUNCTION_ARGS) +Datum vector_spherical_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - double distance; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + double distance; CheckDims(a, b); - distance = (double) VectorInnerProduct(a->dim, a->x, b->x); + distance = (double)VectorInnerProduct(a->dim, a->x, b->x); /* Prevent NaN with acos with loss of precision */ if (distance > 1) @@ -759,10 +671,9 @@ vector_spherical_distance(PG_FUNCTION_ARGS) } /* Does not require FMA, but keep logic simple */ -VECTOR_TARGET_CLONES static float -VectorL1Distance(int dim, float *ax, float *bx) +VECTOR_TARGET_CLONES static float VectorL1Distance(int dim, float *ax, float *bx) { - float distance = 0.0; + float distance = 0.0; /* Auto-vectorized */ for (int i = 0; i < dim; i++) @@ -775,25 +686,23 @@ VectorL1Distance(int dim, float *ax, float *bx) * Get the L1 distance between two vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(l1_distance); -Datum -l1_distance(PG_FUNCTION_ARGS) +Datum l1_distance(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); CheckDims(a, b); - PG_RETURN_FLOAT8((double) VectorL1Distance(a->dim, a->x, b->x)); + PG_RETURN_FLOAT8((double)VectorL1Distance(a->dim, a->x, b->x)); } /* * Get the dimensions of a vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_dims); -Datum -vector_dims(PG_FUNCTION_ARGS) +Datum vector_dims(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); + Vector *a = PG_GETARG_VECTOR_P(0); PG_RETURN_INT32(a->dim); } @@ -802,16 +711,15 @@ vector_dims(PG_FUNCTION_ARGS) * Get the L2 norm of a vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_norm); -Datum -vector_norm(PG_FUNCTION_ARGS) +Datum vector_norm(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - float *ax = a->x; - double norm = 0.0; + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + double norm = 0.0; /* Auto-vectorized */ for (int i = 0; i < a->dim; i++) - norm += (double) ax[i] * (double) ax[i]; + norm += (double)ax[i] * (double)ax[i]; PG_RETURN_FLOAT8(sqrt(norm)); } @@ -820,33 +728,30 @@ vector_norm(PG_FUNCTION_ARGS) * Normalize a vector with the L2 norm */ PGDLLEXPORT PG_FUNCTION_INFO_V1(l2_normalize); -Datum -l2_normalize(PG_FUNCTION_ARGS) +Datum l2_normalize(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - float *ax = a->x; - double norm = 0; - Vector *result; - float *rx; + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + double norm = 0; + Vector *result; + float *rx; result = InitVector(a->dim); rx = result->x; /* Auto-vectorized */ for (int i = 0; i < a->dim; i++) - norm += (double) ax[i] * (double) ax[i]; + norm += (double)ax[i] * (double)ax[i]; norm = sqrt(norm); /* Return zero vector for zero norm */ - if (norm > 0) - { + if (norm > 0) { for (int i = 0; i < a->dim; i++) rx[i] = ax[i] / norm; /* Check for overflow */ - for (int i = 0; i < a->dim; i++) - { + for (int i = 0; i < a->dim; i++) { if (isinf(rx[i])) float_overflow_error(); } @@ -859,15 +764,14 @@ l2_normalize(PG_FUNCTION_ARGS) * Add vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_add); -Datum -vector_add(PG_FUNCTION_ARGS) +Datum vector_add(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - float *ax = a->x; - float *bx = b->x; - Vector *result; - float *rx; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; CheckDims(a, b); @@ -879,8 +783,7 @@ vector_add(PG_FUNCTION_ARGS) rx[i] = ax[i] + bx[i]; /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { if (isinf(rx[i])) float_overflow_error(); } @@ -892,15 +795,14 @@ vector_add(PG_FUNCTION_ARGS) * Subtract vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_sub); -Datum -vector_sub(PG_FUNCTION_ARGS) +Datum vector_sub(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - float *ax = a->x; - float *bx = b->x; - Vector *result; - float *rx; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; CheckDims(a, b); @@ -912,8 +814,7 @@ vector_sub(PG_FUNCTION_ARGS) rx[i] = ax[i] - bx[i]; /* Check for overflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { if (isinf(rx[i])) float_overflow_error(); } @@ -925,15 +826,14 @@ vector_sub(PG_FUNCTION_ARGS) * Multiply vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_mul); -Datum -vector_mul(PG_FUNCTION_ARGS) +Datum vector_mul(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - float *ax = a->x; - float *bx = b->x; - Vector *result; - float *rx; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + float *ax = a->x; + float *bx = b->x; + Vector *result; + float *rx; CheckDims(a, b); @@ -945,8 +845,7 @@ vector_mul(PG_FUNCTION_ARGS) rx[i] = ax[i] * bx[i]; /* Check for overflow and underflow */ - for (int i = 0, imax = a->dim; i < imax; i++) - { + for (int i = 0, imax = a->dim; i < imax; i++) { if (isinf(rx[i])) float_overflow_error(); @@ -961,13 +860,12 @@ vector_mul(PG_FUNCTION_ARGS) * Concatenate vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_concat); -Datum -vector_concat(PG_FUNCTION_ARGS) +Datum vector_concat(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); - Vector *result; - int dim = a->dim + b->dim; + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); + Vector *result; + int dim = a->dim + b->dim; CheckDim(dim); result = InitVector(dim); @@ -985,12 +883,11 @@ vector_concat(PG_FUNCTION_ARGS) * Quantize a vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(binary_quantize); -Datum -binary_quantize(PG_FUNCTION_ARGS) +Datum binary_quantize(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - float *ax = a->x; - VarBit *result = InitBitVector(a->dim); + Vector *a = PG_GETARG_VECTOR_P(0); + float *ax = a->x; + VarBit *result = InitBitVector(a->dim); unsigned char *rx = VARBITS(result); for (int i = 0; i < a->dim; i++) @@ -1003,21 +900,18 @@ binary_quantize(PG_FUNCTION_ARGS) * Get a subvector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(subvector); -Datum -subvector(PG_FUNCTION_ARGS) +Datum subvector(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - int32 start = PG_GETARG_INT32(1); - int32 count = PG_GETARG_INT32(2); - int32 end; - float *ax = a->x; - Vector *result; - int dim; + Vector *a = PG_GETARG_VECTOR_P(0); + int32 start = PG_GETARG_INT32(1); + int32 count = PG_GETARG_INT32(2); + int32 end; + float *ax = a->x; + Vector *result; + int dim; if (count < 1) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("vector must have at least 1 dimension"))); /* * Check if (start + count > a->dim), avoiding integer overflow. a->dim @@ -1032,9 +926,7 @@ subvector(PG_FUNCTION_ARGS) if (start < 1) start = 1; else if (start > a->dim) - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("vector must have at least 1 dimension"))); + ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("vector must have at least 1 dimension"))); dim = end - start; CheckDim(dim); @@ -1049,14 +941,12 @@ subvector(PG_FUNCTION_ARGS) /* * Internal helper to compare vectors */ -int -vector_cmp_internal(Vector * a, Vector * b) +int vector_cmp_internal(Vector *a, Vector *b) { - int dim = Min(a->dim, b->dim); + int dim = Min(a->dim, b->dim); /* Check values before dimensions to be consistent with Postgres arrays */ - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { if (a->x[i] < b->x[i]) return -1; @@ -1077,11 +967,10 @@ vector_cmp_internal(Vector * a, Vector * b) * Less than */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_lt); -Datum -vector_lt(PG_FUNCTION_ARGS) +Datum vector_lt(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); PG_RETURN_BOOL(vector_cmp_internal(a, b) < 0); } @@ -1090,11 +979,10 @@ vector_lt(PG_FUNCTION_ARGS) * Less than or equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_le); -Datum -vector_le(PG_FUNCTION_ARGS) +Datum vector_le(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); PG_RETURN_BOOL(vector_cmp_internal(a, b) <= 0); } @@ -1103,11 +991,10 @@ vector_le(PG_FUNCTION_ARGS) * Equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_eq); -Datum -vector_eq(PG_FUNCTION_ARGS) +Datum vector_eq(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); PG_RETURN_BOOL(vector_cmp_internal(a, b) == 0); } @@ -1116,11 +1003,10 @@ vector_eq(PG_FUNCTION_ARGS) * Not equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ne); -Datum -vector_ne(PG_FUNCTION_ARGS) +Datum vector_ne(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); PG_RETURN_BOOL(vector_cmp_internal(a, b) != 0); } @@ -1129,11 +1015,10 @@ vector_ne(PG_FUNCTION_ARGS) * Greater than or equal */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_ge); -Datum -vector_ge(PG_FUNCTION_ARGS) +Datum vector_ge(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); PG_RETURN_BOOL(vector_cmp_internal(a, b) >= 0); } @@ -1142,11 +1027,10 @@ vector_ge(PG_FUNCTION_ARGS) * Greater than */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_gt); -Datum -vector_gt(PG_FUNCTION_ARGS) +Datum vector_gt(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); PG_RETURN_BOOL(vector_cmp_internal(a, b) > 0); } @@ -1155,11 +1039,10 @@ vector_gt(PG_FUNCTION_ARGS) * Compare vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_cmp); -Datum -vector_cmp(PG_FUNCTION_ARGS) +Datum vector_cmp(PG_FUNCTION_ARGS) { - Vector *a = PG_GETARG_VECTOR_P(0); - Vector *b = PG_GETARG_VECTOR_P(1); + Vector *a = PG_GETARG_VECTOR_P(0); + Vector *b = PG_GETARG_VECTOR_P(1); PG_RETURN_INT32(vector_cmp_internal(a, b)); } @@ -1168,18 +1051,17 @@ vector_cmp(PG_FUNCTION_ARGS) * Accumulate vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_accum); -Datum -vector_accum(PG_FUNCTION_ARGS) +Datum vector_accum(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); - Vector *newval = PG_GETARG_VECTOR_P(1); - float8 *statevalues; - int16 dim; - bool newarr; - float8 n; - Datum *statedatums; - float *x = newval->x; - ArrayType *result; + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + Vector *newval = PG_GETARG_VECTOR_P(1); + float8 *statevalues; + int16 dim; + bool newarr; + float8 n; + Datum *statedatums; + float *x = newval->x; + ArrayType *result; /* Check array before using */ statevalues = CheckStateArray(statearray, "vector_accum"); @@ -1196,16 +1078,12 @@ vector_accum(PG_FUNCTION_ARGS) statedatums = (Datum *)CreateStateDatums(dim); statedatums[0] = Float8GetDatum(n); - if (newarr) - { + if (newarr) { for (int i = 0; i < dim; i++) - statedatums[i + 1] = Float8GetDatum((double) x[i]); - } - else - { - for (int i = 0; i < dim; i++) - { - double v = statevalues[i + 1] + x[i]; + statedatums[i + 1] = Float8GetDatum((double)x[i]); + } else { + for (int i = 0; i < dim; i++) { + double v = statevalues[i + 1] + x[i]; /* Check for overflow */ if (isinf(v)) @@ -1216,9 +1094,7 @@ vector_accum(PG_FUNCTION_ARGS) } /* Use float8 array like float4_accum */ - result = construct_array(statedatums, dim + 1, - FLOAT8OID, - sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + result = construct_array(statedatums, dim + 1, FLOAT8OID, sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); pfree(statedatums); @@ -1229,20 +1105,19 @@ vector_accum(PG_FUNCTION_ARGS) * Combine vectors or half vectors (also used for halfvec_combine) */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_combine); -Datum -vector_combine(PG_FUNCTION_ARGS) +Datum vector_combine(PG_FUNCTION_ARGS) { /* Must also update parameters of halfvec_combine if modifying */ - ArrayType *statearray1 = PG_GETARG_ARRAYTYPE_P(0); - ArrayType *statearray2 = PG_GETARG_ARRAYTYPE_P(1); - float8 *statevalues1; - float8 *statevalues2; - float8 n; - float8 n1; - float8 n2; - int16 dim; - Datum *statedatums; - ArrayType *result; + ArrayType *statearray1 = PG_GETARG_ARRAYTYPE_P(0); + ArrayType *statearray2 = PG_GETARG_ARRAYTYPE_P(1); + float8 *statevalues1; + float8 *statevalues2; + float8 n; + float8 n1; + float8 n2; + int16 dim; + Datum *statedatums; + ArrayType *result; /* Check arrays before using */ statevalues1 = CheckStateArray(statearray1, "vector_combine"); @@ -1251,31 +1126,25 @@ vector_combine(PG_FUNCTION_ARGS) n1 = statevalues1[0]; n2 = statevalues2[0]; - if (n1 == 0.0) - { + if (n1 == 0.0) { n = n2; dim = STATE_DIMS(statearray2); statedatums = (Datum *)CreateStateDatums(dim); for (int i = 1; i <= dim; i++) statedatums[i] = Float8GetDatum(statevalues2[i]); - } - else if (n2 == 0.0) - { + } else if (n2 == 0.0) { n = n1; dim = STATE_DIMS(statearray1); statedatums = (Datum *)CreateStateDatums(dim); for (int i = 1; i <= dim; i++) statedatums[i] = Float8GetDatum(statevalues1[i]); - } - else - { + } else { n = n1 + n2; dim = STATE_DIMS(statearray1); CheckExpectedDim(dim, STATE_DIMS(statearray2)); statedatums = (Datum *)CreateStateDatums(dim); - for (int i = 1; i <= dim; i++) - { - double v = statevalues1[i] + statevalues2[i]; + for (int i = 1; i <= dim; i++) { + double v = statevalues1[i] + statevalues2[i]; /* Check for overflow */ if (isinf(v)) @@ -1287,9 +1156,7 @@ vector_combine(PG_FUNCTION_ARGS) statedatums[0] = Float8GetDatum(n); - result = construct_array(statedatums, dim + 1, - FLOAT8OID, - sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); + result = construct_array(statedatums, dim + 1, FLOAT8OID, sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE); pfree(statedatums); @@ -1300,14 +1167,13 @@ vector_combine(PG_FUNCTION_ARGS) * Average vectors */ PGDLLEXPORT PG_FUNCTION_INFO_V1(vector_avg); -Datum -vector_avg(PG_FUNCTION_ARGS) +Datum vector_avg(PG_FUNCTION_ARGS) { - ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); - float8 *statevalues; - float8 n; - uint16 dim; - Vector *result; + ArrayType *statearray = PG_GETARG_ARRAYTYPE_P(0); + float8 *statevalues; + float8 n; + uint16 dim; + Vector *result; /* Check array before using */ statevalues = CheckStateArray(statearray, "vector_avg"); @@ -1321,8 +1187,7 @@ vector_avg(PG_FUNCTION_ARGS) dim = STATE_DIMS(statearray); CheckDim(dim); result = InitVector(dim); - for (int i = 0; i < dim; i++) - { + for (int i = 0; i < dim; i++) { result->x[i] = statevalues[i + 1] / n; CheckElement(result->x[i]); } @@ -1334,14 +1199,13 @@ vector_avg(PG_FUNCTION_ARGS) * Convert sparse vector to dense vector */ PGDLLEXPORT PG_FUNCTION_INFO_V1(sparsevec_to_vector); -Datum -sparsevec_to_vector(PG_FUNCTION_ARGS) +Datum sparsevec_to_vector(PG_FUNCTION_ARGS) { SparseVector *svec = PG_GETARG_SPARSEVEC_P(0); - int32 typmod = PG_GETARG_INT32(1); - Vector *result; - int dim = svec->dim; - float *values = SPARSEVEC_VALUES(svec); + int32 typmod = PG_GETARG_INT32(1); + Vector *result; + int dim = svec->dim; + float *values = SPARSEVEC_VALUES(svec); CheckDim(dim); CheckExpectedDim(typmod, dim); @@ -1370,79 +1234,71 @@ sparsevec_to_vector(PG_FUNCTION_ARGS) * same time. If that's not the case, you must ensure that this does not * cause a deadlock through some other means. */ -void -log_newpage_range(Relation rel, ForkNumber forknum, - BlockNumber startblk, BlockNumber endblk, - bool page_std) +void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std) { - int flags; - BlockNumber blkno; - - flags = REGBUF_FORCE_IMAGE; - if (page_std) - flags |= REGBUF_STANDARD; - - /* - * Iterate over all the pages in the range. They are collected into - * batches of XLR_MAX_BLOCK_ID pages, and a single WAL-record is written - * for each batch. - */ - XLogEnsureRecordSpace(XLR_MAX_BLOCK_ID - 1, 0); - - blkno = startblk; - while (blkno < endblk) - { - Buffer bufpack[XLR_MAX_BLOCK_ID]; - XLogRecPtr recptr; - int nbufs; - int i; - - CHECK_FOR_INTERRUPTS(); - - /* Collect a batch of blocks. */ - nbufs = 0; - while (nbufs < XLR_MAX_BLOCK_ID && blkno < endblk) - { - Buffer buf = ReadBufferExtended(rel, forknum, blkno, - RBM_NORMAL, NULL); - - LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); - - /* - * Completely empty pages are not WAL-logged. Writing a WAL record - * would change the LSN, and we don't want that. We want the page - * to stay empty. - */ - if (!PageIsNew(BufferGetPage(buf))) - bufpack[nbufs++] = buf; - else - UnlockReleaseBuffer(buf); - blkno++; - } - - /* Nothing more to do if all remaining blocks were empty. */ - if (nbufs == 0) - break; - - /* Write WAL record for this batch. */ - XLogBeginInsert(); - - START_CRIT_SECTION(); - for (i = 0; i < nbufs; i++) - { - MarkBufferDirty(bufpack[i]); - XLogRegisterBuffer(i, bufpack[i], flags); - } - - recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI); - - for (i = 0; i < nbufs; i++) - { - PageSetLSN(BufferGetPage(bufpack[i]), recptr); - UnlockReleaseBuffer(bufpack[i]); - } - END_CRIT_SECTION(); + int flags; + BlockNumber blkno; + + flags = REGBUF_FORCE_IMAGE; + if (page_std) + flags |= REGBUF_STANDARD; + + /* + * Iterate over all the pages in the range. They are collected into + * batches of XLR_MAX_BLOCK_ID pages, and a single WAL-record is written + * for each batch. + */ + XLogEnsureRecordSpace(XLR_MAX_BLOCK_ID - 1, 0); + + blkno = startblk; + while (blkno < endblk) { + Buffer bufpack[XLR_MAX_BLOCK_ID]; + XLogRecPtr recptr; + int nbufs; + int i; + + CHECK_FOR_INTERRUPTS(); + + /* Collect a batch of blocks. */ + nbufs = 0; + while (nbufs < XLR_MAX_BLOCK_ID && blkno < endblk) { + Buffer buf = ReadBufferExtended(rel, forknum, blkno, RBM_NORMAL, NULL); + + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + + /* + * Completely empty pages are not WAL-logged. Writing a WAL record + * would change the LSN, and we don't want that. We want the page + * to stay empty. + */ + if (!PageIsNew(BufferGetPage(buf))) + bufpack[nbufs++] = buf; + else + UnlockReleaseBuffer(buf); + blkno++; } + + /* Nothing more to do if all remaining blocks were empty. */ + if (nbufs == 0) + break; + + /* Write WAL record for this batch. */ + XLogBeginInsert(); + + START_CRIT_SECTION(); + for (i = 0; i < nbufs; i++) { + MarkBufferDirty(bufpack[i]); + XLogRegisterBuffer(i, bufpack[i], flags); + } + + recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI); + + for (i = 0; i < nbufs; i++) { + PageSetLSN(BufferGetPage(bufpack[i]), recptr); + UnlockReleaseBuffer(bufpack[i]); + } + END_CRIT_SECTION(); + } } int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo) diff --git a/src/include/access/datavec/bitvec.h b/src/include/access/datavec/bitvec.h index 5a1aa58820..9e6cc588b7 100644 --- a/src/include/access/datavec/bitvec.h +++ b/src/include/access/datavec/bitvec.h @@ -4,12 +4,13 @@ #include "postgres.h" #include "utils/varbit.h" -extern uint64 (*BitHammingDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance); -extern double (*BitJaccardDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb); +extern uint64 (*BitHammingDistance)(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance); +extern double (*BitJaccardDistance)(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, + uint64 bb); void BitvecInit(void); -VarBit *InitBitVector(int dim); +VarBit *InitBitVector(int dim); Datum hamming_distance(PG_FUNCTION_ARGS); Datum jaccard_distance(PG_FUNCTION_ARGS); diff --git a/src/include/access/datavec/halfutils.h b/src/include/access/datavec/halfutils.h index 906a8157c1..fc9b761e58 100644 --- a/src/include/access/datavec/halfutils.h +++ b/src/include/access/datavec/halfutils.h @@ -10,18 +10,17 @@ #include #endif -extern float (*HalfvecL2SquaredDistance) (int dim, half * ax, half * bx); -extern float (*HalfvecInnerProduct) (int dim, half * ax, half * bx); -extern double (*HalfvecCosineSimilarity) (int dim, half * ax, half * bx); -extern float (*HalfvecL1Distance) (int dim, half * ax, half * bx); +extern float (*HalfvecL2SquaredDistance)(int dim, half *ax, half *bx); +extern float (*HalfvecInnerProduct)(int dim, half *ax, half *bx); +extern double (*HalfvecCosineSimilarity)(int dim, half *ax, half *bx); +extern float (*HalfvecL1Distance)(int dim, half *ax, half *bx); -void HalfvecInit(void); +void HalfvecInit(void); /* * Check if half is NaN */ -static inline bool -HalfIsNan(half num) +static inline bool HalfIsNan(half num) { #ifdef FLT16_SUPPORT return isnan(num); @@ -33,8 +32,7 @@ HalfIsNan(half num) /* * Check if half is infinite */ -static inline bool -HalfIsInf(half num) +static inline bool HalfIsInf(half num) { #ifdef FLT16_SUPPORT return isinf(num); @@ -46,8 +44,7 @@ HalfIsInf(half num) /* * Check if half is zero */ -static inline bool -HalfIsZero(half num) +static inline bool HalfIsZero(half num) { #ifdef FLT16_SUPPORT return num == 0; @@ -59,30 +56,27 @@ HalfIsZero(half num) /* * Convert a half to a float4 */ -static inline float -HalfToFloat4(half num) +static inline float HalfToFloat4(half num) { #if defined(F16C_SUPPORT) return _cvtsh_ss(num); #elif defined(FLT16_SUPPORT) - return (float) num; + return (float)num; #else - union - { - float f; - uint32 i; - } swapfloat; - - union - { - half h; - uint16 i; - } swaphalf; - - uint16 bin; - uint32 exponent; - uint32 mantissa; - uint32 result; + union { + float f; + uint32 i; + } swapfloat; + + union { + half h; + uint16 i; + } swaphalf; + + uint16 bin; + uint32 exponent; + uint32 mantissa; + uint32 result; swaphalf.h = num; bin = swaphalf.i; @@ -92,33 +86,24 @@ HalfToFloat4(half num) /* Sign */ result = (bin & 0x8000) << 16; - if (unlikely(exponent == 31)) - { - if (mantissa == 0) - { + if (unlikely(exponent == 31)) { + if (mantissa == 0) { /* Infinite */ result |= 0x7F800000; - } - else - { + } else { /* NaN */ result |= 0x7FC00000; } - } - else if (unlikely(exponent == 0)) - { + } else if (unlikely(exponent == 0)) { /* Subnormal */ - if (mantissa != 0) - { + if (mantissa != 0) { exponent = -14; - for (int i = 0; i < 10; i++) - { + for (int i = 0; i < 10; i++) { mantissa <<= 1; exponent -= 1; - if ((mantissa >> 10) % 2 == 1) - { + if ((mantissa >> 10) % 2 == 1) { mantissa &= 0x03ff; break; } @@ -126,9 +111,7 @@ HalfToFloat4(half num) result |= (exponent + 127) << 23; } - } - else - { + } else { /* Normal */ result |= (exponent - 15 + 127) << 23; } @@ -143,30 +126,27 @@ HalfToFloat4(half num) /* * Convert a float4 to a half */ -static inline half -Float4ToHalfUnchecked(float num) +static inline half Float4ToHalfUnchecked(float num) { #if defined(F16C_SUPPORT) return _cvtss_sh(num, 0); #elif defined(FLT16_SUPPORT) return num; #else - union - { - float f; - uint32 i; - } swapfloat; - - union - { - half h; - uint16 i; - } swaphalf; - - uint32 bin; - int exponent; - int mantissa; - uint16 result; + union { + float f; + uint32 i; + } swapfloat; + + union { + half h; + uint16 i; + } swaphalf; + + uint32 bin; + int exponent; + int mantissa; + uint16 result; swapfloat.f = num; bin = swapfloat.i; @@ -176,30 +156,24 @@ Float4ToHalfUnchecked(float num) /* Sign */ result = (bin & 0x80000000) >> 16; - if (isinf(num)) - { + if (isinf(num)) { /* Infinite */ result |= 0x7C00; - } - else if (isnan(num)) - { + } else if (isnan(num)) { /* NaN */ result |= 0x7E00; result |= mantissa >> 13; - } - else if (exponent > 98) - { - int m; - int gr; - int s; + } else if (exponent > 98) { + int m; + int gr; + int s; exponent -= 127; s = mantissa & 0x00000FFF; /* Subnormal */ - if (exponent < -14) - { - int diff = -exponent - 14; + if (exponent < -14) { + int diff = -exponent - 14; mantissa >>= diff; mantissa += 1 << (23 - diff); @@ -213,19 +187,15 @@ Float4ToHalfUnchecked(float num) if (gr == 3 || (gr == 1 && s != 0)) m += 1; - if (m == 1024) - { + if (m == 1024) { m = 0; exponent += 1; } - if (exponent > 15) - { + if (exponent > 15) { /* Infinite */ result |= 0x7C00; - } - else - { + } else { if (exponent >= -14) result |= (exponent + 15) << 10; @@ -241,20 +211,17 @@ Float4ToHalfUnchecked(float num) /* * Convert a float4 to a half */ -static inline half -Float4ToHalf(float num) +static inline half Float4ToHalf(float num) { - half result = Float4ToHalfUnchecked(num); + half result = Float4ToHalfUnchecked(num); - if (unlikely(HalfIsInf(result)) && !isinf(num)) - { - char *buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); + if (unlikely(HalfIsInf(result)) && !isinf(num)) { + char *buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); float_to_shortest_decimal_buf(num, buf); ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type halfvec", buf))); + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("\"%s\" is out of range for type halfvec", buf))); } return result; diff --git a/src/include/access/datavec/halfvec.h b/src/include/access/datavec/halfvec.h index eadefb5627..ffee898f19 100644 --- a/src/include/access/datavec/halfvec.h +++ b/src/include/access/datavec/halfvec.h @@ -43,7 +43,7 @@ #define FLT16_SUPPORT #endif -//TODO support _Float16 +// TODO support _Float16 #ifdef FLT16_SUPPORT #define half float #define HALF_MAX FLT16_MAX @@ -54,18 +54,17 @@ #define HALFVEC_MAX_DIM 16000 -#define HALFVEC_SIZE(_dim) (offsetof(HalfVector, x) + sizeof(half)*(_dim)) -#define DatumGetHalfVector(x) ((HalfVector *) PG_DETOAST_DATUM(x)) -#define PG_GETARG_HALFVEC_P(x) DatumGetHalfVector(PG_GETARG_DATUM(x)) -#define PG_RETURN_HALFVEC_P(x) PG_RETURN_POINTER(x) +#define HALFVEC_SIZE(_dim) (offsetof(HalfVector, x) + sizeof(half) * (_dim)) +#define DatumGetHalfVector(x) ((HalfVector *)PG_DETOAST_DATUM(x)) +#define PG_GETARG_HALFVEC_P(x) DatumGetHalfVector(PG_GETARG_DATUM(x)) +#define PG_RETURN_HALFVEC_P(x) PG_RETURN_POINTER(x) -typedef struct HalfVector -{ - int32 vl_len_; /* varlena header (do not touch directly!) */ - int16 dim; /* number of dimensions */ - int16 unused; /* reserved for future use, always zero */ - half x[FLEXIBLE_ARRAY_MEMBER]; -} HalfVector; +typedef struct HalfVector { + int32 vl_len_; /* varlena header (do not touch directly!) */ + int16 dim; /* number of dimensions */ + int16 unused; /* reserved for future use, always zero */ + half x[FLEXIBLE_ARRAY_MEMBER]; +} HalfVector; HalfVector *InitHalfVector(int dim); diff --git a/src/include/access/datavec/hnsw.h b/src/include/access/datavec/hnsw.h index 642a983787..a30837a37d 100644 --- a/src/include/access/datavec/hnsw.h +++ b/src/include/access/datavec/hnsw.h @@ -6,7 +6,7 @@ #include "access/genam.h" #include "lib/pairingheap.h" #include "nodes/execnodes.h" -#include "port.h" /* for random() */ +#include "port.h" /* for random() */ #include "access/datavec/vector.h" #include "access/datavec/vecindex.h" @@ -18,44 +18,44 @@ #define HNSW_NORM_PROC 2 #define HNSW_TYPE_INFO_PROC 3 -#define HNSW_VERSION 1 +#define HNSW_VERSION 1 #define HNSW_MAGIC_NUMBER 0xA953A953 -#define HNSW_PAGE_ID 0xFF90 +#define HNSW_PAGE_ID 0xFF90 /* Preserved page numbers */ -#define HNSW_METAPAGE_BLKNO 0 -#define HNSW_HEAD_BLKNO 1 /* first element page */ -#define HNSW_PQTABLE_START_BLKNO 1 /* pqtable start page */ -#define HNSW_PQTABLE_STORAGE_SIZE (uint16)(6*1024) /* pqtable storage size in each page */ +#define HNSW_METAPAGE_BLKNO 0 +#define HNSW_HEAD_BLKNO 1 /* first element page */ +#define HNSW_PQTABLE_START_BLKNO 1 /* pqtable start page */ +#define HNSW_PQTABLE_STORAGE_SIZE (uint16)(6 * 1024) /* pqtable storage size in each page */ /* Append page slot info */ #define HNSW_DEFAULT_NPAGES_PER_SLOT 50 #define HNSW_BUFFER_THRESHOLD 4 /* Must correspond to page numbers since page lock is used */ -#define HNSW_UPDATE_LOCK 0 -#define HNSW_SCAN_LOCK 1 +#define HNSW_UPDATE_LOCK 0 +#define HNSW_SCAN_LOCK 1 /* HNSW parameters */ -#define HNSW_DEFAULT_M 16 -#define HNSW_MIN_M 2 -#define HNSW_MAX_M 100 -#define HNSW_DEFAULT_EF_CONSTRUCTION 64 -#define HNSW_MIN_EF_CONSTRUCTION 4 -#define HNSW_MAX_EF_CONSTRUCTION 1000 -#define HNSW_DEFAULT_EF_SEARCH 40 -#define HNSW_MIN_EF_SEARCH 1 -#define HNSW_MAX_EF_SEARCH 1000 -#define HNSW_DEFAULT_ENABLE_PQ false -#define HNSW_DEFAULT_PQ_M 1 -#define HNSW_MIN_PQ_M 1 +#define HNSW_DEFAULT_M 16 +#define HNSW_MIN_M 2 +#define HNSW_MAX_M 100 +#define HNSW_DEFAULT_EF_CONSTRUCTION 64 +#define HNSW_MIN_EF_CONSTRUCTION 4 +#define HNSW_MAX_EF_CONSTRUCTION 1000 +#define HNSW_DEFAULT_EF_SEARCH 40 +#define HNSW_MIN_EF_SEARCH 1 +#define HNSW_MAX_EF_SEARCH 1000 +#define HNSW_DEFAULT_ENABLE_PQ false +#define HNSW_DEFAULT_PQ_M 1 +#define HNSW_MIN_PQ_M 1 #define HNSW_MAX_PQ_M 65535 #define HNSW_DEFAULT_PQ_KSUB 1 #define HNSW_MIN_PQ_KSUB 1 #define HNSW_MAX_PQ_KSUB 65535 /* Tuple types */ -#define HNSW_ELEMENT_TUPLE_TYPE 1 +#define HNSW_ELEMENT_TUPLE_TYPE 1 #define HNSW_NEIGHBOR_TUPLE_TYPE 2 /* page types */ @@ -72,68 +72,67 @@ /* Build phases */ /* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 */ -#define PROGRESS_HNSW_PHASE_LOAD 2 +#define PROGRESS_HNSW_PHASE_LOAD 2 -#define HNSW_MAX_SIZE (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - sizeof(ItemIdData)) +#define HNSW_MAX_SIZE \ + (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - sizeof(ItemIdData)) #define HNSW_TUPLE_ALLOC_SIZE BLCKSZ -#define HNSW_ELEMENT_TUPLE_SIZE(size) MAXALIGN(offsetof(HnswElementTupleData, data) + (size)) -#define HNSW_NEIGHBOR_TUPLE_SIZE(level, m) MAXALIGN(offsetof(HnswNeighborTupleData, indextids) + ((level) + 2) * (m) * sizeof(ItemPointerData)) +#define HNSW_ELEMENT_TUPLE_SIZE(size) MAXALIGN(offsetof(HnswElementTupleData, data) + (size)) +#define HNSW_NEIGHBOR_TUPLE_SIZE(level, m) \ + MAXALIGN(offsetof(HnswNeighborTupleData, indextids) + ((level) + 2) * (m) * sizeof(ItemPointerData)) -#define HNSW_NEIGHBOR_ARRAY_SIZE(lm) (offsetof(HnswNeighborArray, items) + sizeof(HnswCandidate) * (lm)) +#define HNSW_NEIGHBOR_ARRAY_SIZE(lm) (offsetof(HnswNeighborArray, items) + sizeof(HnswCandidate) * (lm)) -#define HnswPageGetOpaque(page) ((HnswPageOpaque) PageGetSpecialPointer(page)) -#define HnswPageGetMeta(page) ((HnswMetaPageData *) PageGetContents(page)) -#define HnswPageGetAppendMeta(page) ((HnswAppendMetaPageData *) PageGetContents(page)) +#define HnswPageGetOpaque(page) ((HnswPageOpaque)PageGetSpecialPointer(page)) +#define HnswPageGetMeta(page) ((HnswMetaPageData *)PageGetContents(page)) +#define HnswPageGetAppendMeta(page) ((HnswAppendMetaPageData *)PageGetContents(page)) -#define HnswDefaultMaxItemSize \ - MAXALIGN_DOWN((BLCKSZ - \ - MAXALIGN(SizeOfPageHeaderData + \ - sizeof(ItemIdData) + \ - sizeof(ItemPointerData)) - \ +#define HnswDefaultMaxItemSize \ + MAXALIGN_DOWN((BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData) + sizeof(ItemPointerData)) - \ MAXALIGN(sizeof(HnswPageOpaqueData)))) #if PG_VERSION_NUM >= 150000 #define RandomDouble() pg_prng_double(&pg_global_prng_state) #define SeedRandom(seed) pg_prng_seed(&pg_global_prng_state, seed) #else -#define RandomDouble() (((double) random()) / MAX_RANDOM_VALUE) +#define RandomDouble() (((double)random()) / MAX_RANDOM_VALUE) #define SeedRandom(seed) srandom(seed) #endif #if PG_VERSION_NUM < 130000 #define list_delete_last(list) list_truncate(list, list_length(list) - 1) -#define list_sort(list, cmp) \ - do { \ - ListCell *cell; \ - int i; \ - int len = list_length(list); \ - ListCell **list_arr; \ - List *new_list; \ - \ - if (len == 0) { \ - list = NIL; \ - return list; \ - } \ - i = 0; \ +#define list_sort(list, cmp) \ + do { \ + ListCell *cell; \ + int i; \ + int len = list_length(list); \ + ListCell **list_arr; \ + List *new_list; \ + \ + if (len == 0) { \ + list = NIL; \ + return list; \ + } \ + i = 0; \ list_arr = (ListCell **)palloc(sizeof(ListCell *) * len); \ - foreach(cell, list) \ - list_arr[i++] = cell; \ - \ - qsort(list_arr, len, sizeof(ListCell *), cmp); \ - \ - new_list = (List *) palloc(sizeof(List)); \ - new_list->type = list->type; \ - new_list->length = len; \ - new_list->head = list_arr[len - 1]; \ - new_list->tail = list_arr[0]; \ - \ - for (i = len - 1; i > 0; i--) \ - list_arr[i]->next = list_arr[i - 1]; \ - \ - list_arr[0]->next = NULL; \ - pfree(list_arr); \ - list = new_list; \ + foreach (cell, list) \ + list_arr[i++] = cell; \ + \ + qsort(list_arr, len, sizeof(ListCell *), cmp); \ + \ + new_list = (List *)palloc(sizeof(List)); \ + new_list->type = list->type; \ + new_list->length = len; \ + new_list->head = list_arr[len - 1]; \ + new_list->tail = list_arr[0]; \ + \ + for (i = len - 1; i > 0; i--) \ + list_arr[i]->next = list_arr[i - 1]; \ + \ + list_arr[0]->next = NULL; \ + pfree(list_arr); \ + list = new_list; \ } while (0) #endif @@ -147,7 +146,12 @@ #define HnswGetMl(m) (1 / log(m)) /* Ensure fits on page and in uint8 */ -#define HnswGetMaxLevel(m) Min(((BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - offsetof(HnswNeighborTupleData, indextids) - sizeof(ItemIdData)) / (sizeof(ItemPointerData)) / (m)) - 2, 255) +#define HnswGetMaxLevel(m) \ + Min(((BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(HnswPageOpaqueData)) - \ + offsetof(HnswNeighborTupleData, indextids) - sizeof(ItemIdData)) / \ + (sizeof(ItemPointerData)) / (m)) - \ + 2, \ + 255) #define HnswGetValue(base, element) PointerGetDatum(HnswPtrAccess(base, (element)->value)) @@ -157,78 +161,77 @@ /* Pointer macros */ #define HnswPtrAccess(base, hp) ((base) == NULL ? (hp).ptr : relptr_access(base, (hp).relptr)) -#define HnswPtrStore(base, hp, value) ((base) == NULL ? (void) ((hp).ptr = (value)) : (void) relptr_store(base, (hp).relptr, value)) +#define HnswPtrStore(base, hp, value) \ + ((base) == NULL ? (void)((hp).ptr = (value)) : (void)relptr_store(base, (hp).relptr, value)) #define HnswPtrIsNull(base, hp) ((base) == NULL ? (hp).ptr == NULL : relptr_is_null((hp).relptr)) -#define HnswPtrEqual(base, hp1, hp2) ((base) == NULL ? (hp1).ptr == (hp2).ptr : relptr_offset((hp1).relptr) == relptr_offset((hp2).relptr)) +#define HnswPtrEqual(base, hp1, hp2) \ + ((base) == NULL ? (hp1).ptr == (hp2).ptr : relptr_offset((hp1).relptr) == relptr_offset((hp2).relptr)) /* For code paths dedicated to each type */ #define HnswPtrPointer(hp) (hp).ptr #define HnswPtrOffset(hp) relptr_offset((hp).relptr) /* Variables */ -extern int hnsw_lock_tranche_id; +extern int hnsw_lock_tranche_id; typedef struct HnswElementData HnswElementData; typedef struct HnswNeighborArray HnswNeighborArray; +#define relptr(type) \ + union { \ + type *relptr_type; \ + Size relptr_off; \ + } -#define relptr(type) union { type *relptr_type; Size relptr_off; } - -#define relptr_declare(type, relptrtype) \ - typedef relptr(type) relptrtype +#define relptr_declare(type, relptrtype) typedef relptr(type) relptrtype #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P -#define relptr_access(base, rp) \ - (AssertVariableIsOfTypeMacro(base, char *), \ - (__typeof__((rp).relptr_type)) ((rp).relptr_off == 0 ? NULL : \ - (base) + (rp).relptr_off - 1)) +#define relptr_access(base, rp) \ + (AssertVariableIsOfTypeMacro(base, char *), \ + (__typeof__((rp).relptr_type))((rp).relptr_off == 0 ? NULL : (base) + (rp).relptr_off - 1)) #else /* * If we don't have __builtin_types_compatible_p, assume we might not have * __typeof__ either. */ #define relptr_access(base, rp) \ - (AssertVariableIsOfTypeMacro(base, char *), \ - (void *) ((rp).relptr_off == 0 ? NULL : (base) + (rp).relptr_off - 1)) + (AssertVariableIsOfTypeMacro(base, char *), (void *)((rp).relptr_off == 0 ? NULL : (base) + (rp).relptr_off - 1)) #endif -#define relptr_is_null(rp) \ - ((rp).relptr_off == 0) +#define relptr_is_null(rp) ((rp).relptr_off == 0) -#define relptr_offset(rp) \ - ((rp).relptr_off - 1) +#define relptr_offset(rp) ((rp).relptr_off - 1) /* We use this inline to avoid double eval of "val" in relptr_store */ -static inline Size -relptr_store_eval(char *base, char *val) +static inline Size relptr_store_eval(char *base, char *val) { - if (val == NULL) - return 0; - else - { - Assert(val >= base); - return val - base + 1; - } + if (val == NULL) + return 0; + else { + Assert(val >= base); + return val - base + 1; + } } #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P -#define relptr_store(base, rp, val) \ - (AssertVariableIsOfTypeMacro(base, char *), \ - AssertVariableIsOfTypeMacro(val, __typeof__((rp).relptr_type)), \ - (rp).relptr_off = relptr_store_eval((base), (char *) (val))) +#define relptr_store(base, rp, val) \ + (AssertVariableIsOfTypeMacro(base, char *), AssertVariableIsOfTypeMacro(val, __typeof__((rp).relptr_type)), \ + (rp).relptr_off = relptr_store_eval((base), (char *)(val))) #else /* * If we don't have __builtin_types_compatible_p, assume we might not have * __typeof__ either. */ #define relptr_store(base, rp, val) \ - (AssertVariableIsOfTypeMacro(base, char *), \ - (rp).relptr_off = relptr_store_eval((base), (char *) (val))) + (AssertVariableIsOfTypeMacro(base, char *), (rp).relptr_off = relptr_store_eval((base), (char *)(val))) #endif #define HnswPtrDeclare(type, relptrtype, ptrtype) \ - relptr_declare(type, relptrtype); \ - typedef union { type *ptr; relptrtype relptr; } ptrtype; + relptr_declare(type, relptrtype); \ + typedef union { \ + type *ptr; \ + relptrtype relptr; \ + } ptrtype; /* Pointers that can be absolute or relative */ /* Use char for HnswDatumPtr so works with Pointer */ @@ -237,119 +240,108 @@ HnswPtrDeclare(HnswNeighborArray, HnswNeighborArrayRelptr, HnswNeighborArrayPtr) HnswPtrDeclare(HnswNeighborArrayPtr, HnswNeighborsRelptr, HnswNeighborsPtr); HnswPtrDeclare(char, DatumRelptr, HnswDatumPtr); -struct HnswElementData -{ +struct HnswElementData { HnswElementPtr next; ItemPointerData heaptids[HNSW_HEAPTIDS]; - uint8 heaptidsLength; - uint8 level; - uint8 deleted; - uint32 hash; + uint8 heaptidsLength; + uint8 level; + uint8 deleted; + uint32 hash; HnswNeighborsPtr neighbors; BlockNumber blkno; OffsetNumber offno; OffsetNumber neighborOffno; BlockNumber neighborPage; - HnswDatumPtr value; + HnswDatumPtr value; uint8 *pqcodes; - LWLock lock; + LWLock lock; }; -typedef HnswElementData * HnswElement; +typedef HnswElementData *HnswElement; -typedef struct HnswCandidate -{ +typedef struct HnswCandidate { HnswElementPtr element; - float distance; - bool closer; -} HnswCandidate; + float distance; + bool closer; +} HnswCandidate; -struct HnswNeighborArray -{ - int length; - bool closerSet; +struct HnswNeighborArray { + int length; + bool closerSet; HnswCandidate items[FLEXIBLE_ARRAY_MEMBER]; }; -typedef struct HnswPairingHeapNode -{ +typedef struct HnswPairingHeapNode { pairingheap_node ph_node; HnswCandidate *inner; -} HnswPairingHeapNode; +} HnswPairingHeapNode; /* HNSW index options */ -typedef struct HnswOptions -{ - int32 vl_len_; /* varlena header (do not touch directly!) */ - int m; /* number of connections */ +typedef struct HnswOptions { + int32 vl_len_; /* varlena header (do not touch directly!) */ + int m; /* number of connections */ int efConstruction; /* size of dynamic candidate list */ bool enablePQ; - int pqM; /* number of subquantizer */ - int pqKsub; /* number of centroids for each subquantizer */ - char* storage_type; /* table access method kind */ + int pqM; /* number of subquantizer */ + int pqKsub; /* number of centroids for each subquantizer */ + char *storage_type; /* table access method kind */ } HnswOptions; -typedef struct HnswGraph -{ +typedef struct HnswGraph { /* Graph state */ - slock_t lock; + slock_t lock; HnswElementPtr head; - double indtuples; + double indtuples; /* Entry state */ - LWLock entryLock; - LWLock entryWaitLock; + LWLock entryLock; + LWLock entryWaitLock; HnswElementPtr entryPoint; /* Allocations state */ - LWLock allocatorLock; - long memoryUsed; - long memoryTotal; + LWLock allocatorLock; + long memoryUsed; + long memoryTotal; /* Flushed state */ - LWLock flushLock; - bool flushed; -} HnswGraph; + LWLock flushLock; + bool flushed; +} HnswGraph; -typedef struct HnswShared -{ +typedef struct HnswShared { /* Immutable state */ - Oid heaprelid; - Oid indexrelid; + Oid heaprelid; + Oid indexrelid; /* Mutex for mutable state */ - slock_t mutex; + slock_t mutex; /* Mutable state */ - int nparticipantsdone; - double reltuples; - HnswGraph graphData; + int nparticipantsdone; + double reltuples; + HnswGraph graphData; char *hnswarea; ParallelHeapScanDescData heapdesc; -} HnswShared; +} HnswShared; -typedef struct HnswLeader -{ - int nparticipanttuplesorts; +typedef struct HnswLeader { + int nparticipanttuplesorts; HnswShared *hnswshared; -} HnswLeader; +} HnswLeader; -typedef struct HnswAllocator -{ - void *(*alloc) (Size size, void *state); - void *state; -} HnswAllocator; +typedef struct HnswAllocator { + void *(*alloc)(Size size, void *state); + void *state; +} HnswAllocator; -typedef struct HnswTypeInfo -{ - int maxDimensions; - Datum (*normalize) (PG_FUNCTION_ARGS); - void (*checkValue) (Pointer v); -} HnswTypeInfo; +typedef struct HnswTypeInfo { + int maxDimensions; + Datum (*normalize)(PG_FUNCTION_ARGS); + void (*checkValue)(Pointer v); +} HnswTypeInfo; -typedef struct HnswBuildState -{ +typedef struct HnswBuildState { /* Info */ Relation heap; Relation index; @@ -399,23 +391,21 @@ typedef struct HnswBuildState bool isUStore; /* false means astore */ } HnswBuildState; -typedef struct HnswMetaPageData -{ - uint32 magicNumber; - uint32 version; - uint32 dimensions; - uint16 m; - uint16 efConstruction; +typedef struct HnswMetaPageData { + uint32 magicNumber; + uint32 version; + uint32 dimensions; + uint16 m; + uint16 efConstruction; BlockNumber entryBlkno; OffsetNumber entryOffno; - int16 entryLevel; + int16 entryLevel; BlockNumber insertPage; -} HnswMetaPageData; +} HnswMetaPageData; -typedef HnswMetaPageData * HnswMetaPage; +typedef HnswMetaPageData *HnswMetaPage; -typedef struct HnswAppendMetaPageData -{ +typedef struct HnswAppendMetaPageData { uint32 magicNumber; uint32 version; uint32 dimensions; @@ -427,34 +417,32 @@ typedef struct HnswAppendMetaPageData /* PQ info */ bool enablePQ; - uint16 pqM; /* number of subquantizer */ - uint16 pqKsub; /* number of centroids for each subquantizer */ - uint16 pqcodeSize; /* number of bits per quantization index */ + uint16 pqM; /* number of subquantizer */ + uint16 pqKsub; /* number of centroids for each subquantizer */ + uint16 pqcodeSize; /* number of bits per quantization index */ uint32 centerTableSize; /* dim * sizeof(float) */ - uint32 pqTableSize; /* dim * pqKsub * sizeof(float) */ - uint16 pqTableNblk; /* total number of blks pqtable */ + uint32 pqTableSize; /* dim * pqKsub * sizeof(float) */ + uint16 pqTableNblk; /* total number of blks pqtable */ /* slot info */ int npages; /* number of pages per slot */ BlockNumber slotStartBlkno; - BlockNumber elementInsertSlot; /* the first page of the element type to be inserted into the slot */ + BlockNumber elementInsertSlot; /* the first page of the element type to be inserted into the slot */ BlockNumber neighborInsertSlot; /* the first page of the neighbor type to be inserted into the slot */ } HnswAppendMetaPageData; typedef HnswAppendMetaPageData *HnswAppendMetaPage; -typedef struct HnswPageOpaqueData -{ +typedef struct HnswPageOpaqueData { BlockNumber nextblkno; uint8 pageType; /* element or neighbor page */ uint8 unused; - uint16 page_id; /* for identification of HNSW indexes */ + uint16 page_id; /* for identification of HNSW indexes */ } HnswPageOpaqueData; -typedef HnswPageOpaqueData * HnswPageOpaque; +typedef HnswPageOpaqueData *HnswPageOpaque; -typedef struct HnswElementTupleData -{ +typedef struct HnswElementTupleData { uint8 type; uint8 level; uint8 deleted; @@ -465,51 +453,48 @@ typedef struct HnswElementTupleData Vector data; } HnswElementTupleData; -typedef HnswElementTupleData * HnswElementTuple; +typedef HnswElementTupleData *HnswElementTuple; -typedef struct HnswNeighborTupleData -{ - uint8 type; - uint8 unused; - uint16 count; +typedef struct HnswNeighborTupleData { + uint8 type; + uint8 unused; + uint16 count; ItemPointerData indextids[FLEXIBLE_ARRAY_MEMBER]; -} HnswNeighborTupleData; +} HnswNeighborTupleData; -typedef HnswNeighborTupleData * HnswNeighborTuple; +typedef HnswNeighborTupleData *HnswNeighborTuple; -typedef struct HnswScanOpaqueData -{ - const HnswTypeInfo *typeInfo; - bool first; - List *w; +typedef struct HnswScanOpaqueData { + const HnswTypeInfo *typeInfo; + bool first; + List *w; MemoryContext tmpCtx; /* Support functions */ - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - Oid collation; + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; /* used in ustore only */ VectorScanData vs; -} HnswScanOpaqueData; +} HnswScanOpaqueData; -typedef HnswScanOpaqueData * HnswScanOpaque; +typedef HnswScanOpaqueData *HnswScanOpaque; -typedef struct HnswVacuumState -{ +typedef struct HnswVacuumState { /* Info */ - Relation index; + Relation index; IndexBulkDeleteResult *stats; IndexBulkDeleteCallback callback; - void *callback_state; + void *callback_state; /* Settings */ - int m; - int efConstruction; + int m; + int efConstruction; /* Support functions */ - FmgrInfo *procinfo; - Oid collation; + FmgrInfo *procinfo; + Oid collation; /* Variables */ struct tidhash_hash *deleted; @@ -519,44 +504,49 @@ typedef struct HnswVacuumState /* Memory */ MemoryContext tmpCtx; -} HnswVacuumState; +} HnswVacuumState; /* Methods */ -int HnswGetM(Relation index); -int HnswGetEfConstruction(Relation index); +int HnswGetM(Relation index); +int HnswGetEfConstruction(Relation index); bool HnswGetEnablePQ(Relation index); int HnswGetPqM(Relation index); int HnswGetPqKsub(Relation index); -FmgrInfo *HnswOptionalProcInfo(Relation index, uint16 procnum); -Datum HnswNormValue(const HnswTypeInfo * typeInfo, Oid collation, Datum value); -bool HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value); -Buffer HnswNewBuffer(Relation index, ForkNumber forkNum); -void HnswInitPage(Buffer buf, Page page); -void HnswInit(void); -List *HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *procinfo, - Oid collation, int m, bool inserting, HnswElement skipElement, IndexScanDesc scan = NULL); +FmgrInfo *HnswOptionalProcInfo(Relation index, uint16 procnum); +Datum HnswNormValue(const HnswTypeInfo *typeInfo, Oid collation, Datum value); +bool HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value); +Buffer HnswNewBuffer(Relation index, ForkNumber forkNum); +void HnswInitPage(Buffer buf, Page page); +void HnswInit(void); +List *HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *procinfo, Oid collation, + int m, bool inserting, HnswElement skipElement, IndexScanDesc scan = NULL); HnswElement HnswGetEntryPoint(Relation index); -void HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint); -void *HnswAlloc(HnswAllocator * allocator, Size size); -HnswElement HnswInitElement(char *base, ItemPointer tid, int m, double ml, int maxLevel, HnswAllocator * alloc); +void HnswGetMetaPageInfo(Relation index, int *m, HnswElement *entryPoint); +void *HnswAlloc(HnswAllocator *allocator, Size size); +HnswElement HnswInitElement(char *base, ItemPointer tid, int m, double ml, int maxLevel, HnswAllocator *alloc); HnswElement HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno); -void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing); -HnswCandidate *HnswEntryCandidate(char *base, HnswElement em, Datum q, Relation rel, FmgrInfo *procinfo, - Oid collation, bool loadVec, IndexScanDesc scan = NULL); -void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum, bool building); -void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m); -void HnswAddHeapTid(HnswElement element, ItemPointer heaptid); -void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * alloc); -bool HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *isnull, ItemPointer heap_tid, bool building); -void HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting, bool building); -void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec); -bool HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, - Oid collation, bool loadVec, float *maxDistance, IndexScanDesc scan = NULL); -void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element); -void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation); -void HnswLoadNeighbors(HnswElement element, Relation index, int m); -const HnswTypeInfo *HnswGetTypeInfo(Relation index); -bool HnswDelete(Relation index, Datum* values, const bool* isnull, ItemPointer heapTCtid, bool isRollbackIndex); +void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, + FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing); +HnswCandidate *HnswEntryCandidate(char *base, HnswElement em, Datum q, Relation rel, FmgrInfo *procinfo, Oid collation, + bool loadVec, IndexScanDesc scan = NULL); +void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, + ForkNumber forkNum, bool building); +void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m); +void HnswAddHeapTid(HnswElement element, ItemPointer heaptid); +void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator *alloc); +bool HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *isnull, ItemPointer heap_tid, + bool building); +void HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, + bool checkExisting, bool building); +void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec); +bool HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, Oid collation, + bool loadVec, float *maxDistance, IndexScanDesc scan = NULL); +void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element); +void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate *hc, int lm, int lc, int *updateIdx, + Relation index, FmgrInfo *procinfo, Oid collation); +void HnswLoadNeighbors(HnswElement element, Relation index, int m); +const HnswTypeInfo *HnswGetTypeInfo(Relation index); +bool HnswDelete(Relation index, Datum *values, const bool *isnull, ItemPointer heapTCtid, bool isRollbackIndex); Datum hnswhandler(PG_FUNCTION_ARGS); Datum hnswbuild(PG_FUNCTION_ARGS); @@ -578,19 +568,20 @@ Datum hnsw_sparsevec_support(PG_FUNCTION_ARGS); /* Index access methods */ IndexBuildResult *hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo); -void hnswbuildempty_internal(Relation index); -bool hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique); -IndexBulkDeleteResult *hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state); +void hnswbuildempty_internal(Relation index); +bool hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, + IndexUniqueCheck checkUnique); +IndexBulkDeleteResult *hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state); IndexBulkDeleteResult *hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); IndexScanDesc hnswbeginscan_internal(Relation index, int nkeys, int norderbys); -void hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); -bool hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir); -void hnswendscan_internal(IndexScanDesc scan); -bool hnswdelete_internal(Relation index, Datum* values, const bool* isnull, ItemPointer heapTCtid, +void hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); +bool hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir); +void hnswendscan_internal(IndexScanDesc scan); +bool hnswdelete_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heapTCtid, bool isRollbackIndex); -static inline HnswNeighborArray * -HnswGetNeighbors(char *base, HnswElement element, int lc) +static inline HnswNeighborArray *HnswGetNeighbors(char *base, HnswElement element, int lc) { HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *)HnswPtrAccess(base, element->neighbors); @@ -600,11 +591,10 @@ HnswGetNeighbors(char *base, HnswElement element, int lc) } /* Hash tables */ -typedef struct TidHashEntry -{ +typedef struct TidHashEntry { ItemPointerData tid; - char status; -} TidHashEntry; + char status; +} TidHashEntry; #define SH_PREFIX tidhash #define SH_ELEMENT_TYPE TidHashEntry @@ -613,11 +603,10 @@ typedef struct TidHashEntry #define SH_DECLARE #include "lib/simplehash.h" -typedef struct PointerHashEntry -{ - uintptr_t ptr; - char status; -} PointerHashEntry; +typedef struct PointerHashEntry { + uintptr_t ptr; + char status; +} PointerHashEntry; #define SH_PREFIX pointerhash #define SH_ELEMENT_TYPE PointerHashEntry @@ -626,11 +615,10 @@ typedef struct PointerHashEntry #define SH_DECLARE #include "lib/simplehash.h" -typedef struct OffsetHashEntry -{ - Size offset; - char status; -} OffsetHashEntry; +typedef struct OffsetHashEntry { + Size offset; + char status; +} OffsetHashEntry; #define SH_PREFIX offsethash #define SH_ELEMENT_TYPE OffsetHashEntry diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h index af0dfe578c..963f43de70 100644 --- a/src/include/access/datavec/ivfflat.h +++ b/src/include/access/datavec/ivfflat.h @@ -8,7 +8,7 @@ #include "catalog/pg_operator.h" #include "lib/pairingheap.h" #include "nodes/execnodes.h" -#include "port.h" /* for random() */ +#include "port.h" /* for random() */ #include "sampling.h" #include "utils/tuplesort.h" #include "access/datavec/vector.h" @@ -31,40 +31,40 @@ #define IVFFLAT_KMEANS_NORM_PROC 4 #define IVFFLAT_TYPE_INFO_PROC 5 -#define IVFFLAT_VERSION 1 +#define IVFFLAT_VERSION 1 #define IVFFLAT_MAGIC_NUMBER 0x14FF1A7 -#define IVFFLAT_PAGE_ID 0xFF84 +#define IVFFLAT_PAGE_ID 0xFF84 /* Preserved page numbers */ -#define IVFFLAT_METAPAGE_BLKNO 0 -#define IVFFLAT_HEAD_BLKNO 1 /* first list page */ +#define IVFFLAT_METAPAGE_BLKNO 0 +#define IVFFLAT_HEAD_BLKNO 1 /* first list page */ /* IVFFlat parameters */ -#define IVFFLAT_DEFAULT_LISTS 100 -#define IVFFLAT_MIN_LISTS 1 -#define IVFFLAT_MAX_LISTS 32768 -#define IVFFLAT_DEFAULT_PROBES 1 +#define IVFFLAT_DEFAULT_LISTS 100 +#define IVFFLAT_MIN_LISTS 1 +#define IVFFLAT_MAX_LISTS 32768 +#define IVFFLAT_DEFAULT_PROBES 1 /* Build phases */ /* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 */ -#define PROGRESS_IVFFLAT_PHASE_KMEANS 2 -#define PROGRESS_IVFFLAT_PHASE_ASSIGN 3 -#define PROGRESS_IVFFLAT_PHASE_LOAD 4 +#define PROGRESS_IVFFLAT_PHASE_KMEANS 2 +#define PROGRESS_IVFFLAT_PHASE_ASSIGN 3 +#define PROGRESS_IVFFLAT_PHASE_LOAD 4 -#define IVFFLAT_LIST_SIZE(size) (offsetof(IvfflatListData, center) + size) +#define IVFFLAT_LIST_SIZE(size) (offsetof(IvfflatListData, center) + size) -#define IvfflatPageGetOpaque(page) ((IvfflatPageOpaque) PageGetSpecialPointer(page)) -#define IvfflatPageGetMeta(page) ((IvfflatMetaPageData *) PageGetContents(page)) +#define IvfflatPageGetOpaque(page) ((IvfflatPageOpaque)PageGetSpecialPointer(page)) +#define IvfflatPageGetMeta(page) ((IvfflatMetaPageData *)PageGetContents(page)) #ifdef IVFFLAT_BENCH -#define IvfflatBench(name, code) \ - do { \ - instr_time start; \ - instr_time duration; \ - INSTR_TIME_SET_CURRENT(start); \ - (code); \ - INSTR_TIME_SET_CURRENT(duration); \ - INSTR_TIME_SUBTRACT(duration, start); \ +#define IvfflatBench(name, code) \ + do { \ + instr_time start; \ + instr_time duration; \ + INSTR_TIME_SET_CURRENT(start); \ + (code); \ + INSTR_TIME_SET_CURRENT(duration); \ + INSTR_TIME_SUBTRACT(duration, start); \ elog(INFO, "%s: %.3f ms", name, INSTR_TIME_GET_MILLISEC(duration)); \ } while (0) #else @@ -75,125 +75,117 @@ #define RandomDouble() pg_prng_double(&pg_global_prng_state) #define RandomInt() pg_prng_uint32(&pg_global_prng_state) #else -#define RandomDouble() (((double) random()) / MAX_RANDOM_VALUE) +#define RandomDouble() (((double)random()) / MAX_RANDOM_VALUE) #define RandomInt() random() #endif -typedef struct VectorArrayData -{ - int length; - int maxlen; - int dim; - Size itemsize; - char *items; -} VectorArrayData; +typedef struct VectorArrayData { + int length; + int maxlen; + int dim; + Size itemsize; + char *items; +} VectorArrayData; -typedef VectorArrayData * VectorArray; +typedef VectorArrayData *VectorArray; -typedef struct ListInfo -{ +typedef struct ListInfo { BlockNumber blkno; OffsetNumber offno; -} ListInfo; +} ListInfo; /* IVFFlat index options */ -typedef struct IvfflatOptions -{ - int32 vl_len_; /* varlena header (do not touch directly!) */ - int lists; /* number of lists */ -} IvfflatOptions; +typedef struct IvfflatOptions { + int32 vl_len_; /* varlena header (do not touch directly!) */ + int lists; /* number of lists */ +} IvfflatOptions; -typedef struct IvfflatSpool -{ +typedef struct IvfflatSpool { Tuplesortstate *sortstate; - Relation heap; - Relation index; -} IvfflatSpool; + Relation heap; + Relation index; +} IvfflatSpool; -typedef struct IvfflatShared -{ +typedef struct IvfflatShared { /* Immutable state */ - Oid heaprelid; - Oid indexrelid; - int scantuplesortstates; + Oid heaprelid; + Oid indexrelid; + int scantuplesortstates; /* Mutex for mutable state */ - slock_t mutex; + slock_t mutex; /* Mutable state */ - int nparticipantsdone; - double reltuples; - double indtuples; + int nparticipantsdone; + double reltuples; + double indtuples; - Sharedsort *sharedsort; - Vector *ivfcenters; - int workmem; + Sharedsort *sharedsort; + Vector *ivfcenters; + int workmem; #ifdef IVFFLAT_KMEANS_DEBUG - double inertia; + double inertia; #endif - ParallelHeapScanDescData heapdesc; // must come last -} IvfflatShared; + ParallelHeapScanDescData heapdesc; // must come last +} IvfflatShared; #define ParallelTableScanFromIvfflatShared(shared) \ - (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(IvfflatShared))) - -typedef struct IvfflatLeader -{ - int nparticipanttuplesorts; - IvfflatShared *ivfshared; -} IvfflatLeader; - -typedef struct IvfflatTypeInfo -{ - int maxDimensions; - Datum (*normalize) (PG_FUNCTION_ARGS); - Size (*itemSize) (int dimensions); - void (*updateCenter) (Pointer v, int dimensions, float *x); - void (*sumCenter) (Pointer v, float *x); -} IvfflatTypeInfo; - -typedef struct IvfflatBuildState -{ + (ParallelTableScanDesc)((char *)(shared) + BUFFERALIGN(sizeof(IvfflatShared))) + +typedef struct IvfflatLeader { + int nparticipanttuplesorts; + IvfflatShared *ivfshared; +} IvfflatLeader; + +typedef struct IvfflatTypeInfo { + int maxDimensions; + Datum (*normalize)(PG_FUNCTION_ARGS); + Size (*itemSize)(int dimensions); + void (*updateCenter)(Pointer v, int dimensions, float *x); + void (*sumCenter)(Pointer v, float *x); +} IvfflatTypeInfo; + +typedef struct IvfflatBuildState { /* Info */ - Relation heap; - Relation index; - IndexInfo *indexInfo; - const IvfflatTypeInfo *typeInfo; + Relation heap; + Relation index; + IndexInfo *indexInfo; + const IvfflatTypeInfo *typeInfo; /* Settings */ - int dimensions; - int lists; + int dimensions; + int lists; /* Statistics */ - double indtuples; - double reltuples; + double indtuples; + double reltuples; /* Support functions */ - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - FmgrInfo *kmeansnormprocinfo; - Oid collation; + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + FmgrInfo *kmeansnormprocinfo; + Oid collation; /* Variables */ VectorArray samples; VectorArray centers; - ListInfo *listInfo; + ListInfo *listInfo; #ifdef IVFFLAT_KMEANS_DEBUG - double inertia; - double *listSums; - int *listCounts; + double inertia; + double *listSums; + int *listCounts; #endif /* Sampling */ BlockSamplerData bs; double rstate; - int rowstoskip; + int rowstoskip; /* Sorting */ Tuplesortstate *sortstate; - TupleDesc tupdesc; + TupleDesc tupdesc; TupleTableSlot *slot; /* Memory */ @@ -202,103 +194,97 @@ typedef struct IvfflatBuildState /* Parallel builds */ IvfflatLeader *ivfleader; -} IvfflatBuildState; +} IvfflatBuildState; -typedef struct IvfflatMetaPageData -{ - uint32 magicNumber; - uint32 version; - uint16 dimensions; - uint16 lists; -} IvfflatMetaPageData; +typedef struct IvfflatMetaPageData { + uint32 magicNumber; + uint32 version; + uint16 dimensions; + uint16 lists; +} IvfflatMetaPageData; -typedef IvfflatMetaPageData * IvfflatMetaPage; +typedef IvfflatMetaPageData *IvfflatMetaPage; -typedef struct IvfflatPageOpaqueData -{ +typedef struct IvfflatPageOpaqueData { BlockNumber nextblkno; - uint16 unused; - uint16 page_id; /* for identification of IVFFlat indexes */ -} IvfflatPageOpaqueData; + uint16 unused; + uint16 page_id; /* for identification of IVFFlat indexes */ +} IvfflatPageOpaqueData; -typedef IvfflatPageOpaqueData * IvfflatPageOpaque; +typedef IvfflatPageOpaqueData *IvfflatPageOpaque; -typedef struct IvfflatListData -{ +typedef struct IvfflatListData { BlockNumber startPage; BlockNumber insertPage; - Vector center; -} IvfflatListData; + Vector center; +} IvfflatListData; -typedef IvfflatListData * IvfflatList; +typedef IvfflatListData *IvfflatList; -typedef struct IvfflatScanList -{ +typedef struct IvfflatScanList { pairingheap_node ph_node; BlockNumber startPage; - double distance; -} IvfflatScanList; + double distance; +} IvfflatScanList; -typedef struct IvfflatScanOpaqueData -{ - const IvfflatTypeInfo *typeInfo; - int probes; - int dimensions; - bool first; +typedef struct IvfflatScanOpaqueData { + const IvfflatTypeInfo *typeInfo; + int probes; + int dimensions; + bool first; /* Sorting */ Tuplesortstate *sortstate; - TupleDesc tupdesc; + TupleDesc tupdesc; TupleTableSlot *slot; - bool isnull; + bool isnull; /* Support functions */ - FmgrInfo *procinfo; - FmgrInfo *normprocinfo; - Oid collation; - Datum (*distfunc) (FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2); + FmgrInfo *procinfo; + FmgrInfo *normprocinfo; + Oid collation; + Datum (*distfunc)(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2); /* Lists */ pairingheap *listQueue; - IvfflatScanList lists[FLEXIBLE_ARRAY_MEMBER]; /* must come last */ -} IvfflatScanOpaqueData; + IvfflatScanList lists[FLEXIBLE_ARRAY_MEMBER]; /* must come last */ +} IvfflatScanOpaqueData; -typedef IvfflatScanOpaqueData * IvfflatScanOpaque; +typedef IvfflatScanOpaqueData *IvfflatScanOpaque; #define VECTOR_ARRAY_SIZE(_length, _size) (sizeof(VectorArrayData) + (_length) * MAXALIGN(_size)) /* Use functions instead of macros to avoid double evaluation */ -static inline Pointer -VectorArrayGet(VectorArray arr, int offset) +static inline Pointer VectorArrayGet(VectorArray arr, int offset) { - return ((char *) arr->items) + (offset * arr->itemsize); + return ((char *)arr->items) + (offset * arr->itemsize); } -static inline void -VectorArraySet(VectorArray arr, int offset, Pointer val) +static inline void VectorArraySet(VectorArray arr, int offset, Pointer val) { memcpy(VectorArrayGet(arr, offset), val, VARSIZE_ANY(val)); } /* Methods */ VectorArray VectorArrayInit(int maxlen, int dimensions, Size itemsize); -void VectorArrayFree(VectorArray arr); -void IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo); -FmgrInfo *IvfflatOptionalProcInfo(Relation index, uint16 procnum); -Datum IvfflatNormValue(const IvfflatTypeInfo * typeInfo, Oid collation, Datum value); -bool IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value); -int IvfflatGetLists(Relation index); -void IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions); -void IvfflatUpdateList(Relation index, ListInfo listInfo, BlockNumber insertPage, BlockNumber originalInsertPage, BlockNumber startPage, ForkNumber forkNum); -void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state); -void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum); -Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum); -void IvfflatInitPage(Buffer buf, Page page); -void IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state); +void VectorArrayFree(VectorArray arr); +void IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo *typeInfo); +FmgrInfo *IvfflatOptionalProcInfo(Relation index, uint16 procnum); +Datum IvfflatNormValue(const IvfflatTypeInfo *typeInfo, Oid collation, Datum value); +bool IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value); +int IvfflatGetLists(Relation index); +void IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions); +void IvfflatUpdateList(Relation index, ListInfo listInfo, BlockNumber insertPage, BlockNumber originalInsertPage, + BlockNumber startPage, ForkNumber forkNum); +void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state); +void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum); +Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum); +void IvfflatInitPage(Buffer buf, Page page); +void IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state); PGDLLEXPORT void IvfflatParallelBuildMain(const BgWorkerContext *bwc); -void IvfflatInit(void); -const IvfflatTypeInfo *IvfflatGetTypeInfo(Relation index); +void IvfflatInit(void); +const IvfflatTypeInfo *IvfflatGetTypeInfo(Relation index); Datum ivfflathandler(PG_FUNCTION_ARGS); Datum ivfflatbuild(PG_FUNCTION_ARGS); @@ -318,13 +304,15 @@ Datum ivfflat_bit_support(PG_FUNCTION_ARGS); /* Index access methods */ IndexBuildResult *ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo); -void ivfflatbuildempty_internal(Relation index); -bool ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique); -IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state); +void ivfflatbuildempty_internal(Relation index); +bool ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, + IndexUniqueCheck checkUnique); +IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state); IndexBulkDeleteResult *ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); IndexScanDesc ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys); -void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); -bool ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir); -void ivfflatendscan_internal(IndexScanDesc scan); +void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); +bool ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir); +void ivfflatendscan_internal(IndexScanDesc scan); #endif diff --git a/src/include/access/datavec/pg_prng.h b/src/include/access/datavec/pg_prng.h index dcdc1875fd..73a53ce66a 100644 --- a/src/include/access/datavec/pg_prng.h +++ b/src/include/access/datavec/pg_prng.h @@ -16,10 +16,8 @@ * opaque typedef, but we expose its definition to allow it to be * embedded in other structs. */ -typedef struct pg_prng_state -{ - uint64 s0, - s1; +typedef struct pg_prng_state { + uint64 s0, s1; } pg_prng_state; /* @@ -44,8 +42,7 @@ extern bool pg_prng_seed_check(pg_prng_state *state); * pg_strong_random.c and thence OpenSSL. */ #define pg_prng_strong_seed(state) \ - (pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \ - pg_prng_seed_check(state) : false) + (pg_strong_random((void *)(state), sizeof(pg_prng_state)) ? pg_prng_seed_check(state) : false) extern uint64 pg_prng_uint64(pg_prng_state *state); extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax); @@ -58,4 +55,4 @@ extern double pg_prng_double(pg_prng_state *state); extern double pg_prng_double_normal(pg_prng_state *state); extern bool pg_prng_bool(pg_prng_state *state); -#endif /* PG_PRNG_H */ +#endif /* PG_PRNG_H */ diff --git a/src/include/access/datavec/ryu_common.h b/src/include/access/datavec/ryu_common.h index 0dbe1b1d73..8713d39474 100644 --- a/src/include/access/datavec/ryu_common.h +++ b/src/include/access/datavec/ryu_common.h @@ -54,21 +54,18 @@ * generation by copying pairs of digits into the final output. */ static const char DIGIT_TABLE[200] = { - '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', - '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', - '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', - '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', - '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', - '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', - '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', - '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', - '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', - '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9' -}; + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', '1', '0', '1', + '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0', '2', '1', '2', '2', + '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', '3', '0', '3', '1', '3', '2', '3', '3', '3', + '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', + '4', '6', '4', '7', '4', '8', '4', '9', '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', + '7', '5', '8', '5', '9', '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', + '6', '9', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '8', + '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', '9', '0', '9', '1', + '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'}; /* Returns e == 0 ? 1 : ceil(log_2(5^e)). */ -static inline uint32 -pow5bits(const int32 e) +static inline uint32 pow5bits(const int32 e) { /* * This approximation works up to the point that the multiplication @@ -79,12 +76,11 @@ pow5bits(const int32 e) */ Assert(e >= 0); Assert(e <= 3528); - return ((((uint32) e) * 1217359) >> 19) + 1; + return ((((uint32)e) * 1217359) >> 19) + 1; } /* Returns floor(log_10(2^e)). */ -static inline int32 -log10Pow2(const int32 e) +static inline int32 log10Pow2(const int32 e) { /* * The first value this approximation fails for is 2^1651 which is just @@ -92,12 +88,11 @@ log10Pow2(const int32 e) */ Assert(e >= 0); Assert(e <= 1650); - return (int32) ((((uint32) e) * 78913) >> 18); + return (int32)((((uint32)e) * 78913) >> 18); } /* Returns floor(log_10(5^e)). */ -static inline int32 -log10Pow5(const int32 e) +static inline int32 log10Pow5(const int32 e) { /* * The first value this approximation fails for is 5^2621 which is just @@ -105,23 +100,19 @@ log10Pow5(const int32 e) */ Assert(e >= 0); Assert(e <= 2620); - return (int32) ((((uint32) e) * 732923) >> 20); + return (int32)((((uint32)e) * 732923) >> 20); } -static inline int -copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) +static inline int copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) { - if (mantissa) - { + if (mantissa) { memcpy(result, "NaN", 3); return 3; } - if (sign) - { + if (sign) { result[0] = '-'; } - if (exponent) - { + if (exponent) { memcpy(result + sign, "Infinity", 8); return sign + 8; } @@ -129,22 +120,20 @@ copy_special_str(char *const result, const bool sign, const bool exponent, const return sign + 1; } -static inline uint32 -float_to_bits(const float f) +static inline uint32 float_to_bits(const float f) { - uint32 bits = 0; + uint32 bits = 0; memcpy(&bits, &f, sizeof(float)); return bits; } -static inline uint64 -double_to_bits(const double d) +static inline uint64 double_to_bits(const double d) { - uint64 bits = 0; + uint64 bits = 0; memcpy(&bits, &d, sizeof(double)); return bits; } -#endif /* RYU_COMMON_H */ +#endif /* RYU_COMMON_H */ diff --git a/src/include/access/datavec/sampling.h b/src/include/access/datavec/sampling.h index 5f3772fb5f..0c51c2cd19 100644 --- a/src/include/access/datavec/sampling.h +++ b/src/include/access/datavec/sampling.h @@ -2,39 +2,34 @@ #define SAMPLING_H #include "access/datavec/pg_prng.h" -#include "storage/buf/block.h" /* for typedef BlockNumber */ - +#include "storage/buf/block.h" /* for typedef BlockNumber */ /* Random generator for sampling code */ -extern void sampler_random_init_state(uint32 seed, - pg_prng_state *randstate); +extern void sampler_random_init_state(uint32 seed, pg_prng_state *randstate); extern double sampler_random_fract(pg_prng_state *randstate); /* Block sampling methods */ /* Data structure for Algorithm S from Knuth 3.4.2 */ -typedef struct -{ - BlockNumber N; /* number of blocks, known in advance */ - uint32 n; /* desired sample size */ - BlockNumber t; /* current block number */ - uint32 m; /* blocks selected so far */ - pg_prng_state randstate; /* random generator state */ +typedef struct { + BlockNumber N; /* number of blocks, known in advance */ + uint32 n; /* desired sample size */ + BlockNumber t; /* current block number */ + uint32 m; /* blocks selected so far */ + pg_prng_state randstate; /* random generator state */ } BlockSamplerData2; typedef BlockSamplerData2 *BlockSampler2; -extern BlockNumber BlockSampler_Init2(BlockSampler2 bs, BlockNumber nblocks, - int samplesize, uint32 randseed); +extern BlockNumber BlockSampler_Init2(BlockSampler2 bs, BlockNumber nblocks, int samplesize, uint32 randseed); extern bool BlockSampler_HasMore2(BlockSampler2 bs); extern BlockNumber BlockSampler_Next2(BlockSampler2 bs); /* Reservoir sampling methods */ -typedef struct -{ - double W; - pg_prng_state randstate; /* random generator state */ +typedef struct { + double W; + pg_prng_state randstate; /* random generator state */ } ReservoirStateData; typedef ReservoirStateData *ReservoirState; @@ -42,4 +37,4 @@ typedef ReservoirStateData *ReservoirState; extern void reservoir_init_selection_state(ReservoirState rs, int n); extern double reservoir_get_next_S(ReservoirState rs, double t, int n); -#endif /* SAMPLING_H */ +#endif /* SAMPLING_H */ diff --git a/src/include/access/datavec/sparsevec.h b/src/include/access/datavec/sparsevec.h index 6809e8d4d2..a1a2fb9fdd 100644 --- a/src/include/access/datavec/sparsevec.h +++ b/src/include/access/datavec/sparsevec.h @@ -4,9 +4,9 @@ #define SPARSEVEC_MAX_DIM 1000000000 #define SPARSEVEC_MAX_NNZ 16000 -#define DatumGetSparseVector(x) ((SparseVector *) PG_DETOAST_DATUM(x)) -#define PG_GETARG_SPARSEVEC_P(x) DatumGetSparseVector(PG_GETARG_DATUM(x)) -#define PG_RETURN_SPARSEVEC_P(x) PG_RETURN_POINTER(x) +#define DatumGetSparseVector(x) ((SparseVector *)PG_DETOAST_DATUM(x)) +#define PG_GETARG_SPARSEVEC_P(x) DatumGetSparseVector(PG_GETARG_DATUM(x)) +#define PG_RETURN_SPARSEVEC_P(x) PG_RETURN_POINTER(x) /* * Indices use 0-based numbering for the on-disk (and binary) format (consistent with C) @@ -39,27 +39,24 @@ Datum sparsevec_to_vector(PG_FUNCTION_ARGS); Datum halfvec_to_sparsevec(PG_FUNCTION_ARGS); Datum sparsevec_to_halfvec(PG_FUNCTION_ARGS); -typedef struct SparseVector -{ - int32 vl_len_; /* varlena header (do not touch directly!) */ - int32 dim; /* number of dimensions */ - int32 nnz; /* number of non-zero elements */ - int32 unused; /* reserved for future use, always zero */ - int32 indices[FLEXIBLE_ARRAY_MEMBER]; -} SparseVector; +typedef struct SparseVector { + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 dim; /* number of dimensions */ + int32 nnz; /* number of non-zero elements */ + int32 unused; /* reserved for future use, always zero */ + int32 indices[FLEXIBLE_ARRAY_MEMBER]; +} SparseVector; /* Use functions instead of macros to avoid double evaluation */ -static inline Size -SPARSEVEC_SIZE(int nnz) +static inline Size SPARSEVEC_SIZE(int nnz) { return offsetof(SparseVector, indices) + (nnz * sizeof(int32)) + (nnz * sizeof(float)); } -static inline float * -SPARSEVEC_VALUES(SparseVector * x) +static inline float *SPARSEVEC_VALUES(SparseVector *x) { - return (float *) (((char *) x) + offsetof(SparseVector, indices) + (x->nnz * sizeof(int32))); + return (float *)(((char *)x) + offsetof(SparseVector, indices) + (x->nnz * sizeof(int32))); } SparseVector *InitSparseVector(int dim, int nnz); diff --git a/src/include/access/datavec/vecindex.h b/src/include/access/datavec/vecindex.h index 410d1d4878..73ff5af5a1 100644 --- a/src/include/access/datavec/vecindex.h +++ b/src/include/access/datavec/vecindex.h @@ -4,13 +4,13 @@ #define MIN(A, B) ((B) < (A) ? (B) : (A)) #define MAX(A, B) ((B) > (A) ? (B) : (A)) -#define VecIndexTupleGetXid(itup) (((char*)(itup)) + HNSW_ELEMENT_TUPLE_SIZE(VARSIZE_ANY(&(itup)->data))) +#define VecIndexTupleGetXid(itup) (((char *)(itup)) + HNSW_ELEMENT_TUPLE_SIZE(VARSIZE_ANY(&(itup)->data))) struct VectorScanData { /* - * used in ustore only, indicate the last returned index tuple which is modified - * by current transaction. see VecVisibilityCheckCid() for more information. - */ + * used in ustore only, indicate the last returned index tuple which is modified + * by current transaction. see VecVisibilityCheckCid() for more information. + */ char *lastSelfModifiedItup; uint16 lastSelfModifiedItupBufferSize; Buffer buf; @@ -20,4 +20,4 @@ bool VecItupGetXminXmax(Page page, OffsetNumber offnum, TransactionId oldest_xmi TransactionId *xmax, bool *xminCommitted, bool *xmaxCommitted, bool isToast); bool VecVisibilityCheck(IndexScanDesc scan, Page page, OffsetNumber offnum, bool *needRecheck); -#endif //VECINDEX_H +#endif // VECINDEX_H diff --git a/src/include/access/datavec/vector.h b/src/include/access/datavec/vector.h index fc9ff17530..0fa8924fb2 100644 --- a/src/include/access/datavec/vector.h +++ b/src/include/access/datavec/vector.h @@ -4,23 +4,22 @@ #define VECTOR_MAX_DIM 16000 #define MEM_INFO_NUM (1024 * 1024) -#define VECTOR_SIZE(_dim) (offsetof(Vector, x) + sizeof(float)*(_dim)) -#define DatumGetVector(x) ((Vector *) PG_DETOAST_DATUM(x)) -#define PG_GETARG_VECTOR_P(x) DatumGetVector(PG_GETARG_DATUM(x)) -#define PG_RETURN_VECTOR_P(x) PG_RETURN_POINTER(x) +#define VECTOR_SIZE(_dim) (offsetof(Vector, x) + sizeof(float) * (_dim)) +#define DatumGetVector(x) ((Vector *)PG_DETOAST_DATUM(x)) +#define PG_GETARG_VECTOR_P(x) DatumGetVector(PG_GETARG_DATUM(x)) +#define PG_RETURN_VECTOR_P(x) PG_RETURN_POINTER(x) #define UpdateProgress(index, val) ((void)val) -typedef struct Vector -{ - int32 vl_len_; /* varlena header (do not touch directly!) */ - int16 dim; /* number of dimensions */ - int16 unused; /* reserved for future use, always zero */ - float x[FLEXIBLE_ARRAY_MEMBER]; -} Vector; +typedef struct Vector { + int32 vl_len_; /* varlena header (do not touch directly!) */ + int16 dim; /* number of dimensions */ + int16 unused; /* reserved for future use, always zero */ + float x[FLEXIBLE_ARRAY_MEMBER]; +} Vector; -Vector *InitVector(int dim); -void PrintVector(char *msg, Vector * vector); -int vector_cmp_internal(Vector * a, Vector * b); +Vector *InitVector(int dim); +void PrintVector(char *msg, Vector *vector); +int vector_cmp_internal(Vector *a, Vector *b); void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std); int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo); @@ -67,6 +66,6 @@ typedef struct datavec_session_context { } datavec_session_context; extern uint32 datavec_index; -extern datavec_session_context* get_session_context(); +extern datavec_session_context *get_session_context(); #endif -- Gitee From 408bc3c56ab5f4bb7384acb57cc251a155d40958 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Fri, 1 Nov 2024 17:07:01 +0800 Subject: [PATCH 10/67] clean code --- src/common/backend/utils/adt/f2s.cpp | 20 +- src/common/backend/utils/adt/halfvec.cpp | 145 ++++--- src/common/backend/utils/adt/sparsevec.cpp | 56 ++- src/common/backend/utils/adt/vector.cpp | 173 ++++++--- .../storage/access/datavec/bitutils.cpp | 46 ++- .../storage/access/datavec/hnsw.cpp | 102 ++--- .../storage/access/datavec/hnswbuild.cpp | 182 ++++----- .../storage/access/datavec/hnswdelete.cpp | 14 +- .../storage/access/datavec/hnswinsert.cpp | 93 ++--- .../storage/access/datavec/hnswscan.cpp | 38 +- .../storage/access/datavec/hnswutils.cpp | 366 +++++++----------- .../storage/access/datavec/hnswvacuum.cpp | 67 ++-- .../storage/access/datavec/ivfbuild.cpp | 191 +++++---- .../storage/access/datavec/ivfflat.cpp | 90 ++--- .../storage/access/datavec/ivfinsert.cpp | 36 +- .../storage/access/datavec/ivfkmeans.cpp | 96 +++-- .../storage/access/datavec/ivfscan.cpp | 66 ++-- .../storage/access/datavec/ivfutils.cpp | 134 +++---- .../storage/access/datavec/ivfvacuum.cpp | 17 +- src/include/access/datavec/hnsw.h | 8 +- 20 files changed, 900 insertions(+), 1040 deletions(-) diff --git a/src/common/backend/utils/adt/f2s.cpp b/src/common/backend/utils/adt/f2s.cpp index 6e10791fe0..ccdce5efdb 100644 --- a/src/common/backend/utils/adt/f2s.cpp +++ b/src/common/backend/utils/adt/f2s.cpp @@ -91,8 +91,9 @@ static inline uint32 pow5Factor(uint32 value) const uint32 q = value / 5; const uint32 r = value % 5; - if (r != 0) + if (r != 0) { break; + } value = q; ++count; @@ -109,7 +110,6 @@ static inline bool multipleOfPowerOf5(const uint32 value, const uint32 p) /* Returns true if value is divisible by 2^p. */ static inline bool multipleOfPowerOf2(const uint32 value, const uint32 p) { - /* return __builtin_ctz(value) >= p; */ return (value & ((1u << p) - 1)) == 0; } @@ -253,7 +253,6 @@ static inline floating_decimal_32 f2d(const uint32 ieeeMantissa, const uint32 ie vr = mulPow5InvDivPow2(mv, q, i); vp = mulPow5InvDivPow2(mp, q, i); vm = mulPow5InvDivPow2(mm, q, i); - if (q != 0 && (vp - 1) / 10 <= vm / 10) { /* * We need to know one removed digit even if we are not going to @@ -292,7 +291,6 @@ static inline floating_decimal_32 f2d(const uint32 ieeeMantissa, const uint32 ie vr = mulPow5divPow2(mv, i, j); vp = mulPow5divPow2(mp, i, j); vm = mulPow5divPow2(mm, i, j); - if (q != 0 && (vp - 1) / 10 <= vm / 10) { j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); lastRemovedDigit = (uint8)(mulPow5divPow2(mv, i + 1, j) % 10); @@ -317,7 +315,6 @@ static inline floating_decimal_32 f2d(const uint32 ieeeMantissa, const uint32 ie --vp; } } else if (q < 31) { - /* TODO(ulfjack):Use a tighter bound here. */ vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); } } @@ -506,16 +503,18 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char *c uint32 olength = decimalLength(output); int32 exp = v.exponent + olength - 1; - if (sign) + if (sign) { result[index++] = '-'; + } /* * The thresholds for fixed-point output are chosen to match printf * defaults. Beware that both the code of to_chars_f and the value * of FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. */ - if (exp >= -4 && exp < 6) + if (exp >= -4 && exp < 6) { return to_chars_f(v, olength, result + index) + sign; + } /* * If v.exponent is exactly 0, we might have reached here via the small @@ -538,8 +537,9 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char *c const uint32 q = output / 10; const uint32 r = output - 10 * q; - if (r != 0) + if (r != 0) { break; + } output = q; --olength; } @@ -601,8 +601,9 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char *c if (exp < 0) { result[index++] = '-'; exp = -exp; - } else + } else { result[index++] = '+'; + } memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); index += 2; @@ -678,7 +679,6 @@ int float_to_shortest_decimal_bufn(float f, char *result) floating_decimal_32 v; const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v); - if (!isSmallInt) { v = f2d(ieeeMantissa, ieeeExponent); } diff --git a/src/common/backend/utils/adt/halfvec.cpp b/src/common/backend/utils/adt/halfvec.cpp index 8db9e0b840..70d810c177 100644 --- a/src/common/backend/utils/adt/halfvec.cpp +++ b/src/common/backend/utils/adt/halfvec.cpp @@ -59,9 +59,10 @@ static void pq_sendhalf(StringInfo buf, half h) */ static inline void CheckDims(HalfVector *a, HalfVector *b) { - if (a->dim != b->dim) + if (a->dim != b->dim) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("different halfvec dimensions %d and %d", a->dim, b->dim))); + } } /* @@ -69,8 +70,9 @@ static inline void CheckDims(HalfVector *a, HalfVector *b) */ static inline void CheckExpectedDim(int32 typmod, int dim) { - if (typmod != -1 && typmod != dim) + if (typmod != -1 && typmod != dim) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected %d dimensions, not %d", typmod, dim))); + } } /* @@ -119,8 +121,9 @@ HalfVector *InitHalfVector(int dim) */ static inline bool halfvec_isspace(char ch) { - if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') { return true; + } return false; } @@ -160,8 +163,9 @@ Datum halfvec_in(PG_FUNCTION_ARGS) char *pt = lit; HalfVector *result; - while (halfvec_isspace(*pt)) + while (halfvec_isspace(*pt)) { pt++; + } if (*pt != '[') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -170,8 +174,9 @@ Datum halfvec_in(PG_FUNCTION_ARGS) pt++; - while (halfvec_isspace(*pt)) + while (halfvec_isspace(*pt)) { pt++; + } if (*pt == ']') ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("halfvec must have at least 1 dimension"))); @@ -184,8 +189,9 @@ Datum halfvec_in(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); - while (halfvec_isspace(*pt)) + while (halfvec_isspace(*pt)) { pt++; + } /* Check for empty string like float4in */ if (*pt == '\0') @@ -197,50 +203,57 @@ Datum halfvec_in(PG_FUNCTION_ARGS) /* Postgres sets LC_NUMERIC to C on startup */ val = strtof(pt, &stringEnd); - if (stringEnd == pt) + if (stringEnd == pt) { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + } 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, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("\"%s\" is out of range for type halfvec", pnstrdup(pt, stringEnd - pt)))); + } CheckElement(x[dim]); dim++; pt = stringEnd; - while (halfvec_isspace(*pt)) + while (halfvec_isspace(*pt)) { pt++; + } - if (*pt == ',') + if (*pt == ',') { pt++; - else if (*pt == ']') { + } else if (*pt == ']') { pt++; break; - } else + } else { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type halfvec: \"%s\"", lit))); + } } /* Only whitespace is allowed after the closing brace */ - while (halfvec_isspace(*pt)) + while (halfvec_isspace(*pt)) { pt++; + } - if (*pt != '\0') + if (*pt != '\0') { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type halfvec: \"%s\"", lit), errdetail("Junk after closing right brace."))); + } CheckDim(dim); CheckExpectedDim(typmod, dim); result = InitHalfVector(dim); - for (int i = 0; i < dim; i++) + for (int i = 0; i < dim; i++) { result->x[i] = x[i]; + } PG_RETURN_POINTER(result); } @@ -275,8 +288,9 @@ Datum halfvec_out(PG_FUNCTION_ARGS) AppendChar(ptr, '['); for (int i = 0; i < dim; i++) { - if (i > 0) + if (i > 0) { AppendChar(ptr, ','); + } /* * Use shortest decimal representation of single-precision float for @@ -304,16 +318,19 @@ Datum halfvec_typmod_in(PG_FUNCTION_ARGS) tl = ArrayGetIntegerTypmods(ta, &n); - if (n != 1) + if (n != 1) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid type modifier"))); + } - if (*tl < 1) + if (*tl < 1) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dimensions for type halfvec must be at least 1"))); + } - if (*tl > HALFVEC_MAX_DIM) + if (*tl > HALFVEC_MAX_DIM) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dimensions for type halfvec cannot exceed %d", HALFVEC_MAX_DIM))); + } PG_RETURN_INT32(*tl); } @@ -336,8 +353,9 @@ Datum halfvec_recv(PG_FUNCTION_ARGS) CheckDim(dim); CheckExpectedDim(typmod, dim); - if (unused != 0) + if (unused != 0) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected unused to be 0, not %d", unused))); + } result = InitHalfVector(dim); for (int i = 0; i < dim; i++) { @@ -360,8 +378,9 @@ Datum halfvec_send(PG_FUNCTION_ARGS) pq_begintypsend(&buf); pq_sendint(&buf, vec->dim, sizeof(int16)); pq_sendint(&buf, vec->unused, sizeof(int16)); - for (int i = 0; i < vec->dim; i++) + for (int i = 0; i < vec->dim; i++) { pq_sendhalf(&buf, vec->x[i]); + } PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } @@ -396,11 +415,13 @@ Datum array_to_halfvec(PG_FUNCTION_ARGS) Datum *elemsp; int nelemsp; - if (ARR_NDIM(array) > 1) + if (ARR_NDIM(array) > 1) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("array must be 1-D"))); + } - if (ARR_HASNULL(array) && array_contains_nulls(array)) + if (ARR_HASNULL(array) && array_contains_nulls(array)) { ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("array must not contain nulls"))); + } get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); @@ -433,8 +454,9 @@ Datum array_to_halfvec(PG_FUNCTION_ARGS) pfree(elemsp); /* Check elements */ - for (int i = 0; i < result->dim; i++) + for (int i = 0; i < result->dim; i++) { CheckElement(result->x[i]); + } PG_RETURN_POINTER(result); } @@ -451,8 +473,9 @@ Datum halfvec_to_float4(PG_FUNCTION_ARGS) datums = (Datum *)palloc(sizeof(Datum) * vec->dim); - for (int i = 0; i < vec->dim; i++) + for (int i = 0; i < vec->dim; i++) { datums[i] = Float4GetDatum(HalfToFloat4(vec->x[i])); + } /* Use TYPALIGN_INT for float4 */ result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); @@ -552,18 +575,19 @@ Datum halfvec_cosine_distance(PG_FUNCTION_ARGS) CheckDims(a, b); similarity = HalfvecCosineSimilarity(a->dim, a->x, b->x); - #ifdef _MSC_VER /* /fp:fast may not propagate NaN */ - if (isnan(similarity)) + if (isnan(similarity)) { PG_RETURN_FLOAT8(NAN); + } #endif /* Keep in range */ - if (similarity > 1) + if (similarity > 1) { similarity = 1; - else if (similarity < -1) + } else if (similarity < -1) { similarity = -1; + } PG_RETURN_FLOAT8(1 - similarity); } @@ -583,12 +607,12 @@ Datum halfvec_spherical_distance(PG_FUNCTION_ARGS) CheckDims(a, b); distance = (double)HalfvecInnerProduct(a->dim, a->x, b->x); - /* Prevent NaN with acos with loss of precision */ - if (distance > 1) + if (distance > 1) { distance = 1; - else if (distance < -1) + } else if (distance < -1) { distance = -1; + } PG_RETURN_FLOAT8(acos(distance) / M_PI); } @@ -658,7 +682,6 @@ Datum halfvec_l2_normalize(PG_FUNCTION_ARGS) norm += (double)HalfToFloat4(ax[i]) * (double)HalfToFloat4(ax[i]); norm = sqrt(norm); - /* Return zero vector for zero norm */ if (norm > 0) { for (int i = 0; i < a->dim; i++) @@ -703,8 +726,9 @@ Datum halfvec_add(PG_FUNCTION_ARGS) /* Check for overflow */ for (int i = 0, imax = a->dim; i < imax; i++) { - if (HalfIsInf(rx[i])) + if (HalfIsInf(rx[i])) { float_overflow_error(); + } } PG_RETURN_POINTER(result); @@ -739,8 +763,9 @@ Datum halfvec_sub(PG_FUNCTION_ARGS) /* Check for overflow */ for (int i = 0, imax = a->dim; i < imax; i++) { - if (HalfIsInf(rx[i])) + if (HalfIsInf(rx[i])) { float_overflow_error(); + } } PG_RETURN_POINTER(result); @@ -775,11 +800,13 @@ Datum halfvec_mul(PG_FUNCTION_ARGS) /* Check for overflow and underflow */ for (int i = 0, imax = a->dim; i < imax; i++) { - if (HalfIsInf(rx[i])) + if (HalfIsInf(rx[i])) { float_overflow_error(); + } - if (HalfIsZero(rx[i]) && !(HalfIsZero(ax[i]) || HalfIsZero(bx[i]))) + if (HalfIsZero(rx[i]) && !(HalfIsZero(ax[i]) || HalfIsZero(bx[i]))) { float_underflow_error(); + } } PG_RETURN_POINTER(result); @@ -799,11 +826,13 @@ Datum halfvec_concat(PG_FUNCTION_ARGS) CheckDim(dim); result = InitHalfVector(dim); - for (int i = 0; i < a->dim; i++) + for (int i = 0; i < a->dim; i++) { result->x[i] = a->x[i]; + } - for (int i = 0; i < b->dim; i++) + for (int i = 0; i < b->dim; i++) { result->x[i + a->dim] = b->x[i]; + } PG_RETURN_POINTER(result); } @@ -819,8 +848,9 @@ Datum halfvec_binary_quantize(PG_FUNCTION_ARGS) VarBit *result = InitBitVector(a->dim); unsigned char *rx = VARBITS(result); - for (int i = 0; i < a->dim; i++) + for (int i = 0; i < a->dim; i++) { rx[i / 8] |= (HalfToFloat4(ax[i]) > 0) << (7 - (i % 8)); + } PG_RETURN_VARBIT_P(result); } @@ -839,30 +869,34 @@ Datum halfvec_subvector(PG_FUNCTION_ARGS) HalfVector *result; int32 dim; - if (count < 1) + if (count < 1) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("halfvec must have at least 1 dimension"))); + } /* * Check if (start + count > a->dim), avoiding integer overflow. a->dim * and count are both positive, so a->dim - count won't overflow. */ - if (start > a->dim - count) + if (start > a->dim - count) { end = a->dim + 1; - else + } else { end = start + count; + } /* Indexing starts at 1, like substring */ - if (start < 1) + if (start < 1) { start = 1; - else if (start > a->dim) + } else if (start > a->dim) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("halfvec must have at least 1 dimension"))); + } dim = end - start; CheckDim(dim); result = InitHalfVector(dim); - for (int i = 0; i < dim; i++) + for (int i = 0; i < dim; i++) { result->x[i] = ax[start - 1 + i]; + } PG_RETURN_POINTER(result); } @@ -876,18 +910,22 @@ static int halfvec_cmp_internal(HalfVector *a, HalfVector *b) /* Check values before dimensions to be consistent with Postgres arrays */ for (int i = 0; i < dim; i++) { - if (HalfToFloat4(a->x[i]) < HalfToFloat4(b->x[i])) + if (HalfToFloat4(a->x[i]) < HalfToFloat4(b->x[i])) { return -1; + } - if (HalfToFloat4(a->x[i]) > HalfToFloat4(b->x[i])) + if (HalfToFloat4(a->x[i]) > HalfToFloat4(b->x[i])) { return 1; + } } - if (a->dim < b->dim) + if (a->dim < b->dim) { return -1; + } - if (a->dim > b->dim) + if (a->dim > b->dim) { return 1; + } return 0; } @@ -1013,7 +1051,6 @@ Datum halfvec_accum(PG_FUNCTION_ARGS) } else { for (int i = 0; i < dim; i++) { double v = statevalues[i + 1] + (double)HalfToFloat4(x[i]); - /* Check for overflow */ if (isinf(v)) float_overflow_error(); @@ -1047,8 +1084,9 @@ Datum halfvec_avg(PG_FUNCTION_ARGS) n = statevalues[0]; /* SQL defines AVG of no values to be NULL */ - if (n == 0.0) + if (n == 0.0) { PG_RETURN_NULL(); + } /* Create half vector */ dim = STATE_DIMS(statearray); @@ -1078,8 +1116,9 @@ Datum sparsevec_to_halfvec(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, 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]] = Float4ToHalf(values[i]); + } PG_RETURN_POINTER(result); } diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index a35d457580..34d0aaccd5 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -31,9 +31,10 @@ typedef struct SparseInputElement { */ static inline void CheckDims(SparseVector *a, SparseVector *b) { - if (a->dim != b->dim) + if (a->dim != b->dim) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("different sparsevec dimensions %d and %d", a->dim, b->dim))); + } } /* @@ -41,8 +42,9 @@ static inline void CheckDims(SparseVector *a, SparseVector *b) */ static inline void CheckExpectedDim(int32 typmod, int dim) { - if (typmod != -1 && typmod != dim) + if (typmod != -1 && typmod != dim) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected %d dimensions, not %d", typmod, dim))); + } } /* @@ -50,12 +52,14 @@ static inline void CheckExpectedDim(int32 typmod, int dim) */ static inline void CheckDim(int dim) { - if (dim < 1) + if (dim < 1) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("sparsevec must have at least 1 dimension"))); + } - if (dim > SPARSEVEC_MAX_DIM) + if (dim > SPARSEVEC_MAX_DIM) { ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("sparsevec cannot have more than %d dimensions", SPARSEVEC_MAX_DIM))); + } } /* @@ -129,8 +133,9 @@ SparseVector *InitSparseVector(int dim, int nnz) */ static inline bool sparsevec_isspace(char ch) { - if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') { return true; + } return false; } @@ -139,11 +144,13 @@ static inline bool sparsevec_isspace(char ch) */ static int CompareIndices(const void *a, const void *b) { - if (((SparseInputElement *)a)->index < ((SparseInputElement *)b)->index) + if (((SparseInputElement *)a)->index < ((SparseInputElement *)b)->index) { return -1; + } - if (((SparseInputElement *)a)->index > ((SparseInputElement *)b)->index) + if (((SparseInputElement *)a)->index > ((SparseInputElement *)b)->index) { return 1; + } return 0; } @@ -167,8 +174,9 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) maxNnz = 1; while (*pt != '\0') { - if (*pt == ',') + if (*pt == ',') { maxNnz++; + } pt++; } @@ -181,8 +189,9 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt = lit; - while (sparsevec_isspace(*pt)) + while (sparsevec_isspace(*pt)) { pt++; + } if (*pt != '{') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -267,32 +276,37 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt = stringEnd; - while (sparsevec_isspace(*pt)) + while (sparsevec_isspace(*pt)) { pt++; + } - if (*pt == ',') + if (*pt == ',') { pt++; - else if (*pt == '}') { + } else if (*pt == '}') { pt++; break; - } else + } else { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); + } } } - while (sparsevec_isspace(*pt)) + while (sparsevec_isspace(*pt)) { pt++; + } - if (*pt != '/') + if (*pt != '/') { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type sparsevec: \"%s\"", lit), errdetail("Unexpected end of input."))); + } pt++; - while (sparsevec_isspace(*pt)) + while (sparsevec_isspace(*pt)) { pt++; + } /* Use similar logic as int2vectorin */ dim = strtol(pt, &stringEnd, 10); @@ -302,16 +316,18 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); /* Keep in int range for correct error message later */ - if (dim > INT_MAX) + if (dim > INT_MAX) { dim = INT_MAX; - else if (dim < INT_MIN) + } else if (dim < INT_MIN) { dim = INT_MIN; + } pt = stringEnd; /* Only whitespace is allowed after the closing brace */ - while (sparsevec_isspace(*pt)) + while (sparsevec_isspace(*pt)) { pt++; + } if (*pt != '\0') ereport(ERROR, @@ -751,7 +767,6 @@ Datum sparsevec_cosine_distance(PG_FUNCTION_ARGS) /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ similarity /= sqrt((double)norma * (double)normb); - #ifdef _MSC_VER /* /fp:fast may not propagate NaN */ if (isnan(similarity)) @@ -855,7 +870,6 @@ Datum sparsevec_l2_normalize(PG_FUNCTION_ARGS) norm += (double)ax[i] * (double)ax[i]; norm = sqrt(norm); - /* Return zero vector for zero norm */ if (norm > 0) { int zeros = 0; diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index e3786f1506..02cd2de357 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -147,8 +147,9 @@ Vector *InitVector(int dim) */ static inline bool vector_isspace(char ch) { - if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') + if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') { return true; + } return false; } @@ -188,8 +189,9 @@ Datum vector_in(PG_FUNCTION_ARGS) char *pt = lit; Vector *result; - while (vector_isspace(*pt)) + while (vector_isspace(*pt)) { pt++; + } if (*pt != '[') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -198,11 +200,13 @@ Datum vector_in(PG_FUNCTION_ARGS) pt++; - while (vector_isspace(*pt)) + while (vector_isspace(*pt)) { pt++; + } - if (*pt == ']') + if (*pt == ']') { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("vector must have at least 1 dimension"))); + } for (;;) { float val; @@ -212,8 +216,9 @@ Datum vector_in(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); - while (vector_isspace(*pt)) + while (vector_isspace(*pt)) { pt++; + } /* Check for empty string like float4in */ if (*pt == '\0') @@ -226,9 +231,10 @@ Datum vector_in(PG_FUNCTION_ARGS) /* Postgres sets LC_NUMERIC to C on startup */ val = strtof(pt, &stringEnd); - if (stringEnd == pt) + if (stringEnd == pt) { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type vector: \"%s\"", lit))); + } /* Check for range error like float4in */ if (errno == ERANGE && isinf(val)) @@ -243,14 +249,15 @@ Datum vector_in(PG_FUNCTION_ARGS) while (vector_isspace(*pt)) pt++; - if (*pt == ',') + if (*pt == ',') { pt++; - else if (*pt == ']') { + } else if (*pt == ']') { pt++; break; - } else + } else { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type vector: \"%s\"", lit))); + } } /* Only whitespace is allowed after the closing brace */ @@ -266,8 +273,9 @@ Datum vector_in(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, dim); result = InitVector(dim); - for (int i = 0; i < dim; i++) + for (int i = 0; i < dim; i++) { result->x[i] = x[i]; + } PG_RETURN_POINTER(result); } @@ -302,8 +310,9 @@ Datum vector_out(PG_FUNCTION_ARGS) AppendChar(ptr, '['); for (int i = 0; i < dim; i++) { - if (i > 0) + if (i > 0) { AppendChar(ptr, ','); + } AppendFloat(ptr, vector->x[i]); } @@ -338,16 +347,19 @@ Datum vector_typmod_in(PG_FUNCTION_ARGS) tl = ArrayGetIntegerTypmods(ta, &n); - if (n != 1) + if (n != 1) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid type modifier"))); + } - if (*tl < 1) + if (*tl < 1) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dimensions for type vector must be at least 1"))); + } - if (*tl > VECTOR_MAX_DIM) + if (*tl > VECTOR_MAX_DIM) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("dimensions for type vector cannot exceed %d", VECTOR_MAX_DIM))); + } PG_RETURN_INT32(*tl); } @@ -370,8 +382,9 @@ Datum vector_recv(PG_FUNCTION_ARGS) CheckDim(dim); CheckExpectedDim(typmod, dim); - if (unused != 0) + if (unused != 0) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("expected unused to be 0, not %d", unused))); + } result = InitVector(dim); for (int i = 0; i < dim; i++) { @@ -430,11 +443,13 @@ Datum array_to_vector(PG_FUNCTION_ARGS) Datum *elemsp; int nelemsp; - if (ARR_NDIM(array) > 1) + if (ARR_NDIM(array) > 1) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("array must be 1-D"))); + } - if (ARR_HASNULL(array) && array_contains_nulls(array)) + if (ARR_HASNULL(array) && array_contains_nulls(array)) { ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("array must not contain nulls"))); + } get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); @@ -467,8 +482,9 @@ Datum array_to_vector(PG_FUNCTION_ARGS) pfree(elemsp); /* Check elements */ - for (int i = 0; i < result->dim; i++) + for (int i = 0; i < result->dim; i++) { CheckElement(result->x[i]); + } PG_RETURN_POINTER(result); } @@ -485,8 +501,9 @@ Datum vector_to_float4(PG_FUNCTION_ARGS) datums = (Datum *)palloc(sizeof(Datum) * vec->dim); - for (int i = 0; i < vec->dim; i++) + for (int i = 0; i < vec->dim; i++) { datums[i] = Float4GetDatum(vec->x[i]); + } /* Use TYPALIGN_INT for float4 */ result = construct_array(datums, vec->dim, FLOAT4OID, sizeof(float4), true, TYPALIGN_INT); @@ -511,8 +528,9 @@ Datum halfvec_to_vector(PG_FUNCTION_ARGS) result = InitVector(vec->dim); - for (int i = 0; i < vec->dim; i++) + for (int i = 0; i < vec->dim; i++) { result->x[i] = HalfToFloat4(vec->x[i]); + } PG_RETURN_POINTER(result); } @@ -565,8 +583,9 @@ VECTOR_TARGET_CLONES static float VectorInnerProduct(int dim, float *ax, float * float distance = 0.0; /* Auto-vectorized */ - for (int i = 0; i < dim; i++) + for (int i = 0; i < dim; i++) { distance += ax[i] * bx[i]; + } return distance; } @@ -629,11 +648,11 @@ Datum cosine_distance(PG_FUNCTION_ARGS) CheckDims(a, b); similarity = VectorCosineSimilarity(a->dim, a->x, b->x); - #ifdef _MSC_VER /* /fp:fast may not propagate NaN */ - if (isnan(similarity)) + if (isnan(similarity)) { PG_RETURN_FLOAT8(NAN); + } #endif /* Keep in range */ @@ -660,12 +679,12 @@ Datum vector_spherical_distance(PG_FUNCTION_ARGS) CheckDims(a, b); distance = (double)VectorInnerProduct(a->dim, a->x, b->x); - /* Prevent NaN with acos with loss of precision */ - if (distance > 1) + if (distance > 1) { distance = 1; - else if (distance < -1) + } else if (distance < -1) { distance = -1; + } PG_RETURN_FLOAT8(acos(distance) / M_PI); } @@ -676,8 +695,9 @@ VECTOR_TARGET_CLONES static float VectorL1Distance(int dim, float *ax, float *bx float distance = 0.0; /* Auto-vectorized */ - for (int i = 0; i < dim; i++) + for (int i = 0; i < dim; i++) { distance += fabsf(ax[i] - bx[i]); + } return distance; } @@ -718,8 +738,9 @@ Datum vector_norm(PG_FUNCTION_ARGS) double norm = 0.0; /* Auto-vectorized */ - for (int i = 0; i < a->dim; i++) + for (int i = 0; i < a->dim; i++) { norm += (double)ax[i] * (double)ax[i]; + } PG_RETURN_FLOAT8(sqrt(norm)); } @@ -740,20 +761,22 @@ Datum l2_normalize(PG_FUNCTION_ARGS) rx = result->x; /* Auto-vectorized */ - for (int i = 0; i < a->dim; i++) + for (int i = 0; i < a->dim; i++) { norm += (double)ax[i] * (double)ax[i]; + } norm = sqrt(norm); - /* Return zero vector for zero norm */ if (norm > 0) { - for (int i = 0; i < a->dim; i++) + for (int i = 0; i < a->dim; i++) { rx[i] = ax[i] / norm; + } /* Check for overflow */ for (int i = 0; i < a->dim; i++) { - if (isinf(rx[i])) + if (isinf(rx[i])) { float_overflow_error(); + } } } @@ -779,13 +802,15 @@ Datum vector_add(PG_FUNCTION_ARGS) rx = result->x; /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) + for (int i = 0, imax = a->dim; i < imax; i++) { rx[i] = ax[i] + bx[i]; + } /* Check for overflow */ for (int i = 0, imax = a->dim; i < imax; i++) { - if (isinf(rx[i])) + if (isinf(rx[i])) { float_overflow_error(); + } } PG_RETURN_POINTER(result); @@ -810,13 +835,15 @@ Datum vector_sub(PG_FUNCTION_ARGS) rx = result->x; /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) + for (int i = 0, imax = a->dim; i < imax; i++) { rx[i] = ax[i] - bx[i]; + } /* Check for overflow */ for (int i = 0, imax = a->dim; i < imax; i++) { - if (isinf(rx[i])) + if (isinf(rx[i])) { float_overflow_error(); + } } PG_RETURN_POINTER(result); @@ -841,16 +868,19 @@ Datum vector_mul(PG_FUNCTION_ARGS) rx = result->x; /* Auto-vectorized */ - for (int i = 0, imax = a->dim; i < imax; i++) + for (int i = 0, imax = a->dim; i < imax; i++) { rx[i] = ax[i] * bx[i]; + } /* Check for overflow and underflow */ for (int i = 0, imax = a->dim; i < imax; i++) { - if (isinf(rx[i])) + if (isinf(rx[i])) { float_overflow_error(); + } - if (rx[i] == 0 && !(ax[i] == 0 || bx[i] == 0)) + if (rx[i] == 0 && !(ax[i] == 0 || bx[i] == 0)) { float_underflow_error(); + } } PG_RETURN_POINTER(result); @@ -870,11 +900,13 @@ Datum vector_concat(PG_FUNCTION_ARGS) CheckDim(dim); result = InitVector(dim); - for (int i = 0; i < a->dim; i++) + for (int i = 0; i < a->dim; i++) { result->x[i] = a->x[i]; + } - for (int i = 0; i < b->dim; i++) + for (int i = 0; i < b->dim; i++) { result->x[i + a->dim] = b->x[i]; + } PG_RETURN_POINTER(result); } @@ -890,8 +922,9 @@ Datum binary_quantize(PG_FUNCTION_ARGS) VarBit *result = InitBitVector(a->dim); unsigned char *rx = VARBITS(result); - for (int i = 0; i < a->dim; i++) + for (int i = 0; i < a->dim; i++) { rx[i / 8] |= (ax[i] > 0) << (7 - (i % 8)); + } PG_RETURN_VARBIT_P(result); } @@ -910,30 +943,34 @@ Datum subvector(PG_FUNCTION_ARGS) Vector *result; int dim; - if (count < 1) + if (count < 1) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("vector must have at least 1 dimension"))); + } /* * Check if (start + count > a->dim), avoiding integer overflow. a->dim * and count are both positive, so a->dim - count won't overflow. */ - if (start > a->dim - count) + if (start > a->dim - count) { end = a->dim + 1; - else + } else { end = start + count; + } /* Indexing starts at 1, like substring */ - if (start < 1) + if (start < 1) { start = 1; - else if (start > a->dim) + } else if (start > a->dim) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("vector must have at least 1 dimension"))); + } dim = end - start; CheckDim(dim); result = InitVector(dim); - for (int i = 0; i < dim; i++) + for (int i = 0; i < dim; i++) { result->x[i] = ax[start - 1 + i]; + } PG_RETURN_POINTER(result); } @@ -947,18 +984,22 @@ int vector_cmp_internal(Vector *a, Vector *b) /* Check values before dimensions to be consistent with Postgres arrays */ for (int i = 0; i < dim; i++) { - if (a->x[i] < b->x[i]) + if (a->x[i] < b->x[i]) { return -1; + } - if (a->x[i] > b->x[i]) + if (a->x[i] > b->x[i]) { return 1; + } } - if (a->dim < b->dim) + if (a->dim < b->dim) { return -1; + } - if (a->dim > b->dim) + if (a->dim > b->dim) { return 1; + } return 0; } @@ -1068,10 +1109,11 @@ Datum vector_accum(PG_FUNCTION_ARGS) dim = STATE_DIMS(statearray); newarr = dim == 0; - if (newarr) + if (newarr) { dim = newval->dim; - else + } else { CheckExpectedDim(dim, newval->dim); + } n = statevalues[0] + 1.0; @@ -1079,15 +1121,17 @@ Datum vector_accum(PG_FUNCTION_ARGS) statedatums[0] = Float8GetDatum(n); if (newarr) { - for (int i = 0; i < dim; i++) + for (int i = 0; i < dim; i++) { statedatums[i + 1] = Float8GetDatum((double)x[i]); + } } else { for (int i = 0; i < dim; i++) { double v = statevalues[i + 1] + x[i]; /* Check for overflow */ - if (isinf(v)) + if (isinf(v)) { float_overflow_error(); + } statedatums[i + 1] = Float8GetDatum(v); } @@ -1180,8 +1224,9 @@ Datum vector_avg(PG_FUNCTION_ARGS) n = statevalues[0]; /* SQL defines AVG of no values to be NULL */ - if (n == 0.0) + if (n == 0.0) { PG_RETURN_NULL(); + } /* Create vector */ dim = STATE_DIMS(statearray); @@ -1211,8 +1256,9 @@ Datum sparsevec_to_vector(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, 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]] = values[i]; + } PG_RETURN_POINTER(result); } @@ -1240,8 +1286,9 @@ void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, B BlockNumber blkno; flags = REGBUF_FORCE_IMAGE; - if (page_std) + if (page_std) { flags |= REGBUF_STANDARD; + } /* * Iterate over all the pages in the range. They are collected into @@ -1271,16 +1318,18 @@ void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, B * would change the LSN, and we don't want that. We want the page * to stay empty. */ - if (!PageIsNew(BufferGetPage(buf))) + if (!PageIsNew(BufferGetPage(buf))) { bufpack[nbufs++] = buf; - else + } else { UnlockReleaseBuffer(buf); + } blkno++; } /* Nothing more to do if all remaining blocks were empty. */ - if (nbufs == 0) + if (nbufs == 0) { break; + } /* Write WAL record for this batch. */ XLogBeginInsert(); diff --git a/src/gausskernel/storage/access/datavec/bitutils.cpp b/src/gausskernel/storage/access/datavec/bitutils.cpp index c2f59152fa..4c6e1a827c 100644 --- a/src/gausskernel/storage/access/datavec/bitutils.cpp +++ b/src/gausskernel/storage/access/datavec/bitutils.cpp @@ -37,12 +37,11 @@ #define popcount64(x) pg_popcount64(x) #endif -BIT_TARGET_CLONES static uint64 -BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance) +BIT_TARGET_CLONES static uint64 BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, + uint64 distance) { #ifdef popcount64 - for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) - { + for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) { uint64 axs; uint64 bxs; @@ -64,14 +63,14 @@ BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui } #ifdef BIT_DISPATCH -TARGET_AVX512_POPCOUNT static uint64 -BitHammingDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance) +TARGET_AVX512_POPCOUNT static uint64 BitHammingDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, + unsigned char *bx, uint64 distance) { - __m512i dist = _mm512_setzero_si512(); + __m512i dist = _mm512_setzero_si512(); for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) { - __m512i axs = _mm512_loadu_si512((const __m512i *) ax); - __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + __m512i axs = _mm512_loadu_si512((const __m512i *)ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *)bx); dist = _mm512_add_epi64(dist, _mm512_popcnt_epi64(_mm512_xor_si512(axs, bxs))); @@ -85,8 +84,8 @@ BitHammingDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char } #endif -BIT_TARGET_CLONES static double -BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) +BIT_TARGET_CLONES static double BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, + uint64 aa, uint64 bb) { #ifdef popcount64 for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) { @@ -115,20 +114,21 @@ BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, ui if (ab == 0) return 1; else - return 1 - (ab / ((double) (aa + bb - ab))); + return 1 - (ab / ((double)(aa + bb - ab))); } #ifdef BIT_DISPATCH -TARGET_AVX512_POPCOUNT static double -BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb) +TARGET_AVX512_POPCOUNT static double BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, + unsigned char *bx, uint64 ab, uint64 aa, + uint64 bb) { __m512i abx = _mm512_setzero_si512(); __m512i aax = _mm512_setzero_si512(); - __m512i bbx = _mm512_setzero_si512(); + __m512i bbx = _mm512_setzero_si512(); for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i)) { - __m512i axs = _mm512_loadu_si512((const __m512i *) ax); - __m512i bxs = _mm512_loadu_si512((const __m512i *) bx); + __m512i axs = _mm512_loadu_si512((const __m512i *)ax); + __m512i bxs = _mm512_loadu_si512((const __m512i *)bx); abx = _mm512_add_epi64(abx, _mm512_popcnt_epi64(_mm512_and_si512(axs, bxs))); aax = _mm512_add_epi64(aax, _mm512_popcnt_epi64(axs)); @@ -147,9 +147,9 @@ BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char #endif #ifdef BIT_DISPATCH -#define CPU_FEATURE_OSXSAVE (1 << 27) /* F1 ECX */ -#define CPU_FEATURE_AVX512F (1 << 16) /* F7,0 EBX */ -#define CPU_FEATURE_AVX512VPOPCNTDQ (1 << 14) /* F7,0 ECX */ +#define CPU_FEATURE_OSXSAVE (1 << 27) /* F1 ECX */ +#define CPU_FEATURE_AVX512F (1 << 16) /* F7,0 EBX */ +#define CPU_FEATURE_AVX512VPOPCNTDQ (1 << 14) /* F7,0 ECX */ #ifdef _MSC_VER #define TARGET_XSAVE @@ -157,8 +157,7 @@ BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char #define TARGET_XSAVE __attribute__((target("xsave"))) #endif -TARGET_XSAVE static bool -SupportsAvx512Popcount() +TARGET_XSAVE static bool SupportsAvx512Popcount() { unsigned int exx[4] = {0, 0, 0, 0}; @@ -191,8 +190,7 @@ SupportsAvx512Popcount() } #endif -void -BitvecInit(void) +void BitvecInit(void) { /* * Could skip pointer when single function, but no difference in diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp index 29d2827df0..0a386f30d4 100644 --- a/src/gausskernel/storage/access/datavec/hnsw.cpp +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -18,33 +18,29 @@ static THR_LOCAL bool HnswNeedInitialization = true; /* * Initialize index options and variables */ -void -HnswInit(void) +void HnswInit(void) { hnsw_relopt_kind = RELOPT_KIND_DATAVEC; - add_int_reloption(hnsw_relopt_kind, "m", "Max number of connections", - HNSW_DEFAULT_M, HNSW_MIN_M, HNSW_MAX_M); + add_int_reloption(hnsw_relopt_kind, "m", "Max number of connections", HNSW_DEFAULT_M, HNSW_MIN_M, HNSW_MAX_M); add_int_reloption(hnsw_relopt_kind, "ef_construction", "Size of the dynamic candidate list for construction", HNSW_DEFAULT_EF_CONSTRUCTION, HNSW_MIN_EF_CONSTRUCTION, HNSW_MAX_EF_CONSTRUCTION); - add_int_reloption(hnsw_relopt_kind, "pq_m", "Number of PQ subquantizer", - HNSW_DEFAULT_PQ_M, HNSW_MIN_PQ_M, HNSW_MAX_PQ_M); - add_int_reloption(hnsw_relopt_kind, "pq_ksub", "Number of centroids for each PQ subquantizer", - HNSW_DEFAULT_PQ_KSUB, HNSW_MIN_PQ_KSUB, HNSW_MAX_PQ_KSUB); + add_int_reloption(hnsw_relopt_kind, "pq_m", "Number of PQ subquantizer", HNSW_DEFAULT_PQ_M, HNSW_MIN_PQ_M, + HNSW_MAX_PQ_M); + add_int_reloption(hnsw_relopt_kind, "pq_ksub", "Number of centroids for each PQ subquantizer", HNSW_DEFAULT_PQ_KSUB, + HNSW_MIN_PQ_KSUB, HNSW_MAX_PQ_KSUB); add_bool_reloption(hnsw_relopt_kind, "enable_pq", "Whether to enable PQ", HNSW_DEFAULT_ENABLE_PQ); } /* * Estimate the cost of an index scan */ -static void -hnswcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, - Cost *indexStartupCost, Cost *indexTotalCost, - Selectivity *indexSelectivity, double *indexCorrelation) +static void hnswcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, + Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation) { GenericCosts costs; int m; int entryLevel; - Relation index; + Relation index; /* Never use index without order */ if (path->indexorderbys == NULL) { @@ -62,14 +58,14 @@ hnswcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, index_close(index, NoLock); /* Approximate entry level */ - entryLevel = (int) -log(1.0 / path->indexinfo->tuples) * HnswGetMl(m); + entryLevel = (int)-log(1.0 / path->indexinfo->tuples) * HnswGetMl(m); /* TODO Improve estimate of visited tuples (currently underestimates) */ /* Account for number of tuples (or entry level), m, and ef_search */ costs.numIndexTuples = (entryLevel + 2) * m; - genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, - &costs.indexTotalCost, &costs.indexSelectivity, &costs.indexCorrelation); + genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, &costs.indexTotalCost, + &costs.indexSelectivity, &costs.indexCorrelation); /* Use total cost since most work happens before first tuple is returned */ *indexStartupCost = costs.indexTotalCost; @@ -81,8 +77,7 @@ hnswcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, /* * Parse and validate the reloptions */ -static bytea * -hnswoptions_internal(Datum reloptions, bool validate) +static bytea *hnswoptions_internal(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"m", RELOPT_TYPE_INT, offsetof(HnswOptions, m)}, @@ -91,14 +86,10 @@ hnswoptions_internal(Datum reloptions, bool validate) {"pq_m", RELOPT_TYPE_INT, offsetof(HnswOptions, pqM)}, {"pq_ksub", RELOPT_TYPE_INT, offsetof(HnswOptions, pqKsub)}, {"parallel_workers", RELOPT_TYPE_INT, offsetof(StdRdOptions, parallel_workers)}, - {"storage_type", RELOPT_TYPE_STRING, offsetof(HnswOptions, storage_type)} - }; + {"storage_type", RELOPT_TYPE_STRING, offsetof(HnswOptions, storage_type)}}; #if PG_VERSION_NUM >= 130000 - return (bytea *) build_reloptions(reloptions, validate, - hnsw_relopt_kind, - sizeof(HnswOptions), - tab, lengthof(tab)); + return (bytea *)build_reloptions(reloptions, validate, hnsw_relopt_kind, sizeof(HnswOptions), tab, lengthof(tab)); #else relopt_value *options; int numoptions; @@ -110,18 +101,16 @@ hnswoptions_internal(Datum reloptions, bool validate) } options = parseRelOptions(reloptions, validate, hnsw_relopt_kind, &numoptions); rdopts = (HnswOptions *)allocateReloptStruct(sizeof(HnswOptions), options, numoptions); - fillRelOptions((void *) rdopts, sizeof(HnswOptions), options, numoptions, - validate, tab, lengthof(tab)); + fillRelOptions((void *)rdopts, sizeof(HnswOptions), options, numoptions, validate, tab, lengthof(tab)); - return (bytea *) rdopts; + return (bytea *)rdopts; #endif } /* * Validate catalog entries for the specified operator class */ -static bool -hnswvalidate_internal(Oid opclassoid) +static bool hnswvalidate_internal(Oid opclassoid) { return true; } @@ -132,8 +121,7 @@ hnswvalidate_internal(Oid opclassoid) * See https://www.postgresql.org/docs/current/index-api.html */ PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswhandler); -Datum -hnswhandler(PG_FUNCTION_ARGS) +Datum hnswhandler(PG_FUNCTION_ARGS) { IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); @@ -144,7 +132,7 @@ hnswhandler(PG_FUNCTION_ARGS) #endif amroutine->amcanorder = false; amroutine->amcanorderbyop = true; - amroutine->amcanbackward = false; /* can change direction mid-scan */ + amroutine->amcanbackward = false; /* can change direction mid-scan */ amroutine->amcanunique = false; amroutine->amcanmulticol = false; amroutine->amoptionalkey = true; @@ -194,8 +182,7 @@ hnswhandler(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbuild); -Datum -hnswbuild(PG_FUNCTION_ARGS) +Datum hnswbuild(PG_FUNCTION_ARGS) { Relation heap = (Relation)PG_GETARG_POINTER(0); Relation index = (Relation)PG_GETARG_POINTER(1); @@ -206,8 +193,7 @@ hnswbuild(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbuildempty); -Datum -hnswbuildempty(PG_FUNCTION_ARGS) +Datum hnswbuildempty(PG_FUNCTION_ARGS) { Relation index = (Relation)PG_GETARG_POINTER(0); hnswbuildempty_internal(index); @@ -216,11 +202,10 @@ hnswbuildempty(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswinsert); -Datum -hnswinsert(PG_FUNCTION_ARGS) +Datum hnswinsert(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); - Datum * values = (Datum *)PG_GETARG_POINTER(1); + Datum *values = (Datum *)PG_GETARG_POINTER(1); bool *isnull = (bool *)PG_GETARG_POINTER(2); ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); Relation heaprel = (Relation)PG_GETARG_POINTER(4); @@ -231,8 +216,7 @@ hnswinsert(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbulkdelete); -Datum -hnswbulkdelete(PG_FUNCTION_ARGS) +Datum hnswbulkdelete(PG_FUNCTION_ARGS) { IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); @@ -244,8 +228,7 @@ hnswbulkdelete(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswvacuumcleanup); -Datum -hnswvacuumcleanup(PG_FUNCTION_ARGS) +Datum hnswvacuumcleanup(PG_FUNCTION_ARGS) { IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); @@ -255,8 +238,7 @@ hnswvacuumcleanup(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswcostestimate); -Datum -hnswcostestimate(PG_FUNCTION_ARGS) +Datum hnswcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); @@ -267,12 +249,11 @@ hnswcostestimate(PG_FUNCTION_ARGS) double *correlation = (double *)PG_GETARG_POINTER(6); hnswcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); - PG_RETURN_VOID(); + PG_RETURN_VOID(); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswoptions); -Datum -hnswoptions(PG_FUNCTION_ARGS) +Datum hnswoptions(PG_FUNCTION_ARGS) { Datum reloptions = PG_GETARG_DATUM(0); bool validate = PG_GETARG_BOOL(1); @@ -285,8 +266,7 @@ hnswoptions(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswvalidate); -Datum -hnswvalidate(PG_FUNCTION_ARGS) +Datum hnswvalidate(PG_FUNCTION_ARGS) { Oid opclassoid = PG_GETARG_OID(0); bool result = hnswvalidate_internal(opclassoid); @@ -295,8 +275,7 @@ hnswvalidate(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswbeginscan); -Datum -hnswbeginscan(PG_FUNCTION_ARGS) +Datum hnswbeginscan(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); int nkeys = PG_GETARG_INT32(1); @@ -307,8 +286,7 @@ hnswbeginscan(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswrescan); -Datum -hnswrescan(PG_FUNCTION_ARGS) +Datum hnswrescan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); @@ -321,23 +299,22 @@ hnswrescan(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswgettuple); -Datum -hnswgettuple(PG_FUNCTION_ARGS) +Datum hnswgettuple(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); if (NULL == scan) - ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function hnswgettuple"))); - + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function hnswgettuple"))); + bool result = hnswgettuple_internal(scan, direction); PG_RETURN_BOOL(result); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswendscan); -Datum -hnswendscan(PG_FUNCTION_ARGS) +Datum hnswendscan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); hnswendscan_internal(scan); @@ -346,12 +323,11 @@ hnswendscan(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnswdelete); -Datum -hnswdelete(PG_FUNCTION_ARGS) +Datum hnswdelete(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); Datum *values = (Datum *)PG_GETARG_POINTER(1); - const bool* isnull = (const bool*)PG_GETARG_POINTER(2); + const bool *isnull = (const bool *)PG_GETARG_POINTER(2); ItemPointer heapTCtid = (ItemPointer)PG_GETARG_POINTER(3); bool isRollbackIndex = (bool)PG_GETARG_POINTER(4); diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp index e1547b65e0..d2621e8824 100644 --- a/src/gausskernel/storage/access/datavec/hnswbuild.cpp +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -67,9 +67,9 @@ #include "utils/wait_event.h" #endif -#define PARALLEL_KEY_HNSW_SHARED UINT64CONST(0xA000000000000001) -#define PARALLEL_KEY_HNSW_AREA UINT64CONST(0xA000000000000002) -#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000003) +#define PARALLEL_KEY_HNSW_SHARED UINT64CONST(0xA000000000000001) +#define PARALLEL_KEY_HNSW_AREA UINT64CONST(0xA000000000000002) +#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000003) #define PROGRESS_CREATEIDX_TUPLES_DONE 0 #if PG_VERSION_NUM < 130000 @@ -79,8 +79,7 @@ /* * Create the metapage */ -static void -CreateMetaPage(HnswBuildState * buildstate) +static void CreateMetaPage(HnswBuildState *buildstate) { Relation index = buildstate->index; ForkNumber forkNum = buildstate->forkNum; @@ -107,8 +106,7 @@ CreateMetaPage(HnswBuildState * buildstate) metap->entryOffno = InvalidOffsetNumber; metap->entryLevel = -1; metap->insertPage = InvalidBlockNumber; - ((PageHeader) page)->pd_lower = - ((char *) metap + sizeof(HnswMetaPageData)) - (char *) page; + ((PageHeader)page)->pd_lower = ((char *)metap + sizeof(HnswMetaPageData)) - (char *)page; MarkBufferDirty(buf); UnlockReleaseBuffer(buf); @@ -117,8 +115,7 @@ CreateMetaPage(HnswBuildState * buildstate) /* * Create the append metapage */ -static void -CreateAppendMetaPage(HnswBuildState *buildstate) +static void CreateAppendMetaPage(HnswBuildState *buildstate) { Relation index = buildstate->index; ForkNumber forkNum = buildstate->forkNum; @@ -150,8 +147,8 @@ CreateAppendMetaPage(HnswBuildState *buildstate) if (buildstate->enablePQ) { appMetap->centerTableSize = (uint32)buildstate->dimensions * sizeof(float); appMetap->pqTableSize = (uint32)buildstate->dimensions * buildstate->pqKsub * sizeof(float); - appMetap->pqTableNblk = (uint16)((appMetap->pqTableSize + HNSW_PQTABLE_STORAGE_SIZE - 1) / - HNSW_PQTABLE_STORAGE_SIZE); + appMetap->pqTableNblk = + (uint16)((appMetap->pqTableSize + HNSW_PQTABLE_STORAGE_SIZE - 1) / HNSW_PQTABLE_STORAGE_SIZE); } else { appMetap->centerTableSize = 0; appMetap->pqTableSize = 0; @@ -159,15 +156,15 @@ CreateAppendMetaPage(HnswBuildState *buildstate) } /* set slot info */ - appMetap->npages = (HNSW_DEFAULT_NPAGES_PER_SLOT * slotTypeNum) < - (g_instance.attr.attr_storage.NBuffers / HNSW_BUFFER_THRESHOLD) ? HNSW_DEFAULT_NPAGES_PER_SLOT : - (g_instance.attr.attr_storage.NBuffers / (slotTypeNum * HNSW_BUFFER_THRESHOLD)); + appMetap->npages = + (HNSW_DEFAULT_NPAGES_PER_SLOT * slotTypeNum) < (g_instance.attr.attr_storage.NBuffers / HNSW_BUFFER_THRESHOLD) + ? HNSW_DEFAULT_NPAGES_PER_SLOT + : (g_instance.attr.attr_storage.NBuffers / (slotTypeNum * HNSW_BUFFER_THRESHOLD)); appMetap->slotStartBlkno = HNSW_PQTABLE_START_BLKNO + appMetap->pqTableNblk; appMetap->elementInsertSlot = InvalidBlockNumber; appMetap->neighborInsertSlot = InvalidBlockNumber; - ((PageHeader) page)->pd_lower = - ((char *) appMetap + sizeof(HnswAppendMetaPageData)) - (char *) page; + ((PageHeader)page)->pd_lower = ((char *)appMetap + sizeof(HnswAppendMetaPageData)) - (char *)page; MarkBufferDirty(buf); UnlockReleaseBuffer(buf); @@ -176,8 +173,7 @@ CreateAppendMetaPage(HnswBuildState *buildstate) /* * Add a new page */ -static void -HnswBuildAppendPage(Relation index, Buffer *buf, Page *page, ForkNumber forkNum) +static void HnswBuildAppendPage(Relation index, Buffer *buf, Page *page, ForkNumber forkNum) { /* Add a new page */ Buffer newbuf = HnswNewBuffer(index, forkNum); @@ -204,8 +200,7 @@ HnswBuildAppendPage(Relation index, Buffer *buf, Page *page, ForkNumber forkNum) /* * Create graph pages */ -static void -CreateGraphPages(HnswBuildState * buildstate) +static void CreateGraphPages(HnswBuildState *buildstate) { Relation index = buildstate->index; ForkNumber forkNum = buildstate->forkNum; @@ -218,7 +213,7 @@ CreateGraphPages(HnswBuildState * buildstate) Page page; HnswElementPtr iter = buildstate->graph->head; char *base = buildstate->hnswarea; - IndexTransInfo* idxXid; + IndexTransInfo *idxXid; /* Calculate sizes */ maxSize = HNSW_MAX_SIZE; @@ -288,13 +283,13 @@ CreateGraphPages(HnswBuildState * buildstate) if (buildstate->isUStore) { ((PageHeader)page)->pd_upper -= sizeof(IndexTransInfo); - idxXid = (IndexTransInfo*)(((char*)page) + ((PageHeader)page)->pd_upper); + idxXid = (IndexTransInfo *)(((char *)page) + ((PageHeader)page)->pd_upper); idxXid->xmin = FrozenTransactionId; idxXid->xmax = InvalidTransactionId; } /* Add element */ - if (PageAddItem(page, (Item) etup, etupSize, InvalidOffsetNumber, false, false) != element->offno) { + if (PageAddItem(page, (Item)etup, etupSize, InvalidOffsetNumber, false, false) != element->offno) { elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); } @@ -306,7 +301,7 @@ CreateGraphPages(HnswBuildState * buildstate) } } /* Add placeholder for neighbors */ - if (PageAddItem(page, (Item) ntup, ntupSize, InvalidOffsetNumber, false, false) != element->neighborOffno) { + if (PageAddItem(page, (Item)ntup, ntupSize, InvalidOffsetNumber, false, false) != element->neighborOffno) { elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); } } @@ -327,8 +322,7 @@ CreateGraphPages(HnswBuildState * buildstate) /* * Write neighbor tuples */ -static void -WriteNeighborTuples(HnswBuildState * buildstate) +static void WriteNeighborTuples(HnswBuildState *buildstate) { Relation index = buildstate->index; ForkNumber forkNum = buildstate->forkNum; @@ -362,7 +356,7 @@ WriteNeighborTuples(HnswBuildState * buildstate) HnswSetNeighborTuple(base, ntup, element, m); - if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) + if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item)ntup, ntupSize)) elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); /* Commit */ @@ -376,8 +370,7 @@ WriteNeighborTuples(HnswBuildState * buildstate) /* * Flush pages */ -static void -FlushPages(HnswBuildState * buildstate) +static void FlushPages(HnswBuildState *buildstate) { #ifdef HNSW_MEMORY elog(INFO, "memory: %zu MB", buildstate->graph->memoryUsed / (1024 * 1024)); @@ -394,8 +387,7 @@ FlushPages(HnswBuildState * buildstate) /* * Add a heap TID to an existing element */ -static bool -AddDuplicateInMemory(HnswElement element, HnswElement dup) +static bool AddDuplicateInMemory(HnswElement element, HnswElement dup) { LWLockAcquire(&dup->lock, LW_EXCLUSIVE); @@ -414,8 +406,7 @@ AddDuplicateInMemory(HnswElement element, HnswElement dup) /* * Find duplicate element */ -static bool -FindDuplicateInMemory(char *base, HnswElement element) +static bool FindDuplicateInMemory(char *base, HnswElement element) { HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); Datum value = HnswGetValue(base, element); @@ -440,8 +431,7 @@ FindDuplicateInMemory(char *base, HnswElement element) /* * Add to element list */ -static void -AddElementInMemory(char *base, HnswGraph * graph, HnswElement element) +static void AddElementInMemory(char *base, HnswGraph *graph, HnswElement element) { SpinLockAcquire(&graph->lock); element->next = graph->head; @@ -452,8 +442,7 @@ AddElementInMemory(char *base, HnswGraph * graph, HnswElement element) /* * Update neighbors */ -static void -UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswElement e, int m) +static void UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswElement e, int m) { for (int lc = e->level; lc >= 0; lc--) { int lm = HnswGetLayerM(m, lc); @@ -477,8 +466,8 @@ UpdateNeighborsInMemory(char *base, FmgrInfo *procinfo, Oid collation, HnswEleme /* * Update graph in memory */ -static void -UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, HnswBuildState * buildstate) +static void UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, + HnswElement entryPoint, HnswBuildState *buildstate) { HnswGraph *graph = buildstate->graph; char *base = buildstate->hnswarea; @@ -501,8 +490,7 @@ UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement element, int /* * Insert tuple in memory */ -static void -InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) +static void InsertTupleInMemory(HnswBuildState *buildstate, HnswElement element) { FmgrInfo *procinfo = buildstate->procinfo; Oid collation = buildstate->collation; @@ -549,8 +537,8 @@ InsertTupleInMemory(HnswBuildState * buildstate, HnswElement element) /* * Insert tuple */ -static bool -InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heaptid, HnswBuildState * buildstate) +static bool InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heaptid, + HnswBuildState *buildstate) { const HnswTypeInfo *typeInfo = buildstate->typeInfo; HnswGraph *graph = buildstate->graph; @@ -606,10 +594,10 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heapt LWLockAcquire(flushLock, LW_EXCLUSIVE); if (!graph->flushed) { - ereport(NOTICE, - (errmsg("hnsw graph no longer fits into maintenance_work_mem after " INT64_FORMAT " tuples", (int64) graph->indtuples), - errdetail("Building will take significantly more time."), - errhint("Increase maintenance_work_mem to speed up builds."))); + ereport(NOTICE, (errmsg("hnsw graph no longer fits into maintenance_work_mem after " INT64_FORMAT " tuples", + (int64)graph->indtuples), + errdetail("Building will take significantly more time."), + errhint("Increase maintenance_work_mem to speed up builds."))); FlushPages(buildstate); } @@ -649,11 +637,10 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heapt /* * Callback for table_index_build_scan */ -static void -BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, - const bool *isnull, bool tupleIsAlive, void *state) +static void BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, const bool *isnull, bool tupleIsAlive, + void *state) { - HnswBuildState *buildstate = (HnswBuildState *) state; + HnswBuildState *buildstate = (HnswBuildState *)state; HnswGraph *graph = buildstate->graph; MemoryContext oldCtx; @@ -684,11 +671,10 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, /* * Initialize the graph */ -static void -InitGraph(HnswGraph * graph, char *base, long memoryTotal) +static void InitGraph(HnswGraph *graph, char *base, long memoryTotal) { - HnswPtrStore(base, graph->head, (HnswElement) NULL); - HnswPtrStore(base, graph->entryPoint, (HnswElement) NULL); + HnswPtrStore(base, graph->head, (HnswElement)NULL); + HnswPtrStore(base, graph->entryPoint, (HnswElement)NULL); graph->memoryUsed = 0; graph->memoryTotal = memoryTotal; graph->flushed = false; @@ -703,8 +689,7 @@ InitGraph(HnswGraph * graph, char *base, long memoryTotal) /* * Initialize an allocator */ -static void -InitAllocator(HnswAllocator * allocator, void *(*alloc) (Size size, void *state), void *state) +static void InitAllocator(HnswAllocator *allocator, void *(*alloc)(Size size, void *state), void *state) { allocator->alloc = alloc; allocator->state = state; @@ -713,11 +698,10 @@ InitAllocator(HnswAllocator * allocator, void *(*alloc) (Size size, void *state) /* * Memory context allocator */ -static void * -HnswMemoryContextAlloc(Size size, void *state) +static void *HnswMemoryContextAlloc(Size size, void *state) { - HnswBuildState *buildstate = (HnswBuildState *) state; - void *chunk = MemoryContextAlloc(buildstate->graphCtx, size); + HnswBuildState *buildstate = (HnswBuildState *)state; + void *chunk = MemoryContextAlloc(buildstate->graphCtx, size); #if PG_VERSION_NUM >= 130000 buildstate->graphData.memoryUsed = MemoryContextMemAllocated(buildstate->graphCtx, false); @@ -731,10 +715,9 @@ HnswMemoryContextAlloc(Size size, void *state) /* * Shared memory allocator */ -static void * -HnswSharedMemoryAlloc(Size size, void *state) +static void *HnswSharedMemoryAlloc(Size size, void *state) { - HnswBuildState *buildstate = (HnswBuildState *) state; + HnswBuildState *buildstate = (HnswBuildState *)state; void *chunk = buildstate->hnswarea + buildstate->graph->memoryUsed; buildstate->graph->memoryUsed += MAXALIGN(size); @@ -744,8 +727,8 @@ HnswSharedMemoryAlloc(Size size, void *state) /* * Initialize the build state */ -static void -InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, IndexInfo *indexInfo, ForkNumber forkNum) +static void InitBuildState(HnswBuildState *buildstate, Relation heap, Relation index, IndexInfo *indexInfo, + ForkNumber forkNum) { buildstate->heap = heap; buildstate->index = index; @@ -788,12 +771,10 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index buildstate->ml = HnswGetMl(buildstate->m); buildstate->maxLevel = HnswGetMaxLevel(buildstate->m); - buildstate->graphCtx = AllocSetContextCreate(CurrentMemoryContext, - "Hnsw build graph context", - ALLOCSET_DEFAULT_SIZES); - buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, - "Hnsw build temporary context", - ALLOCSET_DEFAULT_SIZES); + buildstate->graphCtx = + AllocSetContextCreate(CurrentMemoryContext, "Hnsw build graph context", ALLOCSET_DEFAULT_SIZES); + buildstate->tmpCtx = + AllocSetContextCreate(CurrentMemoryContext, "Hnsw build temporary context", ALLOCSET_DEFAULT_SIZES); InitAllocator(&buildstate->allocator, &HnswMemoryContextAlloc, buildstate); @@ -814,15 +795,13 @@ InitBuildState(HnswBuildState * buildstate, Relation heap, Relation index, Index /* * Free resources */ -static void -FreeBuildState(HnswBuildState * buildstate) +static void FreeBuildState(HnswBuildState *buildstate) { MemoryContextDelete(buildstate->graphCtx); MemoryContextDelete(buildstate->tmpCtx); } -static double -ParallelHeapScan(HnswBuildState * buildstate, int* nparticipanttuplesorts) +static double ParallelHeapScan(HnswBuildState *buildstate, int *nparticipanttuplesorts) { HnswShared *hnswshared = buildstate->hnswleader->hnswshared; double reltuples; @@ -841,13 +820,12 @@ ParallelHeapScan(HnswBuildState * buildstate, int* nparticipanttuplesorts) /* * Perform a worker's portion of a parallel insert */ -static void -HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared * hnswshared, char *hnswarea) +static void HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared *hnswshared, char *hnswarea) { HnswBuildState buildstate; TableScanDesc scan; double reltuples; - IndexInfo *indexInfo; + IndexInfo *indexInfo; /* Join parallel scan */ indexInfo = BuildIndexInfo(indexRel); @@ -856,8 +834,7 @@ HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared * hnsw buildstate.hnswarea = hnswarea; InitAllocator(&buildstate.allocator, &HnswSharedMemoryAlloc, &buildstate); scan = tableam_scan_begin_parallel(heapRel, &hnswshared->heapdesc); - reltuples = tableam_index_build_scan(heapRel, indexRel, indexInfo, - true, BuildCallback, (void *) &buildstate, scan); + reltuples = tableam_index_build_scan(heapRel, indexRel, indexInfo, true, BuildCallback, (void *)&buildstate, scan); /* Record statistics */ SpinLockAcquire(&hnswshared->mutex); @@ -871,8 +848,7 @@ HnswParallelScanAndInsert(Relation heapRel, Relation indexRel, HnswShared * hnsw /* * Perform work within a launched parallel process */ -void -HnswParallelBuildMain(const BgWorkerContext *bwc) +void HnswParallelBuildMain(const BgWorkerContext *bwc) { HnswShared *hnswshared; char *hnswarea; @@ -880,7 +856,7 @@ HnswParallelBuildMain(const BgWorkerContext *bwc) Relation indexRel; /* Look up shared state */ - hnswshared = (HnswShared*)bwc->bgshared; + hnswshared = (HnswShared *)bwc->bgshared; /* Open relations within worker */ heapRel = heap_open(hnswshared->heaprelid, NoLock); @@ -899,14 +875,12 @@ HnswParallelBuildMain(const BgWorkerContext *bwc) /* * End parallel build */ -static void -HnswEndParallel() +static void HnswEndParallel() { BgworkerListSyncQuit(); } -static HnswShared* -HnswParallelInitshared(HnswBuildState * buildstate) +static HnswShared *HnswParallelInitshared(HnswBuildState *buildstate) { HnswShared *hnswshared; char *hnswarea; @@ -914,7 +888,8 @@ HnswParallelInitshared(HnswBuildState * buildstate) Size estother; /* Store shared build state, for which we reserved space */ - hnswshared = (HnswShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(HnswShared)); + hnswshared = + (HnswShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(HnswShared)); /* Initialize immutable state */ hnswshared->heaprelid = RelationGetRelid(buildstate->heap); @@ -933,7 +908,7 @@ HnswParallelInitshared(HnswBuildState * buildstate) if (esthnswarea > estother) esthnswarea -= estother; - hnswarea = (char *) palloc0_huge(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), esthnswarea); + hnswarea = (char *)palloc0_huge(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), esthnswarea); /* Report less than allocated so never fails */ InitGraph(&hnswshared->graphData, hnswarea, esthnswarea - 1024 * 1024); @@ -952,11 +927,10 @@ HnswParallelInitshared(HnswBuildState * buildstate) /* * Begin parallel build */ -static void -HnswBeginParallel(HnswBuildState * buildstate, int request) +static void HnswBeginParallel(HnswBuildState *buildstate, int request) { HnswShared *hnswshared; - HnswLeader *hnswleader = (HnswLeader *) palloc0(sizeof(HnswLeader)); + HnswLeader *hnswleader = (HnswLeader *)palloc0(sizeof(HnswLeader)); Assert(request > 0); @@ -981,8 +955,7 @@ HnswBeginParallel(HnswBuildState * buildstate, int request) /* * Build graph */ -static void -BuildGraph(HnswBuildState * buildstate, ForkNumber forkNum) +static void BuildGraph(HnswBuildState *buildstate, ForkNumber forkNum) { int parallel_workers = 0; @@ -999,9 +972,9 @@ BuildGraph(HnswBuildState * buildstate, ForkNumber forkNum) /* Add tuples to graph */ if (buildstate->heap != NULL) { if (!buildstate->hnswleader) { -serial_build: + serial_build: buildstate->reltuples = tableam_index_build_scan(buildstate->heap, buildstate->index, buildstate->indexInfo, - true, BuildCallback, (void *) buildstate, NULL); + true, BuildCallback, (void *)buildstate, NULL); } else { int nruns; buildstate->reltuples = ParallelHeapScan(buildstate, &nruns); @@ -1028,9 +1001,8 @@ serial_build: /* * Build the index */ -static void -BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, - HnswBuildState * buildstate, ForkNumber forkNum) +static void BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, HnswBuildState *buildstate, + ForkNumber forkNum) { #ifdef HNSW_MEMORY SeedRandom(42); @@ -1049,15 +1021,14 @@ BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, /* * Build the index for a logged table */ -IndexBuildResult * -hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) +IndexBuildResult *hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) { IndexBuildResult *result; HnswBuildState buildstate; BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); - result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + result = (IndexBuildResult *)palloc(sizeof(IndexBuildResult)); result->heap_tuples = buildstate.reltuples; result->index_tuples = buildstate.indtuples; @@ -1067,10 +1038,9 @@ hnswbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) /* * Build the index for an unlogged table */ -void -hnswbuildempty_internal(Relation index) +void hnswbuildempty_internal(Relation index) { - IndexInfo *indexInfo = BuildIndexInfo(index); + IndexInfo *indexInfo = BuildIndexInfo(index); HnswBuildState buildstate; BuildIndex(NULL, index, indexInfo, &buildstate, INIT_FORKNUM); diff --git a/src/gausskernel/storage/access/datavec/hnswdelete.cpp b/src/gausskernel/storage/access/datavec/hnswdelete.cpp index 408d0f0025..4f287ede0c 100644 --- a/src/gausskernel/storage/access/datavec/hnswdelete.cpp +++ b/src/gausskernel/storage/access/datavec/hnswdelete.cpp @@ -81,14 +81,14 @@ OffsetNumber HnswFindDeleteLocation(Relation index, Buffer buf, HnswElementTuple void HnswDeleteOnPage(Relation index, Buffer buf, OffsetNumber offset) { ItemId iid; - IndexTransInfo* idxXid; + IndexTransInfo *idxXid; Page page; HnswElementTuple etup; page = BufferGetPage(buf); iid = PageGetItemId(page, offset); etup = (HnswElementTuple)PageGetItem(page, iid); - idxXid = (IndexTransInfo*)VecIndexTupleGetXid(etup); + idxXid = (IndexTransInfo *)VecIndexTupleGetXid(etup); idxXid->xmax = GetCurrentTransactionId(); @@ -142,8 +142,8 @@ bool HnswDeleteIndex(Relation index, HnswElementTuple etup) ep = w; } - foreach(cell, ep) { - HnswCandidate *hc = (HnswCandidate *) lfirst(cell); + foreach (cell, ep) { + HnswCandidate *hc = (HnswCandidate *)lfirst(cell); HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); blkno = element->blkno; } @@ -152,7 +152,7 @@ bool HnswDeleteIndex(Relation index, HnswElementTuple etup) buf = ReadBuffer(index, blkno); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); offset = HnswFindDeleteLocation(index, buf, etup); - if (offset != InvalidOffsetNumber && ! IsHnswEntryPoint(index, blkno, offset)) { + if (offset != InvalidOffsetNumber && !IsHnswEntryPoint(index, blkno, offset)) { HnswDeleteOnPage(index, buf, offset); UnlockReleaseBuffer(buf); found = true; @@ -166,7 +166,7 @@ bool HnswDeleteIndex(Relation index, HnswElementTuple etup) return found; } -HnswElementTuple IndexFormHnswElementTuple(TupleDesc tupleDesc, Datum* values, const bool* isnull, +HnswElementTuple IndexFormHnswElementTuple(TupleDesc tupleDesc, Datum *values, const bool *isnull, ItemPointer heapTCtid) { Datum value; @@ -187,7 +187,7 @@ HnswElementTuple IndexFormHnswElementTuple(TupleDesc tupleDesc, Datum* values, c return etup; } -bool hnswdelete_internal(Relation index, Datum* values, const bool* isnull, ItemPointer heapTCtid, bool isRollbackIndex) +bool hnswdelete_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heapTCtid, bool isRollbackIndex) { bool found; HnswElementTuple etup; diff --git a/src/gausskernel/storage/access/datavec/hnswinsert.cpp b/src/gausskernel/storage/access/datavec/hnswinsert.cpp index bf787056dd..72700dbe74 100644 --- a/src/gausskernel/storage/access/datavec/hnswinsert.cpp +++ b/src/gausskernel/storage/access/datavec/hnswinsert.cpp @@ -13,8 +13,7 @@ /* * Get the insert page */ -static BlockNumber -GetInsertPage(Relation index) +static BlockNumber GetInsertPage(Relation index) { Buffer buf; Page page; @@ -36,14 +35,15 @@ GetInsertPage(Relation index) /* * Check for a free offset */ -static bool -HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size ntupSize, Buffer *nbuf, Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, BlockNumber *newInsertPage) +static bool HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size ntupSize, Buffer *nbuf, + Page *npage, OffsetNumber *freeOffno, OffsetNumber *freeNeighborOffno, + BlockNumber *newInsertPage) { OffsetNumber offno; OffsetNumber maxoffno = PageGetMaxOffsetNumber(page); for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswElementTuple etup = (HnswElementTuple)PageGetItem(page, PageGetItemId(page, offno)); /* Skip neighbor tuples */ if (!HnswIsElementTuple(etup)) @@ -53,7 +53,7 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size BlockNumber elementPage = BufferGetBlockNumber(buf); BlockNumber neighborPage = ItemPointerGetBlockNumber(&etup->neighbortid); OffsetNumber neighborOffno = ItemPointerGetOffsetNumber(&etup->neighbortid); - ItemId itemid; + ItemId itemid; if (!BlockNumberIsValid(*newInsertPage)) *newInsertPage = elementPage; @@ -87,8 +87,8 @@ HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement element, Size /* * Add a new page */ -static void -HnswInsertAppendPage(Relation index, Buffer *nbuf, Page *npage, GenericXLogState *state, Page page, bool building) +static void HnswInsertAppendPage(Relation index, Buffer *nbuf, Page *npage, GenericXLogState *state, Page page, + bool building) { /* Add a new page */ LockRelationForExtension(index, ExclusiveLock); @@ -110,8 +110,8 @@ HnswInsertAppendPage(Relation index, Buffer *nbuf, Page *npage, GenericXLogState /* * Add to element and neighbor pages */ -static void -AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, BlockNumber *updatedInsertPage, bool building) +static void AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, + BlockNumber *updatedInsertPage, bool building) { Buffer buf; Page page; @@ -131,7 +131,7 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B BlockNumber newInsertPage = InvalidBlockNumber; char *base = NULL; bool isUStore; - IndexTransInfo* idxXid; + IndexTransInfo *idxXid; /* Calculate sizes */ etupSize = HNSW_ELEMENT_TUPLE_SIZE(VARSIZE_ANY(HnswPtrAccess(base, e->value))); @@ -156,7 +156,7 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B if (building) { state = NULL; page = BufferGetPage(buf); - } else { + } else { state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); } @@ -177,8 +177,8 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B } /* Next, try space from a deleted element */ - if (HnswFreeOffset(index, buf, page, e, ntupSize, &nbuf, &npage, &freeOffno, - &freeNeighborOffno, &newInsertPage)) { + if (HnswFreeOffset(index, buf, page, e, ntupSize, &nbuf, &npage, &freeOffno, &freeNeighborOffno, + &newInsertPage)) { if (nbuf != buf) { if (building) { npage = BufferGetPage(nbuf); @@ -195,9 +195,9 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B if (combinedSize > maxSize && PageGetFreeSpace(page) >= etupSize && !BlockNumberIsValid(HnswPageGetOpaque(page)->nextblkno)) { HnswInsertAppendPage(index, &nbuf, &npage, state, page, building); - if (isUStore) { - HnswPageGetOpaque(npage)->pageType = HNSW_USTORE_PAGE_TYPE; - } + if (isUStore) { + HnswPageGetOpaque(npage)->pageType = HNSW_USTORE_PAGE_TYPE; + } break; } @@ -209,8 +209,8 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B GenericXLogAbort(state); UnlockReleaseBuffer(buf); } else { - Buffer newbuf; - Page newpage; + Buffer newbuf; + Page newpage; HnswInsertAppendPage(index, &newbuf, &newpage, state, page, building); if (isUStore) { @@ -280,29 +280,29 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B ItemId item_id = PageGetItemId(page, e->offno); Size aligned_size = MAXALIGN(ItemIdGetLength(item_id)); unsigned offset = ItemIdGetOffset(item_id); - idxXid = (IndexTransInfo*)((char*)page + offset + aligned_size); + idxXid = (IndexTransInfo *)((char *)page + offset + aligned_size); idxXid->xmin = GetCurrentTransactionId(); idxXid->xmax = InvalidTransactionId; } - if (!page_index_tuple_overwrite(page, e->offno, (Item) etup, etupSize)) { + if (!page_index_tuple_overwrite(page, e->offno, (Item)etup, etupSize)) { elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); } - if (!page_index_tuple_overwrite(npage, e->neighborOffno, (Item) ntup, ntupSize)) { + if (!page_index_tuple_overwrite(npage, e->neighborOffno, (Item)ntup, ntupSize)) { elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); } } else { if (isUStore) { ((PageHeader)page)->pd_upper -= sizeof(IndexTransInfo); - idxXid = (IndexTransInfo*)(((char*)page) + ((PageHeader)page)->pd_upper); + idxXid = (IndexTransInfo *)(((char *)page) + ((PageHeader)page)->pd_upper); idxXid->xmin = GetCurrentTransactionId(); idxXid->xmax = InvalidTransactionId; } - if (PageAddItem(page, (Item) etup, etupSize, InvalidOffsetNumber, false, false) != e->offno) { + if (PageAddItem(page, (Item)etup, etupSize, InvalidOffsetNumber, false, false) != e->offno) { elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); } - if (PageAddItem(npage, (Item) ntup, ntupSize, InvalidOffsetNumber, false, false) != e->neighborOffno) { + if (PageAddItem(npage, (Item)ntup, ntupSize, InvalidOffsetNumber, false, false) != e->neighborOffno) { elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); } } @@ -327,8 +327,7 @@ AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber insertPage, B /* * Check if connection already exists */ -static bool -ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) +static bool ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) { for (int i = 0; i < lm; i++) { ItemPointer indextid = &ntup->indextids[startIdx + i]; @@ -346,10 +345,10 @@ ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx, int lm) /* * Update neighbors */ -void -HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, bool checkExisting, bool building) +void HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement e, int m, + bool checkExisting, bool building) { - char *base = NULL; + char *base = NULL; for (int lc = e->level; lc >= 0; lc--) { int lm = HnswGetLayerM(m, lc); @@ -396,7 +395,7 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns } /* Get tuple */ - ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, offno)); + ntup = (HnswNeighborTuple)PageGetItem(page, PageGetItemId(page, offno)); /* Calculate index for update */ startIdx = (neighborElement->level - lc) * m; @@ -439,10 +438,9 @@ HnswUpdateNeighborsOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, Hns /* * Add a heap TID to an existing element */ -static bool -AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool building) +static bool AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool building) { - Buffer buf; + Buffer buf; Page page; GenericXLogState *state; HnswElementTuple etup; @@ -460,7 +458,7 @@ AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool bu } /* Find space */ - etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, dup->offno)); + etup = (HnswElementTuple)PageGetItem(page, PageGetItemId(page, dup->offno)); for (i = 0; i < HNSW_HEAPTIDS; i++) { if (!ItemPointerIsValid(&etup->heaptids[i])) break; @@ -490,8 +488,7 @@ AddDuplicateOnDisk(Relation index, HnswElement element, HnswElement dup, bool bu /* * Find duplicate element */ -static bool -FindDuplicateOnDisk(Relation index, HnswElement element, bool building) +static bool FindDuplicateOnDisk(Relation index, HnswElement element, bool building) { char *base = NULL; HnswNeighborArray *neighbors = HnswGetNeighbors(base, element, 0); @@ -516,8 +513,8 @@ FindDuplicateOnDisk(Relation index, HnswElement element, bool building) /* * Update graph on disk */ -static void -UpdateGraphOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement element, int m, int efConstruction, HnswElement entryPoint, bool building) +static void UpdateGraphOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement element, int m, + int efConstruction, HnswElement entryPoint, bool building) { BlockNumber newInsertPage = InvalidBlockNumber; @@ -543,8 +540,8 @@ UpdateGraphOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, HnswElement /* * Insert a tuple into the index */ -bool -HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *isnull, ItemPointer heap_tid, bool building) +bool HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *isnull, ItemPointer heap_tid, + bool building) { HnswElement entryPoint; HnswElement element; @@ -597,13 +594,12 @@ HnswInsertTupleOnDisk(Relation index, Datum value, Datum *values, const bool *is /* * Insert a tuple into the index */ -static void -HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid) +static void HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid) { Datum value; const HnswTypeInfo *typeInfo = HnswGetTypeInfo(index); FmgrInfo *normprocinfo; - Oid collation = index->rd_indcollation[0]; + Oid collation = index->rd_indcollation[0]; /* Detoast once for all calls */ value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); @@ -627,9 +623,8 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti /* * Insert a tuple into the index */ -bool -hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, - Relation heap, IndexUniqueCheck checkUnique) +bool hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, + IndexUniqueCheck checkUnique) { MemoryContext oldCtx; MemoryContext insertCtx; @@ -639,9 +634,7 @@ hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer hea return false; /* Create memory context */ - insertCtx = AllocSetContextCreate(CurrentMemoryContext, - "Hnsw insert temporary context", - ALLOCSET_DEFAULT_SIZES); + insertCtx = AllocSetContextCreate(CurrentMemoryContext, "Hnsw insert temporary context", ALLOCSET_DEFAULT_SIZES); oldCtx = MemoryContextSwitchTo(insertCtx); /* Insert tuple */ diff --git a/src/gausskernel/storage/access/datavec/hnswscan.cpp b/src/gausskernel/storage/access/datavec/hnswscan.cpp index c702a9c2ac..a4b764f207 100644 --- a/src/gausskernel/storage/access/datavec/hnswscan.cpp +++ b/src/gausskernel/storage/access/datavec/hnswscan.cpp @@ -10,12 +10,11 @@ /* * Algorithm 5 from paper */ -static List * -GetScanItems(IndexScanDesc scan, Datum q) +static List *GetScanItems(IndexScanDesc scan, Datum q) { - HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + HnswScanOpaque so = (HnswScanOpaque)scan->opaque; Relation index = scan->indexRelation; - FmgrInfo *procinfo = so->procinfo; + FmgrInfo *procinfo = so->procinfo; Oid collation = so->collation; List *ep; List *w; @@ -43,10 +42,9 @@ GetScanItems(IndexScanDesc scan, Datum q) /* * Get scan value */ -static Datum -GetScanValue(IndexScanDesc scan) +static Datum GetScanValue(IndexScanDesc scan) { - HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + HnswScanOpaque so = (HnswScanOpaque)scan->opaque; Datum value; if (scan->orderByData->sk_flags & SK_ISNULL) @@ -69,20 +67,17 @@ GetScanValue(IndexScanDesc scan) /* * Prepare for an index scan */ -IndexScanDesc -hnswbeginscan_internal(Relation index, int nkeys, int norderbys) +IndexScanDesc hnswbeginscan_internal(Relation index, int nkeys, int norderbys) { IndexScanDesc scan; HnswScanOpaque so; scan = RelationGetIndexScan(index, nkeys, norderbys); - so = (HnswScanOpaque) palloc(sizeof(HnswScanOpaqueData)); + so = (HnswScanOpaque)palloc(sizeof(HnswScanOpaqueData)); so->typeInfo = HnswGetTypeInfo(index); so->first = true; - so->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, - "Hnsw scan temporary context", - ALLOCSET_DEFAULT_SIZES); + so->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, "Hnsw scan temporary context", ALLOCSET_DEFAULT_SIZES); so->vs.buf = InvalidBuffer; so->vs.lastSelfModifiedItup = NULL; @@ -101,10 +96,9 @@ hnswbeginscan_internal(Relation index, int nkeys, int norderbys) /* * Start or restart an index scan */ -void -hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) +void hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) { - HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + HnswScanOpaque so = (HnswScanOpaque)scan->opaque; if (so->vs.lastSelfModifiedItup) { IndexTupleSetSize(((IndexTuple)(so->vs.lastSelfModifiedItup)), 0); /* clear */ @@ -123,10 +117,9 @@ hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderby /* * Fetch the next tuple in the given scan */ -bool -hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir) +bool hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir) { - HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + HnswScanOpaque so = (HnswScanOpaque)scan->opaque; MemoryContext oldCtx = MemoryContextSwitchTo(so->tmpCtx); /* @@ -136,7 +129,7 @@ hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir) Assert(ScanDirectionIsForward(dir)); if (so->first) { - Datum value; + Datum value; /* Count index scan for stats */ pgstat_count_index_scan(scan->indexRelation); @@ -199,10 +192,9 @@ hnswgettuple_internal(IndexScanDesc scan, ScanDirection dir) /* * End a scan and release resources */ -void -hnswendscan_internal(IndexScanDesc scan) +void hnswendscan_internal(IndexScanDesc scan) { - HnswScanOpaque so = (HnswScanOpaque) scan->opaque; + HnswScanOpaque so = (HnswScanOpaque)scan->opaque; FREE_POINTER(so->vs.lastSelfModifiedItup); diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index f3786e8a2b..1203597e95 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -20,8 +20,7 @@ #endif #if PG_VERSION_NUM < 170000 -static inline uint64 -murmurhash64(uint64 data) +static inline uint64 murmurhash64(uint64 data) { uint64 h = data; @@ -36,11 +35,9 @@ murmurhash64(uint64 data) #endif /* TID hash table */ -static uint32 -hash_tid(ItemPointerData tid) +static uint32 hash_tid(ItemPointerData tid) { - union - { + union { uint64 i; ItemPointerData tid; } x; @@ -52,62 +49,61 @@ hash_tid(ItemPointerData tid) return murmurhash64(x.i); } -#define VALGRIND_MAKE_MEM_DEFINED(addr, size) do {} while (0) - -#define SH_PREFIX tidhash -#define SH_ELEMENT_TYPE TidHashEntry -#define SH_KEY_TYPE ItemPointerData -#define SH_KEY tid -#define SH_HASH_KEY(tb, key) hash_tid(key) -#define SH_EQUAL(tb, a, b) ItemPointerEquals(&a, &b) -#define SH_SCOPE extern +#define VALGRIND_MAKE_MEM_DEFINED(addr, size) \ + do { \ + } while (0) + +#define SH_PREFIX tidhash +#define SH_ELEMENT_TYPE TidHashEntry +#define SH_KEY_TYPE ItemPointerData +#define SH_KEY tid +#define SH_HASH_KEY(tb, key) hash_tid(key) +#define SH_EQUAL(tb, a, b) ItemPointerEquals(&a, &b) +#define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" /* Pointer hash table */ -static uint32 -hash_pointer(uintptr_t ptr) +static uint32 hash_pointer(uintptr_t ptr) { #if SIZEOF_VOID_P == 8 - return murmurhash64((uint64) ptr); + return murmurhash64((uint64)ptr); #else - return murmurhash32((uint32) ptr); + return murmurhash32((uint32)ptr); #endif } -#define SH_PREFIX pointerhash -#define SH_ELEMENT_TYPE PointerHashEntry -#define SH_KEY_TYPE uintptr_t -#define SH_KEY ptr -#define SH_HASH_KEY(tb, key) hash_pointer(key) -#define SH_EQUAL(tb, a, b) (a == b) -#define SH_SCOPE extern +#define SH_PREFIX pointerhash +#define SH_ELEMENT_TYPE PointerHashEntry +#define SH_KEY_TYPE uintptr_t +#define SH_KEY ptr +#define SH_HASH_KEY(tb, key) hash_pointer(key) +#define SH_EQUAL(tb, a, b) (a == b) +#define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" /* Offset hash table */ -static uint32 -hash_offset(Size offset) +static uint32 hash_offset(Size offset) { #if SIZEOF_SIZE_T == 8 - return murmurhash64((uint64) offset); + return murmurhash64((uint64)offset); #else - return murmurhash32((uint32) offset); + return murmurhash32((uint32)offset); #endif } -#define SH_PREFIX offsethash -#define SH_ELEMENT_TYPE OffsetHashEntry -#define SH_KEY_TYPE Size -#define SH_KEY offset -#define SH_HASH_KEY(tb, key) hash_offset(key) -#define SH_EQUAL(tb, a, b) (a == b) -#define SH_SCOPE extern +#define SH_PREFIX offsethash +#define SH_ELEMENT_TYPE OffsetHashEntry +#define SH_KEY_TYPE Size +#define SH_KEY offset +#define SH_HASH_KEY(tb, key) hash_offset(key) +#define SH_EQUAL(tb, a, b) (a == b) +#define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" -typedef union -{ +typedef union { pointerhash_hash *pointers; offsethash_hash *offsets; tidhash_hash *tids; @@ -116,10 +112,9 @@ typedef union /* * Get the max number of connections in an upper layer for each element in the index */ -int -HnswGetM(Relation index) +int HnswGetM(Relation index) { - HnswOptions *opts = (HnswOptions *) index->rd_options; + HnswOptions *opts = (HnswOptions *)index->rd_options; if (opts) return opts->m; @@ -130,10 +125,9 @@ HnswGetM(Relation index) /* * Get the size of the dynamic candidate list in the index */ -int -HnswGetEfConstruction(Relation index) +int HnswGetEfConstruction(Relation index) { - HnswOptions *opts = (HnswOptions *) index->rd_options; + HnswOptions *opts = (HnswOptions *)index->rd_options; if (opts) return opts->efConstruction; @@ -144,10 +138,9 @@ HnswGetEfConstruction(Relation index) /* * Get whether to enable PQ */ -bool -HnswGetEnablePQ(Relation index) +bool HnswGetEnablePQ(Relation index) { - HnswOptions *opts = (HnswOptions *) index->rd_options; + HnswOptions *opts = (HnswOptions *)index->rd_options; if (opts) { return opts->enablePQ; @@ -159,10 +152,9 @@ HnswGetEnablePQ(Relation index) /* * Get the number of subquantizer */ -int -HnswGetPqM(Relation index) +int HnswGetPqM(Relation index) { - HnswOptions *opts = (HnswOptions *) index->rd_options; + HnswOptions *opts = (HnswOptions *)index->rd_options; if (opts) { return opts->pqM; @@ -174,10 +166,9 @@ HnswGetPqM(Relation index) /* * Get the number of centroids for each subquantizer */ -int -HnswGetPqKsub(Relation index) +int HnswGetPqKsub(Relation index) { - HnswOptions *opts = (HnswOptions *) index->rd_options; + HnswOptions *opts = (HnswOptions *)index->rd_options; if (opts) { return opts->pqKsub; @@ -186,12 +177,10 @@ HnswGetPqKsub(Relation index) return HNSW_DEFAULT_PQ_KSUB; } - /* * Get proc */ -FmgrInfo * -HnswOptionalProcInfo(Relation index, uint16 procnum) +FmgrInfo *HnswOptionalProcInfo(Relation index, uint16 procnum) { if (!OidIsValid(index_getprocid(index, 1, procnum))) return NULL; @@ -202,8 +191,7 @@ HnswOptionalProcInfo(Relation index, uint16 procnum) /* * Normalize value */ -Datum -HnswNormValue(const HnswTypeInfo * typeInfo, Oid collation, Datum value) +Datum HnswNormValue(const HnswTypeInfo *typeInfo, Oid collation, Datum value) { return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); } @@ -211,8 +199,7 @@ HnswNormValue(const HnswTypeInfo * typeInfo, Oid collation, Datum value) /* * Check if non-zero norm */ -bool -HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) +bool HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) { return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; } @@ -220,8 +207,7 @@ HnswCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) /* * New buffer */ -Buffer -HnswNewBuffer(Relation index, ForkNumber forkNum) +Buffer HnswNewBuffer(Relation index, ForkNumber forkNum) { Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); @@ -232,8 +218,7 @@ HnswNewBuffer(Relation index, ForkNumber forkNum) /* * Init page */ -void -HnswInitPage(Buffer buf, Page page) +void HnswInitPage(Buffer buf, Page page) { PageInit(page, BufferGetPageSize(buf), sizeof(HnswPageOpaqueData)); HnswPageGetOpaque(page)->nextblkno = InvalidBlockNumber; @@ -244,8 +229,7 @@ HnswInitPage(Buffer buf, Page page) /* * Allocate a neighbor array */ -static HnswNeighborArray * -HnswInitNeighborArray(int lm, HnswAllocator * allocator) +static HnswNeighborArray *HnswInitNeighborArray(int lm, HnswAllocator *allocator) { HnswNeighborArray *a = (HnswNeighborArray *)HnswAlloc(allocator, HNSW_NEIGHBOR_ARRAY_SIZE(lm)); @@ -257,11 +241,11 @@ HnswInitNeighborArray(int lm, HnswAllocator * allocator) /* * Allocate neighbors */ -void -HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * allocator) +void HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator *allocator) { int level = element->level; - HnswNeighborArrayPtr *neighborList = (HnswNeighborArrayPtr *) HnswAlloc(allocator, sizeof(HnswNeighborArrayPtr) * (level + 1)); + HnswNeighborArrayPtr *neighborList = + (HnswNeighborArrayPtr *)HnswAlloc(allocator, sizeof(HnswNeighborArrayPtr) * (level + 1)); HnswPtrStore(base, element->neighbors, neighborList); @@ -272,11 +256,10 @@ HnswInitNeighbors(char *base, HnswElement element, int m, HnswAllocator * alloca /* * Allocate memory from the allocator */ -void * -HnswAlloc(HnswAllocator * allocator, Size size) +void *HnswAlloc(HnswAllocator *allocator, Size size) { if (allocator) - return (*(allocator)->alloc) (size, (allocator)->state); + return (*(allocator)->alloc)(size, (allocator)->state); return palloc(size); } @@ -284,12 +267,11 @@ HnswAlloc(HnswAllocator * allocator, Size size) /* * Allocate an element */ -HnswElement -HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, HnswAllocator * allocator) +HnswElement HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, HnswAllocator *allocator) { HnswElement element = (HnswElement)HnswAlloc(allocator, sizeof(HnswElementData)); - int level = (int) (-log(RandomDouble()) * ml); + int level = (int)(-log(RandomDouble()) * ml); /* Cap level */ if (level > maxLevel) @@ -303,7 +285,7 @@ HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, HnswInitNeighbors(base, element, m, allocator); - HnswPtrStore(base, element->value, (Pointer) NULL); + HnswPtrStore(base, element->value, (Pointer)NULL); return element; } @@ -311,8 +293,7 @@ HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, int maxLevel, /* * Add a heap TID to an element */ -void -HnswAddHeapTid(HnswElement element, ItemPointer heaptid) +void HnswAddHeapTid(HnswElement element, ItemPointer heaptid) { element->heaptids[element->heaptidsLength++] = *heaptid; } @@ -320,24 +301,22 @@ HnswAddHeapTid(HnswElement element, ItemPointer heaptid) /* * Allocate an element from block and offset numbers */ -HnswElement -HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno) +HnswElement HnswInitElementFromBlock(BlockNumber blkno, OffsetNumber offno) { HnswElement element = (HnswElement)palloc(sizeof(HnswElementData)); char *base = NULL; element->blkno = blkno; element->offno = offno; - HnswPtrStore(base, element->neighbors, (HnswNeighborArrayPtr *) NULL); - HnswPtrStore(base, element->value, (Pointer) NULL); + HnswPtrStore(base, element->neighbors, (HnswNeighborArrayPtr *)NULL); + HnswPtrStore(base, element->value, (Pointer)NULL); return element; } /* * Get the metapage info */ -void -HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint) +void HnswGetMetaPageInfo(Relation index, int *m, HnswElement *entryPoint) { Buffer buf; Page page; @@ -368,8 +347,7 @@ HnswGetMetaPageInfo(Relation index, int *m, HnswElement * entryPoint) /* * Get the entry point */ -HnswElement -HnswGetEntryPoint(Relation index) +HnswElement HnswGetEntryPoint(Relation index) { HnswElement entryPoint; @@ -381,8 +359,7 @@ HnswGetEntryPoint(Relation index) /* * Update the metapage info */ -static void -HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, BlockNumber insertPage) +static void HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, BlockNumber insertPage) { HnswMetaPage metap = HnswPageGetMeta(page); @@ -405,9 +382,8 @@ HnswUpdateMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, Block /* * Update the append metapage info */ -static void -HnswUpdateAppendMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, - BlockNumber eleInsertSlotStartPage, BlockNumber neiInsertSlotStartPage) +static void HnswUpdateAppendMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, + BlockNumber eleInsertSlotStartPage, BlockNumber neiInsertSlotStartPage) { HnswAppendMetaPage metap = HnswPageGetAppendMeta(page); @@ -435,8 +411,8 @@ HnswUpdateAppendMetaPageInfo(Page page, int updateEntry, HnswElement entryPoint, /* * Update the metapage */ -void -HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, ForkNumber forkNum, bool building) +void HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber insertPage, + ForkNumber forkNum, bool building) { Buffer buf; Page page; @@ -464,9 +440,8 @@ HnswUpdateMetaPage(Relation index, int updateEntry, HnswElement entryPoint, Bloc /* * Update the append metapage */ -void -HnswUpdateAppendMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber eleInsertPage, - BlockNumber neiInsertPage, ForkNumber forkNum, bool building) +void HnswUpdateAppendMetaPage(Relation index, int updateEntry, HnswElement entryPoint, BlockNumber eleInsertPage, + BlockNumber neiInsertPage, ForkNumber forkNum, bool building) { Buffer buf; Page page; @@ -495,8 +470,7 @@ HnswUpdateAppendMetaPage(Relation index, int updateEntry, HnswElement entryPoint /* * Set element tuple, except for neighbor info */ -void -HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) +void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) { Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); @@ -515,8 +489,7 @@ HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) /* * Set neighbor tuple */ -void -HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) +void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) { int idx = 0; @@ -545,12 +518,11 @@ HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int m) /* * Load neighbors from page */ -static void -LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) +static void LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) { char *base = NULL; - HnswNeighborTuple ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); + HnswNeighborTuple ntup = (HnswNeighborTuple)PageGetItem(page, PageGetItemId(page, element->neighborOffno)); int neighborCount = (element->level + 2) * m; Assert(HnswIsNeighborTuple(ntup)); @@ -589,8 +561,7 @@ LoadNeighborsFromPage(HnswElement element, Relation index, Page page, int m) /* * Load neighbors */ -void -HnswLoadNeighbors(HnswElement element, Relation index, int m) +void HnswLoadNeighbors(HnswElement element, Relation index, int m) { Buffer buf; Page page; @@ -607,8 +578,7 @@ HnswLoadNeighbors(HnswElement element, Relation index, int m) /* * Load an element from a tuple */ -void -HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec) +void HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHeaptids, bool loadVec) { element->level = etup->level; element->deleted = etup->deleted; @@ -637,9 +607,8 @@ HnswLoadElementFromTuple(HnswElement element, HnswElementTuple etup, bool loadHe /* * Load an element and optionally get its distance from q */ -bool -HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, - Oid collation, bool loadVec, float *maxDistance, IndexScanDesc scan) +bool HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, FmgrInfo *procinfo, Oid collation, + bool loadVec, float *maxDistance, IndexScanDesc scan) { Buffer buf; Page page; @@ -657,7 +626,7 @@ HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, isVisible = VecVisibilityCheck(scan, page, element->offno, &needRecheck); } - etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, element->offno)); + etup = (HnswElementTuple)PageGetItem(page, PageGetItemId(page, element->offno)); Assert(HnswIsElementTuple(etup)); @@ -666,8 +635,7 @@ HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, if (DatumGetPointer(*q) == NULL) { *distance = 0; } else { - *distance = (float) DatumGetFloat8(FunctionCall2Coll(procinfo, collation, *q, - PointerGetDatum(&etup->data))); + *distance = (float)DatumGetFloat8(FunctionCall2Coll(procinfo, collation, *q, PointerGetDatum(&etup->data))); } } @@ -683,8 +651,7 @@ HnswLoadElement(HnswElement element, float *distance, Datum *q, Relation index, /* * Get the distance for a candidate */ -static float -GetCandidateDistance(char *base, HnswCandidate * hc, Datum q, FmgrInfo *procinfo, Oid collation) +static float GetCandidateDistance(char *base, HnswCandidate *hc, Datum q, FmgrInfo *procinfo, Oid collation) { HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); Datum value = HnswGetValue(base, hce); @@ -695,9 +662,8 @@ GetCandidateDistance(char *base, HnswCandidate * hc, Datum q, FmgrInfo *procinfo /* * Create a candidate for the entry point */ -HnswCandidate * -HnswEntryCandidate(char *base, HnswElement entryPoint, Datum q, Relation index, FmgrInfo *procinfo, - Oid collation, bool loadVec, IndexScanDesc scan) +HnswCandidate *HnswEntryCandidate(char *base, HnswElement entryPoint, Datum q, Relation index, FmgrInfo *procinfo, + Oid collation, bool loadVec, IndexScanDesc scan) { HnswCandidate *hc = (HnswCandidate *)palloc(sizeof(HnswCandidate)); @@ -705,8 +671,8 @@ HnswEntryCandidate(char *base, HnswElement entryPoint, Datum q, Relation index, if (index == NULL) { hc->distance = GetCandidateDistance(base, hc, q, procinfo, collation); } else { - bool isVisible = HnswLoadElement(entryPoint, &hc->distance, &q, index, procinfo, - collation, loadVec, NULL, scan); + bool isVisible = + HnswLoadElement(entryPoint, &hc->distance, &q, index, procinfo, collation, loadVec, NULL, scan); if (!isVisible) { elog(ERROR, "hnsw entryPoint is invisible\n"); } @@ -717,13 +683,12 @@ HnswEntryCandidate(char *base, HnswElement entryPoint, Datum q, Relation index, /* * Compare candidate distances */ -static int -CompareNearestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) +static int CompareNearestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance < ((const HnswPairingHeapNode *)b)->inner->distance) return 1; - if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance > ((const HnswPairingHeapNode *)b)->inner->distance) return -1; return 0; @@ -732,13 +697,12 @@ CompareNearestCandidates(const pairingheap_node *a, const pairingheap_node *b, v /* * Compare candidate distances */ -static int -CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) +static int CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const HnswPairingHeapNode *) a)->inner->distance < ((const HnswPairingHeapNode *) b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance < ((const HnswPairingHeapNode *)b)->inner->distance) return -1; - if (((const HnswPairingHeapNode *) a)->inner->distance > ((const HnswPairingHeapNode *) b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance > ((const HnswPairingHeapNode *)b)->inner->distance) return 1; return 0; @@ -747,8 +711,7 @@ CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b, /* * Create a pairing heap node for a candidate */ -static HnswPairingHeapNode * -CreatePairingHeapNode(HnswCandidate * c) +static HnswPairingHeapNode *CreatePairingHeapNode(HnswCandidate *c) { HnswPairingHeapNode *node = (HnswPairingHeapNode *)palloc(sizeof(HnswPairingHeapNode)); @@ -759,8 +722,7 @@ CreatePairingHeapNode(HnswCandidate * c) /* * Init visited */ -static inline void -InitVisited(char *base, visited_hash * v, Relation index, int ef, int m) +static inline void InitVisited(char *base, visited_hash *v, Relation index, int ef, int m) { if (index != NULL) v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL); @@ -773,8 +735,7 @@ InitVisited(char *base, visited_hash * v, Relation index, int ef, int m) /* * Add to visited */ -static inline void -AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, bool *found) +static inline void AddToVisited(char *base, visited_hash *v, HnswCandidate *hc, Relation index, bool *found) { if (index != NULL) { HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); @@ -794,9 +755,9 @@ AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, b #if PG_VERSION_NUM >= 130000 HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); - pointerhash_insert_hash(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), element->hash, found); + pointerhash_insert_hash(v->pointers, (uintptr_t)HnswPtrPointer(hc->element), element->hash, found); #else - pointerhash_insert(v->pointers, (uintptr_t) HnswPtrPointer(hc->element), found); + pointerhash_insert(v->pointers, (uintptr_t)HnswPtrPointer(hc->element), found); #endif } } @@ -804,8 +765,7 @@ AddToVisited(char *base, visited_hash * v, HnswCandidate * hc, Relation index, b /* * Count element towards ef */ -static inline bool -CountElement(char *base, HnswElement skipElement, HnswCandidate * hc) +static inline bool CountElement(char *base, HnswElement skipElement, HnswCandidate *hc) { HnswElement e; @@ -822,9 +782,8 @@ CountElement(char *base, HnswElement skipElement, HnswCandidate * hc) /* * Algorithm 2 from paper */ -List * -HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *procinfo, - Oid collation, int m, bool inserting, HnswElement skipElement, IndexScanDesc scan) +List *HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, FmgrInfo *procinfo, Oid collation, + int m, bool inserting, HnswElement skipElement, IndexScanDesc scan) { List *w = NIL; pairingheap *C = pairingheap_allocate(CompareNearestCandidates, NULL); @@ -845,8 +804,8 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F } /* Add entry points to v, C, and W */ - foreach(lc2, ep) { - HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); + foreach (lc2, ep) { + HnswCandidate *hc = (HnswCandidate *)lfirst(lc2); bool found; AddToVisited(base, &v, hc, index, &found); @@ -865,8 +824,8 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F while (!pairingheap_is_empty(C)) { HnswNeighborArray *neighborhood; - HnswCandidate *c = ((HnswPairingHeapNode *) pairingheap_remove_first(C))->inner; - HnswCandidate *f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner; + HnswCandidate *c = ((HnswPairingHeapNode *)pairingheap_remove_first(C))->inner; + HnswCandidate *f = ((HnswPairingHeapNode *)pairingheap_first(W))->inner; HnswElement cElement; if (c->distance > f->distance) @@ -899,7 +858,7 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); bool alwaysAdd = wlen < ef; - f = ((HnswPairingHeapNode *) pairingheap_first(W))->inner; + f = ((HnswPairingHeapNode *)pairingheap_first(W))->inner; if (index == NULL) { eDistance = GetCandidateDistance(base, e, q, procinfo, collation); @@ -947,7 +906,7 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F /* Add each element of W to w */ while (!pairingheap_is_empty(W)) { - HnswCandidate *hc = ((HnswPairingHeapNode *) pairingheap_remove_first(W))->inner; + HnswCandidate *hc = ((HnswPairingHeapNode *)pairingheap_remove_first(W))->inner; w = lcons(hc, w); } @@ -960,15 +919,15 @@ HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation index, F */ static int #if PG_VERSION_NUM >= 130000 -CompareCandidateDistances(const ListCell *a, const ListCell *b) + CompareCandidateDistances(const ListCell *a, const ListCell *b) { HnswCandidate *hca = (HnswCandidate *)lfirst(a); HnswCandidate *hcb = (HnswCandidate *)lfirst(b); #else -CompareCandidateDistances(const void *a, const void *b) + CompareCandidateDistances(const void *a, const void *b) { - HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); - HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); + HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **)a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **)b); #endif if (hca->distance < hcb->distance) @@ -991,15 +950,15 @@ CompareCandidateDistances(const void *a, const void *b) */ static int #if PG_VERSION_NUM >= 130000 -CompareCandidateDistancesOffset(const ListCell *a, const ListCell *b) + CompareCandidateDistancesOffset(const ListCell *a, const ListCell *b) { HnswCandidate *hca = (HnswCandidate *)lfirst(a); HnswCandidate *hcb = (HnswCandidate *)lfirst(b); #else -CompareCandidateDistancesOffset(const void *a, const void *b) + CompareCandidateDistancesOffset(const void *a, const void *b) { - HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **) a); - HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **) b); + HnswCandidate *hca = (HnswCandidate *)lfirst(*(ListCell **)a); + HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **)b); #endif if (hca->distance < hcb->distance) @@ -1020,8 +979,7 @@ CompareCandidateDistancesOffset(const void *a, const void *b) /* * Calculate the distance between elements */ -static float -HnswGetDistance(char *base, HnswElement a, HnswElement b, FmgrInfo *procinfo, Oid collation) +static float HnswGetDistance(char *base, HnswElement a, HnswElement b, FmgrInfo *procinfo, Oid collation) { Datum aValue = HnswGetValue(base, a); Datum bValue = HnswGetValue(base, b); @@ -1032,13 +990,12 @@ HnswGetDistance(char *base, HnswElement a, HnswElement b, FmgrInfo *procinfo, Oi /* * Check if an element is closer to q than any element from R */ -static bool -CheckElementCloser(char *base, HnswCandidate * e, List *r, FmgrInfo *procinfo, Oid collation) +static bool CheckElementCloser(char *base, HnswCandidate *e, List *r, FmgrInfo *procinfo, Oid collation) { HnswElement eElement = (HnswElement)HnswPtrAccess(base, e->element); ListCell *lc2; - foreach(lc2, r) { + foreach (lc2, r) { HnswCandidate *ri = (HnswCandidate *)lfirst(lc2); HnswElement riElement = (HnswElement)HnswPtrAccess(base, ri->element); float distance = HnswGetDistance(base, eElement, riElement, procinfo, collation); @@ -1053,8 +1010,8 @@ CheckElementCloser(char *base, HnswCandidate * e, List *r, FmgrInfo *procinfo, O /* * Algorithm 4 from paper */ -static List * -SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid collation, HnswElement e2, HnswCandidate * newCandidate, HnswCandidate * *pruned, bool sortCandidates) +static List *SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid collation, HnswElement e2, + HnswCandidate *newCandidate, HnswCandidate **pruned, bool sortCandidates) { List *r = NIL; List *w = list_copy(c); @@ -1075,8 +1032,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col if (sortCandidates) { if (base == NULL) { list_sort(w, CompareCandidateDistances); - } - else { + } else { list_sort(w, CompareCandidateDistancesOffset); } } @@ -1090,8 +1046,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col /* Use previous state of r and wd to skip work when possible */ if (mustCalculate) { e->closer = CheckElementCloser(base, e, r, procinfo, collation); - } - else if (list_length(added) > 0) { + } else if (list_length(added) > 0) { /* Keep Valgrind happy for in-memory, parallel builds */ if (base != NULL) { VALGRIND_MAKE_MEM_DEFINED(&e->closer, 1); @@ -1133,8 +1088,7 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col if (e->closer) { r = lappend(r, e); - } - else { + } else { wd[wdlen++] = e; } } @@ -1162,21 +1116,20 @@ SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *procinfo, Oid col /* * Add connections */ -static void -AddConnections(char *base, HnswElement element, List *neighbors, int lc) +static void AddConnections(char *base, HnswElement element, List *neighbors, int lc) { ListCell *lc2; HnswNeighborArray *a = HnswGetNeighbors(base, element, lc); - foreach(lc2, neighbors) - a->items[a->length++] = *((HnswCandidate *) lfirst(lc2)); + foreach (lc2, neighbors) + a->items[a->length++] = *((HnswCandidate *)lfirst(lc2)); } /* * Update connections */ -void -HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm, int lc, int *updateIdx, Relation index, FmgrInfo *procinfo, Oid collation) +void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate *hc, int lm, int lc, int *updateIdx, + Relation index, FmgrInfo *procinfo, Oid collation) { HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); HnswNeighborArray *currentNeighbors = HnswGetNeighbors(base, hce, lc); @@ -1197,7 +1150,7 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm /* Load elements on insert */ if (index != NULL) { - Datum q = HnswGetValue(base, hce); + Datum q = HnswGetValue(base, hce); for (int i = 0; i < currentNeighbors->length; i++) { HnswCandidate *hc3 = ¤tNeighbors->items[i]; @@ -1217,7 +1170,7 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm } if (pruned == NULL) { - List *c = NIL; + List *c = NIL; /* Add candidates */ for (int i = 0; i < currentNeighbors->length; i++) @@ -1249,8 +1202,7 @@ HnswUpdateConnection(char *base, HnswElement element, HnswCandidate * hc, int lm /* * Remove elements being deleted or skipped */ -static List * -RemoveElements(char *base, List *w, HnswElement skipElement) +static List *RemoveElements(char *base, List *w, HnswElement skipElement) { ListCell *lc2; List *w2 = NIL; @@ -1258,8 +1210,8 @@ RemoveElements(char *base, List *w, HnswElement skipElement) /* Ensure does not access heaptidsLength during in-memory build */ pg_memory_barrier(); - foreach(lc2, w) { - HnswCandidate *hc = (HnswCandidate *) lfirst(lc2); + foreach (lc2, w) { + HnswCandidate *hc = (HnswCandidate *)lfirst(lc2); HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); /* Skip self for vacuuming update */ @@ -1277,15 +1229,14 @@ RemoveElements(char *base, List *w, HnswElement skipElement) /* * Precompute hash */ -static void -PrecomputeHash(char *base, HnswElement element) +static void PrecomputeHash(char *base, HnswElement element) { HnswElementPtr ptr; HnswPtrStore(base, ptr, element); if (base == NULL) - element->hash = hash_pointer((uintptr_t) HnswPtrPointer(ptr)); + element->hash = hash_pointer((uintptr_t)HnswPtrPointer(ptr)); else element->hash = hash_offset(HnswPtrOffset(ptr)); } @@ -1294,8 +1245,8 @@ PrecomputeHash(char *base, HnswElement element) /* * Algorithm 1 from paper */ -void -HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing) +void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint, Relation index, + FmgrInfo *procinfo, Oid collation, int m, int efConstruction, bool existing) { List *ep; List *w; @@ -1359,10 +1310,9 @@ HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entryPoint } } -static void -SparsevecCheckValue(Pointer v) +static void SparsevecCheckValue(Pointer v) { - SparseVector *vec = (SparseVector *) v; + SparseVector *vec = (SparseVector *)v; if (vec->nnz > HNSW_MAX_NNZ) elog(ERROR, "sparsevec cannot have more than %d non-zero elements for hnsw index", HNSW_MAX_NNZ); @@ -1371,59 +1321,41 @@ SparsevecCheckValue(Pointer v) /* * Get type info */ -const HnswTypeInfo * -HnswGetTypeInfo(Relation index) +const HnswTypeInfo *HnswGetTypeInfo(Relation index) { FmgrInfo *procinfo = HnswOptionalProcInfo(index, HNSW_TYPE_INFO_PROC); if (procinfo == NULL) { static const HnswTypeInfo typeInfo = { - .maxDimensions = HNSW_MAX_DIM, - .normalize = l2_normalize, - .checkValue = NULL - }; + .maxDimensions = HNSW_MAX_DIM, .normalize = l2_normalize, .checkValue = NULL}; return (&typeInfo); - } - else - return (const HnswTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); + } else + return (const HnswTypeInfo *)DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_halfvec_support); -Datum -hnsw_halfvec_support(PG_FUNCTION_ARGS) +Datum hnsw_halfvec_support(PG_FUNCTION_ARGS) { static const HnswTypeInfo typeInfo = { - .maxDimensions = HNSW_MAX_DIM * 2, - .normalize = halfvec_l2_normalize, - .checkValue = NULL - }; + .maxDimensions = HNSW_MAX_DIM * 2, .normalize = halfvec_l2_normalize, .checkValue = NULL}; PG_RETURN_POINTER(&typeInfo); }; PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_bit_support); -Datum -hnsw_bit_support(PG_FUNCTION_ARGS) +Datum hnsw_bit_support(PG_FUNCTION_ARGS) { - static const HnswTypeInfo typeInfo = { - .maxDimensions = HNSW_MAX_DIM * 32, - .normalize = NULL, - .checkValue = NULL - }; + static const HnswTypeInfo typeInfo = {.maxDimensions = HNSW_MAX_DIM * 32, .normalize = NULL, .checkValue = NULL}; PG_RETURN_POINTER(&typeInfo); }; PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_sparsevec_support); -Datum -hnsw_sparsevec_support(PG_FUNCTION_ARGS) +Datum hnsw_sparsevec_support(PG_FUNCTION_ARGS) { static const HnswTypeInfo typeInfo = { - .maxDimensions = SPARSEVEC_MAX_DIM, - .normalize = sparsevec_l2_normalize, - .checkValue = SparsevecCheckValue - }; + .maxDimensions = SPARSEVEC_MAX_DIM, .normalize = sparsevec_l2_normalize, .checkValue = SparsevecCheckValue}; PG_RETURN_POINTER(&typeInfo); }; diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp index de9558961f..9266f69ca9 100644 --- a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -12,8 +12,7 @@ /* * Check if deleted list contains an index TID */ -static bool -DeletedContains(tidhash_hash * deleted, ItemPointer indextid) +static bool DeletedContains(tidhash_hash *deleted, ItemPointer indextid) { return tidhash_lookup(deleted, *indextid) != NULL; } @@ -23,8 +22,7 @@ DeletedContains(tidhash_hash * deleted, ItemPointer indextid) * * OK to remove for entry point, since always considered for searches and inserts */ -static void -RemoveHeapTids(HnswVacuumState * vacuumstate) +static void RemoveHeapTids(HnswVacuumState *vacuumstate) { BlockNumber blkno = HNSW_HEAD_BLKNO; HnswElement highestPoint = &vacuumstate->highestPoint; @@ -58,7 +56,7 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) /* Iterate over nodes */ for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswElementTuple etup = (HnswElementTuple)PageGetItem(page, PageGetItemId(page, offno)); int idx = 0; bool itemUpdated = false; @@ -72,7 +70,8 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) if (!ItemPointerIsValid(&etup->heaptids[i])) break; - if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, InvalidBktId)) { + if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, + InvalidBktId)) { itemUpdated = true; stats->tuples_removed++; } else { @@ -100,7 +99,8 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) tidhash_insert(vacuumstate->deleted, ip, &found); Assert(!found); - } else if (etup->level > highestLevel && !(entryPoint != NULL && blkno == entryPoint->blkno && offno == entryPoint->offno)) { + } else if (etup->level > highestLevel && + !(entryPoint != NULL && blkno == entryPoint->blkno && offno == entryPoint->offno)) { /* Keep track of highest non-entry point */ highestPoint->blkno = blkno; highestPoint->offno = offno; @@ -123,8 +123,7 @@ RemoveHeapTids(HnswVacuumState * vacuumstate) /* * Check for deleted neighbors */ -static bool -NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) +static bool NeedsUpdated(HnswVacuumState *vacuumstate, HnswElement element) { Relation index = vacuumstate->index; BufferAccessStrategy bas = vacuumstate->bas; @@ -136,7 +135,7 @@ NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) buf = ReadBufferExtended(index, MAIN_FORKNUM, element->neighborPage, RBM_NORMAL, bas); LockBuffer(buf, BUFFER_LOCK_SHARE); page = BufferGetPage(buf); - ntup = (HnswNeighborTuple) PageGetItem(page, PageGetItemId(page, element->neighborOffno)); + ntup = (HnswNeighborTuple)PageGetItem(page, PageGetItemId(page, element->neighborOffno)); Assert(HnswIsNeighborTuple(ntup)); @@ -167,8 +166,7 @@ NeedsUpdated(HnswVacuumState * vacuumstate, HnswElement element) /* * Repair graph for a single element */ -static void -RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswElement entryPoint) +static void RepairGraphElement(HnswVacuumState *vacuumstate, HnswElement element, HnswElement entryPoint) { Relation index = vacuumstate->index; Buffer buf; @@ -208,7 +206,7 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme page = GenericXLogRegisterBuffer(state, buf, 0); /* Overwrite tuple */ - if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item) ntup, ntupSize)) + if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item)ntup, ntupSize)) elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); /* Commit */ @@ -222,8 +220,7 @@ RepairGraphElement(HnswVacuumState * vacuumstate, HnswElement element, HnswEleme /* * Repair graph entry point */ -static void -RepairGraphEntryPoint(HnswVacuumState * vacuumstate) +static void RepairGraphEntryPoint(HnswVacuumState *vacuumstate) { Relation index = vacuumstate->index; HnswElement highestPoint = &vacuumstate->highestPoint; @@ -281,7 +278,7 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) if (NeedsUpdated(vacuumstate, entryPoint)) { /* Reset neighbors from previous update */ if (highestPoint != NULL) - HnswPtrStore((char *) NULL, highestPoint->neighbors, (HnswNeighborArrayPtr *) NULL); + HnswPtrStore((char *)NULL, highestPoint->neighbors, (HnswNeighborArrayPtr *)NULL); RepairGraphElement(vacuumstate, entryPoint, highestPoint); } @@ -299,8 +296,7 @@ RepairGraphEntryPoint(HnswVacuumState * vacuumstate) /* * Repair graph for all elements */ -static void -RepairGraph(HnswVacuumState * vacuumstate) +static void RepairGraph(HnswVacuumState *vacuumstate) { Relation index = vacuumstate->index; BufferAccessStrategy bas = vacuumstate->bas; @@ -336,7 +332,7 @@ RepairGraph(HnswVacuumState * vacuumstate) /* Load items into memory to minimize locking */ for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswElementTuple etup = (HnswElementTuple)PageGetItem(page, PageGetItemId(page, offno)); HnswElement element; /* Skip neighbor tuples */ @@ -359,8 +355,8 @@ RepairGraph(HnswVacuumState * vacuumstate) UnlockReleaseBuffer(buf); /* Update neighbor pages */ - foreach(lc2, elements) { - HnswElement element = (HnswElement) lfirst(lc2); + foreach (lc2, elements) { + HnswElement element = (HnswElement)lfirst(lc2); HnswElement entryPoint; LOCKMODE lockmode = ShareLock; @@ -410,8 +406,7 @@ RepairGraph(HnswVacuumState * vacuumstate) /* * Mark items as deleted */ -static void -MarkDeleted(HnswVacuumState * vacuumstate) +static void MarkDeleted(HnswVacuumState *vacuumstate) { BlockNumber blkno = HNSW_HEAD_BLKNO; BlockNumber insertPage = InvalidBlockNumber; @@ -451,7 +446,7 @@ MarkDeleted(HnswVacuumState * vacuumstate) /* Update element and neighbors together */ for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { - HnswElementTuple etup = (HnswElementTuple) PageGetItem(page, PageGetItemId(page, offno)); + HnswElementTuple etup = (HnswElementTuple)PageGetItem(page, PageGetItemId(page, offno)); HnswNeighborTuple ntup; Buffer nbuf; Page npage; @@ -488,7 +483,7 @@ MarkDeleted(HnswVacuumState * vacuumstate) npage = GenericXLogRegisterBuffer(state, nbuf, 0); } - ntup = (HnswNeighborTuple) PageGetItem(npage, PageGetItemId(npage, neighborOffno)); + ntup = (HnswNeighborTuple)PageGetItem(npage, PageGetItemId(npage, neighborOffno)); /* Overwrite element */ etup->deleted = 1; @@ -530,13 +525,13 @@ MarkDeleted(HnswVacuumState * vacuumstate) /* * Initialize the vacuum state */ -static void -InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) +static void InitVacuumState(HnswVacuumState *vacuumstate, IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) { Relation index = info->index; if (stats == NULL) - stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + stats = (IndexBulkDeleteResult *)palloc0(sizeof(IndexBulkDeleteResult)); vacuumstate->index = index; vacuumstate->stats = stats; @@ -547,9 +542,8 @@ InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkD vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); vacuumstate->collation = index->rd_indcollation[0]; vacuumstate->ntup = (HnswNeighborTuple)palloc0(HNSW_TUPLE_ALLOC_SIZE); - vacuumstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, - "Hnsw vacuum temporary context", - ALLOCSET_DEFAULT_SIZES); + vacuumstate->tmpCtx = + AllocSetContextCreate(CurrentMemoryContext, "Hnsw vacuum temporary context", ALLOCSET_DEFAULT_SIZES); /* Get m from metapage */ HnswGetMetaPageInfo(index, &vacuumstate->m, NULL); @@ -561,8 +555,7 @@ InitVacuumState(HnswVacuumState * vacuumstate, IndexVacuumInfo *info, IndexBulkD /* * Free resources */ -static void -FreeVacuumState(HnswVacuumState * vacuumstate) +static void FreeVacuumState(HnswVacuumState *vacuumstate) { tidhash_destroy(vacuumstate->deleted); FreeAccessStrategy(vacuumstate->bas); @@ -573,9 +566,8 @@ FreeVacuumState(HnswVacuumState * vacuumstate) /* * Bulk delete tuples from the index */ -IndexBulkDeleteResult * -hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) +IndexBulkDeleteResult *hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) { HnswVacuumState vacuumstate; @@ -598,8 +590,7 @@ hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* * Clean up after a VACUUM operation */ -IndexBulkDeleteResult * -hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) +IndexBulkDeleteResult *hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { Relation rel = info->index; diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index 7db0050482..b7e06c4c17 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -33,16 +33,15 @@ #include "utils/wait_event.h" #endif -#define PARALLEL_KEY_IVFFLAT_SHARED UINT64CONST(0xA000000000000001) -#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xA000000000000002) -#define PARALLEL_KEY_IVFFLAT_CENTERS UINT64CONST(0xA000000000000003) -#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000004) +#define PARALLEL_KEY_IVFFLAT_SHARED UINT64CONST(0xA000000000000001) +#define PARALLEL_KEY_TUPLESORT UINT64CONST(0xA000000000000002) +#define PARALLEL_KEY_IVFFLAT_CENTERS UINT64CONST(0xA000000000000003) +#define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xA000000000000004) /* * Add sample */ -static void -AddSample(Datum *values, IvfflatBuildState *buildstate) +static void AddSample(Datum *values, IvfflatBuildState *buildstate) { VectorArray samples = buildstate->samples; int targsamples = samples->maxlen; @@ -71,7 +70,7 @@ AddSample(Datum *values, IvfflatBuildState *buildstate) } if (buildstate->rowstoskip <= 0) { - int k = (int) (targsamples * anl_random_fract()); + int k = (int)(targsamples * anl_random_fract()); Assert(k >= 0 && k < targsamples); VectorArraySet(samples, k, DatumGetPointer(value)); } @@ -83,11 +82,10 @@ AddSample(Datum *values, IvfflatBuildState *buildstate) /* * Callback for sampling */ -static void -SampleCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, - const bool *isnull, bool tupleIsAlive, void *state) +static void SampleCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, const bool *isnull, bool tupleIsAlive, + void *state) { - IvfflatBuildState *buildstate = (IvfflatBuildState *) state; + IvfflatBuildState *buildstate = (IvfflatBuildState *)state; MemoryContext oldCtx; /* Skip nulls */ @@ -109,8 +107,7 @@ SampleCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, /* * Sample rows with same logic as ANALYZE */ -static void -SampleRows(IvfflatBuildState *buildstate) +static void SampleRows(IvfflatBuildState *buildstate) { int targsamples = buildstate->samples->maxlen; BlockNumber totalblocks = RelationGetNumberOfBlocks(buildstate->heap); @@ -123,16 +120,15 @@ SampleRows(IvfflatBuildState *buildstate) while (BlockSampler_HasMore(&buildstate->bs)) { BlockNumber targblock = BlockSampler_Next(&buildstate->bs); - tableam_index_build_scan(buildstate->heap, buildstate->index, buildstate->indexInfo, - false, SampleCallback, (void *) buildstate, NULL, targblock, 1); + tableam_index_build_scan(buildstate->heap, buildstate->index, buildstate->indexInfo, false, SampleCallback, + (void *)buildstate, NULL, targblock, 1); } } /* * Add tuple to sort */ -static void -AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState * buildstate) +static void AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState *buildstate) { double distance; double minDistance = DBL_MAX; @@ -153,7 +149,8 @@ AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState /* Find the list that minimizes the distance */ for (int i = 0; i < centers->length; i++) { - distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, value, PointerGetDatum(VectorArrayGet(centers, i)))); + distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, value, + PointerGetDatum(VectorArrayGet(centers, i)))); if (distance < minDistance) { minDistance = distance; @@ -191,11 +188,10 @@ AddTupleToSort(Relation index, ItemPointer tid, Datum *values, IvfflatBuildState /* * Callback for table_index_build_scan */ -static void -BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, - const bool *isnull, bool tupleIsAlive, void *state) +static void BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, const bool *isnull, bool tupleIsAlive, + void *state) { - IvfflatBuildState *buildstate = (IvfflatBuildState *) state; + IvfflatBuildState *buildstate = (IvfflatBuildState *)state; MemoryContext oldCtx; #if PG_VERSION_NUM < 130000 @@ -220,8 +216,8 @@ BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, /* * Get index tuple from sort state */ -static inline void -GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, IndexTuple *itup, int *list) +static inline void GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, IndexTuple *itup, + int *list) { Datum value; bool isnull; @@ -232,7 +228,7 @@ GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, /* Form the index tuple */ *itup = index_form_tuple(tupdesc, &value, &isnull); - (*itup)->t_tid = *((ItemPointer) DatumGetPointer(heap_slot_getattr(slot, 2, &isnull))); + (*itup)->t_tid = *((ItemPointer)DatumGetPointer(heap_slot_getattr(slot, 2, &isnull))); } else *list = -1; } @@ -240,11 +236,10 @@ GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, TupleTableSlot *slot, /* * Create initial entry pages */ -static void -InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) +static void InsertTuples(Relation index, IvfflatBuildState *buildstate, ForkNumber forkNum) { int list; - IndexTuple itup = NULL; /* silence compiler warning */ + IndexTuple itup = NULL; /* silence compiler warning */ int64 inserted = 0; TupleTableSlot *slot = MakeSingleTupleTableSlot(buildstate->tupdesc); @@ -277,7 +272,7 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) IvfflatAppendPage(index, &buf, &page, &state, forkNum); /* Add the item */ - if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) + if (PageAddItem(page, (Item)itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); pfree(itup); @@ -299,8 +294,7 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum) /* * Initialize the build state */ -static void -InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, IndexInfo *indexInfo) +static void InitBuildState(IvfflatBuildState *buildstate, Relation heap, Relation index, IndexInfo *indexInfo) { buildstate->heap = heap; buildstate->index = index; @@ -319,7 +313,8 @@ InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, In elog(ERROR, "column does not have dimensions"); if (buildstate->dimensions > buildstate->typeInfo->maxDimensions) - elog(ERROR, "column cannot have more than %d dimensions for ivfflat index", buildstate->typeInfo->maxDimensions); + elog(ERROR, "column cannot have more than %d dimensions for ivfflat index", + buildstate->typeInfo->maxDimensions); buildstate->reltuples = 0; buildstate->indtuples = 0; @@ -336,18 +331,18 @@ InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, In /* Create tuple description for sorting */ buildstate->tupdesc = CreateTemplateTupleDesc(3, false); - TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 1, "list", INT4OID, -1, 0); - TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 2, "tid", TIDOID, -1, 0); - TupleDescInitEntry(buildstate->tupdesc, (AttrNumber) 3, "vector", RelationGetDescr(index)->attrs[0].atttypid, -1, 0); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber)1, "list", INT4OID, -1, 0); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber)2, "tid", TIDOID, -1, 0); + TupleDescInitEntry(buildstate->tupdesc, (AttrNumber)3, "vector", RelationGetDescr(index)->attrs[0].atttypid, -1, 0); buildstate->slot = MakeSingleTupleTableSlot(buildstate->tupdesc); - buildstate->centers = VectorArrayInit(buildstate->lists, buildstate->dimensions, buildstate->typeInfo->itemSize(buildstate->dimensions)); + buildstate->centers = VectorArrayInit(buildstate->lists, buildstate->dimensions, + buildstate->typeInfo->itemSize(buildstate->dimensions)); buildstate->listInfo = (ListInfo *)palloc(sizeof(ListInfo) * buildstate->lists); - buildstate->tmpCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat build temporary context", - ALLOCSET_DEFAULT_SIZES); + buildstate->tmpCtx = + AllocSetContextCreate(CurrentMemoryContext, "Ivfflat build temporary context", ALLOCSET_DEFAULT_SIZES); #ifdef IVFFLAT_KMEANS_DEBUG buildstate->inertia = 0; @@ -360,8 +355,7 @@ InitBuildState(IvfflatBuildState * buildstate, Relation heap, Relation index, In /* * Free resources */ -static void -FreeBuildState(IvfflatBuildState * buildstate) +static void FreeBuildState(IvfflatBuildState *buildstate) { VectorArrayFree(buildstate->centers); pfree(buildstate->listInfo); @@ -377,8 +371,7 @@ FreeBuildState(IvfflatBuildState * buildstate) /* * Compute centers */ -static void -ComputeCenters(IvfflatBuildState *buildstate) +static void ComputeCenters(IvfflatBuildState *buildstate) { int numSamples; @@ -400,16 +393,14 @@ ComputeCenters(IvfflatBuildState *buildstate) if (buildstate->heap != NULL) { SampleRows(buildstate); if (buildstate->samples->length < buildstate->lists) { - ereport(NOTICE, - (errmsg("ivfflat index created with little data"), - errdetail("This will cause low recall."), - errhint("Drop the index until the table has more data."))); + ereport(NOTICE, (errmsg("ivfflat index created with little data"), errdetail("This will cause low recall."), + errhint("Drop the index until the table has more data."))); } } /* Calculate centers */ - IvfflatBench("k-means", IvfflatKmeans(buildstate->index, buildstate->samples, - buildstate->centers, buildstate->typeInfo)); + IvfflatBench("k-means", + IvfflatKmeans(buildstate->index, buildstate->samples, buildstate->centers, buildstate->typeInfo)); /* Free samples before we allocate more memory */ VectorArrayFree(buildstate->samples); @@ -418,8 +409,7 @@ ComputeCenters(IvfflatBuildState *buildstate) /* * Create the metapage */ -static void -CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) +static void CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) { Buffer buf; Page page; @@ -435,8 +425,7 @@ CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) metap->version = IVFFLAT_VERSION; metap->dimensions = dimensions; metap->lists = lists; - ((PageHeader) page)->pd_lower = - ((char *) metap + sizeof(IvfflatMetaPageData)) - (char *) page; + ((PageHeader)page)->pd_lower = ((char *)metap + sizeof(IvfflatMetaPageData)) - (char *)page; IvfflatCommitBuffer(buf, state); } @@ -444,9 +433,8 @@ CreateMetaPage(Relation index, int dimensions, int lists, ForkNumber forkNum) /* * Create list pages */ -static void -CreateListPages(Relation index, VectorArray centers, int dimensions, - int lists, ForkNumber forkNum, ListInfo * *listInfo) +static void CreateListPages(Relation index, VectorArray centers, int dimensions, int lists, ForkNumber forkNum, + ListInfo **listInfo) { Buffer buf; Page page; @@ -476,7 +464,7 @@ CreateListPages(Relation index, VectorArray centers, int dimensions, IvfflatAppendPage(index, &buf, &page, &state, forkNum); /* Add the item */ - offno = PageAddItem(page, (Item) list, listSize, InvalidOffsetNumber, false, false); + offno = PageAddItem(page, (Item)list, listSize, InvalidOffsetNumber, false, false); if (offno == InvalidOffsetNumber) elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); @@ -494,8 +482,7 @@ CreateListPages(Relation index, VectorArray centers, int dimensions, /* * Print k-means metrics */ -static void -PrintKmeansMetrics(IvfflatBuildState * buildstate) +static void PrintKmeansMetrics(IvfflatBuildState *buildstate) { elog(INFO, "inertia: %.3e", buildstate->inertia); @@ -517,7 +504,9 @@ PrintKmeansMetrics(IvfflatBuildState * buildstate) if (j == i) continue; - distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, PointerGetDatum(VectorArrayGet(buildstate->centers, i)), PointerGetDatum(VectorArrayGet(buildstate->centers, j)))); + distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, + PointerGetDatum(VectorArrayGet(buildstate->centers, i)), + PointerGetDatum(VectorArrayGet(buildstate->centers, j)))); distance = (buildstate->listSums[i] + buildstate->listSums[j]) / distance; if (distance > max) @@ -534,8 +523,7 @@ PrintKmeansMetrics(IvfflatBuildState * buildstate) /* * Within leader, wait for end of heap scan */ -static double -ParallelHeapScan(IvfflatBuildState * buildstate) +static double ParallelHeapScan(IvfflatBuildState *buildstate) { IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; double reltuples; @@ -560,8 +548,7 @@ ParallelHeapScan(IvfflatBuildState * buildstate) /* * Perform a worker's portion of a parallel sort */ -static void -IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, Vector *ivfcenters) +static void IvfflatParallelScanAndSort(IvfflatSpool *ivfspool, IvfflatShared *ivfshared, Vector *ivfcenters) { SortCoordinate coordinate; IvfflatBuildState buildstate; @@ -589,12 +576,13 @@ IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, V InitBuildState(&buildstate, ivfspool->heap, ivfspool->index, indexInfo); memcpy(buildstate.centers->items, ivfcenters, VECTOR_SIZE(buildstate.centers->dim) * buildstate.centers->maxlen); buildstate.centers->length = buildstate.centers->maxlen; - ivfspool->sortstate = tuplesort_begin_heap(buildstate.tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, sortmem, false, 0, 0, 1, coordinate); + ivfspool->sortstate = tuplesort_begin_heap(buildstate.tupdesc, 1, attNums, sortOperators, sortCollations, + nullsFirstFlags, sortmem, false, 0, 0, 1, coordinate); buildstate.sortstate = ivfspool->sortstate; scan = tableam_scan_begin_parallel(ivfspool->heap, &ivfshared->heapdesc); - reltuples = tableam_index_build_scan(ivfspool->heap, ivfspool->index, indexInfo, - true, BuildCallback, (void *) &buildstate, scan); + reltuples = tableam_index_build_scan(ivfspool->heap, ivfspool->index, indexInfo, true, BuildCallback, + (void *)&buildstate, scan); /* Execute this worker's part of the sort */ tuplesort_performsort(ivfspool->sortstate); @@ -618,22 +606,21 @@ IvfflatParallelScanAndSort(IvfflatSpool * ivfspool, IvfflatShared * ivfshared, V /* * Perform work within a launched parallel process */ -void -IvfflatParallelBuildMain(const BgWorkerContext *bwc) +void IvfflatParallelBuildMain(const BgWorkerContext *bwc) { IvfflatSpool *ivfspool; IvfflatShared *ivfshared; Relation heapRel; Relation indexRel; - ivfshared = (IvfflatShared*)bwc->bgshared; + ivfshared = (IvfflatShared *)bwc->bgshared; /* Open relations within worker */ heapRel = heap_open(ivfshared->heaprelid, NoLock); indexRel = index_open(ivfshared->indexrelid, NoLock); /* Initialize worker's own spool */ - ivfspool = (IvfflatSpool *) palloc0(sizeof(IvfflatSpool)); + ivfspool = (IvfflatSpool *)palloc0(sizeof(IvfflatSpool)); ivfspool->heap = heapRel; ivfspool->index = indexRel; @@ -647,10 +634,9 @@ IvfflatParallelBuildMain(const BgWorkerContext *bwc) /* * End parallel build */ -static void -IvfflatParallelCleanup(const BgWorkerContext *bwc) +static void IvfflatParallelCleanup(const BgWorkerContext *bwc) { - IvfflatShared *ivfshared = (IvfflatShared*)bwc->bgshared; + IvfflatShared *ivfshared = (IvfflatShared *)bwc->bgshared; /* delete shared fileset */ Assert(ivfshared->sharedsort); @@ -658,8 +644,7 @@ IvfflatParallelCleanup(const BgWorkerContext *bwc) pfree_ext(ivfshared->sharedsort); } -static IvfflatShared* -IvfflatParallelInitshared(IvfflatBuildState * buildstate, int workmem, int scantuplesortstates) +static IvfflatShared *IvfflatParallelInitshared(IvfflatBuildState *buildstate, int workmem, int scantuplesortstates) { IvfflatShared *ivfshared; Sharedsort *sharedsort; @@ -668,7 +653,8 @@ IvfflatParallelInitshared(IvfflatBuildState * buildstate, int workmem, int scant char *ivfcenters; /* Store shared build state, for which we reserved space */ - ivfshared = (IvfflatShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), sizeof(IvfflatShared)); + ivfshared = (IvfflatShared *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), + sizeof(IvfflatShared)); /* Initialize immutable state */ ivfshared->heaprelid = RelationGetRelid(buildstate->heap); @@ -695,7 +681,7 @@ IvfflatParallelInitshared(IvfflatBuildState * buildstate, int workmem, int scant estcenters = VECTOR_SIZE(buildstate->dimensions) * buildstate->lists; ivfcenters = (char *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estcenters); memcpy(ivfcenters, buildstate->centers->items, estcenters); - ivfshared->ivfcenters = (Vector*)ivfcenters; + ivfshared->ivfcenters = (Vector *)ivfcenters; return ivfshared; } @@ -703,17 +689,17 @@ IvfflatParallelInitshared(IvfflatBuildState * buildstate, int workmem, int scant /* * Begin parallel build */ -static void -IvfflatBeginParallel(IvfflatBuildState * buildstate, int request, int workmem) +static void IvfflatBeginParallel(IvfflatBuildState *buildstate, int request, int workmem) { IvfflatShared *ivfshared; - IvfflatLeader *ivfleader = (IvfflatLeader *) palloc0(sizeof(IvfflatLeader)); + IvfflatLeader *ivfleader = (IvfflatLeader *)palloc0(sizeof(IvfflatLeader)); Assert(request > 0); ivfshared = IvfflatParallelInitshared(buildstate, workmem, request); /* Launch workers, saving status for leader/caller */ - ivfleader->nparticipanttuplesorts = LaunchBackgroundWorkers(request, ivfshared, IvfflatParallelBuildMain, IvfflatParallelCleanup); + ivfleader->nparticipanttuplesorts = + LaunchBackgroundWorkers(request, ivfshared, IvfflatParallelBuildMain, IvfflatParallelCleanup); /* If no workers were successfully launched, back out (do serial build) */ if (ivfleader->nparticipanttuplesorts == 0) { @@ -730,7 +716,7 @@ IvfflatBeginParallel(IvfflatBuildState * buildstate, int request, int workmem) buildstate->ivfleader = ivfleader; } -static double AssignTupleUtility(IvfflatBuildState * buildstate) +static double AssignTupleUtility(IvfflatBuildState *buildstate) { Relation heap = buildstate->heap; Relation index = buildstate->index; @@ -739,8 +725,8 @@ static double AssignTupleUtility(IvfflatBuildState * buildstate) /* Fill spool using either serial or parallel heap scan */ if (!buildstate->ivfleader) { -serial_build: - reltuples = tableam_index_build_scan(heap, index, indexInfo, true, BuildCallback, (void*)buildstate, NULL); + serial_build: + reltuples = tableam_index_build_scan(heap, index, indexInfo, true, BuildCallback, (void *)buildstate, NULL); } else { reltuples = ParallelHeapScan(buildstate); IvfflatShared *ivfshared = buildstate->ivfleader->ivfshared; @@ -764,8 +750,7 @@ void IvfflatEndParallel() /* * Scan table for tuples to index */ -static void -AssignTuples(IvfflatBuildState * buildstate) +static void AssignTuples(IvfflatBuildState *buildstate) { SortCoordinate coordinate = NULL; int parallel_workers = 0; @@ -779,8 +764,8 @@ AssignTuples(IvfflatBuildState * buildstate) Oid sortCollations[] = {InvalidOid}; bool nullsFirstFlags[] = {false}; - workmem = (desc->query_mem[0] > 0) ? (desc->query_mem[0] - SIMPLE_THRESHOLD) : - u_sess->attr.attr_memory.maintenance_work_mem; + workmem = (desc->query_mem[0] > 0) ? (desc->query_mem[0] - SIMPLE_THRESHOLD) + : u_sess->attr.attr_memory.maintenance_work_mem; /* Calculate parallel workers */ if (buildstate->heap != NULL) @@ -789,20 +774,21 @@ AssignTuples(IvfflatBuildState * buildstate) /* Attempt to launch parallel worker scan when required */ if (parallel_workers > 0) { Assert(!indexInfo->ii_Concurrent); - IvfflatBeginParallel(buildstate, parallel_workers,workmem); + IvfflatBeginParallel(buildstate, parallel_workers, workmem); } /* Set up coordination state if at least one worker launched */ if (buildstate->ivfleader) { - coordinate = (SortCoordinate) palloc0(sizeof(SortCoordinateData)); + coordinate = (SortCoordinate)palloc0(sizeof(SortCoordinateData)); coordinate->isWorker = false; coordinate->nParticipants = buildstate->ivfleader->nparticipanttuplesorts; coordinate->sharedsort = buildstate->ivfleader->ivfshared->sharedsort; } /* Begin serial/leader tuplesort */ - buildstate->sortstate = tuplesort_begin_heap(buildstate->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, - u_sess->attr.attr_memory.maintenance_work_mem, false, 0, 0, 1, coordinate); + buildstate->sortstate = + tuplesort_begin_heap(buildstate->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, + u_sess->attr.attr_memory.maintenance_work_mem, false, 0, 0, 1, coordinate); /* Add tuples to sort */ if (buildstate->heap != NULL) { @@ -817,8 +803,7 @@ AssignTuples(IvfflatBuildState * buildstate) /* * Create entry pages */ -static void -CreateEntryPages(IvfflatBuildState * buildstate, ForkNumber forkNum) +static void CreateEntryPages(IvfflatBuildState *buildstate, ForkNumber forkNum) { /* Assign */ IvfflatBench("assign tuples", AssignTuples(buildstate)); @@ -840,9 +825,8 @@ CreateEntryPages(IvfflatBuildState * buildstate, ForkNumber forkNum) /* * Build the index */ -static void -BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, - IvfflatBuildState * buildstate, ForkNumber forkNum) +static void BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, IvfflatBuildState *buildstate, + ForkNumber forkNum) { InitBuildState(buildstate, heap, index, indexInfo); @@ -850,7 +834,8 @@ BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, /* Create pages */ CreateMetaPage(index, buildstate->dimensions, buildstate->lists, forkNum); - CreateListPages(index, buildstate->centers, buildstate->dimensions, buildstate->lists, forkNum, &buildstate->listInfo); + CreateListPages(index, buildstate->centers, buildstate->dimensions, buildstate->lists, forkNum, + &buildstate->listInfo); CreateEntryPages(buildstate, forkNum); /* Write WAL for initialization fork since GenericXLog functions do not */ @@ -863,15 +848,14 @@ BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, /* * Build the index for a logged table */ -IndexBuildResult * -ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) +IndexBuildResult *ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) { IndexBuildResult *result; IvfflatBuildState buildstate; BuildIndex(heap, index, indexInfo, &buildstate, MAIN_FORKNUM); - result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + result = (IndexBuildResult *)palloc(sizeof(IndexBuildResult)); result->heap_tuples = buildstate.reltuples; result->index_tuples = buildstate.indtuples; @@ -881,8 +865,7 @@ ivfflatbuild_internal(Relation heap, Relation index, IndexInfo *indexInfo) /* * Build the index for an unlogged table */ -void -ivfflatbuildempty_internal(Relation index) +void ivfflatbuildempty_internal(Relation index) { IndexInfo *indexInfo = BuildIndexInfo(index); IvfflatBuildState buildstate; diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index 009350b462..c039630fcc 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -16,25 +16,23 @@ static THR_LOCAL bool IvfflatNeedInitialization = true; /* * Initialize index options and variables */ -void -IvfflatInit(void) +void IvfflatInit(void) { ivfflat_relopt_kind = add_reloption_kind(); - add_int_reloption(ivfflat_relopt_kind, "lists", "Number of inverted lists", - IVFFLAT_DEFAULT_LISTS, IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS + add_int_reloption(ivfflat_relopt_kind, "lists", "Number of inverted lists", IVFFLAT_DEFAULT_LISTS, + IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS #if PG_VERSION_NUM >= 130000 - ,AccessExclusiveLock + , + AccessExclusiveLock #endif - ); + ); } /* * Estimate the cost of an index scan */ -static void -ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, - Cost *indexStartupCost, Cost *indexTotalCost, - Selectivity *indexSelectivity, double *indexCorrelation) +static void ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, + Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation) { GenericCosts costs; int lists; @@ -59,7 +57,7 @@ ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_cou index_close(index, NoLock); /* Get the ratio of lists that we need to visit */ - ratio = ((double) get_session_context()->ivfflat_probes) / lists; + ratio = ((double)get_session_context()->ivfflat_probes) / lists; if (ratio > 1.0) { ratio = 1.0; } @@ -71,8 +69,8 @@ ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_cou */ costs.numIndexTuples = path->indexinfo->tuples * ratio; - genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, - &costs.indexTotalCost, &costs.indexSelectivity, &costs.indexCorrelation); + genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, &costs.indexTotalCost, + &costs.indexSelectivity, &costs.indexCorrelation); get_tablespace_page_costs(path->indexinfo->reltablespace, NULL, &spc_seq_page_cost); @@ -106,19 +104,15 @@ ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, double loop_cou /* * Parse and validate the reloptions */ -static bytea * -ivfflatoptions_internal(Datum reloptions, bool validate) +static bytea *ivfflatoptions_internal(Datum reloptions, bool validate) { static const relopt_parse_elt tab[] = { {"lists", RELOPT_TYPE_INT, offsetof(IvfflatOptions, lists)}, - {"parallel_workers", RELOPT_TYPE_INT, offsetof(StdRdOptions, parallel_workers)} - }; + {"parallel_workers", RELOPT_TYPE_INT, offsetof(StdRdOptions, parallel_workers)}}; #if PG_VERSION_NUM >= 130000 - return (bytea *) build_reloptions(reloptions, validate, - ivfflat_relopt_kind, - sizeof(IvfflatOptions), - tab, lengthof(tab)); + return (bytea *)build_reloptions(reloptions, validate, ivfflat_relopt_kind, sizeof(IvfflatOptions), tab, + lengthof(tab)); #else relopt_value *options; int numoptions; @@ -131,18 +125,16 @@ ivfflatoptions_internal(Datum reloptions, bool validate) options = parseRelOptions(reloptions, validate, ivfflat_relopt_kind, &numoptions); rdopts = (IvfflatOptions *)allocateReloptStruct(sizeof(IvfflatOptions), options, numoptions); - fillRelOptions((void *) rdopts, sizeof(IvfflatOptions), options, numoptions, - validate, tab, lengthof(tab)); + fillRelOptions((void *)rdopts, sizeof(IvfflatOptions), options, numoptions, validate, tab, lengthof(tab)); - return (bytea *) rdopts; + return (bytea *)rdopts; #endif } /* * Validate catalog entries for the specified operator class */ -static bool -ivfflatvalidate_internal(Oid opclassoid) +static bool ivfflatvalidate_internal(Oid opclassoid) { return true; } @@ -153,8 +145,7 @@ ivfflatvalidate_internal(Oid opclassoid) * See https://www.postgresql.org/docs/current/index-api.html */ PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflathandler); -Datum -ivfflathandler(PG_FUNCTION_ARGS) +Datum ivfflathandler(PG_FUNCTION_ARGS) { IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); @@ -165,7 +156,7 @@ ivfflathandler(PG_FUNCTION_ARGS) #endif amroutine->amcanorder = false; amroutine->amcanorderbyop = true; - amroutine->amcanbackward = false; /* can change direction mid-scan */ + amroutine->amcanbackward = false; /* can change direction mid-scan */ amroutine->amcanunique = false; amroutine->amcanmulticol = false; amroutine->amoptionalkey = true; @@ -213,8 +204,7 @@ ivfflathandler(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbuild); -Datum -ivfflatbuild(PG_FUNCTION_ARGS) +Datum ivfflatbuild(PG_FUNCTION_ARGS) { Relation heap = (Relation)PG_GETARG_POINTER(0); Relation index = (Relation)PG_GETARG_POINTER(1); @@ -225,8 +215,7 @@ ivfflatbuild(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbuildempty); -Datum -ivfflatbuildempty(PG_FUNCTION_ARGS) +Datum ivfflatbuildempty(PG_FUNCTION_ARGS) { Relation index = (Relation)PG_GETARG_POINTER(0); ivfflatbuildempty_internal(index); @@ -235,11 +224,10 @@ ivfflatbuildempty(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatinsert); -Datum -ivfflatinsert(PG_FUNCTION_ARGS) +Datum ivfflatinsert(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); - Datum * values = (Datum *)PG_GETARG_POINTER(1); + Datum *values = (Datum *)PG_GETARG_POINTER(1); bool *isnull = (bool *)PG_GETARG_POINTER(2); ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); Relation heaprel = (Relation)PG_GETARG_POINTER(4); @@ -250,8 +238,7 @@ ivfflatinsert(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbulkdelete); -Datum -ivfflatbulkdelete(PG_FUNCTION_ARGS) +Datum ivfflatbulkdelete(PG_FUNCTION_ARGS) { IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); @@ -263,8 +250,7 @@ ivfflatbulkdelete(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatvacuumcleanup); -Datum -ivfflatvacuumcleanup(PG_FUNCTION_ARGS) +Datum ivfflatvacuumcleanup(PG_FUNCTION_ARGS) { IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); @@ -274,8 +260,7 @@ ivfflatvacuumcleanup(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatcostestimate); -Datum -ivfflatcostestimate(PG_FUNCTION_ARGS) +Datum ivfflatcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); @@ -290,8 +275,7 @@ ivfflatcostestimate(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatoptions); -Datum -ivfflatoptions(PG_FUNCTION_ARGS) +Datum ivfflatoptions(PG_FUNCTION_ARGS) { Datum reloptions = PG_GETARG_DATUM(0); bool validate = PG_GETARG_BOOL(1); @@ -304,8 +288,7 @@ ivfflatoptions(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatvalidate); -Datum -ivfflatvalidate(PG_FUNCTION_ARGS) +Datum ivfflatvalidate(PG_FUNCTION_ARGS) { Oid opclassoid = PG_GETARG_OID(0); bool result = ivfflatvalidate_internal(opclassoid); @@ -314,8 +297,7 @@ ivfflatvalidate(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatbeginscan); -Datum -ivfflatbeginscan(PG_FUNCTION_ARGS) +Datum ivfflatbeginscan(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); int nkeys = PG_GETARG_INT32(1); @@ -326,8 +308,7 @@ ivfflatbeginscan(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatrescan); -Datum -ivfflatrescan(PG_FUNCTION_ARGS) +Datum ivfflatrescan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); ScanKey scankey = (ScanKey)PG_GETARG_POINTER(1); @@ -340,14 +321,14 @@ ivfflatrescan(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatgettuple); -Datum -ivfflatgettuple(PG_FUNCTION_ARGS) +Datum ivfflatgettuple(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); ScanDirection direction = (ScanDirection)PG_GETARG_INT32(1); if (NULL == scan) - ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function ivfflatgettuple"))); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Invalid arguments for function ivfflatgettuple"))); bool result = ivfflatgettuple_internal(scan, direction); @@ -355,8 +336,7 @@ ivfflatgettuple(PG_FUNCTION_ARGS) } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflatendscan); -Datum -ivfflatendscan(PG_FUNCTION_ARGS) +Datum ivfflatendscan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc)PG_GETARG_POINTER(0); ivfflatendscan_internal(scan); diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp index 0e201b4ae8..54c595d5f6 100644 --- a/src/gausskernel/storage/access/datavec/ivfinsert.cpp +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -11,8 +11,7 @@ /* * Find the list that minimizes the distance function */ -static void -FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo * listInfo) +static void FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo *listInfo) { double minDistance = DBL_MAX; BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; @@ -27,8 +26,7 @@ FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo collation = index->rd_indcollation[0]; /* Search all list pages */ - while (BlockNumberIsValid(nextblkno)) - { + while (BlockNumberIsValid(nextblkno)) { Buffer cbuf; Page cpage; OffsetNumber maxoffno; @@ -38,16 +36,15 @@ FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo cpage = BufferGetPage(cbuf); maxoffno = PageGetMaxOffsetNumber(cpage); - for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) - { + for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { IvfflatList list; double distance; - list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); - distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, values[0], PointerGetDatum(&list->center))); + list = (IvfflatList)PageGetItem(cpage, PageGetItemId(cpage, offno)); + distance = + DatumGetFloat8(FunctionCall2Coll(procinfo, collation, values[0], PointerGetDatum(&list->center))); - if (distance < minDistance || !BlockNumberIsValid(*insertPage)) - { + if (distance < minDistance || !BlockNumberIsValid(*insertPage)) { *insertPage = list->insertPage; listInfo->blkno = nextblkno; listInfo->offno = offno; @@ -64,8 +61,7 @@ FindInsertPage(Relation index, Datum *values, BlockNumber *insertPage, ListInfo /* * Insert a tuple into the index */ -static void -InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heapRel) +static void InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heapRel) { const IvfflatTypeInfo *typeInfo = IvfflatGetTypeInfo(index); IndexTuple itup; @@ -84,8 +80,7 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ /* Normalize if needed */ normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); - if (normprocinfo != NULL) - { + if (normprocinfo != NULL) { Oid collation = index->rd_indcollation[0]; if (!IvfflatCheckNorm(normprocinfo, collation, value)) @@ -108,7 +103,8 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ /* Get tuple size */ itemsz = MAXALIGN(IndexTupleSize(itup)); - Assert(itemsz <= BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)) - sizeof(ItemIdData)); + Assert(itemsz <= + BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)) - sizeof(ItemIdData)); /* Find a page to insert the item */ for (;;) { @@ -161,7 +157,7 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ } /* Add to next offset */ - if (PageAddItem(page, (Item) itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) + if (PageAddItem(page, (Item)itup, itemsz, InvalidOffsetNumber, false, false) == InvalidOffsetNumber) elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); IvfflatCommitBuffer(buf, state); @@ -174,8 +170,8 @@ InsertTuple(Relation index, Datum *values, const bool *isnull, ItemPointer heap_ /* * Insert a tuple into the index */ -bool -ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique) +bool ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, + IndexUniqueCheck checkUnique) { MemoryContext oldCtx; MemoryContext insertCtx; @@ -188,9 +184,7 @@ ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPo * Use memory context since detoast, IvfflatNormValue, and * index_form_tuple can allocate */ - insertCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat insert temporary context", - ALLOCSET_DEFAULT_SIZES); + insertCtx = AllocSetContextCreate(CurrentMemoryContext, "Ivfflat insert temporary context", ALLOCSET_DEFAULT_SIZES); oldCtx = MemoryContextSwitchTo(insertCtx); /* Insert tuple */ diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index cbeaea1aeb..8c3f3c8dd3 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -18,8 +18,7 @@ * * https://theory.stanford.edu/~sergei/papers/kMeansPP-soda.pdf */ -static void -InitCenters(Relation index, VectorArray samples, VectorArray centers, float *lowerBound) +static void InitCenters(Relation index, VectorArray samples, VectorArray centers, float *lowerBound) { FmgrInfo *procinfo; Oid collation; @@ -52,7 +51,8 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low /* Only need to compute distance for new center */ /* TODO Use triangle inequality to reduce distance calculations */ - distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, i)))); + distance = DatumGetFloat8( + FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, i)))); /* Set lower bound */ lowerBound[j * numCenters + i] = distance; @@ -88,12 +88,10 @@ InitCenters(Relation index, VectorArray samples, VectorArray centers, float *low /* * Norm centers */ -static void -NormCenters(const IvfflatTypeInfo * typeInfo, Oid collation, VectorArray centers) +static void NormCenters(const IvfflatTypeInfo *typeInfo, Oid collation, VectorArray centers) { - MemoryContext normCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat norm temporary context", - ALLOCSET_DEFAULT_SIZES); + MemoryContext normCtx = + AllocSetContextCreate(CurrentMemoryContext, "Ivfflat norm temporary context", ALLOCSET_DEFAULT_SIZES); MemoryContext oldCtx = MemoryContextSwitchTo(normCtx); for (int j = 0; j < centers->length; j++) { @@ -115,20 +113,19 @@ NormCenters(const IvfflatTypeInfo * typeInfo, Oid collation, VectorArray centers /* * Quick approach if we have no data */ -static void -RandomCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeInfo) +static void RandomCenters(Relation index, VectorArray centers, const IvfflatTypeInfo *typeInfo) { int dimensions = centers->dim; FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); Oid collation = index->rd_indcollation[0]; - float *x = (float *) palloc(sizeof(float) * dimensions); + float *x = (float *)palloc(sizeof(float) * dimensions); /* Fill with random data */ while (centers->length < centers->maxlen) { Pointer center = VectorArrayGet(centers, centers->length); for (int i = 0; i < dimensions; i++) - x[i] = (float) RandomDouble(); + x[i] = (float)RandomDouble(); typeInfo->updateCenter(center, dimensions, x); @@ -143,12 +140,10 @@ RandomCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeI /* * Show memory usage */ -static void -ShowMemoryUsage(MemoryContext context, Size estimatedSize) +static void ShowMemoryUsage(MemoryContext context, Size estimatedSize) { #if PG_VERSION_NUM >= 130000 - elog(INFO, "total memory: %zu MB", - MemoryContextMemAllocated(context, true) / (1024 * 1024)); + elog(INFO, "total memory: %zu MB", MemoryContextMemAllocated(context, true) / (1024 * 1024)); #else MemoryContextStats(context); #endif @@ -159,11 +154,10 @@ ShowMemoryUsage(MemoryContext context, Size estimatedSize) /* * Sum centers */ -static void -SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTypeInfo * typeInfo) +static void SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTypeInfo *typeInfo) { for (int j = 0; j < samples->length; j++) { - float *x = agg + ((int64) closestCenters[j] * samples->dim); + float *x = agg + ((int64)closestCenters[j] * samples->dim); typeInfo->sumCenter(VectorArrayGet(samples, j), x); } @@ -172,11 +166,10 @@ SumCenters(VectorArray samples, float *agg, int *closestCenters, const IvfflatTy /* * Update centers */ -static void -UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo) +static void UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo *typeInfo) { for (int j = 0; j < centers->length; j++) { - float *x = agg + ((int64) j * centers->dim); + float *x = agg + ((int64)j * centers->dim); typeInfo->updateCenter(VectorArrayGet(centers, j), centers->dim, x); } @@ -185,8 +178,9 @@ UpdateCenters(float *agg, VectorArray centers, const IvfflatTypeInfo * typeInfo) /* * Compute new centers */ -static void -ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *centerCounts, int *closestCenters, FmgrInfo *normprocinfo, Oid collation, const IvfflatTypeInfo * typeInfo) +static void ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int *centerCounts, + int *closestCenters, FmgrInfo *normprocinfo, Oid collation, + const IvfflatTypeInfo *typeInfo) { int dimensions = newCenters->dim; int numCenters = newCenters->length; @@ -194,7 +188,7 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int * /* Reset sum and count */ for (int j = 0; j < numCenters; j++) { - float *x = agg + ((int64) j * dimensions); + float *x = agg + ((int64)j * dimensions); for (int k = 0; k < dimensions; k++) x[k] = 0.0; @@ -211,7 +205,7 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int * /* Divide sum by count */ for (int j = 0; j < numCenters; j++) { - float *x = agg + ((int64) j * dimensions); + float *x = agg + ((int64)j * dimensions); if (centerCounts[j] > 0) { /* Double avoids overflow, but requires more memory */ @@ -246,8 +240,7 @@ ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCenters, int * * * https://www.aaai.org/Papers/ICML/2003/ICML03-022.pdf */ -static void -ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo) +static void ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo *typeInfo) { FmgrInfo *procinfo; FmgrInfo *normprocinfo; @@ -269,7 +262,7 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff Size samplesSize = VECTOR_ARRAY_SIZE(samples->maxlen, samples->itemsize); Size centersSize = VECTOR_ARRAY_SIZE(centers->maxlen, centers->itemsize); Size newCentersSize = VECTOR_ARRAY_SIZE(numCenters, centers->itemsize); - Size aggSize = sizeof(float) * (int64) numCenters * dimensions; + Size aggSize = sizeof(float) * (int64)numCenters * dimensions; Size centerCountsSize = sizeof(int) * numCenters; Size closestCentersSize = sizeof(int) * numSamples; Size lowerBoundSize = sizeof(float) * numSamples * numCenters; @@ -279,15 +272,15 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff Size newcdistSize = sizeof(float) * numCenters; /* Calculate total size */ - Size totalSize = samplesSize + centersSize + newCentersSize + aggSize + centerCountsSize + closestCentersSize + lowerBoundSize + upperBoundSize + sSize + halfcdistSize + newcdistSize; + Size totalSize = samplesSize + centersSize + newCentersSize + aggSize + centerCountsSize + closestCentersSize + + lowerBoundSize + upperBoundSize + sSize + halfcdistSize + newcdistSize; /* Check memory requirements */ /* Add one to error message to ceil */ - if (totalSize > (Size) u_sess->attr.attr_memory.maintenance_work_mem * 1024L) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("memory required is %zu MB, maintenance_work_mem is %d MB", - totalSize / (1024 * 1024) + 1, u_sess->attr.attr_memory.maintenance_work_mem / 1024))); + if (totalSize > (Size)u_sess->attr.attr_memory.maintenance_work_mem * 1024L) + ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("memory required is %zu MB, maintenance_work_mem is %d MB", + totalSize / (1024 * 1024) + 1, u_sess->attr.attr_memory.maintenance_work_mem / 1024))); /* Ensure indexing does not overflow */ if (numCenters * numCenters > INT_MAX) @@ -353,7 +346,8 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff Datum vec = PointerGetDatum(VectorArrayGet(centers, j)); for (int64 k = j + 1; k < numCenters; k++) { - float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + float distance = 0.5 * DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, + PointerGetDatum(VectorArrayGet(centers, k)))); halfcdist[j * numCenters + k] = distance; halfcdist[k * numCenters + j] = distance; @@ -407,7 +401,8 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff /* Step 3a */ if (rj) { - dxcx = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j])))); + dxcx = DatumGetFloat8(FunctionCall2Coll( + procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, closestCenters[j])))); /* d(x,c(x)) computed, which is a form of d(x,c) */ lowerBound[j * numCenters + closestCenters[j]] = dxcx; @@ -419,7 +414,8 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff /* Step 3b */ if (dxcx > lowerBound[j * numCenters + k] || dxcx > halfcdist[closestCenters[j] * numCenters + k]) { - float dxc = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); + float dxc = DatumGetFloat8( + FunctionCall2Coll(procinfo, collation, vec, PointerGetDatum(VectorArrayGet(centers, k)))); /* d(x,c) calculated */ lowerBound[j * numCenters + k] = dxc; @@ -441,7 +437,9 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff /* Step 5 */ for (int j = 0; j < numCenters; j++) - newcdist[j] = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), PointerGetDatum(VectorArrayGet(newCenters, j)))); + newcdist[j] = + DatumGetFloat8(FunctionCall2Coll(procinfo, collation, PointerGetDatum(VectorArrayGet(centers, j)), + PointerGetDatum(VectorArrayGet(newCenters, j)))); for (int64 j = 0; j < numSamples; j++) { for (int64 k = 0; k < numCenters; k++) { @@ -471,8 +469,7 @@ ElkanKmeans(Relation index, VectorArray samples, VectorArray centers, const Ivff /* * Ensure no NaN or infinite values */ -static void -CheckElements(VectorArray centers, const IvfflatTypeInfo * typeInfo) +static void CheckElements(VectorArray centers, const IvfflatTypeInfo *typeInfo) { float *scratch = (float *)palloc(sizeof(float) * centers->dim); @@ -496,8 +493,7 @@ CheckElements(VectorArray centers, const IvfflatTypeInfo * typeInfo) /* * Ensure no zero vectors for cosine distance */ -static void -CheckNorms(VectorArray centers, Relation index) +static void CheckNorms(VectorArray centers, Relation index) { /* Check NORM_PROC instead of KMEANS_NORM_PROC */ FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); @@ -507,7 +503,8 @@ CheckNorms(VectorArray centers, Relation index) return; for (int i = 0; i < centers->length; i++) { - double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); + double norm = + DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); if (norm == 0) elog(ERROR, "Zero norm detected. Please report a bug."); @@ -517,8 +514,7 @@ CheckNorms(VectorArray centers, Relation index) /* * Detect issues with centers */ -static void -CheckCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeInfo) +static void CheckCenters(Relation index, VectorArray centers, const IvfflatTypeInfo *typeInfo) { if (centers->length != centers->maxlen) elog(ERROR, "Not enough centers. Please report a bug."); @@ -531,12 +527,10 @@ CheckCenters(Relation index, VectorArray centers, const IvfflatTypeInfo * typeIn * Perform naive k-means centering * We use spherical k-means for inner product and cosine */ -void -IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo * typeInfo) +void IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers, const IvfflatTypeInfo *typeInfo) { - MemoryContext kmeansCtx = AllocSetContextCreate(CurrentMemoryContext, - "Ivfflat kmeans temporary context", - ALLOCSET_DEFAULT_SIZES); + MemoryContext kmeansCtx = + AllocSetContextCreate(CurrentMemoryContext, "Ivfflat kmeans temporary context", ALLOCSET_DEFAULT_SIZES); MemoryContext oldCtx = MemoryContextSwitchTo(kmeansCtx); if (samples->length == 0) diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index 8499704dc3..1041e2d2ef 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -12,13 +12,12 @@ /* * Compare list distances */ -static int -CompareLists(const pairingheap_node *a, const pairingheap_node *b, void *arg) +static int CompareLists(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const IvfflatScanList *) a)->distance > ((const IvfflatScanList *) b)->distance) + if (((const IvfflatScanList *)a)->distance > ((const IvfflatScanList *)b)->distance) return 1; - if (((const IvfflatScanList *) a)->distance < ((const IvfflatScanList *) b)->distance) + if (((const IvfflatScanList *)a)->distance < ((const IvfflatScanList *)b)->distance) return -1; return 0; @@ -27,10 +26,9 @@ CompareLists(const pairingheap_node *a, const pairingheap_node *b, void *arg) /* * Get lists and sort by distance */ -static void -GetScanLists(IndexScanDesc scan, Datum value) +static void GetScanLists(IndexScanDesc scan, Datum value) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO; int listCount = 0; double maxDistance = DBL_MAX; @@ -48,7 +46,7 @@ GetScanLists(IndexScanDesc scan, Datum value) maxoffno = PageGetMaxOffsetNumber(cpage); for (OffsetNumber offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { - IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, offno)); + IvfflatList list = (IvfflatList)PageGetItem(cpage, PageGetItemId(cpage, offno)); double distance; /* Use procinfo from the index instead of scan key for performance */ @@ -67,12 +65,12 @@ GetScanLists(IndexScanDesc scan, Datum value) /* Calculate max distance */ if (listCount == so->probes) - maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; + maxDistance = ((IvfflatScanList *)pairingheap_first(so->listQueue))->distance; } else if (distance < maxDistance) { IvfflatScanList *scanlist; /* Remove */ - scanlist = (IvfflatScanList *) pairingheap_remove_first(so->listQueue); + scanlist = (IvfflatScanList *)pairingheap_remove_first(so->listQueue); /* Reuse */ scanlist->startPage = list->startPage; @@ -80,7 +78,7 @@ GetScanLists(IndexScanDesc scan, Datum value) pairingheap_add(so->listQueue, &scanlist->ph_node); /* Update max distance */ - maxDistance = ((IvfflatScanList *) pairingheap_first(so->listQueue))->distance; + maxDistance = ((IvfflatScanList *)pairingheap_first(so->listQueue))->distance; } } @@ -93,10 +91,9 @@ GetScanLists(IndexScanDesc scan, Datum value) /* * Get items */ -static void -GetScanItems(IndexScanDesc scan, Datum value) +static void GetScanItems(IndexScanDesc scan, Datum value) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; TupleDesc tupdesc = RelationGetDescr(scan->indexRelation); double tuples = 0; TupleTableSlot *slot = MakeSingleTupleTableSlot(so->tupdesc); @@ -110,7 +107,7 @@ GetScanItems(IndexScanDesc scan, Datum value) /* Search closest probes lists */ while (!pairingheap_is_empty(so->listQueue)) { - BlockNumber searchPage = ((IvfflatScanList *) pairingheap_remove_first(so->listQueue))->startPage; + BlockNumber searchPage = ((IvfflatScanList *)pairingheap_remove_first(so->listQueue))->startPage; /* Search all entry pages for list */ while (BlockNumberIsValid(searchPage)) { @@ -129,7 +126,7 @@ GetScanItems(IndexScanDesc scan, Datum value) bool isnull; ItemId itemid = PageGetItemId(page, offno); - itup = (IndexTuple) PageGetItem(page, itemid); + itup = (IndexTuple)PageGetItem(page, itemid); datum = index_getattr(itup, 1, tupdesc, &isnull); /* @@ -160,8 +157,7 @@ GetScanItems(IndexScanDesc scan, Datum value) if (tuples < 100) ereport(DEBUG1, - (errmsg("index scan found few tuples"), - errdetail("Index may have been created with little data."), + (errmsg("index scan found few tuples"), errdetail("Index may have been created with little data."), errhint("Recreate the index and possibly decrease lists."))); tuplesort_performsort(so->sortstate); @@ -170,8 +166,7 @@ GetScanItems(IndexScanDesc scan, Datum value) /* * Zero distance */ -static Datum -ZeroDistance(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) +static Datum ZeroDistance(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) { return Float8GetDatum(0.0); } @@ -179,10 +174,9 @@ ZeroDistance(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) /* * Get scan value */ -static Datum -GetScanValue(IndexScanDesc scan) +static Datum GetScanValue(IndexScanDesc scan) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; Datum value; if (scan->orderByData->sk_flags & SK_ISNULL) { @@ -207,8 +201,7 @@ GetScanValue(IndexScanDesc scan) /* * Prepare for an index scan */ -IndexScanDesc -ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) +IndexScanDesc ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) { IndexScanDesc scan; IvfflatScanOpaque so; @@ -232,7 +225,7 @@ ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) probes = lists; } - so = (IvfflatScanOpaque) palloc(offsetof(IvfflatScanOpaqueData, lists) + probes * sizeof(IvfflatScanList)); + so = (IvfflatScanOpaque)palloc(offsetof(IvfflatScanOpaqueData, lists) + probes * sizeof(IvfflatScanList)); so->typeInfo = IvfflatGetTypeInfo(index); so->first = true; so->probes = probes; @@ -245,8 +238,8 @@ ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) /* Create tuple description for sorting */ so->tupdesc = CreateTemplateTupleDesc(natts, false); - TupleDescInitEntry(so->tupdesc, (AttrNumber) attDistance, "distance", FLOAT8OID, -1, 0); - TupleDescInitEntry(so->tupdesc, (AttrNumber) attHeaptid, "heaptid", TIDOID, -1, 0); + TupleDescInitEntry(so->tupdesc, (AttrNumber)attDistance, "distance", FLOAT8OID, -1, 0); + TupleDescInitEntry(so->tupdesc, (AttrNumber)attHeaptid, "heaptid", TIDOID, -1, 0); /* Prep sort */ so->sortstate = tuplesort_begin_heap(so->tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, @@ -264,10 +257,9 @@ ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys) /* * Start or restart an index scan */ -void -ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) +void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; #if PG_VERSION_NUM >= 130000 if (!so->first) @@ -287,10 +279,9 @@ ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orde /* * Fetch the next tuple in the given scan */ -bool -ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) +bool ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; /* * Index can be used to scan backward, but Postgres doesn't support @@ -324,7 +315,7 @@ ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) } if (tuplesort_gettupleslot(so->sortstate, true, so->slot, NULL)) { - ItemPointer heaptid = (ItemPointer) DatumGetPointer(heap_slot_getattr(so->slot, 2, &so->isnull)); + ItemPointer heaptid = (ItemPointer)DatumGetPointer(heap_slot_getattr(so->slot, 2, &so->isnull)); scan->xs_ctup.t_self = *heaptid; scan->xs_recheck = false; @@ -337,10 +328,9 @@ ivfflatgettuple_internal(IndexScanDesc scan, ScanDirection dir) /* * End a scan and release resources */ -void -ivfflatendscan_internal(IndexScanDesc scan) +void ivfflatendscan_internal(IndexScanDesc scan) { - IvfflatScanOpaque so = (IvfflatScanOpaque) scan->opaque; + IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; pairingheap_free(so->listQueue); tuplesort_end(so->sortstate); diff --git a/src/gausskernel/storage/access/datavec/ivfutils.cpp b/src/gausskernel/storage/access/datavec/ivfutils.cpp index 3adf630c3b..d6b7d65032 100644 --- a/src/gausskernel/storage/access/datavec/ivfutils.cpp +++ b/src/gausskernel/storage/access/datavec/ivfutils.cpp @@ -12,8 +12,7 @@ /* * Allocate a vector array */ -VectorArray -VectorArrayInit(int maxlen, int dimensions, Size itemsize) +VectorArray VectorArrayInit(int maxlen, int dimensions, Size itemsize) { VectorArray res = (VectorArray)palloc(sizeof(VectorArrayData)); @@ -31,8 +30,7 @@ VectorArrayInit(int maxlen, int dimensions, Size itemsize) /* * Free a vector array */ -void -VectorArrayFree(VectorArray arr) +void VectorArrayFree(VectorArray arr) { pfree(arr->items); pfree(arr); @@ -41,10 +39,9 @@ VectorArrayFree(VectorArray arr) /* * Get the number of lists in the index */ -int -IvfflatGetLists(Relation index) +int IvfflatGetLists(Relation index) { - IvfflatOptions *opts = (IvfflatOptions *) index->rd_options; + IvfflatOptions *opts = (IvfflatOptions *)index->rd_options; if (opts) return opts->lists; @@ -55,8 +52,7 @@ IvfflatGetLists(Relation index) /* * Get proc */ -FmgrInfo * -IvfflatOptionalProcInfo(Relation index, uint16 procnum) +FmgrInfo *IvfflatOptionalProcInfo(Relation index, uint16 procnum) { if (!OidIsValid(index_getprocid(index, 1, procnum))) return NULL; @@ -67,8 +63,7 @@ IvfflatOptionalProcInfo(Relation index, uint16 procnum) /* * Normalize value */ -Datum -IvfflatNormValue(const IvfflatTypeInfo * typeInfo, Oid collation, Datum value) +Datum IvfflatNormValue(const IvfflatTypeInfo *typeInfo, Oid collation, Datum value) { return DirectFunctionCall1Coll(typeInfo->normalize, collation, value); } @@ -76,8 +71,7 @@ IvfflatNormValue(const IvfflatTypeInfo * typeInfo, Oid collation, Datum value) /* * Check if non-zero norm */ -bool -IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) +bool IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) { return DatumGetFloat8(FunctionCall1Coll(procinfo, collation, value)) > 0; } @@ -85,8 +79,7 @@ IvfflatCheckNorm(FmgrInfo *procinfo, Oid collation, Datum value) /* * New buffer */ -Buffer -IvfflatNewBuffer(Relation index, ForkNumber forkNum) +Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum) { Buffer buf = ReadBufferExtended(index, forkNum, P_NEW, RBM_NORMAL, NULL); @@ -97,8 +90,7 @@ IvfflatNewBuffer(Relation index, ForkNumber forkNum) /* * Init page */ -void -IvfflatInitPage(Buffer buf, Page page) +void IvfflatInitPage(Buffer buf, Page page) { PageInit(page, BufferGetPageSize(buf), sizeof(IvfflatPageOpaqueData)); IvfflatPageGetOpaque(page)->nextblkno = InvalidBlockNumber; @@ -108,8 +100,7 @@ IvfflatInitPage(Buffer buf, Page page) /* * Init and register page */ -void -IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state) +void IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state) { *state = GenericXLogStart(index); *page = GenericXLogRegisterBuffer(*state, *buf, GENERIC_XLOG_FULL_IMAGE); @@ -119,8 +110,7 @@ IvfflatInitRegisterPage(Relation index, Buffer *buf, Page *page, GenericXLogStat /* * Commit buffer */ -void -IvfflatCommitBuffer(Buffer buf, GenericXLogState *state) +void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state) { GenericXLogFinish(state); UnlockReleaseBuffer(buf); @@ -131,8 +121,7 @@ IvfflatCommitBuffer(Buffer buf, GenericXLogState *state) * * The order is very important!! */ -void -IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum) +void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum) { /* Get new buffer */ Buffer newbuf = IvfflatNewBuffer(index, forkNum); @@ -158,8 +147,7 @@ IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **st /* * Get the metapage info */ -void -IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) +void IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) { Buffer buf; Page page; @@ -185,10 +173,8 @@ IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) /* * Update the start or insert page of a list */ -void -IvfflatUpdateList(Relation index, ListInfo listInfo, - BlockNumber insertPage, BlockNumber originalInsertPage, - BlockNumber startPage, ForkNumber forkNum) +void IvfflatUpdateList(Relation index, ListInfo listInfo, BlockNumber insertPage, BlockNumber originalInsertPage, + BlockNumber startPage, ForkNumber forkNum) { Buffer buf; Page page; @@ -200,7 +186,7 @@ IvfflatUpdateList(Relation index, ListInfo listInfo, LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); - list = (IvfflatList) PageGetItem(page, PageGetItemId(page, listInfo.offno)); + list = (IvfflatList)PageGetItem(page, PageGetItemId(page, listInfo.offno)); if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage) { /* Skip update if insert page is lower than original insert page */ @@ -225,28 +211,24 @@ IvfflatUpdateList(Relation index, ListInfo listInfo, } } -static Size -VectorItemSize(int dimensions) +static Size VectorItemSize(int dimensions) { return VECTOR_SIZE(dimensions); } -static Size -HalfvecItemSize(int dimensions) +static Size HalfvecItemSize(int dimensions) { return HALFVEC_SIZE(dimensions); } -static Size -BitItemSize(int dimensions) +static Size BitItemSize(int dimensions) { return VARBITTOTALLEN(dimensions); } -static void -VectorUpdateCenter(Pointer v, int dimensions, float *x) +static void VectorUpdateCenter(Pointer v, int dimensions, float *x) { - Vector *vec = (Vector *) v; + Vector *vec = (Vector *)v; SET_VARSIZE(vec, VECTOR_SIZE(dimensions)); vec->dim = dimensions; @@ -255,10 +237,9 @@ VectorUpdateCenter(Pointer v, int dimensions, float *x) vec->x[k] = x[k]; } -static void -HalfvecUpdateCenter(Pointer v, int dimensions, float *x) +static void HalfvecUpdateCenter(Pointer v, int dimensions, float *x) { - HalfVector *vec = (HalfVector *) v; + HalfVector *vec = (HalfVector *)v; SET_VARSIZE(vec, HALFVEC_SIZE(dimensions)); vec->dim = dimensions; @@ -267,10 +248,9 @@ HalfvecUpdateCenter(Pointer v, int dimensions, float *x) vec->x[k] = Float4ToHalfUnchecked(x[k]); } -static void -BitUpdateCenter(Pointer v, int dimensions, float *x) +static void BitUpdateCenter(Pointer v, int dimensions, float *x) { - VarBit *vec = (VarBit *) v; + VarBit *vec = (VarBit *)v; unsigned char *nx = VARBITS(vec); SET_VARSIZE(vec, VARBITTOTALLEN(dimensions)); @@ -283,81 +263,69 @@ BitUpdateCenter(Pointer v, int dimensions, float *x) nx[k / 8] |= (x[k] > 0.5 ? 1 : 0) << (7 - (k % 8)); } -static void -VectorSumCenter(Pointer v, float *x) +static void VectorSumCenter(Pointer v, float *x) { - Vector *vec = (Vector *) v; + Vector *vec = (Vector *)v; for (int k = 0; k < vec->dim; k++) x[k] += vec->x[k]; } -static void -HalfvecSumCenter(Pointer v, float *x) +static void HalfvecSumCenter(Pointer v, float *x) { - HalfVector *vec = (HalfVector *) v; + HalfVector *vec = (HalfVector *)v; for (int k = 0; k < vec->dim; k++) x[k] += HalfToFloat4(vec->x[k]); } -static void -BitSumCenter(Pointer v, float *x) +static void BitSumCenter(Pointer v, float *x) { - VarBit *vec = (VarBit *) v; + VarBit *vec = (VarBit *)v; for (int k = 0; k < VARBITLEN(vec); k++) - x[k] += (float) (((VARBITS(vec)[k / 8]) >> (7 - (k % 8))) & 0x01); + x[k] += (float)(((VARBITS(vec)[k / 8]) >> (7 - (k % 8))) & 0x01); } /* * Get type info */ -const IvfflatTypeInfo * -IvfflatGetTypeInfo(Relation index) +const IvfflatTypeInfo *IvfflatGetTypeInfo(Relation index) { FmgrInfo *procinfo = IvfflatOptionalProcInfo(index, IVFFLAT_TYPE_INFO_PROC); if (procinfo == NULL) { - static const IvfflatTypeInfo typeInfo = { - .maxDimensions = IVFFLAT_MAX_DIM, - .normalize = l2_normalize, - .itemSize = VectorItemSize, - .updateCenter = VectorUpdateCenter, - .sumCenter = VectorSumCenter - }; + static const IvfflatTypeInfo typeInfo = {.maxDimensions = IVFFLAT_MAX_DIM, + .normalize = l2_normalize, + .itemSize = VectorItemSize, + .updateCenter = VectorUpdateCenter, + .sumCenter = VectorSumCenter}; return (&typeInfo); } else - return (const IvfflatTypeInfo *) DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); + return (const IvfflatTypeInfo *)DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflat_halfvec_support); -Datum -ivfflat_halfvec_support(PG_FUNCTION_ARGS) +Datum ivfflat_halfvec_support(PG_FUNCTION_ARGS) { - static const IvfflatTypeInfo typeInfo = { - .maxDimensions = IVFFLAT_MAX_DIM * 2, - .normalize = halfvec_l2_normalize, - .itemSize = HalfvecItemSize, - .updateCenter = HalfvecUpdateCenter, - .sumCenter = HalfvecSumCenter - }; + static const IvfflatTypeInfo typeInfo = {.maxDimensions = IVFFLAT_MAX_DIM * 2, + .normalize = halfvec_l2_normalize, + .itemSize = HalfvecItemSize, + .updateCenter = HalfvecUpdateCenter, + .sumCenter = HalfvecSumCenter}; PG_RETURN_POINTER(&typeInfo); }; PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflat_bit_support); -Datum -ivfflat_bit_support(PG_FUNCTION_ARGS) +Datum ivfflat_bit_support(PG_FUNCTION_ARGS) { - static const IvfflatTypeInfo typeInfo = { - .maxDimensions = IVFFLAT_MAX_DIM * 32, - .normalize = NULL, - .itemSize = BitItemSize, - .updateCenter = BitUpdateCenter, - .sumCenter = BitSumCenter - }; + static const IvfflatTypeInfo typeInfo = {.maxDimensions = IVFFLAT_MAX_DIM * 32, + .normalize = NULL, + .itemSize = BitItemSize, + .updateCenter = BitUpdateCenter, + .sumCenter = BitSumCenter}; PG_RETURN_POINTER(&typeInfo); }; diff --git a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp index 6cf9c772de..66b530f988 100644 --- a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp @@ -8,20 +8,18 @@ /* * Bulk delete tuples from the index */ -IndexBulkDeleteResult * -ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) +IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) { Relation index = info->index; BlockNumber blkno = IVFFLAT_HEAD_BLKNO; BufferAccessStrategy bas = GetAccessStrategy(BAS_BULKREAD); if (stats == NULL) - stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + stats = (IndexBulkDeleteResult *)palloc0(sizeof(IndexBulkDeleteResult)); /* Iterate over list pages */ - while (BlockNumberIsValid(blkno)) - { + while (BlockNumberIsValid(blkno)) { Buffer cbuf; Page cpage; OffsetNumber coffno; @@ -37,7 +35,7 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* Iterate over lists */ for (coffno = FirstOffsetNumber; coffno <= cmaxoffno; coffno = OffsetNumberNext(coffno)) { - IvfflatList list = (IvfflatList) PageGetItem(cpage, PageGetItemId(cpage, coffno)); + IvfflatList list = (IvfflatList)PageGetItem(cpage, PageGetItemId(cpage, coffno)); startPages[coffno - FirstOffsetNumber] = list->startPage; } @@ -81,7 +79,7 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* Find deleted tuples */ for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { - IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offno)); + IndexTuple itup = (IndexTuple)PageGetItem(page, PageGetItemId(page, offno)); ItemPointer htup = &(itup->t_tid); if (callback(htup, callback_state, InvalidOid, InvalidBktId)) { @@ -129,8 +127,7 @@ ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* * Clean up after a VACUUM operation */ -IndexBulkDeleteResult * -ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) +IndexBulkDeleteResult *ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { Relation rel = info->index; diff --git a/src/include/access/datavec/hnsw.h b/src/include/access/datavec/hnsw.h index a30837a37d..e387a40adb 100644 --- a/src/include/access/datavec/hnsw.h +++ b/src/include/access/datavec/hnsw.h @@ -183,7 +183,7 @@ typedef struct HnswNeighborArray HnswNeighborArray; Size relptr_off; \ } -#define relptr_declare(type, relptrtype) typedef relptr(type) relptrtype +#define relptr_declare(type, relptrtype) typedef relptr(type) (relptrtype) #ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P #define relptr_access(base, rp) \ @@ -205,9 +205,9 @@ typedef struct HnswNeighborArray HnswNeighborArray; /* We use this inline to avoid double eval of "val" in relptr_store */ static inline Size relptr_store_eval(char *base, char *val) { - if (val == NULL) + if (val == NULL) { return 0; - else { + } else { Assert(val >= base); return val - base + 1; } @@ -231,7 +231,7 @@ static inline Size relptr_store_eval(char *base, char *val) typedef union { \ type *ptr; \ relptrtype relptr; \ - } ptrtype; + } (ptrtype); /* Pointers that can be absolute or relative */ /* Use char for HnswDatumPtr so works with Pointer */ -- Gitee From 2621b2f9cba89b999e5ecf45451d96f5231af830 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Fri, 1 Nov 2024 18:05:26 +0800 Subject: [PATCH 11/67] cleancode --- src/common/backend/utils/adt/f2s.cpp | 38 +++++++++++++------ .../storage/access/datavec/bitutils.cpp | 14 +++++-- .../storage/access/datavec/hnswdelete.cpp | 4 +- .../storage/access/datavec/hnswscan.cpp | 13 +++++-- .../storage/access/datavec/ivfkmeans.cpp | 4 +- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/common/backend/utils/adt/f2s.cpp b/src/common/backend/utils/adt/f2s.cpp index ccdce5efdb..2d7940d305 100644 --- a/src/common/backend/utils/adt/f2s.cpp +++ b/src/common/backend/utils/adt/f2s.cpp @@ -397,6 +397,7 @@ static inline int to_chars_f(const floating_decimal_32 v, const uint32 olength, uint32 output = v.mantissa; int32 exp = v.exponent; + errno_t rc = EOK; /*---- * On entry, mantissa * 10^exp is the result to be output. @@ -420,7 +421,8 @@ static inline int to_chars_f(const floating_decimal_32 v, const uint32 olength, /* 0.000ddddd */ index = 2 - nexp; /* copy 8 bytes rather than 5 to let compiler optimize */ - memcpy(result, "0.000000", 8); + rc = memcpy_s(result, 8, "0.000000", 8); + securec_check(rc, "\0", "\0"); } else if (exp < 0) { /* * dddd.dddd; leave space at the start and move the '.' in after @@ -434,7 +436,8 @@ static inline int to_chars_f(const floating_decimal_32 v, const uint32 olength, * rather than 6 bytes to let the compiler optimize it. */ Assert(exp < 6 && exp + olength <= 6); - memset(result, '0', 8); + rc = memset_s(result, 8, '0', 8); + securec_check(rc, "\0", "\0"); } while (output >= 10000) { @@ -444,21 +447,25 @@ static inline int to_chars_f(const floating_decimal_32 v, const uint32 olength, output /= 10000; - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); + rc = memcpy_s(result + index + olength - i - 2, 2, DIGIT_TABLE + c0, 2); + securec_check(rc, "\0", "\0"); + rc = memcpy_s(result + index + olength - i - 4, 2, DIGIT_TABLE + c1, 2); + securec_check(rc, "\0", "\0"); i += 4; } if (output >= 100) { const uint32 c = (output % 100) << 1; output /= 100; - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + rc = memcpy_s(result + index + olength - i - 2, 2, DIGIT_TABLE + c, 2); + securec_check(rc, "\0", "\0"); i += 2; } if (output >= 10) { const uint32 c = output << 1; - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + rc = memcpy_s(result + index + olength - i - 2, 2, DIGIT_TABLE + c, 2); + securec_check(rc, "\0", "\0"); } else { result[index] = (char)('0' + output); } @@ -472,11 +479,13 @@ static inline int to_chars_f(const floating_decimal_32 v, const uint32 olength, Assert(nexp < 7); /* gcc only seems to want to optimize memmove for small 2^n */ if (nexp & 4) { - memmove(result + index - 1, result + index, 4); + rc = memmove_s(result + index - 1, 4, result + index, 4); + securec_check(rc, "\0", "\0"); index += 4; } if (nexp & 2) { - memmove(result + index - 1, result + index, 2); + rc = memmove_s(result + index - 1, 2, result + index, 2); + securec_check(rc, "\0", "\0"); index += 2; } if (nexp & 1) { @@ -502,6 +511,7 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char *c uint32 output = v.mantissa; uint32 olength = decimalLength(output); int32 exp = v.exponent + olength - 1; + errno_t rc = EOK; if (sign) { result[index++] = '-'; @@ -564,15 +574,18 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char *c output /= 10000; - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); + rc = memcpy_s(result + index + olength - i - 1, 2, DIGIT_TABLE + c0, 2); + securec_check(rc, "\0", "\0"); + rc = memcpy_s(result + index + olength - i - 3, 2, DIGIT_TABLE + c1, 2); + securec_check(rc, "\0", "\0"); i += 4; } if (output >= 100) { const uint32 c = (output % 100) << 1; output /= 100; - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); + rc = memcpy_s(result + index + olength - i - 1, 2, DIGIT_TABLE + c, 2); + securec_check(rc, "\0", "\0"); i += 2; } if (output >= 10) { @@ -605,7 +618,8 @@ static inline int to_chars(const floating_decimal_32 v, const bool sign, char *c result[index++] = '+'; } - memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); + rc = memcpy_s(result + index, 2, DIGIT_TABLE + 2 * exp, 2); + securec_check(rc, "\0", "\0"); index += 2; return index; diff --git a/src/gausskernel/storage/access/datavec/bitutils.cpp b/src/gausskernel/storage/access/datavec/bitutils.cpp index 4c6e1a827c..48006dcfbe 100644 --- a/src/gausskernel/storage/access/datavec/bitutils.cpp +++ b/src/gausskernel/storage/access/datavec/bitutils.cpp @@ -41,13 +41,16 @@ BIT_TARGET_CLONES static uint64 BitHammingDistanceDefault(uint32 bytes, unsigned uint64 distance) { #ifdef popcount64 + errno_t rc = EOK; for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) { uint64 axs; uint64 bxs; /* Ensure aligned */ - memcpy(&axs, ax, sizeof(uint64)); - memcpy(&bxs, bx, sizeof(uint64)); + rc = memcpy_s(&axs, sizeof(uint64), ax, sizeof(uint64)); + securec_check(rc, "\0", "\0"); + rc = memcpy_s(&bxs, sizeof(uint64), bx, sizeof(uint64)); + securec_check(rc, "\0", "\0"); distance += popcount64(axs ^ bxs); @@ -88,13 +91,16 @@ BIT_TARGET_CLONES static double BitJaccardDistanceDefault(uint32 bytes, unsigned uint64 aa, uint64 bb) { #ifdef popcount64 + errno_t rc = EOK; for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64)) { uint64 axs; uint64 bxs; /* Ensure aligned */ - memcpy(&axs, ax, sizeof(uint64)); - memcpy(&bxs, bx, sizeof(uint64)); + rc = memcpy_s(&axs, sizeof(uint64), ax, sizeof(uint64)); + securec_check(rc, "\0", "\0"); + rc = memcpy_s(&bxs, sizeof(uint64), bx, sizeof(uint64)); + securec_check(rc, "\0", "\0"); ab += popcount64(axs & bxs); aa += popcount64(axs); diff --git a/src/gausskernel/storage/access/datavec/hnswdelete.cpp b/src/gausskernel/storage/access/datavec/hnswdelete.cpp index 4f287ede0c..ff2a24e11f 100644 --- a/src/gausskernel/storage/access/datavec/hnswdelete.cpp +++ b/src/gausskernel/storage/access/datavec/hnswdelete.cpp @@ -172,6 +172,7 @@ HnswElementTuple IndexFormHnswElementTuple(TupleDesc tupleDesc, Datum *values, c Datum value; HnswElementTuple etup; Size etupSize; + errno_t rc = EOK; value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); @@ -183,7 +184,8 @@ HnswElementTuple IndexFormHnswElementTuple(TupleDesc tupleDesc, Datum *values, c ItemPointerSetInvalid(&etup->heaptids[i]); } - memcpy(&etup->data, DatumGetPointer(value), VARSIZE_ANY(DatumGetPointer(value))); + rc = memcpy_s(&etup->data, VARSIZE_ANY(DatumGetPointer(value)), DatumGetPointer(value), VARSIZE_ANY(DatumGetPointer(value))); + securec_check(rc, "\0", "\0"); return etup; } diff --git a/src/gausskernel/storage/access/datavec/hnswscan.cpp b/src/gausskernel/storage/access/datavec/hnswscan.cpp index a4b764f207..1eedbabead 100644 --- a/src/gausskernel/storage/access/datavec/hnswscan.cpp +++ b/src/gausskernel/storage/access/datavec/hnswscan.cpp @@ -99,6 +99,7 @@ IndexScanDesc hnswbeginscan_internal(Relation index, int nkeys, int norderbys) void hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) { HnswScanOpaque so = (HnswScanOpaque)scan->opaque; + errno_t rc = EOK; if (so->vs.lastSelfModifiedItup) { IndexTupleSetSize(((IndexTuple)(so->vs.lastSelfModifiedItup)), 0); /* clear */ @@ -107,11 +108,15 @@ void hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey or so->first = true; MemoryContextReset(so->tmpCtx); - if (keys && scan->numberOfKeys > 0) - memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData)); + if (keys && scan->numberOfKeys > 0) { + rc = memmove_s(scan->keyData, scan->numberOfKeys * sizeof(ScanKeyData), keys, scan->numberOfKeys * sizeof(ScanKeyData)); + securec_check(rc, "\0", "\0"); + } - if (orderbys && scan->numberOfOrderBys > 0) - memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); + if (orderbys && scan->numberOfOrderBys > 0) { + rc = memmove_s(scan->orderByData, scan->numberOfOrderBys * sizeof(ScanKeyData), orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); + securec_check(rc, "\0", "\0"); + } } /* diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index 8c3f3c8dd3..64382863f8 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -93,6 +93,7 @@ static void NormCenters(const IvfflatTypeInfo *typeInfo, Oid collation, VectorAr MemoryContext normCtx = AllocSetContextCreate(CurrentMemoryContext, "Ivfflat norm temporary context", ALLOCSET_DEFAULT_SIZES); MemoryContext oldCtx = MemoryContextSwitchTo(normCtx); + errno_t rc = EOK; for (int j = 0; j < centers->length; j++) { Datum center = PointerGetDatum(VectorArrayGet(centers, j)); @@ -102,7 +103,8 @@ static void NormCenters(const IvfflatTypeInfo *typeInfo, Oid collation, VectorAr if (size > centers->itemsize) elog(ERROR, "safety check failed"); - memcpy(DatumGetPointer(center), DatumGetPointer(newCenter), size); + rc = memcpy_s(DatumGetPointer(center), size, DatumGetPointer(newCenter), size); + securec_check(rc, "\0", "\0"); MemoryContextReset(normCtx); } -- Gitee From 363cc1aab30aedd5055b79c131c42ef7f93fcbcb Mon Sep 17 00:00:00 2001 From: jiwenke Date: Fri, 1 Nov 2024 18:29:55 +0800 Subject: [PATCH 12/67] cleancode --- .../storage/access/datavec/hnswutils.cpp | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index 1203597e95..4fff6e434f 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/generic_xlog.h" #include "catalog/pg_type.h" @@ -107,7 +107,7 @@ typedef union { pointerhash_hash *pointers; offsethash_hash *offsets; tidhash_hash *tids; -} visited_hash; +} VisitedHash; /* * Get the max number of connections in an upper layer for each element in the index @@ -274,8 +274,9 @@ HnswElement HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, i int level = (int)(-log(RandomDouble()) * ml); /* Cap level */ - if (level > maxLevel) + if (level > maxLevel) { level = maxLevel; + } element->heaptidsLength = 0; HnswAddHeapTid(element, heaptid); @@ -326,7 +327,6 @@ void HnswGetMetaPageInfo(Relation index, int *m, HnswElement *entryPoint) LockBuffer(buf, BUFFER_LOCK_SHARE); page = BufferGetPage(buf); metap = HnswPageGetMeta(page); - if (unlikely(metap->magicNumber != HNSW_MAGIC_NUMBER)) elog(ERROR, "hnsw index is not valid"); @@ -337,8 +337,9 @@ void HnswGetMetaPageInfo(Relation index, int *m, HnswElement *entryPoint) if (BlockNumberIsValid(metap->entryBlkno)) { *entryPoint = HnswInitElementFromBlock(metap->entryBlkno, metap->entryOffno); (*entryPoint)->level = metap->entryLevel; - } else + } else { *entryPoint = NULL; + } } UnlockReleaseBuffer(buf); @@ -473,6 +474,7 @@ void HnswUpdateAppendMetaPage(Relation index, int updateEntry, HnswElement entry void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) { Pointer valuePtr = (Pointer)HnswPtrAccess(base, element->value); + errno_t rc = EOK; etup->type = HNSW_ELEMENT_TUPLE_TYPE; etup->level = element->level; @@ -483,7 +485,8 @@ void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) else ItemPointerSetInvalid(&etup->heaptids[i]); } - memcpy(&etup->data, valuePtr, VARSIZE_ANY(valuePtr)); + rc = memcpy_(&etup->data, VARSIZE_ANY(valuePtr), valuePtr, VARSIZE_ANY(valuePtr)); + securec_check(rc, "\0", "\0"); } /* @@ -507,8 +510,9 @@ void HnswSetNeighborTuple(char *base, HnswNeighborTuple ntup, HnswElement e, int HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); ItemPointerSet(indextid, hce->blkno, hce->offno); - } else + } else { ItemPointerSetInvalid(indextid); + } } } @@ -530,8 +534,9 @@ static void LoadNeighborsFromPage(HnswElement element, Relation index, Page page HnswInitNeighbors(base, element, m, NULL); /* Ensure expected neighbors */ - if (ntup->count != neighborCount) + if (ntup->count != neighborCount) { return; + } for (int i = 0; i < neighborCount; i++) { HnswElement e; @@ -542,15 +547,17 @@ static void LoadNeighborsFromPage(HnswElement element, Relation index, Page page indextid = &ntup->indextids[i]; - if (!ItemPointerIsValid(indextid)) + if (!ItemPointerIsValid(indextid)) { continue; + } e = HnswInitElementFromBlock(ItemPointerGetBlockNumber(indextid), ItemPointerGetOffsetNumber(indextid)); /* Calculate level based on offset */ level = element->level - i / m; - if (level < 0) + if (level < 0) { level = 0; + } neighbors = HnswGetNeighbors(base, element, level); hc = &neighbors->items[neighbors->length++]; @@ -722,7 +729,7 @@ static HnswPairingHeapNode *CreatePairingHeapNode(HnswCandidate *c) /* * Init visited */ -static inline void InitVisited(char *base, visited_hash *v, Relation index, int ef, int m) +static inline void InitVisited(char *base, VisitedHash *v, Relation index, int ef, int m) { if (index != NULL) v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL); @@ -735,7 +742,7 @@ static inline void InitVisited(char *base, visited_hash *v, Relation index, int /* * Add to visited */ -static inline void AddToVisited(char *base, visited_hash *v, HnswCandidate *hc, Relation index, bool *found) +static inline void AddToVisited(char *base, VisitedHash *v, HnswCandidate *hc, Relation index, bool *found) { if (index != NULL) { HnswElement element = (HnswElement)HnswPtrAccess(base, hc->element); @@ -789,11 +796,12 @@ List *HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation in pairingheap *C = pairingheap_allocate(CompareNearestCandidates, NULL); pairingheap *W = pairingheap_allocate(CompareFurthestCandidates, NULL); int wlen = 0; - visited_hash v; + VisitedHash v; ListCell *lc2; HnswNeighborArray *neighborhoodData = NULL; Size neighborhoodSize; bool isVisible = true; + errno_t rc = EOK; InitVisited(base, &v, index, ef, m); @@ -832,7 +840,6 @@ List *HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation in break; cElement = (HnswElement)HnswPtrAccess(base, c->element); - if (HnswPtrIsNull(base, cElement->neighbors)) HnswLoadNeighbors(cElement, index, m); @@ -842,7 +849,8 @@ List *HnswSearchLayer(char *base, Datum q, List *ep, int ef, int lc, Relation in /* Copy neighborhood to local memory if needed */ if (index == NULL) { LWLockAcquire(&cElement->lock, LW_SHARED); - memcpy(neighborhoodData, neighborhood, neighborhoodSize); + rc = memcpy_s(neighborhoodData, neighborhoodSize, neighborhood, neighborhoodSize); + securec_check(rc, "\0", "\0"); LWLockRelease(&cElement->lock); neighborhood = neighborhoodData; } @@ -1275,13 +1283,14 @@ void HnswFindElementNeighbors(char *base, HnswElement element, HnswElement entry ep = w; } - if (level > entryLevel) + if (level > entryLevel) { level = entryLevel; + } /* Add one for existing element */ - if (existing) + if (existing) { efConstruction++; - + } /* 2nd phase */ for (int lc = level; lc >= 0; lc--) { int lm = HnswGetLayerM(m, lc); @@ -1330,8 +1339,9 @@ const HnswTypeInfo *HnswGetTypeInfo(Relation index) .maxDimensions = HNSW_MAX_DIM, .normalize = l2_normalize, .checkValue = NULL}; return (&typeInfo); - } else + } else { return (const HnswTypeInfo *)DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); + } } PGDLLEXPORT PG_FUNCTION_INFO_V1(hnsw_halfvec_support); -- Gitee From 6d024c7de8cac1dd4acd7d16e87d0cc598ba9a9f Mon Sep 17 00:00:00 2001 From: jiwenke Date: Fri, 1 Nov 2024 18:58:42 +0800 Subject: [PATCH 13/67] clean code --- src/gausskernel/storage/access/datavec/hnswbuild.cpp | 2 -- src/gausskernel/storage/access/datavec/hnswinsert.cpp | 4 ---- src/gausskernel/storage/access/datavec/hnswutils.cpp | 1 - src/gausskernel/storage/access/datavec/hnswvacuum.cpp | 3 --- src/gausskernel/storage/access/datavec/ivfbuild.cpp | 2 -- src/gausskernel/storage/access/datavec/ivfinsert.cpp | 3 --- src/gausskernel/storage/access/datavec/ivfkmeans.cpp | 2 -- src/gausskernel/storage/access/datavec/ivfutils.cpp | 2 -- src/include/access/datavec/halfutils.h | 1 - src/include/access/datavec/ivfflat.h | 1 - 10 files changed, 21 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp index d2621e8824..5686cbb96c 100644 --- a/src/gausskernel/storage/access/datavec/hnswbuild.cpp +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -415,7 +415,6 @@ static bool FindDuplicateInMemory(char *base, HnswElement element) HnswCandidate *neighbor = &neighbors->items[i]; HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); Datum neighborValue = HnswGetValue(base, neighborElement); - /* Exit early since ordered by distance */ if (!datumIsEqual(value, neighborValue, false, -1)) return false; @@ -509,7 +508,6 @@ static void InsertTupleInMemory(HnswBuildState *buildstate, HnswElement element) /* Get entry point */ LWLockAcquire(entryLock, LW_SHARED); entryPoint = (HnswElement)HnswPtrAccess(base, graph->entryPoint); - /* Prevent concurrent inserts when likely updating entry point */ if (entryPoint == NULL || element->level > entryPoint->level) { /* Release shared lock */ diff --git a/src/gausskernel/storage/access/datavec/hnswinsert.cpp b/src/gausskernel/storage/access/datavec/hnswinsert.cpp index 72700dbe74..2734900517 100644 --- a/src/gausskernel/storage/access/datavec/hnswinsert.cpp +++ b/src/gausskernel/storage/access/datavec/hnswinsert.cpp @@ -44,7 +44,6 @@ static bool HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement el for (offno = FirstOffsetNumber; offno <= maxoffno; offno = OffsetNumberNext(offno)) { HnswElementTuple etup = (HnswElementTuple)PageGetItem(page, PageGetItemId(page, offno)); - /* Skip neighbor tuples */ if (!HnswIsElementTuple(etup)) continue; @@ -70,7 +69,6 @@ static bool HnswFreeOffset(Relation index, Buffer buf, Page page, HnswElement el } itemid = PageGetItemId(*npage, neighborOffno); - /* Check for space on neighbor tuple page */ if (PageGetFreeSpace(*npage) + ItemIdGetLength(itemid) - sizeof(ItemIdData) >= ntupSize) { *freeOffno = offno; @@ -202,7 +200,6 @@ static void AddElementOnDisk(Relation index, HnswElement e, int m, BlockNumber i } currentPage = HnswPageGetOpaque(page)->nextblkno; - if (BlockNumberIsValid(currentPage)) { /* Move to next page */ if (!building) @@ -498,7 +495,6 @@ static bool FindDuplicateOnDisk(Relation index, HnswElement element, bool buildi HnswCandidate *neighbor = &neighbors->items[i]; HnswElement neighborElement = (HnswElement)HnswPtrAccess(base, neighbor->element); Datum neighborValue = HnswGetValue(base, neighborElement); - /* Exit early since ordered by distance */ if (!datumIsEqual(value, neighborValue, false, -1)) return false; diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index 4fff6e434f..f4892dea63 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -272,7 +272,6 @@ HnswElement HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, i HnswElement element = (HnswElement)HnswAlloc(allocator, sizeof(HnswElementData)); int level = (int)(-log(RandomDouble()) * ml); - /* Cap level */ if (level > maxLevel) { level = maxLevel; diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp index 9266f69ca9..4265467f2b 100644 --- a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -204,7 +204,6 @@ static void RepairGraphElement(HnswVacuumState *vacuumstate, HnswElement element LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); - /* Overwrite tuple */ if (!page_index_tuple_overwrite(page, element->neighborOffno, (Item)ntup, ntupSize)) elog(ERROR, "failed to add index item to \"%s\"", RelationGetRelationName(index)); @@ -254,7 +253,6 @@ static void RepairGraphEntryPoint(HnswVacuumState *vacuumstate) /* Get latest entry point */ entryPoint = HnswGetEntryPoint(index); - if (entryPoint != NULL) { ItemPointerData epData; @@ -369,7 +367,6 @@ static void RepairGraph(HnswVacuumState *vacuumstate) /* Refresh entry point for each element */ entryPoint = HnswGetEntryPoint(index); - /* Prevent concurrent inserts when likely updating entry point */ if (entryPoint == NULL || element->level > entryPoint->level) { /* Release shared lock */ diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index b7e06c4c17..c2c805d365 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -151,7 +151,6 @@ static void AddTupleToSort(Relation index, ItemPointer tid, Datum *values, Ivffl for (int i = 0; i < centers->length; i++) { distance = DatumGetFloat8(FunctionCall2Coll(buildstate->procinfo, buildstate->collation, value, PointerGetDatum(VectorArrayGet(centers, i)))); - if (distance < minDistance) { minDistance = distance; closestCenter = i; @@ -267,7 +266,6 @@ static void InsertTuples(Relation index, IvfflatBuildState *buildstate, ForkNumb while (list == i) { /* Check for free space */ Size itemsz = MAXALIGN(IndexTupleSize(itup)); - if (PageGetFreeSpace(page) < itemsz) IvfflatAppendPage(index, &buf, &page, &state, forkNum); diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp index 54c595d5f6..ad222ae868 100644 --- a/src/gausskernel/storage/access/datavec/ivfinsert.cpp +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -43,7 +43,6 @@ static void FindInsertPage(Relation index, Datum *values, BlockNumber *insertPag list = (IvfflatList)PageGetItem(cpage, PageGetItemId(cpage, offno)); distance = DatumGetFloat8(FunctionCall2Coll(procinfo, collation, values[0], PointerGetDatum(&list->center))); - if (distance < minDistance || !BlockNumberIsValid(*insertPage)) { *insertPage = list->insertPage; listInfo->blkno = nextblkno; @@ -113,12 +112,10 @@ static void InsertTuple(Relation index, Datum *values, const bool *isnull, ItemP state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); - if (PageGetFreeSpace(page) >= itemsz) break; insertPage = IvfflatPageGetOpaque(page)->nextblkno; - if (BlockNumberIsValid(insertPage)) { /* Move to next page */ GenericXLogAbort(state); diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index 64382863f8..6ab9ec9521 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -99,7 +99,6 @@ static void NormCenters(const IvfflatTypeInfo *typeInfo, Oid collation, VectorAr Datum center = PointerGetDatum(VectorArrayGet(centers, j)); Datum newCenter = IvfflatNormValue(typeInfo, collation, center); Size size = VARSIZE_ANY(DatumGetPointer(newCenter)); - if (size > centers->itemsize) elog(ERROR, "safety check failed"); @@ -507,7 +506,6 @@ static void CheckNorms(VectorArray centers, Relation index) for (int i = 0; i < centers->length; i++) { double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); - if (norm == 0) elog(ERROR, "Zero norm detected. Please report a bug."); } diff --git a/src/gausskernel/storage/access/datavec/ivfutils.cpp b/src/gausskernel/storage/access/datavec/ivfutils.cpp index d6b7d65032..8adb54e8fa 100644 --- a/src/gausskernel/storage/access/datavec/ivfutils.cpp +++ b/src/gausskernel/storage/access/datavec/ivfutils.cpp @@ -157,7 +157,6 @@ void IvfflatGetMetaPageInfo(Relation index, int *lists, int *dimensions) LockBuffer(buf, BUFFER_LOCK_SHARE); page = BufferGetPage(buf); metap = IvfflatPageGetMeta(page); - if (unlikely(metap->magicNumber != IVFFLAT_MAGIC_NUMBER)) elog(ERROR, "ivfflat index is not valid"); @@ -187,7 +186,6 @@ void IvfflatUpdateList(Relation index, ListInfo listInfo, BlockNumber insertPage state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); list = (IvfflatList)PageGetItem(page, PageGetItemId(page, listInfo.offno)); - if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage) { /* Skip update if insert page is lower than original insert page */ /* This is needed to prevent insert from overwriting vacuum */ diff --git a/src/include/access/datavec/halfutils.h b/src/include/access/datavec/halfutils.h index fc9b761e58..9369a94c87 100644 --- a/src/include/access/datavec/halfutils.h +++ b/src/include/access/datavec/halfutils.h @@ -214,7 +214,6 @@ static inline half Float4ToHalfUnchecked(float num) static inline half Float4ToHalf(float num) { half result = Float4ToHalfUnchecked(num); - if (unlikely(HalfIsInf(result)) && !isinf(num)) { char *buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h index 963f43de70..48275cdf61 100644 --- a/src/include/access/datavec/ivfflat.h +++ b/src/include/access/datavec/ivfflat.h @@ -193,7 +193,6 @@ typedef struct IvfflatBuildState { /* Parallel builds */ IvfflatLeader *ivfleader; - } IvfflatBuildState; typedef struct IvfflatMetaPageData { -- Gitee From 50d416ff46f0dd31ecbff126f0fc34810ca8800a Mon Sep 17 00:00:00 2001 From: jiwenke Date: Fri, 1 Nov 2024 19:19:46 +0800 Subject: [PATCH 14/67] clean code --- src/common/backend/utils/adt/f2s.cpp | 14 ++++++------ src/common/backend/utils/adt/sparsevec.cpp | 20 ++++++++--------- src/common/backend/utils/adt/vector.cpp | 22 +++++++++---------- .../storage/access/datavec/hnsw.cpp | 4 ++-- .../storage/access/datavec/hnswvacuum.cpp | 10 ++++----- .../storage/access/datavec/ivfflat.cpp | 14 ++++++------ .../storage/access/datavec/ivfvacuum.cpp | 4 ++-- src/include/access/datavec/halfutils.h | 2 +- src/include/access/datavec/hnsw.h | 4 ++-- src/include/access/datavec/ivfflat.h | 2 +- src/include/access/datavec/shortest_dec.h | 2 +- src/include/access/datavec/vector.h | 2 +- 12 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/common/backend/utils/adt/f2s.cpp b/src/common/backend/utils/adt/f2s.cpp index 2d7940d305..9ade516383 100644 --- a/src/common/backend/utils/adt/f2s.cpp +++ b/src/common/backend/utils/adt/f2s.cpp @@ -503,7 +503,7 @@ static inline int to_chars_f(const floating_decimal_32 v, const uint32 olength, return index; } -static inline int to_chars(const floating_decimal_32 v, const bool sign, char *const result) +static inline int ToChars(const floating_decimal_32 v, const bool sign, char *const result) { /* Step 5: Print the decimal representation. */ int index = 0; @@ -673,7 +673,7 @@ static inline bool f2d_small_int(const uint32 ieeeMantissa, const uint32 ieeeExp * * Returns the number of bytes stored. */ -int float_to_shortest_decimal_bufn(float f, char *result) +int FloatToShortestDecimalBufn(float f, char *result) { /* * Step 1: Decode the floating-point number, and unify normalized and @@ -697,7 +697,7 @@ int float_to_shortest_decimal_bufn(float f, char *result) v = f2d(ieeeMantissa, ieeeExponent); } - return to_chars(v, ieeeSign, result); + return ToChars(v, ieeeSign, result); } /* @@ -707,9 +707,9 @@ int float_to_shortest_decimal_bufn(float f, char *result) * * Returns the string length. */ -int float_to_shortest_decimal_buf(float f, char *result) +int FloatToShortestDecimalBuf(float f, char *result) { - const int index = float_to_shortest_decimal_bufn(f, result); + const int index = FloatToShortestDecimalBufn(f, result); /* Terminate the string. */ Assert(index < FLOAT_SHORTEST_DECIMAL_LEN); @@ -723,10 +723,10 @@ int float_to_shortest_decimal_buf(float f, char *result) * * Caller is responsible for freeing the result. */ -char *float_to_shortest_decimal(float f) +char *FloatToShortestDecimal(float f) { char *const result = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); - float_to_shortest_decimal_buf(f, result); + FloatToShortestDecimalBuf(f, result); return result; } diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index 34d0aaccd5..79b635fba8 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -131,7 +131,7 @@ SparseVector *InitSparseVector(int dim, int nnz) /* * Check for whitespace, since array_isspace() is static */ -static inline bool sparsevec_isspace(char ch) +static inline bool SparsevecIsspace(char ch) { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') { return true; @@ -189,7 +189,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt = lit; - while (sparsevec_isspace(*pt)) { + while (SparsevecIsspace(*pt)) { pt++; } @@ -200,7 +200,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt++; - while (sparsevec_isspace(*pt)) + while (SparsevecIsspace(*pt)) pt++; if (*pt == '}') @@ -214,7 +214,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("ran out of buffer: \"%s\"", lit))); - while (sparsevec_isspace(*pt)) + while (SparsevecIsspace(*pt)) pt++; /* Check for empty string like float4in */ @@ -237,7 +237,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt = stringEnd; - while (sparsevec_isspace(*pt)) + while (SparsevecIsspace(*pt)) pt++; if (*pt != ':') @@ -246,7 +246,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt++; - while (sparsevec_isspace(*pt)) + while (SparsevecIsspace(*pt)) pt++; errno = 0; @@ -276,7 +276,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt = stringEnd; - while (sparsevec_isspace(*pt)) { + while (SparsevecIsspace(*pt)) { pt++; } @@ -292,7 +292,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) } } - while (sparsevec_isspace(*pt)) { + while (SparsevecIsspace(*pt)) { pt++; } @@ -304,7 +304,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt++; - while (sparsevec_isspace(*pt)) { + while (SparsevecIsspace(*pt)) { pt++; } @@ -325,7 +325,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt = stringEnd; /* Only whitespace is allowed after the closing brace */ - while (sparsevec_isspace(*pt)) { + while (SparsevecIsspace(*pt)) { pt++; } diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 02cd2de357..6454584be1 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -145,7 +145,7 @@ Vector *InitVector(int dim) /* * Check for whitespace, since array_isspace() is static */ -static inline bool vector_isspace(char ch) +static inline bool VectorIsspace(char ch) { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') { return true; @@ -189,7 +189,7 @@ Datum vector_in(PG_FUNCTION_ARGS) char *pt = lit; Vector *result; - while (vector_isspace(*pt)) { + while (VectorIsspace(*pt)) { pt++; } @@ -200,7 +200,7 @@ Datum vector_in(PG_FUNCTION_ARGS) pt++; - while (vector_isspace(*pt)) { + while (VectorIsspace(*pt)) { pt++; } @@ -216,7 +216,7 @@ Datum vector_in(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("vector cannot have more than %d dimensions", VECTOR_MAX_DIM))); - while (vector_isspace(*pt)) { + while (VectorIsspace(*pt)) { pt++; } @@ -246,7 +246,7 @@ Datum vector_in(PG_FUNCTION_ARGS) pt = stringEnd; - while (vector_isspace(*pt)) + while (VectorIsspace(*pt)) pt++; if (*pt == ',') { @@ -261,7 +261,7 @@ Datum vector_in(PG_FUNCTION_ARGS) } /* Only whitespace is allowed after the closing brace */ - while (vector_isspace(*pt)) + while (VectorIsspace(*pt)) pt++; if (*pt != '\0') @@ -281,7 +281,7 @@ Datum vector_in(PG_FUNCTION_ARGS) } #define AppendChar(ptr, c) (*(ptr)++ = (c)) -#define AppendFloat(ptr, f) ((ptr) += float_to_shortest_decimal_bufn((f), (ptr))) +#define AppendFloat(ptr, f) ((ptr) += FloatToShortestDecimalBufn((f), (ptr))) /* * Convert internal representation to textual representation @@ -298,7 +298,7 @@ Datum vector_out(PG_FUNCTION_ARGS) * Need: * * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for - * float_to_shortest_decimal_bufn + * FloatToShortestDecimalBufn * * dim - 1 bytes for separator * @@ -1280,7 +1280,7 @@ Datum sparsevec_to_vector(PG_FUNCTION_ARGS) * same time. If that's not the case, you must ensure that this does not * cause a deadlock through some other means. */ -void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std) +void LogNewpageRange(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std) { int flags; BlockNumber blkno; @@ -1353,10 +1353,10 @@ void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, B int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo) { int parallelWorkers = RelationGetParallelWorkers(heapRelation, 0); - int max_hashbucket_index_worker = 32; + int maxHashbucketIndexWorker = 32; if (parallelWorkers != 0) { - parallelWorkers = Min(max_hashbucket_index_worker, parallelWorkers); + parallelWorkers = Min(maxHashbucketIndexWorker, parallelWorkers); } if (indexInfo->ii_Concurrent && indexInfo->ii_ParallelWorkers > 0) { diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp index 0a386f30d4..d365e8d32b 100644 --- a/src/gausskernel/storage/access/datavec/hnsw.cpp +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -221,8 +221,8 @@ Datum hnswbulkdelete(PG_FUNCTION_ARGS) IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); - void *callback_state = (void *)PG_GETARG_POINTER(3); - stats = hnswbulkdelete_internal(info, stats, callback, callback_state); + void *callbackState = (void *)PG_GETARG_POINTER(3); + stats = hnswbulkdelete_internal(info, stats, callback, callbackState); PG_RETURN_POINTER(stats); } diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp index 4265467f2b..4d7925e61c 100644 --- a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -70,7 +70,7 @@ static void RemoveHeapTids(HnswVacuumState *vacuumstate) if (!ItemPointerIsValid(&etup->heaptids[i])) break; - if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callback_state, InvalidOid, + if (vacuumstate->callback(&etup->heaptids[i], vacuumstate->callbackState, InvalidOid, InvalidBktId)) { itemUpdated = true; stats->tuples_removed++; @@ -523,7 +523,7 @@ static void MarkDeleted(HnswVacuumState *vacuumstate) * Initialize the vacuum state */ static void InitVacuumState(HnswVacuumState *vacuumstate, IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) + IndexBulkDeleteCallback callback, void *callbackState) { Relation index = info->index; @@ -533,7 +533,7 @@ static void InitVacuumState(HnswVacuumState *vacuumstate, IndexVacuumInfo *info, vacuumstate->index = index; vacuumstate->stats = stats; vacuumstate->callback = callback; - vacuumstate->callback_state = callback_state; + vacuumstate->callbackState = callbackState; vacuumstate->efConstruction = HnswGetEfConstruction(index); vacuumstate->bas = GetAccessStrategy(BAS_BULKREAD); vacuumstate->procinfo = index_getprocinfo(index, 1, HNSW_DISTANCE_PROC); @@ -564,11 +564,11 @@ static void FreeVacuumState(HnswVacuumState *vacuumstate) * Bulk delete tuples from the index */ IndexBulkDeleteResult *hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) + IndexBulkDeleteCallback callback, void *callbackState) { HnswVacuumState vacuumstate; - InitVacuumState(&vacuumstate, info, stats, callback, callback_state); + InitVacuumState(&vacuumstate, info, stats, callback, callbackState); /* Pass 1: Remove heap TIDs */ RemoveHeapTids(&vacuumstate); diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index c039630fcc..3d98191bb8 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -37,7 +37,7 @@ static void ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, dou GenericCosts costs; int lists; double ratio; - double spc_seq_page_cost; + double spcSeqPageCost; Relation index; double half = 0.5; @@ -72,18 +72,18 @@ static void ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, dou genericcostestimate(root, path, loop_count, costs.numIndexTuples, &costs.indexStartupCost, &costs.indexTotalCost, &costs.indexSelectivity, &costs.indexCorrelation); - get_tablespace_page_costs(path->indexinfo->reltablespace, NULL, &spc_seq_page_cost); + get_tablespace_page_costs(path->indexinfo->reltablespace, NULL, &spcSeqPageCost); /* Adjust cost if needed since TOAST not included in seq scan cost */ if (costs.numIndexPages > path->indexinfo->rel->pages && ratio < half) { /* Change all page cost from random to sequential */ - costs.indexTotalCost -= costs.numIndexPages * (costs.spc_random_page_cost - spc_seq_page_cost); + costs.indexTotalCost -= costs.numIndexPages * (costs.spc_random_page_cost - spcSeqPageCost); /* Remove cost of extra pages */ - costs.indexTotalCost -= (costs.numIndexPages - path->indexinfo->rel->pages) * spc_seq_page_cost; + costs.indexTotalCost -= (costs.numIndexPages - path->indexinfo->rel->pages) * spcSeqPageCost; } else { /* Change some page cost from random to sequential */ - costs.indexTotalCost -= half * costs.numIndexPages * (costs.spc_random_page_cost - spc_seq_page_cost); + costs.indexTotalCost -= half * costs.numIndexPages * (costs.spc_random_page_cost - spcSeqPageCost); } /* @@ -243,8 +243,8 @@ Datum ivfflatbulkdelete(PG_FUNCTION_ARGS) IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); - void *callback_state = (void *)PG_GETARG_POINTER(3); - stats = ivfflatbulkdelete_internal(info, stats, callback, callback_state); + void *callbackState = (void *)PG_GETARG_POINTER(3); + stats = ivfflatbulkdelete_internal(info, stats, callback, callbackState); PG_RETURN_POINTER(stats); } diff --git a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp index 66b530f988..5a5f256d16 100644 --- a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp @@ -9,7 +9,7 @@ * Bulk delete tuples from the index */ IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) + IndexBulkDeleteCallback callback, void *callbackState) { Relation index = info->index; BlockNumber blkno = IVFFLAT_HEAD_BLKNO; @@ -82,7 +82,7 @@ IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBu IndexTuple itup = (IndexTuple)PageGetItem(page, PageGetItemId(page, offno)); ItemPointer htup = &(itup->t_tid); - if (callback(htup, callback_state, InvalidOid, InvalidBktId)) { + if (callback(htup, callbackState, InvalidOid, InvalidBktId)) { deletable[ndeletable++] = offno; stats->tuples_removed++; } else diff --git a/src/include/access/datavec/halfutils.h b/src/include/access/datavec/halfutils.h index 9369a94c87..7afceafe5c 100644 --- a/src/include/access/datavec/halfutils.h +++ b/src/include/access/datavec/halfutils.h @@ -217,7 +217,7 @@ static inline half Float4ToHalf(float num) if (unlikely(HalfIsInf(result)) && !isinf(num)) { char *buf = (char *)palloc(FLOAT_SHORTEST_DECIMAL_LEN); - float_to_shortest_decimal_buf(num, buf); + FloatToShortestDecimalBuf(num, buf); ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("\"%s\" is out of range for type halfvec", buf))); diff --git a/src/include/access/datavec/hnsw.h b/src/include/access/datavec/hnsw.h index e387a40adb..422ab54295 100644 --- a/src/include/access/datavec/hnsw.h +++ b/src/include/access/datavec/hnsw.h @@ -486,7 +486,7 @@ typedef struct HnswVacuumState { Relation index; IndexBulkDeleteResult *stats; IndexBulkDeleteCallback callback; - void *callback_state; + void *callbackState; /* Settings */ int m; @@ -572,7 +572,7 @@ void hnswbuildempty_internal(Relation index); bool hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique); IndexBulkDeleteResult *hnswbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state); + IndexBulkDeleteCallback callback, void *callbackState); IndexBulkDeleteResult *hnswvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); IndexScanDesc hnswbeginscan_internal(Relation index, int nkeys, int norderbys); void hnswrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h index 48275cdf61..dab90c733d 100644 --- a/src/include/access/datavec/ivfflat.h +++ b/src/include/access/datavec/ivfflat.h @@ -307,7 +307,7 @@ void ivfflatbuildempty_internal(Relation index); bool ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, ItemPointer heap_tid, Relation heap, IndexUniqueCheck checkUnique); IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state); + IndexBulkDeleteCallback callback, void *callbackState); IndexBulkDeleteResult *ivfflatvacuumcleanup_internal(IndexVacuumInfo *info, IndexBulkDeleteResult *stats); IndexScanDesc ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys); void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys); diff --git a/src/include/access/datavec/shortest_dec.h b/src/include/access/datavec/shortest_dec.h index 91d9aa5c94..dd4779ca9f 100644 --- a/src/include/access/datavec/shortest_dec.h +++ b/src/include/access/datavec/shortest_dec.h @@ -3,7 +3,7 @@ #define FLOAT_SHORTEST_DECIMAL_LEN 16 -int float_to_shortest_decimal_bufn(float f, char *result); +int FloatToShortestDecimalBufn(float f, char *result); int float_to_shortest_decimal_buf(float f, char *result); #endif /* SHORTEST_DEC_H */ diff --git a/src/include/access/datavec/vector.h b/src/include/access/datavec/vector.h index 0fa8924fb2..09160abef5 100644 --- a/src/include/access/datavec/vector.h +++ b/src/include/access/datavec/vector.h @@ -20,7 +20,7 @@ typedef struct Vector { Vector *InitVector(int dim); void PrintVector(char *msg, Vector *vector); int vector_cmp_internal(Vector *a, Vector *b); -void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std); +void LogNewpageRange(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std); int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo); Datum vector_in(PG_FUNCTION_ARGS); -- Gitee From 5b22e2417d8903d9165a23f8971f791f5879e19b Mon Sep 17 00:00:00 2001 From: jiwenke Date: Fri, 1 Nov 2024 19:48:17 +0800 Subject: [PATCH 15/67] clean code --- src/common/backend/utils/adt/sparsevec.cpp | 60 ++++++++++------ src/common/backend/utils/adt/vector.cpp | 11 +-- .../storage/access/datavec/bitutils.cpp | 5 +- .../storage/access/datavec/hnswbuild.cpp | 17 +++-- .../storage/access/datavec/hnswinsert.cpp | 24 ++++--- .../storage/access/datavec/hnswscan.cpp | 7 +- .../storage/access/datavec/hnswutils.cpp | 72 ++++++++++++------- .../storage/access/datavec/hnswvacuum.cpp | 3 +- .../storage/access/datavec/ivfbuild.cpp | 14 ++-- .../storage/access/datavec/ivfinsert.cpp | 9 ++- .../storage/access/datavec/ivfkmeans.cpp | 39 ++++++---- .../storage/access/datavec/ivfscan.cpp | 6 +- .../storage/access/datavec/ivfutils.cpp | 13 ++-- 13 files changed, 181 insertions(+), 99 deletions(-) diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index 79b635fba8..2a10ab7e81 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -200,12 +200,13 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt++; - while (SparsevecIsspace(*pt)) + while (SparsevecIsspace(*pt)) { pt++; + } - if (*pt == '}') + if (*pt == '}') { pt++; - else { + } else { for (;;) { long index; float value; @@ -214,8 +215,9 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("ran out of buffer: \"%s\"", lit))); - while (SparsevecIsspace(*pt)) + while (SparsevecIsspace(*pt)) { pt++; + } /* Check for empty string like float4in */ if (*pt == '\0') @@ -230,15 +232,17 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) errmsg("invalid input syntax for type sparsevec: \"%s\"", lit))); /* Keep in int range for correct error message later */ - if (index > INT_MAX) + if (index > INT_MAX) { index = INT_MAX; - else if (index < INT_MIN + 1) + } else if (index < INT_MIN + 1) { index = INT_MIN + 1; + } pt = stringEnd; - while (SparsevecIsspace(*pt)) + while (SparsevecIsspace(*pt)) { pt++; + } if (*pt != ':') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -246,8 +250,9 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) pt++; - while (SparsevecIsspace(*pt)) + while (SparsevecIsspace(*pt)) { pt++; + } errno = 0; @@ -352,7 +357,7 @@ Datum sparsevec_in(PG_FUNCTION_ARGS) } #define AppendChar(ptr, c) (*(ptr)++ = (c)) -#define AppendFloat(ptr, f) ((ptr) += float_to_shortest_decimal_bufn((f), (ptr))) +#define AppendFloat(ptr, f) ((ptr) += FloatToShortestDecimalBufn((f), (ptr))) #if PG_VERSION_NUM >= 140000 #define AppendInt(ptr, i) ((ptr) += pg_ltoa((i), (ptr))) @@ -384,7 +389,7 @@ Datum sparsevec_out(PG_FUNCTION_ARGS) * nnz bytes for : * * nnz * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for - * float_to_shortest_decimal_bufn + * FloatToShortestDecimalBufn * * nnz - 1 bytes for , * @@ -546,8 +551,9 @@ Datum vector_to_sparsevec(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, dim); for (int i = 0; i < dim; i++) { - if (vec->x[i] != 0) + if (vec->x[i] != 0) { nnz++; + } } result = InitSparseVector(dim, nnz); @@ -585,8 +591,9 @@ Datum halfvec_to_sparsevec(PG_FUNCTION_ARGS) CheckExpectedDim(typmod, dim); for (int i = 0; i < dim; i++) { - if (!HalfIsZero(vec->x[i])) + if (!HalfIsZero(vec->x[i])) { nnz++; + } } result = InitSparseVector(dim, nnz); @@ -774,10 +781,11 @@ Datum sparsevec_cosine_distance(PG_FUNCTION_ARGS) #endif /* Keep in range */ - if (similarity > 1) + if (similarity > 1) { similarity = 1.0; - else if (similarity < -1) + } else if (similarity < -1) { similarity = -1.0; + } PG_RETURN_FLOAT8(1.0 - similarity); } @@ -924,30 +932,38 @@ static int sparsevec_cmp_internal(SparseVector *a, SparseVector *b) /* Check values before dimensions to be consistent with Postgres arrays */ for (int i = 0; i < nnz; i++) { - if (a->indices[i] < b->indices[i]) + if (a->indices[i] < b->indices[i]) { return ax[i] < 0 ? -1 : 1; + } - if (a->indices[i] > b->indices[i]) + if (a->indices[i] > b->indices[i]) { return bx[i] < 0 ? 1 : -1; + } - if (ax[i] < bx[i]) + if (ax[i] < bx[i]) { return -1; + } - if (ax[i] > bx[i]) + if (ax[i] > bx[i]) { return 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; + } - 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; + } - if (a->dim < b->dim) + if (a->dim < b->dim) { return -1; + } - if (a->dim > b->dim) + if (a->dim > b->dim) { return 1; + } return 0; } diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 6454584be1..8b3b9f4e1d 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -246,8 +246,9 @@ Datum vector_in(PG_FUNCTION_ARGS) pt = stringEnd; - while (VectorIsspace(*pt)) + while (VectorIsspace(*pt)) { pt++; + } if (*pt == ',') { pt++; @@ -261,8 +262,9 @@ Datum vector_in(PG_FUNCTION_ARGS) } /* Only whitespace is allowed after the closing brace */ - while (VectorIsspace(*pt)) + while (VectorIsspace(*pt)) { pt++; + } if (*pt != '\0') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -656,10 +658,11 @@ Datum cosine_distance(PG_FUNCTION_ARGS) #endif /* Keep in range */ - if (similarity > 1) + if (similarity > 1) { similarity = 1.0; - else if (similarity < -1) + } else if (similarity < -1) { similarity = -1.0; + } PG_RETURN_FLOAT8(1.0 - similarity); } diff --git a/src/gausskernel/storage/access/datavec/bitutils.cpp b/src/gausskernel/storage/access/datavec/bitutils.cpp index 48006dcfbe..dc245477de 100644 --- a/src/gausskernel/storage/access/datavec/bitutils.cpp +++ b/src/gausskernel/storage/access/datavec/bitutils.cpp @@ -117,10 +117,11 @@ BIT_TARGET_CLONES static double BitJaccardDistanceDefault(uint32 bytes, unsigned bb += pg_number_of_ones[bx[i]]; } - if (ab == 0) + if (ab == 0) { return 1; - else + } else { return 1 - (ab / ((double)(aa + bb - ab))); + } } #ifdef BIT_DISPATCH diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp index 5686cbb96c..15aeef1756 100644 --- a/src/gausskernel/storage/access/datavec/hnswbuild.cpp +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -472,8 +472,9 @@ static void UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement e char *base = buildstate->hnswarea; /* Look for duplicate */ - if (FindDuplicateInMemory(base, element)) + if (FindDuplicateInMemory(base, element)) { return; + } /* Add element */ AddElementInMemory(base, graph, element); @@ -482,8 +483,9 @@ static void UpdateGraphInMemory(FmgrInfo *procinfo, Oid collation, HnswElement e UpdateNeighborsInMemory(base, procinfo, collation, element, m); /* Update entry point if needed (already have lock) */ - if (entryPoint == NULL || element->level > entryPoint->level) + if (entryPoint == NULL || element->level > entryPoint->level) { HnswPtrStore(base, graph->entryPoint, element); + } } /* @@ -551,13 +553,15 @@ static bool InsertTuple(Relation index, Datum *values, const bool *isnull, ItemP Datum value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); /* Check value */ - if (typeInfo->checkValue != NULL) + if (typeInfo->checkValue != NULL) { typeInfo->checkValue(DatumGetPointer(value)); + } /* Normalize if needed */ if (buildstate->normprocinfo != NULL) { - if (!HnswCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) + if (!HnswCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) { return false; + } value = HnswNormValue(typeInfo, buildstate->collation, value); } @@ -647,8 +651,9 @@ static void BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, #endif /* Skip nulls */ - if (isnull[0]) + if (isnull[0]) { return; + } /* Use memory context */ oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); @@ -1011,7 +1016,7 @@ static void BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, Hnsw BuildGraph(buildstate, forkNum); if (RelationNeedsWAL(index) || forkNum == INIT_FORKNUM) - log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); + LogNewpageRange(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); FreeBuildState(buildstate); } diff --git a/src/gausskernel/storage/access/datavec/hnswinsert.cpp b/src/gausskernel/storage/access/datavec/hnswinsert.cpp index 2734900517..d40a4c4ec2 100644 --- a/src/gausskernel/storage/access/datavec/hnswinsert.cpp +++ b/src/gausskernel/storage/access/datavec/hnswinsert.cpp @@ -329,11 +329,13 @@ static bool ConnectionExists(HnswElement e, HnswNeighborTuple ntup, int startIdx for (int i = 0; i < lm; i++) { ItemPointer indextid = &ntup->indextids[startIdx + i]; - if (!ItemPointerIsValid(indextid)) + if (!ItemPointerIsValid(indextid)) { break; + } - if (ItemPointerGetBlockNumber(indextid) == e->blkno && ItemPointerGetOffsetNumber(indextid) == e->offno) + if (ItemPointerGetBlockNumber(indextid) == e->blkno && ItemPointerGetOffsetNumber(indextid) == e->offno) { return true; + } } return false; @@ -515,22 +517,25 @@ static void UpdateGraphOnDisk(Relation index, FmgrInfo *procinfo, Oid collation, BlockNumber newInsertPage = InvalidBlockNumber; /* Look for duplicate */ - if (FindDuplicateOnDisk(index, element, building)) + if (FindDuplicateOnDisk(index, element, building)) { return; + } /* Add element */ AddElementOnDisk(index, element, m, GetInsertPage(index), &newInsertPage, building); /* Update insert page if needed */ - if (BlockNumberIsValid(newInsertPage)) + if (BlockNumberIsValid(newInsertPage)) { HnswUpdateMetaPage(index, 0, NULL, newInsertPage, MAIN_FORKNUM, building); + } /* Update neighbors */ HnswUpdateNeighborsOnDisk(index, procinfo, collation, element, m, false, building); /* Update entry point if needed */ - if (entryPoint == NULL || element->level > entryPoint->level) + if (entryPoint == NULL || element->level > entryPoint->level) { HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM, building); + } } /* @@ -601,14 +606,16 @@ static void HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPoi value = PointerGetDatum(PG_DETOAST_DATUM(values[0])); /* Check value */ - if (typeInfo->checkValue != NULL) + if (typeInfo->checkValue != NULL) { typeInfo->checkValue(DatumGetPointer(value)); + } /* Normalize if needed */ normprocinfo = HnswOptionalProcInfo(index, HNSW_NORM_PROC); if (normprocinfo != NULL) { - if (!HnswCheckNorm(normprocinfo, collation, value)) + if (!HnswCheckNorm(normprocinfo, collation, value)) { return; + } value = HnswNormValue(typeInfo, collation, value); } @@ -626,8 +633,9 @@ bool hnswinsert_internal(Relation index, Datum *values, bool *isnull, ItemPointe MemoryContext insertCtx; /* Skip nulls */ - if (isnull[0]) + if (isnull[0]) { return false; + } /* Create memory context */ insertCtx = AllocSetContextCreate(CurrentMemoryContext, "Hnsw insert temporary context", ALLOCSET_DEFAULT_SIZES); diff --git a/src/gausskernel/storage/access/datavec/hnswscan.cpp b/src/gausskernel/storage/access/datavec/hnswscan.cpp index 1eedbabead..8776133367 100644 --- a/src/gausskernel/storage/access/datavec/hnswscan.cpp +++ b/src/gausskernel/storage/access/datavec/hnswscan.cpp @@ -47,9 +47,9 @@ static Datum GetScanValue(IndexScanDesc scan) HnswScanOpaque so = (HnswScanOpaque)scan->opaque; Datum value; - if (scan->orderByData->sk_flags & SK_ISNULL) + if (scan->orderByData->sk_flags & SK_ISNULL) { value = PointerGetDatum(NULL); - else { + } else { value = scan->orderByData->sk_argument; /* Value should not be compressed or toasted */ @@ -57,8 +57,9 @@ static Datum GetScanValue(IndexScanDesc scan) Assert(!VARATT_IS_EXTENDED(DatumGetPointer(value))); /* Normalize if needed */ - if (so->normprocinfo != NULL) + if (so->normprocinfo != NULL) { value = HnswNormValue(so->typeInfo, so->collation, value); + } } return value; diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index f4892dea63..4544dba14a 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -691,11 +691,13 @@ HnswCandidate *HnswEntryCandidate(char *base, HnswElement entryPoint, Datum q, R */ static int CompareNearestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const HnswPairingHeapNode *)a)->inner->distance < ((const HnswPairingHeapNode *)b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance < ((const HnswPairingHeapNode *)b)->inner->distance) { return 1; + } - if (((const HnswPairingHeapNode *)a)->inner->distance > ((const HnswPairingHeapNode *)b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance > ((const HnswPairingHeapNode *)b)->inner->distance) { return -1; + } return 0; } @@ -705,11 +707,13 @@ static int CompareNearestCandidates(const pairingheap_node *a, const pairingheap */ static int CompareFurthestCandidates(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const HnswPairingHeapNode *)a)->inner->distance < ((const HnswPairingHeapNode *)b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance < ((const HnswPairingHeapNode *)b)->inner->distance) { return -1; + } - if (((const HnswPairingHeapNode *)a)->inner->distance > ((const HnswPairingHeapNode *)b)->inner->distance) + if (((const HnswPairingHeapNode *)a)->inner->distance > ((const HnswPairingHeapNode *)b)->inner->distance) { return 1; + } return 0; } @@ -730,12 +734,13 @@ static HnswPairingHeapNode *CreatePairingHeapNode(HnswCandidate *c) */ static inline void InitVisited(char *base, VisitedHash *v, Relation index, int ef, int m) { - if (index != NULL) + if (index != NULL) { v->tids = tidhash_create(CurrentMemoryContext, ef * m * 2, NULL); - else if (base != NULL) + } else if (base != NULL) { v->offsets = offsethash_create(CurrentMemoryContext, ef * m * 2, NULL); - else + } else { v->pointers = pointerhash_create(CurrentMemoryContext, ef * m * 2, NULL); + } } /* @@ -775,8 +780,9 @@ static inline bool CountElement(char *base, HnswElement skipElement, HnswCandida { HnswElement e; - if (skipElement == NULL) + if (skipElement == NULL) { return true; + } /* Ensure does not access heaptidsLength during in-memory build */ pg_memory_barrier(); @@ -937,17 +943,21 @@ static int HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **)b); #endif - if (hca->distance < hcb->distance) + if (hca->distance < hcb->distance) { return 1; + } - if (hca->distance > hcb->distance) + if (hca->distance > hcb->distance) { return -1; + } - if (HnswPtrPointer(hca->element) < HnswPtrPointer(hcb->element)) + if (HnswPtrPointer(hca->element) < HnswPtrPointer(hcb->element)) { return 1; + } - if (HnswPtrPointer(hca->element) > HnswPtrPointer(hcb->element)) + if (HnswPtrPointer(hca->element) > HnswPtrPointer(hcb->element)) { return -1; + } return 0; } @@ -968,17 +978,21 @@ static int HnswCandidate *hcb = (HnswCandidate *)lfirst(*(ListCell **)b); #endif - if (hca->distance < hcb->distance) + if (hca->distance < hcb->distance) { return 1; + } - if (hca->distance > hcb->distance) + if (hca->distance > hcb->distance) { return -1; + } - if (HnswPtrOffset(hca->element) < HnswPtrOffset(hcb->element)) + if (HnswPtrOffset(hca->element) < HnswPtrOffset(hcb->element)) { return 1; + } - if (HnswPtrOffset(hca->element) > HnswPtrOffset(hcb->element)) + if (HnswPtrOffset(hca->element) > HnswPtrOffset(hcb->element)) { return -1; + } return 0; } @@ -1007,8 +1021,9 @@ static bool CheckElementCloser(char *base, HnswCandidate *e, List *r, FmgrInfo * HnswElement riElement = (HnswElement)HnswPtrAccess(base, ri->element); float distance = HnswGetDistance(base, eElement, riElement, procinfo, collation); - if (distance <= e->distance) + if (distance <= e->distance) { return false; + } } return true; @@ -1030,8 +1045,9 @@ static List *SelectNeighbors(char *base, List *c, int lm, int lc, FmgrInfo *proc List *added = NIL; bool removedAny = false; - if (list_length(w) <= lm) + if (list_length(w) <= lm) { return w; + } wd = (HnswCandidate **)palloc(sizeof(HnswCandidate *) * list_length(w)); @@ -1149,8 +1165,9 @@ void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate *hc, in currentNeighbors->items[currentNeighbors->length++] = hc2; /* Track update */ - if (updateIdx != NULL) + if (updateIdx != NULL) { *updateIdx = -2; + } } else { /* Shrink connections */ HnswCandidate *pruned = NULL; @@ -1180,8 +1197,9 @@ void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate *hc, in List *c = NIL; /* Add candidates */ - for (int i = 0; i < currentNeighbors->length; i++) + for (int i = 0; i < currentNeighbors->length; i++) { c = lappend(c, ¤tNeighbors->items[i]); + } c = lappend(c, &hc2); SelectNeighbors(base, c, lm, lc, procinfo, collation, hce, &hc2, &pruned, true); @@ -1197,8 +1215,9 @@ void HnswUpdateConnection(char *base, HnswElement element, HnswCandidate *hc, in currentNeighbors->items[i] = hc2; /* Track update */ - if (updateIdx != NULL) + if (updateIdx != NULL) { *updateIdx = i; + } break; } @@ -1222,11 +1241,13 @@ static List *RemoveElements(char *base, List *w, HnswElement skipElement) HnswElement hce = (HnswElement)HnswPtrAccess(base, hc->element); /* Skip self for vacuuming update */ - if (skipElement != NULL && hce->blkno == skipElement->blkno && hce->offno == skipElement->offno) + if (skipElement != NULL && hce->blkno == skipElement->blkno && hce->offno == skipElement->offno) { continue; + } - if (hce->heaptidsLength != 0) + if (hce->heaptidsLength != 0) { w2 = lappend(w2, hc); + } } return w2; @@ -1242,10 +1263,11 @@ static void PrecomputeHash(char *base, HnswElement element) HnswPtrStore(base, ptr, element); - if (base == NULL) + if (base == NULL) { element->hash = hash_pointer((uintptr_t)HnswPtrPointer(ptr)); - else + } else { element->hash = hash_offset(HnswPtrOffset(ptr)); + } } #endif diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp index 4d7925e61c..0f35fdbba0 100644 --- a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -182,8 +182,9 @@ static void RepairGraphElement(HnswVacuumState *vacuumstate, HnswElement element char *base = NULL; /* Skip if element is entry point */ - if (entryPoint != NULL && element->blkno == entryPoint->blkno && element->offno == entryPoint->offno) + if (entryPoint != NULL && element->blkno == entryPoint->blkno && element->offno == entryPoint->offno) { return; + } /* Init fields */ HnswInitNeighbors(base, element, m, NULL); diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index c2c805d365..eb5fb9dd7e 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -141,8 +141,9 @@ static void AddTupleToSort(Relation index, ItemPointer tid, Datum *values, Ivffl /* Normalize if needed */ if (buildstate->normprocinfo != NULL) { - if (!IvfflatCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) + if (!IvfflatCheckNorm(buildstate->normprocinfo, buildstate->collation, value)) { return; + } value = IvfflatNormValue(buildstate->typeInfo, buildstate->collation, value); } @@ -198,8 +199,9 @@ static void BuildCallback(Relation index, CALLBACK_ITEM_POINTER, Datum *values, #endif /* Skip nulls */ - if (isnull[0]) + if (isnull[0]) { return; + } /* Use memory context since detoast can allocate */ oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx); @@ -228,8 +230,9 @@ static inline void GetNextTuple(Tuplesortstate *sortstate, TupleDesc tupdesc, Tu /* Form the index tuple */ *itup = index_form_tuple(tupdesc, &value, &isnull); (*itup)->t_tid = *((ItemPointer)DatumGetPointer(heap_slot_getattr(slot, 2, &isnull))); - } else + } else { *list = -1; + } } /* @@ -816,8 +819,9 @@ static void CreateEntryPages(IvfflatBuildState *buildstate, ForkNumber forkNum) tuplesort_end(buildstate->sortstate); /* End parallel build */ - if (buildstate->ivfleader) + if (buildstate->ivfleader) { IvfflatEndParallel(); + } } /* @@ -838,7 +842,7 @@ static void BuildIndex(Relation heap, Relation index, IndexInfo *indexInfo, Ivff /* Write WAL for initialization fork since GenericXLog functions do not */ if (forkNum == INIT_FORKNUM) - log_newpage_range(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); + LogNewpageRange(index, forkNum, 0, RelationGetNumberOfBlocksInFork(index, forkNum), true); FreeBuildState(buildstate); } diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp index ad222ae868..6482ce48d8 100644 --- a/src/gausskernel/storage/access/datavec/ivfinsert.cpp +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -82,8 +82,9 @@ static void InsertTuple(Relation index, Datum *values, const bool *isnull, ItemP if (normprocinfo != NULL) { Oid collation = index->rd_indcollation[0]; - if (!IvfflatCheckNorm(normprocinfo, collation, value)) + if (!IvfflatCheckNorm(normprocinfo, collation, value)) { return; + } value = IvfflatNormValue(typeInfo, collation, value); } @@ -112,8 +113,9 @@ static void InsertTuple(Relation index, Datum *values, const bool *isnull, ItemP state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buf, 0); - if (PageGetFreeSpace(page) >= itemsz) + if (PageGetFreeSpace(page) >= itemsz) { break; + } insertPage = IvfflatPageGetOpaque(page)->nextblkno; if (BlockNumberIsValid(insertPage)) { @@ -174,8 +176,9 @@ bool ivfflatinsert_internal(Relation index, Datum *values, const bool *isnull, I MemoryContext insertCtx; /* Skip nulls */ - if (isnull[0]) + if (isnull[0]) { return false; + } /* * Use memory context since detoast, IvfflatNormValue, and diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index 6ab9ec9521..21c249cf93 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -67,8 +67,9 @@ static void InitCenters(Relation index, VectorArray samples, VectorArray centers } /* Only compute lower bound on last iteration */ - if (i + 1 == numCenters) + if (i + 1 == numCenters) { break; + } /* Choose new center using weighted probability distribution. */ choice = sum * RandomDouble(); @@ -125,8 +126,9 @@ static void RandomCenters(Relation index, VectorArray centers, const IvfflatType while (centers->length < centers->maxlen) { Pointer center = VectorArrayGet(centers, centers->length); - for (int i = 0; i < dimensions; i++) + for (int i = 0; i < dimensions; i++) { x[i] = (float)RandomDouble(); + } typeInfo->updateCenter(center, dimensions, x); @@ -191,8 +193,9 @@ static void ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCe for (int j = 0; j < numCenters; j++) { float *x = agg + ((int64)j * dimensions); - for (int k = 0; k < dimensions; k++) + for (int k = 0; k < dimensions; k++) { x[k] = 0.0; + } centerCounts[j] = 0; } @@ -201,8 +204,9 @@ static void ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCe SumCenters(samples, agg, closestCenters, typeInfo); /* Increment count of closest center */ - for (int j = 0; j < numSamples; j++) + for (int j = 0; j < numSamples; j++) { centerCounts[closestCenters[j]] += 1; + } /* Divide sum by count */ for (int j = 0; j < numCenters; j++) { @@ -212,16 +216,19 @@ static void ComputeNewCenters(VectorArray samples, float *agg, VectorArray newCe /* Double avoids overflow, but requires more memory */ /* TODO Update bounds */ for (int k = 0; k < dimensions; k++) { - if (isinf(x[k])) + if (isinf(x[k])) { x[k] = x[k] > 0 ? FLT_MAX : -FLT_MAX; + } } - for (int k = 0; k < dimensions; k++) + for (int k = 0; k < dimensions; k++) { x[k] /= centerCounts[j]; + } } else { /* TODO Handle empty centers properly */ - for (int k = 0; k < dimensions; k++) + for (int k = 0; k < dimensions; k++) { x[k] = RandomDouble(); + } } } @@ -446,8 +453,9 @@ static void ElkanKmeans(Relation index, VectorArray samples, VectorArray centers for (int64 k = 0; k < numCenters; k++) { float distance = lowerBound[j * numCenters + k] - newcdist[k]; - if (distance < 0) + if (distance < 0) { distance = 0; + } lowerBound[j * numCenters + k] = distance; } @@ -455,15 +463,18 @@ static void ElkanKmeans(Relation index, VectorArray samples, VectorArray centers /* Step 6 */ /* We reset r(x) before Step 3 in the next iteration */ - for (int j = 0; j < numSamples; j++) + for (int j = 0; j < numSamples; j++) { upperBound[j] += newcdist[closestCenters[j]]; + } /* Step 7 */ - for (int j = 0; j < numCenters; j++) + for (int j = 0; j < numCenters; j++) { VectorArraySet(centers, j, VectorArrayGet(newCenters, j)); + } - if (changes == 0 && iteration != 0) + if (changes == 0 && iteration != 0) { break; + } } } @@ -500,14 +511,16 @@ static void CheckNorms(VectorArray centers, Relation index) FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_NORM_PROC); Oid collation = index->rd_indcollation[0]; - if (normprocinfo == NULL) + if (normprocinfo == NULL) { return; + } for (int i = 0; i < centers->length; i++) { double norm = DatumGetFloat8(FunctionCall1Coll(normprocinfo, collation, PointerGetDatum(VectorArrayGet(centers, i)))); - if (norm == 0) + if (norm == 0) { elog(ERROR, "Zero norm detected. Please report a bug."); + } } } diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index 1041e2d2ef..836ddb5f7d 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -14,11 +14,13 @@ */ static int CompareLists(const pairingheap_node *a, const pairingheap_node *b, void *arg) { - if (((const IvfflatScanList *)a)->distance > ((const IvfflatScanList *)b)->distance) + if (((const IvfflatScanList *)a)->distance > ((const IvfflatScanList *)b)->distance) { return 1; + } - if (((const IvfflatScanList *)a)->distance < ((const IvfflatScanList *)b)->distance) + if (((const IvfflatScanList *)a)->distance < ((const IvfflatScanList *)b)->distance) { return -1; + } return 0; } diff --git a/src/gausskernel/storage/access/datavec/ivfutils.cpp b/src/gausskernel/storage/access/datavec/ivfutils.cpp index 8adb54e8fa..79ab8ea4d1 100644 --- a/src/gausskernel/storage/access/datavec/ivfutils.cpp +++ b/src/gausskernel/storage/access/datavec/ivfutils.cpp @@ -201,9 +201,9 @@ void IvfflatUpdateList(Relation index, ListInfo listInfo, BlockNumber insertPage } /* Only commit if changed */ - if (changed) + if (changed) { IvfflatCommitBuffer(buf, state); - else { + } else { GenericXLogAbort(state); UnlockReleaseBuffer(buf); } @@ -254,11 +254,13 @@ static void BitUpdateCenter(Pointer v, int dimensions, float *x) SET_VARSIZE(vec, VARBITTOTALLEN(dimensions)); VARBITLEN(vec) = dimensions; - for (uint32 k = 0; k < VARBITBYTES(vec); k++) + for (uint32 k = 0; k < VARBITBYTES(vec); k++) { nx[k] = 0; + } - for (int k = 0; k < dimensions; k++) + for (int k = 0; k < dimensions; k++) { nx[k / 8] |= (x[k] > 0.5 ? 1 : 0) << (7 - (k % 8)); + } } static void VectorSumCenter(Pointer v, float *x) @@ -300,8 +302,9 @@ const IvfflatTypeInfo *IvfflatGetTypeInfo(Relation index) .sumCenter = VectorSumCenter}; return (&typeInfo); - } else + } else { return (const IvfflatTypeInfo *)DatumGetPointer(OidFunctionCall0Coll(procinfo->fn_oid, InvalidOid)); + } } PGDLLEXPORT PG_FUNCTION_INFO_V1(ivfflat_halfvec_support); -- Gitee From c3bbc08ea6bdf4b7d3ac2f42e4762e9debabd6de Mon Sep 17 00:00:00 2001 From: jiwenke Date: Fri, 1 Nov 2024 20:46:42 +0800 Subject: [PATCH 16/67] clean code --- .../storage/access/datavec/ivfflat.cpp | 7 +-- src/include/catalog/pg_amproc.h | 50 +++++++++---------- src/include/catalog/pg_opclass.h | 48 +++++++++--------- src/include/catalog/pg_type.h | 6 +-- 4 files changed, 53 insertions(+), 58 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index 3d98191bb8..f202ab7eac 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -20,12 +20,7 @@ void IvfflatInit(void) { ivfflat_relopt_kind = add_reloption_kind(); add_int_reloption(ivfflat_relopt_kind, "lists", "Number of inverted lists", IVFFLAT_DEFAULT_LISTS, - IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS -#if PG_VERSION_NUM >= 130000 - , - AccessExclusiveLock -#endif - ); + IVFFLAT_MIN_LISTS, IVFFLAT_MAX_LISTS); } /* diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index e8f0a71aa1..1347ab611a 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -655,36 +655,36 @@ DATA(insert ( 8901 3831 3831 1 3870 )); DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); -DATA(insert ( 6030 4409 4409 1 8008 )); -DATA(insert ( 6040 4409 4409 1 8216 )); -DATA(insert ( 6050 4409 4409 1 8216 )); -DATA(insert ( 6060 4409 4409 1 8216 )); +DATA(insert (6030 4409 4409 1 8008)); +DATA(insert (6040 4409 4409 1 8216)); +DATA(insert (6050 4409 4409 1 8216)); +DATA(insert (6060 4409 4409 1 8216)); -DATA(insert OID = 6038( 6035 4410 4410 1 8217 )); -DATA(insert OID = 6048( 6045 4410 4410 1 8217 )); -DATA(insert OID = 6058( 6055 4410 4410 1 8217 )); -DATA(insert OID = 6068( 6065 4410 4410 1 8217 )); +DATA(insert OID = 6038(6035 4410 4410 1 8217)); +DATA(insert OID = 6048(6045 4410 4410 1 8217)); +DATA(insert OID = 6058(6055 4410 4410 1 8217)); +DATA(insert OID = 6068(6065 4410 4410 1 8217)); -DATA(insert OID = 6149( 6075 1560 1560 1 8218 )); -DATA(insert OID = 6150( 6076 1560 1560 1 8218 )); +DATA(insert OID = 6149(6075 1560 1560 1 8218)); +DATA(insert OID = 6150(6076 1560 1560 1 8218)); -DATA(insert OID = 6151( 6071 4411 4411 1 8219 )); -DATA(insert OID = 6152( 6072 4411 4411 1 8219 )); -DATA(insert OID = 6153( 6073 4411 4411 1 8219 )); -DATA(insert OID = 6154( 6074 4411 4411 1 8219 )); +DATA(insert OID = 6151(6071 4411 4411 1 8219)); +DATA(insert OID = 6152(6072 4411 4411 1 8219)); +DATA(insert OID = 6153(6073 4411 4411 1 8219)); +DATA(insert OID = 6154(6074 4411 4411 1 8219)); -DATA(insert ( 6077 4409 4409 1 8008 )); -DATA(insert ( 6077 4409 4409 3 8200 )); +DATA(insert (6077 4409 4409 1 8008)); +DATA(insert (6077 4409 4409 3 8200)); -DATA(insert ( 6078 4409 4409 1 8216 )); -DATA(insert ( 6079 4409 4409 1 8216 )); -DATA(insert ( 6070 4409 4409 1 8216 )); +DATA(insert (6078 4409 4409 1 8216)); +DATA(insert (6079 4409 4409 1 8216)); +DATA(insert (6070 4409 4409 1 8216)); -DATA(insert OID = 6155( 6080 4410 4410 1 8217 )); -DATA(insert OID = 6157( 6081 4410 4410 1 8217 )); -DATA(insert OID = 6158( 6082 4410 4410 1 8217 )); -DATA(insert OID = 6159( 6083 4410 4410 1 8217 )); +DATA(insert OID = 6155(6080 4410 4410 1 8217)); +DATA(insert OID = 6157(6081 4410 4410 1 8217)); +DATA(insert OID = 6158(6082 4410 4410 1 8217)); +DATA(insert OID = 6159(6083 4410 4410 1 8217)); -DATA(insert OID = 6160( 6084 1560 1560 1 8218 )); -DATA(insert OID = 6161( 6085 1560 1560 1 8218 )); +DATA(insert OID = 6160(6084 1560 1560 1 8218)); +DATA(insert OID = 6161(6085 1560 1560 1 8218)); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 7b000a04f2..671ca016e6 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -375,35 +375,35 @@ DATA(insert ( 405 settext_ops PGNSP PGUID 1995 3272 f 0 )); DATA(insert ( 4439 setasint_ops PGNSP PGUID 6976 3272 t 0 )); DATA(insert ( 405 set_ops PGNSP PGUID 8646 3272 t 0 )); -DATA(insert ( 4446 vector_l2_ops PGNSP PGUID 6030 4409 t 0 )); -DATA(insert ( 4446 vector_ip_ops PGNSP PGUID 6040 4409 t 0 )); -DATA(insert ( 4446 vector_cosine_ops PGNSP PGUID 6050 4409 t 0 )); -DATA(insert ( 4446 vector_l1_ops PGNSP PGUID 6060 4409 t 0 )); -DATA(insert OID = 6037 ( 4446 halfvec_l2_ops PGNSP PGUID 6035 4410 t 0 )); -DATA(insert OID = 6047 ( 4446 halfvec_ip_ops PGNSP PGUID 6045 4410 t 0 )); -DATA(insert OID = 6057 ( 4446 halfvec_cosine_ops PGNSP PGUID 6055 4410 t 0 )); -DATA(insert OID = 6067 ( 4446 halfvec_l1_ops PGNSP PGUID 6065 4410 t 0 )); +DATA(insert(4446 vector_l2_ops PGNSP PGUID 6030 4409 t 0)); +DATA(insert(4446 vector_ip_ops PGNSP PGUID 6040 4409 t 0)); +DATA(insert(4446 vector_cosine_ops PGNSP PGUID 6050 4409 t 0)); +DATA(insert(4446 vector_l1_ops PGNSP PGUID 6060 4409 t 0)); +DATA(insert OID = 6037(4446 halfvec_l2_ops PGNSP PGUID 6035 4410 t 0)); +DATA(insert OID = 6047(4446 halfvec_ip_ops PGNSP PGUID 6045 4410 t 0)); +DATA(insert OID = 6057(4446 halfvec_cosine_ops PGNSP PGUID 6055 4410 t 0)); +DATA(insert OID = 6067(4446 halfvec_l1_ops PGNSP PGUID 6065 4410 t 0)); -DATA(insert OID = 6010 ( 4446 bit_jaccard_ops PGNSP PGUID 6075 1560 t 0 )); -DATA(insert OID = 6011 ( 4446 bit_hamming_ops PGNSP PGUID 6076 1560 t 0 )); +DATA(insert OID = 6010(4446 bit_jaccard_ops PGNSP PGUID 6075 1560 t 0)); +DATA(insert OID = 6011(4446 bit_hamming_ops PGNSP PGUID 6076 1560 t 0)); -DATA(insert OID = 6012 ( 4446 sparsevec_l2_ops PGNSP PGUID 6071 4411 t 0 )); -DATA(insert OID = 6013 ( 4446 sparsevec_ip_ops PGNSP PGUID 6072 4411 t 0 )); -DATA(insert OID = 6014 ( 4446 sparsevec_cosine_ops PGNSP PGUID 6073 4411 t 0 )); -DATA(insert OID = 6015 ( 4446 sparsevec_l1_ops PGNSP PGUID 6074 4411 t 0 )); +DATA(insert OID = 6012(4446 sparsevec_l2_ops PGNSP PGUID 6071 4411 t 0)); +DATA(insert OID = 6013(4446 sparsevec_ip_ops PGNSP PGUID 6072 4411 t 0)); +DATA(insert OID = 6014(4446 sparsevec_cosine_ops PGNSP PGUID 6073 4411 t 0)); +DATA(insert OID = 6015(4446 sparsevec_l1_ops PGNSP PGUID 6074 4411 t 0)); -DATA(insert ( 4447 vector_l2_ops PGNSP PGUID 6077 4409 t 0 )); -DATA(insert ( 4447 vector_ip_ops PGNSP PGUID 6078 4409 t 0 )); -DATA(insert ( 4447 vector_cosine_ops PGNSP PGUID 6079 4409 t 0 )); -DATA(insert ( 4447 vector_l1_ops PGNSP PGUID 6070 4409 t 0 )); +DATA(insert(4447 vector_l2_ops PGNSP PGUID 6077 4409 t 0)); +DATA(insert(4447 vector_ip_ops PGNSP PGUID 6078 4409 t 0)); +DATA(insert(4447 vector_cosine_ops PGNSP PGUID 6079 4409 t 0)); +DATA(insert(4447 vector_l1_ops PGNSP PGUID 6070 4409 t 0)); -DATA(insert OID = 6016 ( 4447 halfvec_l2_ops PGNSP PGUID 6080 4410 t 0 )); -DATA(insert OID = 6017 ( 4447 halfvec_ip_ops PGNSP PGUID 6081 4410 t 0 )); -DATA(insert OID = 6018 ( 4447 halfvec_cosine_ops PGNSP PGUID 6082 4410 t 0 )); -DATA(insert OID = 6039 ( 4447 halfvec_l1_ops PGNSP PGUID 6083 4410 t 0 )); +DATA(insert OID = 6016(4447 halfvec_l2_ops PGNSP PGUID 6080 4410 t 0)); +DATA(insert OID = 6017(4447 halfvec_ip_ops PGNSP PGUID 6081 4410 t 0)); +DATA(insert OID = 6018(4447 halfvec_cosine_ops PGNSP PGUID 6082 4410 t 0)); +DATA(insert OID = 6039(4447 halfvec_l1_ops PGNSP PGUID 6083 4410 t 0)); -DATA(insert OID = 6049 ( 4447 bit_jaccard_ops PGNSP PGUID 6084 1560 t 0 )); -DATA(insert OID = 6086 ( 4447 bit_hamming_ops PGNSP PGUID 6085 1560 t 0 )); +DATA(insert OID = 6049(4447 bit_jaccard_ops PGNSP PGUID 6084 1560 t 0)); +DATA(insert OID = 6086(4447 bit_hamming_ops PGNSP PGUID 6085 1560 t 0)); #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index e848f0c9ed..6cc766ae5e 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -823,13 +823,13 @@ DATA(insert OID = 4408 ( undefined PGNSP PGUID -2 f u W f t \054 0 0 0 undefin DESCR("undefined objects as PLSQL compilation time"); #define UNDEFINEDOID 4408 -DATA(insert OID = 4409 ( vector PGNSP PGUID -1 f b U f t \054 0 0 0 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 4409 (vector PGNSP PGUID -1 f b U f t \054 0 0 0 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define VECTOROID 4409 -DATA(insert OID = 4410 ( halfvec PGNSP PGUID -1 f b U f t \054 0 0 0 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 4410 (halfvec PGNSP PGUID -1 f b U f t \054 0 0 0 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define FLOATVECTOROID 4410 -DATA(insert OID = 4411 ( sparsevec PGNSP PGUID -1 f b U f t \054 0 0 0 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 4411 (sparsevec PGNSP PGUID -1 f b U f t \054 0 0 0 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define SPARSEVECTOROID 4411 /* -- Gitee From aef8c04af7886a009cabfc0b1bdd67316b863028 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Fri, 1 Nov 2024 19:28:41 +0800 Subject: [PATCH 17/67] rmc modify oid --- src/common/backend/catalog/builtin_funcs.ini | 297 ++++++++++--------- src/include/catalog/pg_am.h | 8 +- src/include/catalog/pg_amop.data | 172 ++++++----- src/include/catalog/pg_amproc.h | 66 +++-- src/include/catalog/pg_opclass.h | 49 +-- src/include/catalog/pg_operator.data | 62 ++-- src/include/catalog/pg_opfamily.h | 50 ++-- src/include/catalog/pg_type.h | 12 +- 8 files changed, 380 insertions(+), 336 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 99e366d3ed..f619c0ceeb 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13122,278 +13122,291 @@ AddFuncGroup( AddBuiltinFunc(_0(6808), _1("query_imcstore_views"), _2(1), _3(true), _4(true), _5(query_imcstore_views), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1000), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(11, 26, 19, 22, 21, 19, 16, 26, 20, 20, 20, 20), _22(11, 'o', 'o', 'o', 'o','o', 'o', 'o', 'o', 'o','o', 'o'), _23(11, "reloid", "relname", "imcs_attrs", "imcs_nattrs", "imcs_status", "is_partition", "parent_oid", "cu_size_in_mem", "cu_num_in_mem", "cu_size_in_disk", "cu_num_in_disk"), _24(NULL), _25("query_imcstore_views"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("query_imcstore_views"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_in", 1, - AddBuiltinFunc(_0(8000), _1("vector_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswinsert", 1, + AddBuiltinFunc(_0(8401), _1("hnswinsert"), _2(6), _3(true), _4(false), _5(hnswinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_out", 1, - AddBuiltinFunc(_0(8024), _1("vector_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswbeginscan", 1, + AddBuiltinFunc(_0(8402), _1("hnswbeginscan"), _2(3), _3(true), _4(false), _5(hnswbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "vector_typmod_in", 1, - AddBuiltinFunc(_0(8002), _1("vector_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + +AddFuncGroup( + "hnswgettuple", 1, + AddBuiltinFunc(_0(8403), _1("hnswgettuple"), _2(2), _3(true), _4(false), _5(hnswgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_recv", 1, - AddBuiltinFunc(_0(8003), _1("vector_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswrescan", 1, + AddBuiltinFunc(_0(8404), _1("hnswrescan"), _2(5), _3(true), _4(false), _5(hnswrescan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_send", 1, - AddBuiltinFunc(_0(8004), _1("vector_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswendscan", 1, + AddBuiltinFunc(_0(8405), _1("hnswendscan"), _2(1), _3(true), _4(false), _5(hnswendscan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "vector_dims", 1, - AddBuiltinFunc(_0(8005), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddFuncGroup( + "hnswbuild", 1, + AddBuiltinFunc(_0(8406), _1("hnswbuild"), _2(3), _3(true), _4(false), _5(hnswbuild), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "array_to_vector", 1, - AddBuiltinFunc(_0(8006), _1("array_to_vector"), _2(1), _3(true), _4(false), _5(array_to_vector), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswbuildempty", 1, + AddBuiltinFunc(_0(8407), _1("hnswbuildempty"), _2(1), _3(true), _4(false), _5(hnswbuildempty), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_to_float4", 1, - AddBuiltinFunc(_0(8007), _1("vector_to_float4"), _2(1), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswbulkdelete", 1, + AddBuiltinFunc(_0(8408), _1("hnswbulkdelete"), _2(4), _3(true), _4(false), _5(hnswbulkdelete), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_l2_squared_distance", 1, - AddBuiltinFunc(_0(8008), _1("vector_l2_squared_distance"), _2(1), _3(true), _4(false), _5(vector_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswvacuumcleanup", 1, + AddBuiltinFunc(_0(8409), _1("hnswvacuumcleanup"), _2(2), _3(true), _4(false), _5(hnswvacuumcleanup), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_spherical_distance", 1, - AddBuiltinFunc(_0(8009), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hnswcostestimate", 1, + AddBuiltinFunc(_0(8410), _1("hnswcostestimate"), _2(7), _3(true), _4(false), _5(hnswcostestimate), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "inner_product", 1, - AddBuiltinFunc(_0(8011), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddFuncGroup( + "hnswoptions", 1, + AddBuiltinFunc(_0(8411), _1("hnswoptions"), _2(2), _3(true), _4(false), _5(hnswoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + + + AddFuncGroup( - "vector_norm", 1, - AddBuiltinFunc(_0(8012), _1("vector_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatinsert", 1, + AddBuiltinFunc(_0(8412), _1("ivfflatinsert"), _2(6), _3(true), _4(false), _5(ivfflatinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_add", 1, - AddBuiltinFunc(_0(8013), _1("vector_add"), _2(1), _3(true), _4(false), _5(vector_add), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_add"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatbeginscan", 1, + AddBuiltinFunc(_0(8413), _1("ivfflatbeginscan"), _2(3), _3(true), _4(false), _5(ivfflatbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + AddFuncGroup( - "vector_sub", 1, - AddBuiltinFunc(_0(8014), _1("vector_sub"), _2(1), _3(true), _4(false), _5(vector_sub), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatgettuple", 1, + AddBuiltinFunc(_0(8414), _1("ivfflatgettuple"), _2(2), _3(true), _4(false), _5(ivfflatgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_lt", 1, - AddBuiltinFunc(_0(8015), _1("vector_lt"), _2(1), _3(true), _4(false), _5(vector_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatrescan", 1, + AddBuiltinFunc(_0(8415), _1("ivfflatrescan"), _2(5), _3(true), _4(false), _5(ivfflatrescan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_le", 1, - AddBuiltinFunc(_0(8016), _1("vector_le"), _2(1), _3(true), _4(false), _5(vector_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatendscan", 1, + AddBuiltinFunc(_0(8416), _1("ivfflatendscan"), _2(1), _3(true), _4(false), _5(ivfflatendscan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_eq", 1, - AddBuiltinFunc(_0(8017), _1("vector_eq"), _2(1), _3(true), _4(false), _5(vector_eq), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatbuild", 1, + AddBuiltinFunc(_0(8417), _1("ivfflatbuild"), _2(3), _3(true), _4(false), _5(ivfflatbuild), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_ne", 1, - AddBuiltinFunc(_0(8018), _1("vector_ne"), _2(1), _3(true), _4(false), _5(vector_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatbuildempty", 1, + AddBuiltinFunc(_0(8418), _1("ivfflatbuildempty"), _2(1), _3(true), _4(false), _5(ivfflatbuildempty), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_ge", 1, - AddBuiltinFunc(_0(8019), _1("vector_ge"), _2(1), _3(true), _4(false), _5(vector_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatbulkdelete", 1, + AddBuiltinFunc( _0(8419), _1("ivfflatbulkdelete"), _2(4), _3(true), _4(false), _5(ivfflatbulkdelete), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_gt", 1, - AddBuiltinFunc(_0(8020), _1("vector_gt"), _2(1), _3(true), _4(false), _5(vector_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatvacuumcleanup", 1, + AddBuiltinFunc(_0(8420), _1("ivfflatvacuumcleanup"), _2(2), _3(true), _4(false), _5(ivfflatvacuumcleanup), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "vector_accum", 1, - AddBuiltinFunc(_0(8021), _1("vector_accum"), _2(1), _3(true), _4(false), _5(vector_accum), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddFuncGroup( + "ivfflatcostestimate", 1, + AddBuiltinFunc(_0(8421), _1("ivfflatcostestimate"), _2(7), _3(true), _4(false), _5(ivfflatcostestimate), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_combine", 1, - AddBuiltinFunc(_0(8022), _1("vector_combine"), _2(1), _3(true), _4(false), _5(vector_combine), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "ivfflatoptions", 1, + AddBuiltinFunc(_0(8422), _1("ivfflatoptions"), _2(2), _3(true), _4(false), _5(ivfflatoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_avg", 1, - AddBuiltinFunc(_0(8023), _1("vector_avg"), _2(1), _3(true), _4(false), _5(vector_avg), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_in", 1, + AddBuiltinFunc(_0(8423), _1("vector_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswinsert", 1, - AddBuiltinFunc(_0(8226), _1("hnswinsert"), _2(6), _3(true), _4(false), _5(hnswinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_out", 1, + AddBuiltinFunc(_0(8424), _1("vector_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswbeginscan", 1, - AddBuiltinFunc(_0(8220), _1("hnswbeginscan"), _2(3), _3(true), _4(false), _5(hnswbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_typmod_in", 1, + AddBuiltinFunc(_0(8425), _1("vector_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswgettuple", 1, - AddBuiltinFunc(_0(8229), _1("hnswgettuple"), _2(2), _3(true), _4(false), _5(hnswgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_recv", 1, + AddBuiltinFunc(_0(8426), _1("vector_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswrescan", 1, - AddBuiltinFunc(_0(8230), _1("hnswrescan"), _2(5), _3(true), _4(false), _5(hnswrescan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_send", 1, + AddBuiltinFunc(_0(8427), _1("vector_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_dims", 1, + AddBuiltinFunc(_0(8428), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswendscan", 1, - AddBuiltinFunc(_0(8225), _1("hnswendscan"), _2(1), _3(true), _4(false), _5(hnswendscan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "array_to_vector", 1, + AddBuiltinFunc(_0(8429), _1("array_to_vector"), _2(1), _3(true), _4(false), _5(array_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswbuild", 1, - AddBuiltinFunc(_0(8221), _1("hnswbuild"), _2(3), _3(true), _4(false), _5(hnswbuild), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_to_float4", 1, + AddBuiltinFunc(_0(8430), _1("vector_to_float4"), _2(1), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswbuildempty", 1, - AddBuiltinFunc(_0(8222), _1("hnswbuildempty"), _2(1), _3(true), _4(false), _5(hnswbuildempty), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_l2_squared_distance", 1, + AddBuiltinFunc(_0(8431), _1("vector_l2_squared_distance"), _2(1), _3(true), _4(false), _5(vector_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswbulkdelete", 1, - AddBuiltinFunc(_0(8223), _1("hnswbulkdelete"), _2(4), _3(true), _4(false), _5(hnswbulkdelete), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_spherical_distance", 1, + AddBuiltinFunc(_0(8432), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + + AddFuncGroup( - "hnswvacuumcleanup", 1, - AddBuiltinFunc(_0(8228), _1("hnswvacuumcleanup"), _2(2), _3(true), _4(false), _5(hnswvacuumcleanup), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "l2_distance", 1, + AddBuiltinFunc(_0(8433), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswcostestimate", 1, - AddBuiltinFunc(_0(8224), _1("hnswcostestimate"), _2(7), _3(true), _4(false), _5(hnswcostestimate), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_negative_inner_product", 1, + AddBuiltinFunc(_0(8434), _1("vector_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnswoptions", 1, - AddBuiltinFunc(_0(8227), _1("hnswoptions"), _2(2), _3(true), _4(false), _5(hnswoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "cosine_distance", 1, + AddBuiltinFunc(_0(8435), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_cmp", 1, - AddBuiltinFunc(_0(8216), _1("vector_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "l1_distance", 1, + AddBuiltinFunc(_0(8436), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + + AddFuncGroup( - "halfvec_cmp", 1, - AddBuiltinFunc(_0(8217), _1("halfvec_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "inner_product", 1, + AddBuiltinFunc(_0(8437), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l2_distance", 1, - AddBuiltinFunc(_0(8200), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_norm", 1, + AddBuiltinFunc(_0(8438), _1("vector_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_negative_inner_product", 1, - AddBuiltinFunc(_0(8203), _1("vector_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_add", 1, + AddBuiltinFunc(_0(8439), _1("vector_add"), _2(1), _3(true), _4(false), _5(vector_add), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_add"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "cosine_distance", 1, - AddBuiltinFunc(_0(8204), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_sub", 1, + AddBuiltinFunc(_0(8440), _1("vector_sub"), _2(1), _3(true), _4(false), _5(vector_sub), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l1_distance", 1, - AddBuiltinFunc(_0(8205), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_lt", 1, + AddBuiltinFunc(_0(8441), _1("vector_lt"), _2(1), _3(true), _4(false), _5(vector_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "halfvec_in", 1, - AddBuiltinFunc(_0(8206), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_le", 1, + AddBuiltinFunc(_0(8442), _1("vector_le"), _2(1), _3(true), _4(false), _5(vector_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "halfvec_out", 1, - AddBuiltinFunc(_0(8207), _1("halfvec_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_eq", 1, + AddBuiltinFunc(_0(8443), _1("vector_eq"), _2(1), _3(true), _4(false), _5(vector_eq), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "halfvec_typmod_in", 1, - AddBuiltinFunc(_0(8208), _1("halfvec_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_ne", 1, + AddBuiltinFunc(_0(8444), _1("vector_ne"), _2(1), _3(true), _4(false), _5(vector_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "halfvec_recv", 1, - AddBuiltinFunc(_0(8209), _1("halfvec_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(4409), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_ge", 1, + AddBuiltinFunc(_0(8445), _1("vector_ge"), _2(1), _3(true), _4(false), _5(vector_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "halfvec_send", 1, - AddBuiltinFunc(_0(8210), _1("halfvec_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_gt", 1, + AddBuiltinFunc(_0(8446), _1("vector_gt"), _2(1), _3(true), _4(false), _5(vector_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "halfvec_negative_inner_product", 1, - AddBuiltinFunc(_0(8211), _1("halfvec_negative_inner_product"), _2(1), _3(true), _4(false), _5(halfvec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_accum", 1, + AddBuiltinFunc(_0(8447), _1("vector_accum"), _2(1), _3(true), _4(false), _5(vector_accum), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_in", 1, - AddBuiltinFunc(_0(8231), _1("sparsevec_in"), _2(3), _3(true), _4(false), _5(sparsevec_in), _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_combine", 1, + AddBuiltinFunc(_0(8448), _1("vector_combine"), _2(1), _3(true), _4(false), _5(vector_combine), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_out", 1, - AddBuiltinFunc(_0(8232), _1("sparsevec_out"), _2(1), _3(true), _4(false), _5(sparsevec_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_avg", 1, + AddBuiltinFunc(_0(8449), _1("vector_avg"), _2(1), _3(true), _4(false), _5(vector_avg), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_typmod_in", 1, - AddBuiltinFunc(_0(8233), _1("sparsevec_typmod_in"), _2(1), _3(true), _4(false), _5(sparsevec_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_cmp", 1, + AddBuiltinFunc(_0(8450), _1("vector_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_recv", 1, - AddBuiltinFunc(_0(8234), _1("sparsevec_recv"), _2(3), _3(true), _4(false), _5(sparsevec_recv), _6(4411), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "halfvec_cmp", 1, + AddBuiltinFunc(_0(8451), _1("halfvec_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_send", 1, - AddBuiltinFunc(_0(8218), _1("sparsevec_send"), _2(1), _3(true), _4(false), _5(sparsevec_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "l1_distance", 1, + AddBuiltinFunc(_0(8205), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_negative_inner_product", 1, - AddBuiltinFunc(_0(8219), _1("sparsevec_negative_inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "halfvec_in", 1, + AddBuiltinFunc(_0(8452), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_cmp", 1, - AddBuiltinFunc(_0(8235), _1("sparsevec_cmp"), _2(1), _3(true), _4(false), _5(sparsevec_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "halfvec_out", 1, + AddBuiltinFunc(_0(8453), _1("halfvec_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_l2_distance", 1, - AddBuiltinFunc(_0(8236), _1("sparsevec_l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "halfvec_typmod_in", 1, + AddBuiltinFunc(_0(8454), _1("halfvec_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_cosine_distance", 1, - AddBuiltinFunc(_0(8237), _1("sparsevec_cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "halfvec_recv", 1, + AddBuiltinFunc(_0(8455), _1("halfvec_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "sparsevec_l1_distance", 1, - AddBuiltinFunc(_0(8238), _1("sparsevec_l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4411, 4411), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "halfvec_send", 1, + AddBuiltinFunc(_0(8456), _1("halfvec_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "jaccard_distance", 1, - AddBuiltinFunc(_0(8239), _1("jaccard_distance"), _2(1), _3(true), _4(false), _5(jaccard_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "halfvec_negative_inner_product", 1, + AddBuiltinFunc(_0(8457), _1("halfvec_negative_inner_product"), _2(1), _3(true), _4(false), _5(halfvec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hamming_distance", 1, - AddBuiltinFunc(_0(8240), _1("hamming_distance"), _2(1), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_in", 1, + AddBuiltinFunc(_0(8458), _1("sparsevec_in"), _2(3), _3(true), _4(false), _5(sparsevec_in), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatinsert", 1, - AddBuiltinFunc(_0(8241), _1("ivfflatinsert"), _2(6), _3(true), _4(false), _5(ivfflatinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_out", 1, + AddBuiltinFunc(_0(8459), _1("sparsevec_out"), _2(1), _3(true), _4(false), _5(sparsevec_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatbeginscan", 1, - AddBuiltinFunc(_0(8242), _1("ivfflatbeginscan"), _2(3), _3(true), _4(false), _5(ivfflatbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_typmod_in", 1, + AddBuiltinFunc(_0(8460), _1("sparsevec_typmod_in"), _2(1), _3(true), _4(false), _5(sparsevec_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatgettuple", 1, - AddBuiltinFunc(_0(8243), _1("ivfflatgettuple"), _2(2), _3(true), _4(false), _5(ivfflatgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_recv", 1, + AddBuiltinFunc(_0(8461), _1("sparsevec_recv"), _2(3), _3(true), _4(false), _5(sparsevec_recv), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatrescan", 1, - AddBuiltinFunc(_0(8244), _1("ivfflatrescan"), _2(5), _3(true), _4(false), _5(ivfflatrescan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(5, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatrescan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_send", 1, + AddBuiltinFunc(_0(8462), _1("sparsevec_send"), _2(1), _3(true), _4(false), _5(sparsevec_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatendscan", 1, - AddBuiltinFunc(_0(8245), _1("ivfflatendscan"), _2(1), _3(true), _4(false), _5(ivfflatendscan), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatendscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_negative_inner_product", 1, + AddBuiltinFunc(_0(8463), _1("sparsevec_negative_inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatbuild", 1, - AddBuiltinFunc(_0(8246), _1("ivfflatbuild"), _2(3), _3(true), _4(false), _5(ivfflatbuild), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbuild"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_cmp", 1, + AddBuiltinFunc(_0(8464), _1("sparsevec_cmp"), _2(1), _3(true), _4(false), _5(sparsevec_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatbuildempty", 1, - AddBuiltinFunc(_0(8247), _1("ivfflatbuildempty"), _2(1), _3(true), _4(false), _5(ivfflatbuildempty), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbuildempty"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_l2_distance", 1, + AddBuiltinFunc(_0(8465), _1("sparsevec_l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatbulkdelete", 1, - AddBuiltinFunc( _0(8248), _1("ivfflatbulkdelete"), _2(4), _3(true), _4(false), _5(ivfflatbulkdelete), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(4, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbulkdelete"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_cosine_distance", 1, + AddBuiltinFunc(_0(8466), _1("sparsevec_cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatvacuumcleanup", 1, - AddBuiltinFunc(_0(8249), _1("ivfflatvacuumcleanup"), _2(2), _3(true), _4(false), _5(ivfflatvacuumcleanup), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatvacuumcleanup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "sparsevec_l1_distance", 1, + AddBuiltinFunc(_0(8467), _1("sparsevec_l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatcostestimate", 1, - AddBuiltinFunc(_0(8250), _1("ivfflatcostestimate"), _2(7), _3(true), _4(false), _5(ivfflatcostestimate), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(7, 2281, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatcostestimate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "jaccard_distance", 1, + AddBuiltinFunc(_0(8468), _1("jaccard_distance"), _2(1), _3(true), _4(false), _5(jaccard_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "ivfflatoptions", 1, - AddBuiltinFunc(_0(8251), _1("ivfflatoptions"), _2(2), _3(true), _4(false), _5(ivfflatoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "hamming_distance", 1, + AddBuiltinFunc(_0(8469), _1("hamming_distance"), _2(1), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), \ No newline at end of file diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index 73d63084dc..4340bb5089 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -156,13 +156,13 @@ DATA(insert OID = 4439 ( ubtree 5 3 t f t t t t t t f t t 0 ubtinsert ubtbegin DESCR("ustore b-tree index access method"); #define UBTREE_AM_OID 4439 -DATA(insert OID = 4446 ( hnsw 0 3 f t f f f t f f f f f 0 hnswinsert hnswbeginscan hnswgettuple - hnswrescan hnswendscan - - - hnswbuild hnswbuildempty hnswbulkdelete hnswvacuumcleanup - hnswcostestimate hnswoptions - -)); +DATA(insert OID = 8300 ( hnsw 0 3 f t f f f t f f f f f 0 hnswinsert hnswbeginscan hnswgettuple - hnswrescan hnswendscan - - - hnswbuild hnswbuildempty hnswbulkdelete hnswvacuumcleanup - hnswcostestimate hnswoptions - -)); DESCR("hnsw index access method"); -#define HNSW_AM_OID 4446 +#define HNSW_AM_OID 8300 -DATA(insert OID = 4447 ( ivfflat 0 5 f t f f f t f f f f f 0 ivfflatinsert ivfflatbeginscan ivfflatgettuple - ivfflatrescan ivfflatendscan - - - ivfflatbuild ivfflatbuildempty ivfflatbulkdelete ivfflatvacuumcleanup - ivfflatcostestimate ivfflatoptions - -)); +DATA(insert OID = 8301 ( ivfflat 0 5 f t f f f t f f f f f 0 ivfflatinsert ivfflatbeginscan ivfflatgettuple - ivfflatrescan ivfflatendscan - - - ivfflatbuild ivfflatbuildempty ivfflatbulkdelete ivfflatvacuumcleanup - ivfflatcostestimate ivfflatoptions - -)); DESCR("ivfflat index access method"); -#define IVFFLAT_AM_OID 4447 +#define IVFFLAT_AM_OID 8301 #define OID_IS_BTREE(oid) ((oid) == BTREE_AM_OID || (oid) == UBTREE_AM_OID) diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 76293159dc..3086e54016 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1594,82 +1594,96 @@ DATA(insert OID = 7272 ( 9570 9003 9003 2 s 5553 4439 0 )); DATA(insert OID = 7273 ( 9570 9003 9003 3 s 5550 4439 0 )); DATA(insert OID = 7274 ( 9570 9003 9003 4 s 5549 4439 0 )); DATA(insert OID = 7275 ( 9570 9003 9003 5 s 5554 4439 0 )); -DATA(insert OID = 6031 ( 6030 4409 4409 1 o 6019 4446 1970 )); -DATA(insert OID = 6041 ( 6040 4409 4409 1 o 6020 4446 1970 )); -DATA(insert OID = 6051 ( 6050 4409 4409 1 o 6019 4446 1970 )); -DATA(insert OID = 6090 ( 6050 4409 4409 2 o 6020 4446 1970 )); -DATA(insert OID = 6059 ( 6050 4409 4409 3 o 6021 4446 1970 )); -DATA(insert OID = 6054 ( 6050 4409 4409 4 o 6052 4446 1970 )); -DATA(insert OID = 6061 ( 6060 4409 4409 1 o 6019 4446 1970 )); -DATA(insert OID = 6062 ( 6060 4409 4409 2 o 6020 4446 1970 )); -DATA(insert OID = 6063 ( 6060 4409 4409 3 o 6021 4446 1970 )); -DATA(insert OID = 6064 ( 6060 4409 4409 4 o 6052 4446 1970 )); -DATA(insert OID = 6036 ( 6035 4410 4410 1 o 6022 4446 1970 )); -DATA(insert OID = 6136 ( 6035 4410 4410 2 o 6023 4446 1970 )); -DATA(insert OID = 6236 ( 6035 4410 4410 3 o 6024 4446 1970 )); -DATA(insert OID = 6336 ( 6035 4410 4410 4 o 6053 4446 1970 )); -DATA(insert OID = 6046 ( 6045 4410 4410 1 o 6022 4446 1970 )); -DATA(insert OID = 6146 ( 6045 4410 4410 2 o 6023 4446 1970 )); -DATA(insert OID = 6246 ( 6045 4410 4410 3 o 6024 4446 1970 )); -DATA(insert OID = 6346 ( 6045 4410 4410 4 o 6053 4446 1970 )); -DATA(insert OID = 6056 ( 6055 4410 4410 1 o 6022 4446 1970 )); -DATA(insert OID = 6156 ( 6055 4410 4410 2 o 6023 4446 1970 )); -DATA(insert OID = 6256 ( 6055 4410 4410 3 o 6024 4446 1970 )); -DATA(insert OID = 6356 ( 6055 4410 4410 4 o 6053 4446 1970 )); -DATA(insert OID = 6066 ( 6065 4410 4410 1 o 6022 4446 1970 )); -DATA(insert OID = 6166 ( 6065 4410 4410 2 o 6023 4446 1970 )); -DATA(insert OID = 6266 ( 6065 4410 4410 3 o 6024 4446 1970 )); -DATA(insert OID = 6366 ( 6065 4410 4410 4 o 6053 4446 424 )); -DATA(insert OID = 6091 ( 6071 4411 4411 1 o 6025 4446 1970 )); -DATA(insert OID = 6092 ( 6071 4411 4411 2 o 6026 4446 1970 )); -DATA(insert OID = 6093 ( 6071 4411 4411 3 o 6027 4446 1970 )); -DATA(insert OID = 6094 ( 6071 4411 4411 4 o 6069 4446 1970 )); -DATA(insert OID = 6095 ( 6072 4411 4411 1 o 6025 4446 1970 )); -DATA(insert OID = 6096 ( 6072 4411 4411 2 o 6026 4446 1970 )); -DATA(insert OID = 6097 ( 6072 4411 4411 3 o 6027 4446 1970 )); -DATA(insert OID = 6098 ( 6072 4411 4411 4 o 6069 4446 1970 )); -DATA(insert OID = 6099 ( 6073 4411 4411 1 o 6025 4446 1970 )); -DATA(insert OID = 6100 ( 6073 4411 4411 2 o 6026 4446 1970 )); -DATA(insert OID = 6101 ( 6073 4411 4411 3 o 6027 4446 1970 )); -DATA(insert OID = 6102 ( 6073 4411 4411 4 o 6069 4446 1970 )); -DATA(insert OID = 6103 ( 6074 4411 4411 1 o 6025 4446 1970 )); -DATA(insert OID = 6104 ( 6074 4411 4411 2 o 6026 4446 1970 )); -DATA(insert OID = 6105 ( 6074 4411 4411 3 o 6027 4446 1970 )); -DATA(insert OID = 6106 ( 6074 4411 4411 4 o 6069 4446 1970 )); -DATA(insert OID = 6107 ( 6075 1560 1560 1 o 6028 4446 1970 )); -DATA(insert OID = 6108 ( 6075 1560 1560 2 o 6029 4446 1970 )); -DATA(insert OID = 6109 ( 6076 1560 1560 1 o 6028 4446 1970 )); -DATA(insert OID = 6110 ( 6076 1560 1560 2 o 6029 4446 1970 )); -DATA(insert OID = 6111 ( 6077 4409 4409 1 o 6019 4447 1970 )); -DATA(insert OID = 6115 ( 6078 4409 4409 1 o 6019 4447 1970 )); -DATA(insert OID = 6116 ( 6078 4409 4409 2 o 6020 4447 1970 )); -DATA(insert OID = 6117 ( 6078 4409 4409 3 o 6021 4447 1970 )); -DATA(insert OID = 6118 ( 6078 4409 4409 4 o 6052 4447 1970 )); -DATA(insert OID = 6119 ( 6079 4409 4409 1 o 6019 4447 1970 )); -DATA(insert OID = 6120 ( 6079 4409 4409 2 o 6020 4447 1970 )); -DATA(insert OID = 6121 ( 6079 4409 4409 3 o 6021 4447 1970 )); -DATA(insert OID = 6122 ( 6079 4409 4409 4 o 6052 4447 1970 )); -DATA(insert OID = 6123 ( 6070 4409 4409 1 o 6019 4447 1970 )); -DATA(insert OID = 6124 ( 6070 4409 4409 2 o 6020 4447 1970 )); -DATA(insert OID = 6125 ( 6070 4409 4409 3 o 6021 4447 1970 )); -DATA(insert OID = 6126 ( 6070 4409 4409 4 o 6052 4447 1970 )); -DATA(insert OID = 6127 ( 6080 4410 4410 1 o 6022 4447 1970 )); -DATA(insert OID = 6128 ( 6080 4410 4410 2 o 6023 4447 1970 )); -DATA(insert OID = 6129 ( 6080 4410 4410 3 o 6024 4447 1970 )); -DATA(insert OID = 6130 ( 6080 4410 4410 4 o 6053 4447 1970 )); -DATA(insert OID = 6131 ( 6081 4410 4410 1 o 6022 4447 1970 )); -DATA(insert OID = 6132 ( 6081 4410 4410 2 o 6023 4447 1970 )); -DATA(insert OID = 6133 ( 6081 4410 4410 3 o 6024 4447 1970 )); -DATA(insert OID = 6134 ( 6081 4410 4410 4 o 6053 4447 1970 )); -DATA(insert OID = 6135 ( 6082 4410 4410 1 o 6022 4447 1970 )); -DATA(insert OID = 6137 ( 6082 4410 4410 2 o 6023 4447 1970 )); -DATA(insert OID = 6138 ( 6082 4410 4410 3 o 6024 4447 1970 )); -DATA(insert OID = 6139 ( 6082 4410 4410 4 o 6053 4447 1970 )); -DATA(insert OID = 6140 ( 6083 4410 4410 1 o 6022 4447 1970 )); -DATA(insert OID = 6141 ( 6083 4410 4410 2 o 6023 4447 1970 )); -DATA(insert OID = 6142 ( 6083 4410 4410 3 o 6024 4447 1970 )); -DATA(insert OID = 6143 ( 6083 4410 4410 4 o 6053 4447 1970 )); -DATA(insert OID = 6144 ( 6084 1560 1560 1 o 6028 4447 1970 )); -DATA(insert OID = 6145 ( 6084 1560 1560 2 o 6029 4447 1970 )); -DATA(insert OID = 6147 ( 6085 1560 1560 1 o 6028 4447 1970 )); -DATA(insert OID = 6148 ( 6085 1560 1560 2 o 6029 4447 1970 )); + +DATA(insert OID = 6031 ( 8371 8305 8305 1 o 8311 8300 1970 )); + +DATA(insert OID = 6041 ( 8372 8305 8305 1 o 8312 8300 1970 )); + +DATA(insert OID = 6051 ( 8373 8305 8305 1 o 8313 8300 1970 )); + +DATA(insert OID = 6061 ( 8374 8305 8305 1 o 8314 8300 1970 )); + + +DATA(insert OID = 6036 ( 8375 8306 8306 1 o 8315 8300 1970 )); +DATA(insert OID = 6136 ( 8375 8306 8306 2 o 8316 8300 1970 )); +DATA(insert OID = 6236 ( 8375 8306 8306 3 o 8317 8300 1970 )); +DATA(insert OID = 6336 ( 8375 8306 8306 4 o 8318 8300 1970 )); +DATA(insert OID = 6046 ( 8376 8306 8306 1 o 8315 8300 1970 )); +DATA(insert OID = 6146 ( 8376 8306 8306 2 o 8316 8300 1970 )); +DATA(insert OID = 6246 ( 8376 8306 8306 3 o 8317 8300 1970 )); +DATA(insert OID = 6346 ( 8376 8306 8306 4 o 8318 8300 1970 )); +DATA(insert OID = 6056 ( 8377 8306 8306 1 o 8315 8300 1970 )); +DATA(insert OID = 6156 ( 8377 8306 8306 2 o 8316 8300 1970 )); +DATA(insert OID = 6256 ( 8377 8306 8306 3 o 8317 8300 1970 )); +DATA(insert OID = 6356 ( 8377 8306 8306 4 o 8318 8300 1970 )); +DATA(insert OID = 6066 ( 8378 8306 8306 1 o 8315 8300 1970 )); +DATA(insert OID = 6166 ( 8378 8306 8306 2 o 8316 8300 1970 )); +DATA(insert OID = 6266 ( 8378 8306 8306 3 o 8317 8300 1970 )); +DATA(insert OID = 6366 ( 8378 8306 8306 4 o 8318 8300 424 )); + +DATA(insert OID = 6091 ( 8381 8307 8307 1 o 8319 8300 1970 )); +DATA(insert OID = 6092 ( 8381 8307 8307 2 o 8320 8300 1970 )); +DATA(insert OID = 6093 ( 8381 8307 8307 3 o 8321 8300 1970 )); +DATA(insert OID = 6094 ( 8381 8307 8307 4 o 8322 8300 1970 )); +DATA(insert OID = 6095 ( 8382 8307 8307 1 o 8319 8300 1970 )); +DATA(insert OID = 6096 ( 8382 8307 8307 2 o 8320 8300 1970 )); +DATA(insert OID = 6097 ( 8382 8307 8307 3 o 8321 8300 1970 )); +DATA(insert OID = 6098 ( 8382 8307 8307 4 o 8322 8300 1970 )); +DATA(insert OID = 6099 ( 8383 8307 8307 1 o 8319 8300 1970 )); +DATA(insert OID = 6100 ( 8383 8307 8307 2 o 8320 8300 1970 )); +DATA(insert OID = 6101 ( 8383 8307 8307 3 o 8321 8300 1970 )); +DATA(insert OID = 6102 ( 8383 8307 8307 4 o 8322 8300 1970 )); +DATA(insert OID = 6103 ( 8384 8307 8307 1 o 8319 8300 1970 )); +DATA(insert OID = 6104 ( 8384 8307 8307 2 o 8320 8300 1970 )); +DATA(insert OID = 6105 ( 8384 8307 8307 3 o 8321 8300 1970 )); +DATA(insert OID = 6106 ( 8384 8307 8307 4 o 8322 8300 1970 )); + + +DATA(insert OID = 6107 ( 8379 1560 1560 1 o 8323 8300 1970 )); +DATA(insert OID = 6108 ( 8379 1560 1560 2 o 8324 8300 1970 )); +DATA(insert OID = 6109 ( 8380 1560 1560 1 o 8323 8300 1970 )); +DATA(insert OID = 6110 ( 8380 1560 1560 2 o 8324 8300 1970 )); + + + + + + +DATA(insert OID = 6111 ( 8385 8305 8305 1 o 8311 8301 1970 )); + + + +DATA(insert OID = 6115 ( 8386 8305 8305 1 o 8312 8301 1970 )); + + +DATA(insert OID = 6119 ( 8387 8305 8305 1 o 8313 8301 1970 )); + + + + +DATA(insert OID = 6127 ( 8389 8306 8306 1 o 8315 8301 1970 )); +DATA(insert OID = 6128 ( 8389 8306 8306 2 o 8316 8301 1970 )); +DATA(insert OID = 6129 ( 8389 8306 8306 3 o 8317 8301 1970 )); +DATA(insert OID = 6130 ( 8389 8306 8306 4 o 8318 8301 1970 )); +DATA(insert OID = 6131 ( 8390 8306 8306 1 o 8315 8301 1970 )); +DATA(insert OID = 6132 ( 8390 8306 8306 2 o 8316 8301 1970 )); +DATA(insert OID = 6133 ( 8390 8306 8306 3 o 8317 8301 1970 )); +DATA(insert OID = 6134 ( 8390 8306 8306 4 o 8318 8301 1970 )); +DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8315 8301 1970 )); +DATA(insert OID = 6137 ( 8391 8306 8306 2 o 8316 8301 1970 )); +DATA(insert OID = 6138 ( 8391 8306 8306 3 o 8317 8301 1970 )); +DATA(insert OID = 6139 ( 8391 8306 8306 4 o 8318 8301 1970 )); +DATA(insert OID = 6140 ( 8392 8306 8306 1 o 8315 8301 1970 )); +DATA(insert OID = 6141 ( 8392 8306 8306 2 o 8316 8301 1970 )); +DATA(insert OID = 6142 ( 8392 8306 8306 3 o 8317 8301 1970 )); +DATA(insert OID = 6143 ( 8392 8306 8306 4 o 8318 8301 1970 )); + + + + + + +DATA(insert OID = 6144 ( 8393 1560 1560 1 o 8323 8301 1970 )); +DATA(insert OID = 6145 ( 8393 1560 1560 2 o 8324 8301 1970 )); +DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); +DATA(insert OID = 6148 ( 8394 1560 1560 2 o 8324 8301 1970 )); diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 1347ab611a..b663ca7819 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -654,37 +654,53 @@ DATA(insert ( 9570 9003 9003 1 5586 )); DATA(insert ( 8901 3831 3831 1 3870 )); DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); +//hnsw +//vector_l2_ops +DATA(insert OID = 8924( 8371 8305 8305 1 8431 )); +//vector_ip_ops +DATA(insert OID = 8925( 8372 8305 8305 1 8434 )); +//vector_cosine_ops +DATA(insert OID = 8926( 8373 8305 8305 1 8434 )); +DATA(insert OID = 8947( 8373 8305 8305 2 8438 )); +//vector_l1_ops +DATA(insert OID = 8927( 8374 8305 8305 1 8436 )); -DATA(insert (6030 4409 4409 1 8008)); -DATA(insert (6040 4409 4409 1 8216)); -DATA(insert (6050 4409 4409 1 8216)); -DATA(insert (6060 4409 4409 1 8216)); +DATA(insert OID = 8928( 8375 8306 8306 1 8451 )); +DATA(insert OID = 8929( 8376 8306 8306 1 8451 )); +DATA(insert OID = 8930( 8377 8306 8306 1 8451 )); +DATA(insert OID = 8931( 8378 8306 8306 1 8451 )); -DATA(insert OID = 6038(6035 4410 4410 1 8217)); -DATA(insert OID = 6048(6045 4410 4410 1 8217)); -DATA(insert OID = 6058(6055 4410 4410 1 8217)); -DATA(insert OID = 6068(6065 4410 4410 1 8217)); +DATA(insert OID = 8932( 8379 1560 1560 1 8462 )); +DATA(insert OID = 8933( 8380 1560 1560 1 8462 )); -DATA(insert OID = 6149(6075 1560 1560 1 8218)); -DATA(insert OID = 6150(6076 1560 1560 1 8218)); +DATA(insert OID = 8934( 8381 8307 8307 1 8463 )); +DATA(insert OID = 8935( 8382 8307 8307 1 8463 )); +DATA(insert OID = 8936( 8383 8307 8307 1 8463 )); +DATA(insert OID = 8937( 8384 8307 8307 1 8463 )); -DATA(insert OID = 6151(6071 4411 4411 1 8219)); -DATA(insert OID = 6152(6072 4411 4411 1 8219)); -DATA(insert OID = 6153(6073 4411 4411 1 8219)); -DATA(insert OID = 6154(6074 4411 4411 1 8219)); +//ivfflat +//vector_l2_ops +DATA(insert OID = 8938( 8385 8305 8305 1 8431 )); +DATA(insert OID = 8939( 8385 8305 8305 3 8433 )); +//vector_ip_ops +DATA(insert OID = 8940( 8386 8305 8305 1 8434 )); +DATA(insert OID = 8941( 8386 8305 8305 3 8432 )); +DATA(insert OID = 8942( 8386 8305 8305 4 8438 )); +//vector_cosine_ops +DATA(insert OID = 8943( 8387 8305 8305 1 8434 )); +DATA(insert OID = 8944( 8387 8305 8305 2 8438 )); +DATA(insert OID = 8945( 8387 8305 8305 3 8432 )); +DATA(insert OID = 8946( 8387 8305 8305 4 8438 )); +//vector_l1_ops +//DATA(insert OID = 8942( 8388 8305 8305 1 8450 )); -DATA(insert (6077 4409 4409 1 8008)); -DATA(insert (6077 4409 4409 3 8200)); -DATA(insert (6078 4409 4409 1 8216)); -DATA(insert (6079 4409 4409 1 8216)); -DATA(insert (6070 4409 4409 1 8216)); -DATA(insert OID = 6155(6080 4410 4410 1 8217)); -DATA(insert OID = 6157(6081 4410 4410 1 8217)); -DATA(insert OID = 6158(6082 4410 4410 1 8217)); -DATA(insert OID = 6159(6083 4410 4410 1 8217)); +DATA(insert OID = 8948( 8389 8306 8306 1 8451 )); +DATA(insert OID = 8949( 8390 8306 8306 1 8451 )); +DATA(insert OID = 8950( 8391 8306 8306 1 8451 )); +DATA(insert OID = 8951( 8392 8306 8306 1 8451 )); -DATA(insert OID = 6160(6084 1560 1560 1 8218)); -DATA(insert OID = 6161(6085 1560 1560 1 8218)); +DATA(insert OID = 8952( 8393 1560 1560 1 8462 )); +DATA(insert OID = 8953( 8394 1560 1560 1 8462 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 671ca016e6..eac125146d 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -375,35 +375,36 @@ DATA(insert ( 405 settext_ops PGNSP PGUID 1995 3272 f 0 )); DATA(insert ( 4439 setasint_ops PGNSP PGUID 6976 3272 t 0 )); DATA(insert ( 405 set_ops PGNSP PGUID 8646 3272 t 0 )); -DATA(insert(4446 vector_l2_ops PGNSP PGUID 6030 4409 t 0)); -DATA(insert(4446 vector_ip_ops PGNSP PGUID 6040 4409 t 0)); -DATA(insert(4446 vector_cosine_ops PGNSP PGUID 6050 4409 t 0)); -DATA(insert(4446 vector_l1_ops PGNSP PGUID 6060 4409 t 0)); -DATA(insert OID = 6037(4446 halfvec_l2_ops PGNSP PGUID 6035 4410 t 0)); -DATA(insert OID = 6047(4446 halfvec_ip_ops PGNSP PGUID 6045 4410 t 0)); -DATA(insert OID = 6057(4446 halfvec_cosine_ops PGNSP PGUID 6055 4410 t 0)); -DATA(insert OID = 6067(4446 halfvec_l1_ops PGNSP PGUID 6065 4410 t 0)); -DATA(insert OID = 6010(4446 bit_jaccard_ops PGNSP PGUID 6075 1560 t 0)); -DATA(insert OID = 6011(4446 bit_hamming_ops PGNSP PGUID 6076 1560 t 0)); +DATA(insert OID = 8900 ( 8300 vector_l2_ops PGNSP PGUID 8371 8305 t 0 )); +DATA(insert OID = 8999 ( 8300 vector_ip_ops PGNSP PGUID 8372 8305 t 0 )); +DATA(insert OID = 8902 ( 8300 vector_cosine_ops PGNSP PGUID 8373 8305 t 0 )); +DATA(insert OID = 8903 ( 8300 vector_l1_ops PGNSP PGUID 8374 8305 t 0 )); +DATA(insert OID = 8904 ( 8300 halfvec_l2_ops PGNSP PGUID 8375 8306 t 0 )); +DATA(insert OID = 8905 ( 8300 halfvec_ip_ops PGNSP PGUID 8376 8306 t 0 )); +DATA(insert OID = 8906 ( 8300 halfvec_cosine_ops PGNSP PGUID 8377 8306 t 0 )); +DATA(insert OID = 8907 ( 8300 halfvec_l1_ops PGNSP PGUID 8378 8306 t 0 )); -DATA(insert OID = 6012(4446 sparsevec_l2_ops PGNSP PGUID 6071 4411 t 0)); -DATA(insert OID = 6013(4446 sparsevec_ip_ops PGNSP PGUID 6072 4411 t 0)); -DATA(insert OID = 6014(4446 sparsevec_cosine_ops PGNSP PGUID 6073 4411 t 0)); -DATA(insert OID = 6015(4446 sparsevec_l1_ops PGNSP PGUID 6074 4411 t 0)); +DATA(insert OID = 8908 ( 8300 bit_jaccard_ops PGNSP PGUID 8379 1560 t 0 )); +DATA(insert OID = 8909 ( 8300 bit_hamming_ops PGNSP PGUID 8380 1560 t 0 )); -DATA(insert(4447 vector_l2_ops PGNSP PGUID 6077 4409 t 0)); -DATA(insert(4447 vector_ip_ops PGNSP PGUID 6078 4409 t 0)); -DATA(insert(4447 vector_cosine_ops PGNSP PGUID 6079 4409 t 0)); -DATA(insert(4447 vector_l1_ops PGNSP PGUID 6070 4409 t 0)); +DATA(insert OID = 8910 ( 8300 sparsevec_l2_ops PGNSP PGUID 8381 8307 t 0 )); +DATA(insert OID = 8911 ( 8300 sparsevec_ip_ops PGNSP PGUID 8382 8307 t 0 )); +DATA(insert OID = 8912 ( 8300 sparsevec_cosine_ops PGNSP PGUID 8383 8307 t 0 )); +DATA(insert OID = 8913 ( 8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 t 0 )); -DATA(insert OID = 6016(4447 halfvec_l2_ops PGNSP PGUID 6080 4410 t 0)); -DATA(insert OID = 6017(4447 halfvec_ip_ops PGNSP PGUID 6081 4410 t 0)); -DATA(insert OID = 6018(4447 halfvec_cosine_ops PGNSP PGUID 6082 4410 t 0)); -DATA(insert OID = 6039(4447 halfvec_l1_ops PGNSP PGUID 6083 4410 t 0)); +DATA(insert OID = 8914 ( 8301 vector_l2_ops PGNSP PGUID 8385 8305 t 0 )); +DATA(insert OID = 8915 ( 8301 vector_ip_ops PGNSP PGUID 8386 8305 t 0 )); +DATA(insert OID = 8916 ( 8301 vector_cosine_ops PGNSP PGUID 8387 8305 t 0 )); +DATA(insert OID = 8917 ( 8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0 )); -DATA(insert OID = 6049(4447 bit_jaccard_ops PGNSP PGUID 6084 1560 t 0)); -DATA(insert OID = 6086(4447 bit_hamming_ops PGNSP PGUID 6085 1560 t 0)); +DATA(insert OID = 8918 ( 8301 halfvec_l2_ops PGNSP PGUID 8389 8306 t 0 )); +DATA(insert OID = 8919 ( 8301 halfvec_ip_ops PGNSP PGUID 8390 8306 t 0 )); +DATA(insert OID = 8920 ( 8301 halfvec_cosine_ops PGNSP PGUID 8391 8306 t 0 )); +DATA(insert OID = 8921 ( 8301 halfvec_l1_ops PGNSP PGUID 8392 8306 t 0 )); + +DATA(insert OID = 8922 ( 8301 bit_jaccard_ops PGNSP PGUID 8393 1560 t 0 )); +DATA(insert OID = 8923 ( 8301 bit_hamming_ops PGNSP PGUID 8394 1560 t 0 )); #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index 4a4398bef1..74fcad5f3c 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1918,54 +1918,54 @@ DESCR("greater than or equal"); DATA(insert OID = 6565 ("-" PGNSP PGUID l f f 0 16 16 0 0 boolum - -)); DESCR("negate"); -DATA(insert OID = 6019 ("<->" PGNSP PGUID b f f 4409 4409 701 6019 0 l2_distance - -)); +DATA(insert OID = 8311 ("<->" PGNSP PGUID b f f 8305 8305 701 8311 0 l2_distance - -)); DESCR("l2_distance"); -DATA(insert OID = 6020 ("<#>" PGNSP PGUID b f f 4409 4409 701 6020 0 vector_negative_inner_product - -)); +DATA(insert OID = 8312 ("<#>" PGNSP PGUID b f f 8305 8305 701 8312 0 vector_negative_inner_product - -)); DESCR("vector_negative_inner_product"); -DATA(insert OID = 6021 ("<=>" PGNSP PGUID b f f 4409 4409 701 6021 0 cosine_distance - -)); +DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 cosine_distance - -)); DESCR("cosine_distance"); -DATA(insert OID = 6052 ("<+>" PGNSP PGUID b f f 4409 4409 16 6052 0 l1_distance - -)); +DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 l1_distance - -)); DESCR("l1_distance"); -DATA(insert OID = 6162 ("+" PGNSP PGUID b f f 4409 4409 4409 6162 0 vector_add 0 0)); -DESCR("vector_add"); -DATA(insert OID = 6163 ("-" PGNSP PGUID b f f 4409 4409 4409 6163 0 vector_sub 0 0)); -DESCR("vector_sub"); -DATA(insert OID = 6164 ("<" PGNSP PGUID b f f 4409 4409 16 6164 6165 vector_lt scalarltsel scalarltjoinsel)); -DESCR("vector less than"); -DATA(insert OID = 6165 ("<=" PGNSP PGUID b f f 4409 4409 16 6165 6164 vector_le scalarltsel scalarltjoinsel)); -DESCR("vector less than or equal"); -DATA(insert OID = 6167 (">" PGNSP PGUID b f f 4409 4409 16 6167 6168 vector_gt scalargtsel scalargtjoinsel)); -DESCR("vector greater than"); -DATA(insert OID = 6168 (">=" PGNSP PGUID b f f 4409 4409 16 6168 6167 vector_ge scalargtsel scalargtjoinsel)); -DESCR("vector greater than or equal"); -DATA(insert OID = 6169 ("=" PGNSP PGUID b f t 4409 4409 16 6169 6170 vector_eq eqsel eqjoinsel)); -DESCR("vector equal"); -DATA(insert OID = 6170 ("<>" PGNSP PGUID b f f 4409 4409 16 6170 6169 vector_ne neqsel neqjoinsel)); -DESCR("vector unequal"); - -DATA(insert OID = 6022 ("<->" PGNSP PGUID b f f 4410 4410 701 6019 0 l2_distance - -)); +DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 l2_distance - -)); DESCR("l2_distance"); -DATA(insert OID = 6023 ("<#>" PGNSP PGUID b f f 4410 4410 701 6020 0 halfvec_negative_inner_product - -)); +DATA(insert OID = 8316 ("<#>" PGNSP PGUID b f f 8306 8306 701 8312 0 halfvec_negative_inner_product - -)); DESCR("halfvec_negative_inner_product"); -DATA(insert OID = 6024 ("<=>" PGNSP PGUID b f f 4410 4410 701 6021 0 cosine_distance - -)); +DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 cosine_distance - -)); DESCR("cosine_distance"); -DATA(insert OID = 6053 ("<+>" PGNSP PGUID b f f 4410 4410 16 6052 0 l1_distance - -)); +DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 l1_distance - -)); DESCR("l1_distance"); -DATA(insert OID = 6025 ("<->" PGNSP PGUID b f f 4411 4411 701 6025 0 sparsevec_l2_distance - -)); +DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 sparsevec_l2_distance - -)); DESCR("sparsevec_l2_distance"); -DATA(insert OID = 6026 ("<#>" PGNSP PGUID b f f 4411 4411 701 6026 0 sparsevec_negative_inner_product - -)); +DATA(insert OID = 8320 ("<#>" PGNSP PGUID b f f 8307 8307 701 8320 0 sparsevec_negative_inner_product - -)); DESCR("sparsevec_negative_inner_product"); -DATA(insert OID = 6027 ("<=>" PGNSP PGUID b f f 4411 4411 701 6027 0 sparsevec_cosine_distance - -)); +DATA(insert OID = 8321 ("<=>" PGNSP PGUID b f f 8307 8307 701 8321 0 sparsevec_cosine_distance - -)); DESCR("sparsevec_cosine_distance"); -DATA(insert OID = 6069 ("<+>" PGNSP PGUID b f f 4411 4411 16 6069 0 sparsevec_l1_distance - -)); +DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 sparsevec_l1_distance - -)); DESCR("sparsevec_l1_distance"); -DATA(insert OID = 6028 ("<~>" PGNSP PGUID b f f 1560 1560 701 6028 0 jaccard_distance - -)); +DATA(insert OID = 8323 ("<~>" PGNSP PGUID b f f 1560 1560 701 8323 0 jaccard_distance - -)); DESCR("jaccard_distance"); -DATA(insert OID = 6029 ("<%>" PGNSP PGUID b f f 1560 1560 701 6029 0 hamming_distance - -)); +DATA(insert OID = 8324 ("<%>" PGNSP PGUID b f f 1560 1560 701 8324 0 hamming_distance - -)); DESCR("hamming_distance"); + +DATA(insert OID = 8325 ("+" PGNSP PGUID b f f 8305 8305 8305 8325 0 vector_add 0 0)); +DESCR("vector_add"); +DATA(insert OID = 8326 ("-" PGNSP PGUID b f f 8305 8305 8305 8326 0 vector_sub 0 0)); +DESCR("vector_sub"); +DATA(insert OID = 8327 ("<" PGNSP PGUID b f f 8305 8305 16 6164 6165 vector_lt scalarltsel scalarltjoinsel)); +DESCR("vector less than"); +DATA(insert OID = 8328 ("<=" PGNSP PGUID b f f 8305 8305 16 6165 6164 vector_le scalarltsel scalarltjoinsel)); +DESCR("vector less than or equal"); +DATA(insert OID = 8329 (">" PGNSP PGUID b f f 8305 8305 16 6167 6168 vector_gt scalargtsel scalargtjoinsel)); +DESCR("vector greater than"); +DATA(insert OID = 8330 (">=" PGNSP PGUID b f f 8305 8305 16 6168 6167 vector_ge scalargtsel scalargtjoinsel)); +DESCR("vector greater than or equal"); +DATA(insert OID = 8331 ("=" PGNSP PGUID b f t 8305 8305 16 6169 6170 vector_eq eqsel eqjoinsel)); +DESCR("vector equal"); +DATA(insert OID = 8332 ("<>" PGNSP PGUID b f f 8305 8305 16 6170 6169 vector_ne neqsel neqjoinsel)); +DESCR("vector unequal"); /* * function prototypes */ \ No newline at end of file diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 724ed1aa8f..9d8bba0e5d 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -199,37 +199,37 @@ DATA(insert OID = 4262 (4239 int1_ops PGNSP PGUID)); DATA(insert OID = 4263 (4239 bool_ops PGNSP PGUID)); DATA(insert OID = 4264 (4239 smalldatetime_ops PGNSP PGUID)); -/* datavec index */ -DATA(insert OID = 6030 (4446 vector_l2_ops PGNSP PGUID)); -DATA(insert OID = 6040 (4446 vector_ip_ops PGNSP PGUID)); -DATA(insert OID = 6050 (4446 vector_cosine_ops PGNSP PGUID)); -DATA(insert OID = 6060 (4446 vector_l1_ops PGNSP PGUID)); +/*datavec index ops*/ +DATA(insert OID = 8371 (8300 vector_l2_ops PGNSP PGUID)); +DATA(insert OID = 8372 (8300 vector_ip_ops PGNSP PGUID)); +DATA(insert OID = 8373 (8300 vector_cosine_ops PGNSP PGUID)); +DATA(insert OID = 8374 (8300 vector_l1_ops PGNSP PGUID)); -DATA(insert OID = 6035 (4446 halfvec_l2_ops PGNSP PGUID)); -DATA(insert OID = 6045 (4446 halfvec_ip_ops PGNSP PGUID)); -DATA(insert OID = 6055 (4446 halfvec_cosine_ops PGNSP PGUID)); -DATA(insert OID = 6065 (4446 halfvec_l1_ops PGNSP PGUID)); +DATA(insert OID = 8375 (8300 halfvec_l2_ops PGNSP PGUID)); +DATA(insert OID = 8376 (8300 halfvec_ip_ops PGNSP PGUID)); +DATA(insert OID = 8377 (8300 halfvec_cosine_ops PGNSP PGUID)); +DATA(insert OID = 8378 (8300 halfvec_l1_ops PGNSP PGUID)); -DATA(insert OID = 6075 (4446 bit_jaccard_ops PGNSP PGUID)); -DATA(insert OID = 6076 (4446 bit_hamming_ops PGNSP PGUID)); +DATA(insert OID = 8379 (8300 bit_jaccard_ops PGNSP PGUID)); +DATA(insert OID = 8380 (8300 bit_hamming_ops PGNSP PGUID)); -DATA(insert OID = 6071 (4446 sparsevec_l2_ops PGNSP PGUID)); -DATA(insert OID = 6072 (4446 sparsevec_ip_ops PGNSP PGUID)); -DATA(insert OID = 6073 (4446 sparsevec_cosine_ops PGNSP PGUID)); -DATA(insert OID = 6074 (4446 sparsevec_l1_ops PGNSP PGUID)); +DATA(insert OID = 8381 (8300 sparsevec_l2_ops PGNSP PGUID)); +DATA(insert OID = 8382 (8300 sparsevec_ip_ops PGNSP PGUID)); +DATA(insert OID = 8383 (8300 sparsevec_cosine_ops PGNSP PGUID)); +DATA(insert OID = 8384 (8300 sparsevec_l1_ops PGNSP PGUID)); -DATA(insert OID = 6077 (4447 vector_l2_ops PGNSP PGUID)); -DATA(insert OID = 6078 (4447 vector_ip_ops PGNSP PGUID)); -DATA(insert OID = 6079 (4447 vector_cosine_ops PGNSP PGUID)); -DATA(insert OID = 6070 (4447 vector_l1_ops PGNSP PGUID)); +DATA(insert OID = 8385 (8301 vector_l2_ops PGNSP PGUID)); +DATA(insert OID = 8386 (8301 vector_ip_ops PGNSP PGUID)); +DATA(insert OID = 8387 (8301 vector_cosine_ops PGNSP PGUID)); +DATA(insert OID = 8388 (8301 vector_l1_ops PGNSP PGUID)); -DATA(insert OID = 6080 (4447 halfvec_l2_ops PGNSP PGUID)); -DATA(insert OID = 6081 (4447 halfvec_ip_ops PGNSP PGUID)); -DATA(insert OID = 6082 (4447 halfvec_cosine_ops PGNSP PGUID)); -DATA(insert OID = 6083 (4447 halfvec_l1_ops PGNSP PGUID)); +DATA(insert OID = 8389 (8301 halfvec_l2_ops PGNSP PGUID)); +DATA(insert OID = 8390 (8301 halfvec_ip_ops PGNSP PGUID)); +DATA(insert OID = 8391 (8301 halfvec_cosine_ops PGNSP PGUID)); +DATA(insert OID = 8392 (8301 halfvec_l1_ops PGNSP PGUID)); -DATA(insert OID = 6084 (4447 bit_jaccard_ops PGNSP PGUID)); -DATA(insert OID = 6085 (4447 bit_hamming_ops PGNSP PGUID)); +DATA(insert OID = 8393 (8301 bit_jaccard_ops PGNSP PGUID)); +DATA(insert OID = 8394 (8301 bit_hamming_ops PGNSP PGUID)); /* ubtree index */ #define BTREE_UBTREE_FAM_OID_DIFF 5000 diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 6cc766ae5e..4ab3b344c0 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -823,14 +823,14 @@ DATA(insert OID = 4408 ( undefined PGNSP PGUID -2 f u W f t \054 0 0 0 undefin DESCR("undefined objects as PLSQL compilation time"); #define UNDEFINEDOID 4408 -DATA(insert OID = 4409 (vector PGNSP PGUID -1 f b U f t \054 0 0 0 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); -#define VECTOROID 4409 +DATA(insert OID = 8305 ( vector PGNSP PGUID -1 f b U f t \054 0 0 4411 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +#define VECTOROID 8305 -DATA(insert OID = 4410 (halfvec PGNSP PGUID -1 f b U f t \054 0 0 0 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); -#define FLOATVECTOROID 4410 +DATA(insert OID = 8306 ( halfvec PGNSP PGUID -1 f b U f t \054 0 0 4411 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +#define FLOATVECTOROID 8306 -DATA(insert OID = 4411 (sparsevec PGNSP PGUID -1 f b U f t \054 0 0 0 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); -#define SPARSEVECTOROID 4411 +DATA(insert OID = 8307 ( sparsevec PGNSP PGUID -1 f b U f t \054 0 0 4411 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +#define SPARSEVECTOROID 8307 /* * macros -- Gitee From 60bd26d6a01be183c6d29e37695ab406913c98d6 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Fri, 1 Nov 2024 21:18:43 +0800 Subject: [PATCH 18/67] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/catalog/pg_amproc.h | 62 ++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index b663ca7819..8a60128a33 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -656,51 +656,51 @@ DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); //hnsw //vector_l2_ops -DATA(insert OID = 8924( 8371 8305 8305 1 8431 )); +DATA(insert OID = 8924 ( 8371 8305 8305 1 8431 )); //vector_ip_ops -DATA(insert OID = 8925( 8372 8305 8305 1 8434 )); +DATA(insert OID = 8925 ( 8372 8305 8305 1 8434 )); //vector_cosine_ops -DATA(insert OID = 8926( 8373 8305 8305 1 8434 )); -DATA(insert OID = 8947( 8373 8305 8305 2 8438 )); +DATA(insert OID = 8926 ( 8373 8305 8305 1 8434 )); +DATA(insert OID = 8947 ( 8373 8305 8305 2 8438 )); //vector_l1_ops -DATA(insert OID = 8927( 8374 8305 8305 1 8436 )); +DATA(insert OID = 8927 ( 8374 8305 8305 1 8436 )); -DATA(insert OID = 8928( 8375 8306 8306 1 8451 )); -DATA(insert OID = 8929( 8376 8306 8306 1 8451 )); -DATA(insert OID = 8930( 8377 8306 8306 1 8451 )); -DATA(insert OID = 8931( 8378 8306 8306 1 8451 )); +DATA(insert OID = 8928 ( 8375 8306 8306 1 8451 )); +DATA(insert OID = 8929 ( 8376 8306 8306 1 8451 )); +DATA(insert OID = 8930 ( 8377 8306 8306 1 8451 )); +DATA(insert OID = 8931 ( 8378 8306 8306 1 8451 )); -DATA(insert OID = 8932( 8379 1560 1560 1 8462 )); -DATA(insert OID = 8933( 8380 1560 1560 1 8462 )); +DATA(insert OID = 8932 ( 8379 1560 1560 1 8462 )); +DATA(insert OID = 8933 ( 8380 1560 1560 1 8462 )); -DATA(insert OID = 8934( 8381 8307 8307 1 8463 )); -DATA(insert OID = 8935( 8382 8307 8307 1 8463 )); -DATA(insert OID = 8936( 8383 8307 8307 1 8463 )); -DATA(insert OID = 8937( 8384 8307 8307 1 8463 )); +DATA(insert OID = 8934 ( 8381 8307 8307 1 8463 )); +DATA(insert OID = 8935 ( 8382 8307 8307 1 8463 )); +DATA(insert OID = 8936 ( 8383 8307 8307 1 8463 )); +DATA(insert OID = 8937 ( 8384 8307 8307 1 8463 )); //ivfflat //vector_l2_ops -DATA(insert OID = 8938( 8385 8305 8305 1 8431 )); -DATA(insert OID = 8939( 8385 8305 8305 3 8433 )); +DATA(insert OID = 8938 ( 8385 8305 8305 1 8431 )); +DATA(insert OID = 8939 ( 8385 8305 8305 3 8433 )); //vector_ip_ops -DATA(insert OID = 8940( 8386 8305 8305 1 8434 )); -DATA(insert OID = 8941( 8386 8305 8305 3 8432 )); -DATA(insert OID = 8942( 8386 8305 8305 4 8438 )); +DATA(insert OID = 8940 ( 8386 8305 8305 1 8434 )); +DATA(insert OID = 8941 ( 8386 8305 8305 3 8432 )); +DATA(insert OID = 8942 ( 8386 8305 8305 4 8438 )); //vector_cosine_ops -DATA(insert OID = 8943( 8387 8305 8305 1 8434 )); -DATA(insert OID = 8944( 8387 8305 8305 2 8438 )); -DATA(insert OID = 8945( 8387 8305 8305 3 8432 )); -DATA(insert OID = 8946( 8387 8305 8305 4 8438 )); +DATA(insert OID = 8943 ( 8387 8305 8305 1 8434 )); +DATA(insert OID = 8944 ( 8387 8305 8305 2 8438 )); +DATA(insert OID = 8945 ( 8387 8305 8305 3 8432 )); +DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); //vector_l1_ops -//DATA(insert OID = 8942( 8388 8305 8305 1 8450 )); +//DATA(insert OID = 8942 ( 8388 8305 8305 1 8450 )); -DATA(insert OID = 8948( 8389 8306 8306 1 8451 )); -DATA(insert OID = 8949( 8390 8306 8306 1 8451 )); -DATA(insert OID = 8950( 8391 8306 8306 1 8451 )); -DATA(insert OID = 8951( 8392 8306 8306 1 8451 )); +DATA(insert OID = 8948 ( 8389 8306 8306 1 8451 )); +DATA(insert OID = 8949 ( 8390 8306 8306 1 8451 )); +DATA(insert OID = 8950 ( 8391 8306 8306 1 8451 )); +DATA(insert OID = 8951 ( 8392 8306 8306 1 8451 )); -DATA(insert OID = 8952( 8393 1560 1560 1 8462 )); -DATA(insert OID = 8953( 8394 1560 1560 1 8462 )); +DATA(insert OID = 8952 ( 8393 1560 1560 1 8462 )); +DATA(insert OID = 8953 ( 8394 1560 1560 1 8462 )); #endif /* PG_AMPROC_H */ -- Gitee From 66a77b9b55f9241c716734c4d4d0c08028517e02 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 09:12:13 +0800 Subject: [PATCH 19/67] clean code --- src/common/backend/utils/adt/halfvec.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/common/backend/utils/adt/halfvec.cpp b/src/common/backend/utils/adt/halfvec.cpp index 70d810c177..523b905427 100644 --- a/src/common/backend/utils/adt/halfvec.cpp +++ b/src/common/backend/utils/adt/halfvec.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/datavec/bitvec.h" #include "catalog/pg_type.h" @@ -119,7 +119,7 @@ HalfVector *InitHalfVector(int dim) /* * Check for whitespace, since array_isspace() is static */ -static inline bool halfvec_isspace(char ch) +static inline bool HalfvecIsspace(char ch) { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\v' || ch == '\f') { return true; @@ -163,7 +163,7 @@ Datum halfvec_in(PG_FUNCTION_ARGS) char *pt = lit; HalfVector *result; - while (halfvec_isspace(*pt)) { + while (HalfvecIsspace(*pt)) { pt++; } @@ -174,7 +174,7 @@ Datum halfvec_in(PG_FUNCTION_ARGS) pt++; - while (halfvec_isspace(*pt)) { + while (HalfvecIsspace(*pt)) { pt++; } @@ -189,7 +189,7 @@ Datum halfvec_in(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("halfvec cannot have more than %d dimensions", HALFVEC_MAX_DIM))); - while (halfvec_isspace(*pt)) { + while (HalfvecIsspace(*pt)) { pt++; } @@ -221,7 +221,7 @@ Datum halfvec_in(PG_FUNCTION_ARGS) pt = stringEnd; - while (halfvec_isspace(*pt)) { + while (HalfvecIsspace(*pt)) { pt++; } @@ -237,7 +237,7 @@ Datum halfvec_in(PG_FUNCTION_ARGS) } /* Only whitespace is allowed after the closing brace */ - while (halfvec_isspace(*pt)) { + while (HalfvecIsspace(*pt)) { pt++; } @@ -259,7 +259,7 @@ Datum halfvec_in(PG_FUNCTION_ARGS) } #define AppendChar(ptr, c) (*(ptr)++ = (c)) -#define AppendFloat(ptr, f) ((ptr) += float_to_shortest_decimal_bufn((f), (ptr))) +#define AppendFloat(ptr, f) ((ptr) += FloatToShortestDecimalBufn((f), (ptr))) /* * Convert internal representation to textual representation @@ -276,7 +276,7 @@ Datum halfvec_out(PG_FUNCTION_ARGS) * Need: * * dim * (FLOAT_SHORTEST_DECIMAL_LEN - 1) bytes for - * float_to_shortest_decimal_bufn + * FloatToShortestDecimalBufn * * dim - 1 bytes for separator * -- Gitee From 82f6776b7450844bd00001c915404a677f332543 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 09:30:04 +0800 Subject: [PATCH 20/67] clean code --- src/include/access/datavec/shortest_dec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/access/datavec/shortest_dec.h b/src/include/access/datavec/shortest_dec.h index dd4779ca9f..b0312b6f24 100644 --- a/src/include/access/datavec/shortest_dec.h +++ b/src/include/access/datavec/shortest_dec.h @@ -4,6 +4,6 @@ #define FLOAT_SHORTEST_DECIMAL_LEN 16 int FloatToShortestDecimalBufn(float f, char *result); -int float_to_shortest_decimal_buf(float f, char *result); +int FloatToShortestDecimalBuf(float f, char *result); #endif /* SHORTEST_DEC_H */ -- Gitee From 3009526b65237c45959e875274e537f9420acb25 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 09:33:17 +0800 Subject: [PATCH 21/67] clean code --- src/gausskernel/storage/access/datavec/hnswutils.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index 4544dba14a..69de2f78b6 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -484,7 +484,7 @@ void HnswSetElementTuple(char *base, HnswElementTuple etup, HnswElement element) else ItemPointerSetInvalid(&etup->heaptids[i]); } - rc = memcpy_(&etup->data, VARSIZE_ANY(valuePtr), valuePtr, VARSIZE_ANY(valuePtr)); + rc = memcpy_s(&etup->data, VARSIZE_ANY(valuePtr), valuePtr, VARSIZE_ANY(valuePtr)); securec_check(rc, "\0", "\0"); } @@ -1344,8 +1344,9 @@ static void SparsevecCheckValue(Pointer v) { SparseVector *vec = (SparseVector *)v; - if (vec->nnz > HNSW_MAX_NNZ) + if (vec->nnz > HNSW_MAX_NNZ) { elog(ERROR, "sparsevec cannot have more than %d non-zero elements for hnsw index", HNSW_MAX_NNZ); + } } /* -- Gitee From b7a02d8feb180bec9059e6fc065e666f38292789 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 09:44:35 +0800 Subject: [PATCH 22/67] clean code --- src/include/catalog/pg_amproc.h | 48 +++++++++++++++---------------- src/include/catalog/pg_opclass.h | 49 ++++++++++++++++---------------- src/include/catalog/pg_type.h | 6 ++-- 3 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 8a60128a33..2daf1c5e2d 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -656,41 +656,41 @@ DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); //hnsw //vector_l2_ops -DATA(insert OID = 8924 ( 8371 8305 8305 1 8431 )); +DATA(insert OID = 8924 (8371 8305 8305 1 8431)); //vector_ip_ops -DATA(insert OID = 8925 ( 8372 8305 8305 1 8434 )); +DATA(insert OID = 8925 (8372 8305 8305 1 8434)); //vector_cosine_ops -DATA(insert OID = 8926 ( 8373 8305 8305 1 8434 )); -DATA(insert OID = 8947 ( 8373 8305 8305 2 8438 )); +DATA(insert OID = 8926 (8373 8305 8305 1 8434)); +DATA(insert OID = 8947 (8373 8305 8305 2 8438)); //vector_l1_ops -DATA(insert OID = 8927 ( 8374 8305 8305 1 8436 )); +DATA(insert OID = 8927 (8374 8305 8305 1 8436)); -DATA(insert OID = 8928 ( 8375 8306 8306 1 8451 )); -DATA(insert OID = 8929 ( 8376 8306 8306 1 8451 )); -DATA(insert OID = 8930 ( 8377 8306 8306 1 8451 )); -DATA(insert OID = 8931 ( 8378 8306 8306 1 8451 )); +DATA(insert OID = 8928 (8375 8306 8306 1 8451)); +DATA(insert OID = 8929 (8376 8306 8306 1 8451)); +DATA(insert OID = 8930 (8377 8306 8306 1 8451)); +DATA(insert OID = 8931 (8378 8306 8306 1 8451)); -DATA(insert OID = 8932 ( 8379 1560 1560 1 8462 )); -DATA(insert OID = 8933 ( 8380 1560 1560 1 8462 )); +DATA(insert OID = 8932 (8379 1560 1560 1 8462)); +DATA(insert OID = 8933 (8380 1560 1560 1 8462)); -DATA(insert OID = 8934 ( 8381 8307 8307 1 8463 )); -DATA(insert OID = 8935 ( 8382 8307 8307 1 8463 )); -DATA(insert OID = 8936 ( 8383 8307 8307 1 8463 )); -DATA(insert OID = 8937 ( 8384 8307 8307 1 8463 )); +DATA(insert OID = 8934 (8381 8307 8307 1 8463)); +DATA(insert OID = 8935 (8382 8307 8307 1 8463)); +DATA(insert OID = 8936 (8383 8307 8307 1 8463)); +DATA(insert OID = 8937 (8384 8307 8307 1 8463)); //ivfflat //vector_l2_ops -DATA(insert OID = 8938 ( 8385 8305 8305 1 8431 )); -DATA(insert OID = 8939 ( 8385 8305 8305 3 8433 )); +DATA(insert OID = 8938 (8385 8305 8305 1 8431)); +DATA(insert OID = 8939 (8385 8305 8305 3 8433)); //vector_ip_ops -DATA(insert OID = 8940 ( 8386 8305 8305 1 8434 )); -DATA(insert OID = 8941 ( 8386 8305 8305 3 8432 )); -DATA(insert OID = 8942 ( 8386 8305 8305 4 8438 )); +DATA(insert OID = 8940 (8386 8305 8305 1 8434)); +DATA(insert OID = 8941 (8386 8305 8305 3 8432)); +DATA(insert OID = 8942 (8386 8305 8305 4 8438)); //vector_cosine_ops -DATA(insert OID = 8943 ( 8387 8305 8305 1 8434 )); -DATA(insert OID = 8944 ( 8387 8305 8305 2 8438 )); -DATA(insert OID = 8945 ( 8387 8305 8305 3 8432 )); -DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); +DATA(insert OID = 8943 (8387 8305 8305 1 8434)); +DATA(insert OID = 8944 (8387 8305 8305 2 8438)); +DATA(insert OID = 8945 (8387 8305 8305 3 8432)); +DATA(insert OID = 8946 (8387 8305 8305 4 8438)); //vector_l1_ops //DATA(insert OID = 8942 ( 8388 8305 8305 1 8450 )); diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index eac125146d..dc8b32f49c 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -375,36 +375,35 @@ DATA(insert ( 405 settext_ops PGNSP PGUID 1995 3272 f 0 )); DATA(insert ( 4439 setasint_ops PGNSP PGUID 6976 3272 t 0 )); DATA(insert ( 405 set_ops PGNSP PGUID 8646 3272 t 0 )); +DATA(insert OID = 8900 (8300 vector_l2_ops PGNSP PGUID 8371 8305 t 0)); +DATA(insert OID = 8999 (8300 vector_ip_ops PGNSP PGUID 8372 8305 t 0)); +DATA(insert OID = 8902 (8300 vector_cosine_ops PGNSP PGUID 8373 8305 t 0)); +DATA(insert OID = 8903 (8300 vector_l1_ops PGNSP PGUID 8374 8305 t 0)); +DATA(insert OID = 8904 (8300 halfvec_l2_ops PGNSP PGUID 8375 8306 t 0)); +DATA(insert OID = 8905 (8300 halfvec_ip_ops PGNSP PGUID 8376 8306 t 0)); +DATA(insert OID = 8906 (8300 halfvec_cosine_ops PGNSP PGUID 8377 8306 t 0)); +DATA(insert OID = 8907 (8300 halfvec_l1_ops PGNSP PGUID 8378 8306 t 0)); -DATA(insert OID = 8900 ( 8300 vector_l2_ops PGNSP PGUID 8371 8305 t 0 )); -DATA(insert OID = 8999 ( 8300 vector_ip_ops PGNSP PGUID 8372 8305 t 0 )); -DATA(insert OID = 8902 ( 8300 vector_cosine_ops PGNSP PGUID 8373 8305 t 0 )); -DATA(insert OID = 8903 ( 8300 vector_l1_ops PGNSP PGUID 8374 8305 t 0 )); -DATA(insert OID = 8904 ( 8300 halfvec_l2_ops PGNSP PGUID 8375 8306 t 0 )); -DATA(insert OID = 8905 ( 8300 halfvec_ip_ops PGNSP PGUID 8376 8306 t 0 )); -DATA(insert OID = 8906 ( 8300 halfvec_cosine_ops PGNSP PGUID 8377 8306 t 0 )); -DATA(insert OID = 8907 ( 8300 halfvec_l1_ops PGNSP PGUID 8378 8306 t 0 )); +DATA(insert OID = 8908 (8300 bit_jaccard_ops PGNSP PGUID 8379 1560 t 0)); +DATA(insert OID = 8909 (8300 bit_hamming_ops PGNSP PGUID 8380 1560 t 0)); -DATA(insert OID = 8908 ( 8300 bit_jaccard_ops PGNSP PGUID 8379 1560 t 0 )); -DATA(insert OID = 8909 ( 8300 bit_hamming_ops PGNSP PGUID 8380 1560 t 0 )); +DATA(insert OID = 8910 (8300 sparsevec_l2_ops PGNSP PGUID 8381 8307 t 0)); +DATA(insert OID = 8911 (8300 sparsevec_ip_ops PGNSP PGUID 8382 8307 t 0)); +DATA(insert OID = 8912 (8300 sparsevec_cosine_ops PGNSP PGUID 8383 8307 t 0)); +DATA(insert OID = 8913 (8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 t 0)); -DATA(insert OID = 8910 ( 8300 sparsevec_l2_ops PGNSP PGUID 8381 8307 t 0 )); -DATA(insert OID = 8911 ( 8300 sparsevec_ip_ops PGNSP PGUID 8382 8307 t 0 )); -DATA(insert OID = 8912 ( 8300 sparsevec_cosine_ops PGNSP PGUID 8383 8307 t 0 )); -DATA(insert OID = 8913 ( 8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 t 0 )); +DATA(insert OID = 8914 (8301 vector_l2_ops PGNSP PGUID 8385 8305 t 0)); +DATA(insert OID = 8915 (8301 vector_ip_ops PGNSP PGUID 8386 8305 t 0)); +DATA(insert OID = 8916 (8301 vector_cosine_ops PGNSP PGUID 8387 8305 t 0)); +DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0 )); -DATA(insert OID = 8914 ( 8301 vector_l2_ops PGNSP PGUID 8385 8305 t 0 )); -DATA(insert OID = 8915 ( 8301 vector_ip_ops PGNSP PGUID 8386 8305 t 0 )); -DATA(insert OID = 8916 ( 8301 vector_cosine_ops PGNSP PGUID 8387 8305 t 0 )); -DATA(insert OID = 8917 ( 8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0 )); +DATA(insert OID = 8918 (8301 halfvec_l2_ops PGNSP PGUID 8389 8306 t 0)); +DATA(insert OID = 8919 (8301 halfvec_ip_ops PGNSP PGUID 8390 8306 t 0)); +DATA(insert OID = 8920 (8301 halfvec_cosine_ops PGNSP PGUID 8391 8306 t 0)); +DATA(insert OID = 8921 (8301 halfvec_l1_ops PGNSP PGUID 8392 8306 t 0)); -DATA(insert OID = 8918 ( 8301 halfvec_l2_ops PGNSP PGUID 8389 8306 t 0 )); -DATA(insert OID = 8919 ( 8301 halfvec_ip_ops PGNSP PGUID 8390 8306 t 0 )); -DATA(insert OID = 8920 ( 8301 halfvec_cosine_ops PGNSP PGUID 8391 8306 t 0 )); -DATA(insert OID = 8921 ( 8301 halfvec_l1_ops PGNSP PGUID 8392 8306 t 0 )); - -DATA(insert OID = 8922 ( 8301 bit_jaccard_ops PGNSP PGUID 8393 1560 t 0 )); -DATA(insert OID = 8923 ( 8301 bit_hamming_ops PGNSP PGUID 8394 1560 t 0 )); +DATA(insert OID = 8922 (8301 bit_jaccard_ops PGNSP PGUID 8393 1560 t 0)); +DATA(insert OID = 8923 (8301 bit_hamming_ops PGNSP PGUID 8394 1560 t 0)); #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 4ab3b344c0..8b020c61a9 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -823,13 +823,13 @@ DATA(insert OID = 4408 ( undefined PGNSP PGUID -2 f u W f t \054 0 0 0 undefin DESCR("undefined objects as PLSQL compilation time"); #define UNDEFINEDOID 4408 -DATA(insert OID = 8305 ( vector PGNSP PGUID -1 f b U f t \054 0 0 4411 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 8305 (vector PGNSP PGUID -1 f b U f t \054 0 0 0 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define VECTOROID 8305 -DATA(insert OID = 8306 ( halfvec PGNSP PGUID -1 f b U f t \054 0 0 4411 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 8306 (halfvec PGNSP PGUID -1 f b U f t \054 0 0 0 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define FLOATVECTOROID 8306 -DATA(insert OID = 8307 ( sparsevec PGNSP PGUID -1 f b U f t \054 0 0 4411 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 8307 (sparsevec PGNSP PGUID -1 f b U f t \054 0 0 0 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define SPARSEVECTOROID 8307 /* -- Gitee From b35570967b57e61b0938019b0790003f76b9ba16 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 09:48:20 +0800 Subject: [PATCH 23/67] clean code --- src/include/access/datavec/sampling.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/include/access/datavec/sampling.h b/src/include/access/datavec/sampling.h index 0c51c2cd19..6d96ff49eb 100644 --- a/src/include/access/datavec/sampling.h +++ b/src/include/access/datavec/sampling.h @@ -2,15 +2,11 @@ #define SAMPLING_H #include "access/datavec/pg_prng.h" -#include "storage/buf/block.h" /* for typedef BlockNumber */ +#include "storage/buf/block.h" -/* Random generator for sampling code */ extern void sampler_random_init_state(uint32 seed, pg_prng_state *randstate); extern double sampler_random_fract(pg_prng_state *randstate); -/* Block sampling methods */ - -/* Data structure for Algorithm S from Knuth 3.4.2 */ typedef struct { BlockNumber N; /* number of blocks, known in advance */ uint32 n; /* desired sample size */ @@ -25,8 +21,6 @@ extern BlockNumber BlockSampler_Init2(BlockSampler2 bs, BlockNumber nblocks, int extern bool BlockSampler_HasMore2(BlockSampler2 bs); extern BlockNumber BlockSampler_Next2(BlockSampler2 bs); -/* Reservoir sampling methods */ - typedef struct { double W; pg_prng_state randstate; /* random generator state */ -- Gitee From 921f08109ed2ffd70b522d2fd34ae0da042f2c34 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 09:53:47 +0800 Subject: [PATCH 24/67] clean code --- src/common/backend/utils/adt/sparsevec.cpp | 6 +++--- src/common/backend/utils/adt/vector.cpp | 2 +- src/gausskernel/storage/access/datavec/hnsw.cpp | 4 ++-- src/gausskernel/storage/access/datavec/hnswbuild.cpp | 2 +- src/gausskernel/storage/access/datavec/hnswinsert.cpp | 2 +- src/gausskernel/storage/access/datavec/hnswvacuum.cpp | 2 +- src/gausskernel/storage/access/datavec/ivfbuild.cpp | 2 +- src/gausskernel/storage/access/datavec/ivfflat.cpp | 2 +- src/gausskernel/storage/access/datavec/ivfinsert.cpp | 2 +- src/gausskernel/storage/access/datavec/ivfkmeans.cpp | 4 ++-- src/gausskernel/storage/access/datavec/ivfscan.cpp | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index 2a10ab7e81..750f897402 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -1,7 +1,7 @@ #include "postgres.h" -#include -#include +#include +#include #include "fmgr.h" #include "access/datavec/halfutils.h" @@ -17,7 +17,7 @@ #include "common/shortest_dec.h" #include "utils/float.h" #else -#include +#include #include "utils/builtins.h" #endif diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 8b3b9f4e1d..0e27f3e8b0 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/datavec/bitvec.h" #include "catalog/pg_type.h" diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp index d365e8d32b..1b6e7750e3 100644 --- a/src/gausskernel/storage/access/datavec/hnsw.cpp +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -1,7 +1,7 @@ #include "postgres.h" -#include -#include +#include +#include #include "access/amapi.h" #include "access/reloptions.h" diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp index 15aeef1756..c8708ae3c4 100644 --- a/src/gausskernel/storage/access/datavec/hnswbuild.cpp +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -36,7 +36,7 @@ */ #include "postgres.h" -#include +#include #include "access/tableam.h" #include "access/xact.h" diff --git a/src/gausskernel/storage/access/datavec/hnswinsert.cpp b/src/gausskernel/storage/access/datavec/hnswinsert.cpp index d40a4c4ec2..fc8043e0cf 100644 --- a/src/gausskernel/storage/access/datavec/hnswinsert.cpp +++ b/src/gausskernel/storage/access/datavec/hnswinsert.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/generic_xlog.h" #include "access/xact.h" diff --git a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp index 0f35fdbba0..c67bae483a 100644 --- a/src/gausskernel/storage/access/datavec/hnswvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/hnswvacuum.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/generic_xlog.h" #include "commands/vacuum.h" diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index eb5fb9dd7e..a64615732d 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/tableam.h" #include "access/xact.h" diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index f202ab7eac..90c65774bc 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/amapi.h" #include "access/reloptions.h" diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp index 6482ce48d8..0d19d9738d 100644 --- a/src/gausskernel/storage/access/datavec/ivfinsert.cpp +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/generic_xlog.h" #include "access/datavec/ivfflat.h" diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index 21c249cf93..9079a5fcec 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -1,7 +1,7 @@ #include "postgres.h" -#include -#include +#include +#include #include "access/datavec/bitvec.h" #include "access/datavec/halfutils.h" diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index 836ddb5f7d..ce8815bd9f 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -1,6 +1,6 @@ #include "postgres.h" -#include +#include #include "access/relscan.h" #include "lib/pairingheap.h" -- Gitee From c025d4ddfd6546f92ba432a242f60bd43b2c12e2 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Sat, 2 Nov 2024 10:16:10 +0800 Subject: [PATCH 25/67] remove duplicate l1_distance --- src/common/backend/catalog/builtin_funcs.ini | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index f619c0ceeb..5ccb9b2e16 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13129,8 +13129,7 @@ AddFuncGroup( "hnswbeginscan", 1, AddBuiltinFunc(_0(8402), _1("hnswbeginscan"), _2(3), _3(true), _4(false), _5(hnswbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - -AddFuncGroup( + AddFuncGroup( "hnswgettuple", 1, AddBuiltinFunc(_0(8403), _1("hnswgettuple"), _2(2), _3(true), _4(false), _5(hnswgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13166,9 +13165,6 @@ AddFuncGroup( "hnswoptions", 1, AddBuiltinFunc(_0(8411), _1("hnswoptions"), _2(2), _3(true), _4(false), _5(hnswoptions), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 1009, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswoptions"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - AddFuncGroup( "ivfflatinsert", 1, AddBuiltinFunc(_0(8412), _1("ivfflatinsert"), _2(6), _3(true), _4(false), _5(ivfflatinsert), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(6, 2281, 2281, 2281, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatinsert"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13254,8 +13250,6 @@ AddFuncGroup( "vector_spherical_distance", 1, AddBuiltinFunc(_0(8432), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - AddFuncGroup( "l2_distance", 1, AddBuiltinFunc(_0(8433), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13272,8 +13266,6 @@ AddFuncGroup( "l1_distance", 1, AddBuiltinFunc(_0(8436), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - AddFuncGroup( "inner_product", 1, AddBuiltinFunc(_0(8437), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13334,10 +13326,6 @@ AddFuncGroup( "halfvec_cmp", 1, AddBuiltinFunc(_0(8451), _1("halfvec_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "l1_distance", 1, - AddBuiltinFunc(_0(8205), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 4409, 4409), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), AddFuncGroup( "halfvec_in", 1, AddBuiltinFunc(_0(8452), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) -- Gitee From 60cfade46b0eb0ad41e13c2fa8555d861e128e7f Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 10:18:22 +0800 Subject: [PATCH 26/67] clean code --- src/common/backend/utils/adt/halfutils.cpp | 2 +- src/common/backend/utils/adt/sparsevec.cpp | 8 ++++---- src/common/backend/utils/adt/vector.cpp | 2 +- src/gausskernel/storage/access/datavec/hnsw.cpp | 8 ++++---- src/gausskernel/storage/access/datavec/hnswutils.cpp | 2 +- src/gausskernel/storage/access/datavec/ivfbuild.cpp | 2 +- src/gausskernel/storage/access/datavec/ivfflat.cpp | 10 +++++----- src/gausskernel/storage/access/datavec/ivfkmeans.cpp | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/common/backend/utils/adt/halfutils.cpp b/src/common/backend/utils/adt/halfutils.cpp index 92350ddb90..c17908d46d 100644 --- a/src/common/backend/utils/adt/halfutils.cpp +++ b/src/common/backend/utils/adt/halfutils.cpp @@ -124,7 +124,7 @@ static double HalfvecCosineSimilarityDefault(int dim, half *ax, half *bx) } /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double)similarity / sqrt((double)norma * (double)normb); + return static_castsimilarity / sqrt(static_castnorma * static_castnormb); } #ifdef HALFVEC_DISPATCH diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index 750f897402..e4e9f6ad9b 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -144,11 +144,11 @@ static inline bool SparsevecIsspace(char ch) */ static int CompareIndices(const void *a, const void *b) { - if (((SparseInputElement *)a)->index < ((SparseInputElement *)b)->index) { + if ((dynamic_casta)->index < (dynamic_castb)->index) { return -1; } - if (((SparseInputElement *)a)->index > ((SparseInputElement *)b)->index) { + if ((dynamic_casta)->index > (dynamic_castb)->index) { return 1; } @@ -773,7 +773,7 @@ Datum sparsevec_cosine_distance(PG_FUNCTION_ARGS) normb += bx[i] * bx[i]; /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - similarity /= sqrt((double)norma * (double)normb); + similarity /= sqrt(static_castnorma * static_castnormb); #ifdef _MSC_VER /* /fp:fast may not propagate NaN */ if (isnan(similarity)) @@ -833,7 +833,7 @@ Datum sparsevec_l1_distance(PG_FUNCTION_ARGS) for (int j = bpos; j < b->nnz; j++) distance += fabsf(bx[j]); - PG_RETURN_FLOAT8((double)distance); + PG_RETURN_FLOAT8(static_castdistance); } /* diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 0e27f3e8b0..05b138006b 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -634,7 +634,7 @@ VECTOR_TARGET_CLONES static double VectorCosineSimilarity(int dim, float *ax, fl } /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return (double)similarity / sqrt((double)norma * (double)normb); + return static_castsimilarity / sqrt(static_castnorma * static_castnormb); } /* diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp index 1b6e7750e3..a736b7a35b 100644 --- a/src/gausskernel/storage/access/datavec/hnsw.cpp +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -206,7 +206,7 @@ Datum hnswinsert(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); Datum *values = (Datum *)PG_GETARG_POINTER(1); - bool *isnull = (bool *)PG_GETARG_POINTER(2); + bool *isnull = static_cast(PG_GETARG_POINTER(2)); ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); Relation heaprel = (Relation)PG_GETARG_POINTER(4); IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); @@ -221,7 +221,7 @@ Datum hnswbulkdelete(PG_FUNCTION_ARGS) IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); - void *callbackState = (void *)PG_GETARG_POINTER(3); + void *callbackState = static_cast(PG_GETARG_POINTER(3)); stats = hnswbulkdelete_internal(info, stats, callback, callbackState); PG_RETURN_POINTER(stats); @@ -242,11 +242,11 @@ Datum hnswcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); - double loopcount = (double)PG_GETARG_FLOAT8(2); + double loopcount = static_cast(PG_GETARG_FLOAT8(2)); Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); - double *correlation = (double *)PG_GETARG_POINTER(6); + double *correlation = static_cast(PG_GETARG_POINTER(6)); hnswcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); PG_RETURN_VOID(); diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index 69de2f78b6..9577cd0731 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -271,7 +271,7 @@ HnswElement HnswInitElement(char *base, ItemPointer heaptid, int m, double ml, i { HnswElement element = (HnswElement)HnswAlloc(allocator, sizeof(HnswElementData)); - int level = (int)(-log(RandomDouble()) * ml); + int level = static_cast(-log(RandomDouble()) * ml); /* Cap level */ if (level > maxLevel) { level = maxLevel; diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index a64615732d..2f25b622c6 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -70,7 +70,7 @@ static void AddSample(Datum *values, IvfflatBuildState *buildstate) } if (buildstate->rowstoskip <= 0) { - int k = (int)(targsamples * anl_random_fract()); + int k = static_cast(targsamples * anl_random_fract()); Assert(k >= 0 && k < targsamples); VectorArraySet(samples, k, DatumGetPointer(value)); } diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index 90c65774bc..fabc4f1d4d 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -52,7 +52,7 @@ static void ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, dou index_close(index, NoLock); /* Get the ratio of lists that we need to visit */ - ratio = ((double)get_session_context()->ivfflat_probes) / lists; + ratio = (static_cast(get_session_context()->ivfflat_probes)) / lists; if (ratio > 1.0) { ratio = 1.0; } @@ -223,7 +223,7 @@ Datum ivfflatinsert(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); Datum *values = (Datum *)PG_GETARG_POINTER(1); - bool *isnull = (bool *)PG_GETARG_POINTER(2); + bool *isnull = static_cast(PG_GETARG_POINTER(2)); ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); Relation heaprel = (Relation)PG_GETARG_POINTER(4); IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); @@ -238,7 +238,7 @@ Datum ivfflatbulkdelete(PG_FUNCTION_ARGS) IndexVacuumInfo *info = (IndexVacuumInfo *)PG_GETARG_POINTER(0); IndexBulkDeleteResult *volatile stats = (IndexBulkDeleteResult *)PG_GETARG_POINTER(1); IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback)PG_GETARG_POINTER(2); - void *callbackState = (void *)PG_GETARG_POINTER(3); + void *callbackState = static_cast(PG_GETARG_POINTER(3)); stats = ivfflatbulkdelete_internal(info, stats, callback, callbackState); PG_RETURN_POINTER(stats); @@ -259,11 +259,11 @@ Datum ivfflatcostestimate(PG_FUNCTION_ARGS) { PlannerInfo *root = (PlannerInfo *)PG_GETARG_POINTER(0); IndexPath *path = (IndexPath *)PG_GETARG_POINTER(1); - double loopcount = (double)PG_GETARG_FLOAT8(2); + double loopcount = static_cast(PG_GETARG_FLOAT8(2)); Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); - double *correlation = (double *)PG_GETARG_POINTER(6); + double *correlation = static_cast(PG_GETARG_POINTER(6)); ivfflatcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); PG_RETURN_VOID(); diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index 9079a5fcec..abe4bc327a 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -120,14 +120,14 @@ static void RandomCenters(Relation index, VectorArray centers, const IvfflatType int dimensions = centers->dim; FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); Oid collation = index->rd_indcollation[0]; - float *x = (float *)palloc(sizeof(float) * dimensions); + float *x = static_castpalloc(sizeof(float) * dimensions); /* Fill with random data */ while (centers->length < centers->maxlen) { Pointer center = VectorArrayGet(centers, centers->length); for (int i = 0; i < dimensions; i++) { - x[i] = (float)RandomDouble(); + x[i] = static_castRandomDouble(); } typeInfo->updateCenter(center, dimensions, x); -- Gitee From 2173fb6debb29fdcb7ef4084eaab556f47920729 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Sat, 2 Nov 2024 10:22:16 +0800 Subject: [PATCH 27/67] =?UTF-8?q?sparsevec=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 60 +++++++++++++++++++- src/include/catalog/pg_amop.data | 25 ++++---- src/include/catalog/pg_amproc.h | 56 ++++++++++-------- src/include/catalog/pg_operator.data | 14 +++++ 4 files changed, 115 insertions(+), 40 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 5ccb9b2e16..1942d086c9 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13397,4 +13397,62 @@ AddFuncGroup( AddFuncGroup( "hamming_distance", 1, AddBuiltinFunc(_0(8469), _1("hamming_distance"), _2(1), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), \ No newline at end of file + ), + + + + AddFuncGroup( + "sparsevec_l2_squared_distance", 1, + AddBuiltinFunc(_0(8470), _1("sparsevec_l2_squared_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + AddFuncGroup( + "sparsevec_inner_product", 1, + AddBuiltinFunc(_0(8471), _1("sparsevec_inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "sparsevec_lt", 1, + AddBuiltinFunc(_0(8472), _1("sparsevec_lt"), _2(1), _3(true), _4(false), _5(sparsevec_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "sparsevec_le", 1, + AddBuiltinFunc(_0(8473), _1("sparsevec_le"), _2(1), _3(true), _4(false), _5(sparsevec_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_eq", 1, + AddBuiltinFunc(_0(8474), _1("sparsevec_eq"), _2(1), _3(true), _4(false), _5(sparsevec_eq), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_ne", 1, + AddBuiltinFunc(_0(8475), _1("sparsevec_ne"), _2(1), _3(true), _4(false), _5(sparsevec_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_ge", 1, + AddBuiltinFunc(_0(8476), _1("sparsevec_ge"), _2(1), _3(true), _4(false), _5(sparsevec_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_gt", 1, + AddBuiltinFunc(_0(8477), _1("sparsevec_gt"), _2(1), _3(true), _4(false), _5(sparsevec_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), +AddFuncGroup( + "sparsevec_l2_norm", 1, + AddBuiltinFunc(_0(8478), _1("sparsevec_l2_norm"), _2(1), _3(true), _4(false), _5(sparsevec_l2_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnsw_sparsevec_support", 1, + AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(3), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + + + + + + + + diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 3086e54016..51d7ca5ea1 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1622,21 +1622,16 @@ DATA(insert OID = 6266 ( 8378 8306 8306 3 o 8317 8300 1970 )); DATA(insert OID = 6366 ( 8378 8306 8306 4 o 8318 8300 424 )); DATA(insert OID = 6091 ( 8381 8307 8307 1 o 8319 8300 1970 )); -DATA(insert OID = 6092 ( 8381 8307 8307 2 o 8320 8300 1970 )); -DATA(insert OID = 6093 ( 8381 8307 8307 3 o 8321 8300 1970 )); -DATA(insert OID = 6094 ( 8381 8307 8307 4 o 8322 8300 1970 )); -DATA(insert OID = 6095 ( 8382 8307 8307 1 o 8319 8300 1970 )); -DATA(insert OID = 6096 ( 8382 8307 8307 2 o 8320 8300 1970 )); -DATA(insert OID = 6097 ( 8382 8307 8307 3 o 8321 8300 1970 )); -DATA(insert OID = 6098 ( 8382 8307 8307 4 o 8322 8300 1970 )); -DATA(insert OID = 6099 ( 8383 8307 8307 1 o 8319 8300 1970 )); -DATA(insert OID = 6100 ( 8383 8307 8307 2 o 8320 8300 1970 )); -DATA(insert OID = 6101 ( 8383 8307 8307 3 o 8321 8300 1970 )); -DATA(insert OID = 6102 ( 8383 8307 8307 4 o 8322 8300 1970 )); -DATA(insert OID = 6103 ( 8384 8307 8307 1 o 8319 8300 1970 )); -DATA(insert OID = 6104 ( 8384 8307 8307 2 o 8320 8300 1970 )); -DATA(insert OID = 6105 ( 8384 8307 8307 3 o 8321 8300 1970 )); -DATA(insert OID = 6106 ( 8384 8307 8307 4 o 8322 8300 1970 )); + + +DATA(insert OID = 6095 ( 8382 8307 8307 1 o 8320 8300 1970 )); + + +DATA(insert OID = 6101 ( 8383 8307 8307 1 o 8321 8300 1970 )); + + +DATA(insert OID = 6103 ( 8384 8307 8307 1 o 8322 8300 1970 )); + DATA(insert OID = 6107 ( 8379 1560 1560 1 o 8323 8300 1970 )); diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 2daf1c5e2d..b321e9be0e 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -656,41 +656,49 @@ DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); //hnsw //vector_l2_ops -DATA(insert OID = 8924 (8371 8305 8305 1 8431)); +DATA(insert OID = 8924 ( 8371 8305 8305 1 8431 )); //vector_ip_ops -DATA(insert OID = 8925 (8372 8305 8305 1 8434)); +DATA(insert OID = 8925 ( 8372 8305 8305 1 8434 )); //vector_cosine_ops -DATA(insert OID = 8926 (8373 8305 8305 1 8434)); -DATA(insert OID = 8947 (8373 8305 8305 2 8438)); +DATA(insert OID = 8926 ( 8373 8305 8305 1 8434 )); +DATA(insert OID = 8947 ( 8373 8305 8305 2 8438 )); //vector_l1_ops -DATA(insert OID = 8927 (8374 8305 8305 1 8436)); +DATA(insert OID = 8927 ( 8374 8305 8305 1 8436 )); -DATA(insert OID = 8928 (8375 8306 8306 1 8451)); -DATA(insert OID = 8929 (8376 8306 8306 1 8451)); -DATA(insert OID = 8930 (8377 8306 8306 1 8451)); -DATA(insert OID = 8931 (8378 8306 8306 1 8451)); +DATA(insert OID = 8928 ( 8375 8306 8306 1 8451 )); +DATA(insert OID = 8929 ( 8376 8306 8306 1 8451 )); +DATA(insert OID = 8930 ( 8377 8306 8306 1 8451 )); +DATA(insert OID = 8931 ( 8378 8306 8306 1 8451 )); -DATA(insert OID = 8932 (8379 1560 1560 1 8462)); -DATA(insert OID = 8933 (8380 1560 1560 1 8462)); +DATA(insert OID = 8932 ( 8379 1560 1560 1 8462 )); +DATA(insert OID = 8933 ( 8380 1560 1560 1 8462 )); -DATA(insert OID = 8934 (8381 8307 8307 1 8463)); -DATA(insert OID = 8935 (8382 8307 8307 1 8463)); -DATA(insert OID = 8936 (8383 8307 8307 1 8463)); -DATA(insert OID = 8937 (8384 8307 8307 1 8463)); +DATA(insert OID = 8934 ( 8381 8307 8307 1 8470 )); +DATA(insert OID = 8954 ( 8381 8307 8307 3 8479 )); + +DATA(insert OID = 8935 ( 8382 8307 8307 1 8463 )); +DATA(insert OID = 8955 ( 8382 8307 8307 3 8479 )); + +DATA(insert OID = 8936 ( 8383 8307 8307 1 8463 )); +DATA(insert OID = 8956 ( 8383 8307 8307 2 8478 )); +DATA(insert OID = 8957 ( 8383 8307 8307 3 8479 )); + +DATA(insert OID = 8937 ( 8384 8307 8307 1 8467 )); +DATA(insert OID = 8958 ( 8384 8307 8307 3 8479 )); //ivfflat //vector_l2_ops -DATA(insert OID = 8938 (8385 8305 8305 1 8431)); -DATA(insert OID = 8939 (8385 8305 8305 3 8433)); +DATA(insert OID = 8938 ( 8385 8305 8305 1 8431 )); +DATA(insert OID = 8939 ( 8385 8305 8305 3 8433 )); //vector_ip_ops -DATA(insert OID = 8940 (8386 8305 8305 1 8434)); -DATA(insert OID = 8941 (8386 8305 8305 3 8432)); -DATA(insert OID = 8942 (8386 8305 8305 4 8438)); +DATA(insert OID = 8940 ( 8386 8305 8305 1 8434 )); +DATA(insert OID = 8941 ( 8386 8305 8305 3 8432 )); +DATA(insert OID = 8942 ( 8386 8305 8305 4 8438 )); //vector_cosine_ops -DATA(insert OID = 8943 (8387 8305 8305 1 8434)); -DATA(insert OID = 8944 (8387 8305 8305 2 8438)); -DATA(insert OID = 8945 (8387 8305 8305 3 8432)); -DATA(insert OID = 8946 (8387 8305 8305 4 8438)); +DATA(insert OID = 8943 ( 8387 8305 8305 1 8434 )); +DATA(insert OID = 8944 ( 8387 8305 8305 2 8438 )); +DATA(insert OID = 8945 ( 8387 8305 8305 3 8432 )); +DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); //vector_l1_ops //DATA(insert OID = 8942 ( 8388 8305 8305 1 8450 )); diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index 74fcad5f3c..d64d418490 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1966,6 +1966,20 @@ DATA(insert OID = 8331 ("=" PGNSP PGUID b f t 8305 8305 16 6169 6170 vecto DESCR("vector equal"); DATA(insert OID = 8332 ("<>" PGNSP PGUID b f f 8305 8305 16 6170 6169 vector_ne neqsel neqjoinsel)); DESCR("vector unequal"); + +DATA(insert OID = 8333 ("<" PGNSP PGUID b f f 8307 8307 16 6164 6165 sparsevec_lt scalarltsel scalarltjoinsel)); +DESCR("sparsevec less than"); +DATA(insert OID = 8334 ("<=" PGNSP PGUID b f f 8307 8307 16 6165 6164 sparsevec_le scalarltsel scalarltjoinsel)); +DESCR("sparsevec less than or equal"); +DATA(insert OID = 8335 (">" PGNSP PGUID b f f 8307 8307 16 6167 6168 sparsevec_gt scalargtsel scalargtjoinsel)); +DESCR("sparsevec greater than"); +DATA(insert OID = 8336 (">=" PGNSP PGUID b f f 8307 8307 16 6168 6167 sparsevec_ge scalargtsel scalargtjoinsel)); +DESCR("sparsevec greater than or equal"); +DATA(insert OID = 8337 ("=" PGNSP PGUID b f t 8307 8307 16 6169 6170 sparsevec_eq eqsel eqjoinsel)); +DESCR("sparsevec equal"); +DATA(insert OID = 8338 ("<>" PGNSP PGUID b f f 8307 8307 16 6170 6169 sparsevec_ne neqsel neqjoinsel)); +DESCR("sparsevec unequal"); + /* * function prototypes */ \ No newline at end of file -- Gitee From f20b60da215c8a989d1a5c3211bbe3c0f321976c Mon Sep 17 00:00:00 2001 From: h30054849 Date: Sat, 2 Nov 2024 10:30:42 +0800 Subject: [PATCH 28/67] clean code --- src/common/backend/catalog/builtin_funcs.ini | 23 ++------------------ 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 1942d086c9..abf43152a5 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13173,7 +13173,6 @@ AddFuncGroup( "ivfflatbeginscan", 1, AddBuiltinFunc(_0(8413), _1("ivfflatbeginscan"), _2(3), _3(true), _4(false), _5(ivfflatbeginscan), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 2281, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatbeginscan"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "ivfflatgettuple", 1, AddBuiltinFunc(_0(8414), _1("ivfflatgettuple"), _2(2), _3(true), _4(false), _5(ivfflatgettuple), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2281, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatgettuple"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13398,26 +13397,18 @@ AddFuncGroup( "hamming_distance", 1, AddBuiltinFunc(_0(8469), _1("hamming_distance"), _2(1), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - AddFuncGroup( "sparsevec_l2_squared_distance", 1, AddBuiltinFunc(_0(8470), _1("sparsevec_l2_squared_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - AddFuncGroup( + AddFuncGroup( "sparsevec_inner_product", 1, AddBuiltinFunc(_0(8471), _1("sparsevec_inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "sparsevec_lt", 1, AddBuiltinFunc(_0(8472), _1("sparsevec_lt"), _2(1), _3(true), _4(false), _5(sparsevec_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( "sparsevec_le", 1, AddBuiltinFunc(_0(8473), _1("sparsevec_le"), _2(1), _3(true), _4(false), _5(sparsevec_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13438,7 +13429,7 @@ AddFuncGroup( "sparsevec_gt", 1, AddBuiltinFunc(_0(8477), _1("sparsevec_gt"), _2(1), _3(true), _4(false), _5(sparsevec_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), -AddFuncGroup( + AddFuncGroup( "sparsevec_l2_norm", 1, AddBuiltinFunc(_0(8478), _1("sparsevec_l2_norm"), _2(1), _3(true), _4(false), _5(sparsevec_l2_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13446,13 +13437,3 @@ AddFuncGroup( "hnsw_sparsevec_support", 1, AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(3), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - - - - - - - - -- Gitee From 7d480e447e2cddb65a44aad9c718b844c762cfd1 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 10:46:51 +0800 Subject: [PATCH 29/67] clean code --- src/common/backend/utils/adt/halfutils.cpp | 2 +- src/common/backend/utils/adt/sparsevec.cpp | 8 ++++---- src/common/backend/utils/adt/vector.cpp | 2 +- src/gausskernel/storage/access/datavec/ivfkmeans.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/common/backend/utils/adt/halfutils.cpp b/src/common/backend/utils/adt/halfutils.cpp index c17908d46d..cb62c054c0 100644 --- a/src/common/backend/utils/adt/halfutils.cpp +++ b/src/common/backend/utils/adt/halfutils.cpp @@ -124,7 +124,7 @@ static double HalfvecCosineSimilarityDefault(int dim, half *ax, half *bx) } /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return static_castsimilarity / sqrt(static_castnorma * static_castnormb); + return static_cast(similarity) / sqrt(static_cast(norma) * static_cast(normb)); } #ifdef HALFVEC_DISPATCH diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index e4e9f6ad9b..86f3b908c0 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -144,11 +144,11 @@ static inline bool SparsevecIsspace(char ch) */ static int CompareIndices(const void *a, const void *b) { - if ((dynamic_casta)->index < (dynamic_castb)->index) { + if ((dynamic_cast(a))->index < (dynamic_cast(b))->index) { return -1; } - if ((dynamic_casta)->index > (dynamic_castb)->index) { + if ((dynamic_cast(a))->index > (dynamic_cast(b))->index) { return 1; } @@ -773,7 +773,7 @@ Datum sparsevec_cosine_distance(PG_FUNCTION_ARGS) normb += bx[i] * bx[i]; /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - similarity /= sqrt(static_castnorma * static_castnormb); + similarity /= sqrt(static_cast(norma) * static_cast(normb)); #ifdef _MSC_VER /* /fp:fast may not propagate NaN */ if (isnan(similarity)) @@ -833,7 +833,7 @@ Datum sparsevec_l1_distance(PG_FUNCTION_ARGS) for (int j = bpos; j < b->nnz; j++) distance += fabsf(bx[j]); - PG_RETURN_FLOAT8(static_castdistance); + PG_RETURN_FLOAT8(static_cast(distance)); } /* diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 05b138006b..4ba879dcfd 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -634,7 +634,7 @@ VECTOR_TARGET_CLONES static double VectorCosineSimilarity(int dim, float *ax, fl } /* Use sqrt(a * b) over sqrt(a) * sqrt(b) */ - return static_castsimilarity / sqrt(static_castnorma * static_castnormb); + return static_cast(similarity) / sqrt(static_cast(norma) * static_cast(normb)); } /* diff --git a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp index abe4bc327a..34af346dd6 100644 --- a/src/gausskernel/storage/access/datavec/ivfkmeans.cpp +++ b/src/gausskernel/storage/access/datavec/ivfkmeans.cpp @@ -120,14 +120,14 @@ static void RandomCenters(Relation index, VectorArray centers, const IvfflatType int dimensions = centers->dim; FmgrInfo *normprocinfo = IvfflatOptionalProcInfo(index, IVFFLAT_KMEANS_NORM_PROC); Oid collation = index->rd_indcollation[0]; - float *x = static_castpalloc(sizeof(float) * dimensions); + float *x = static_cast(palloc(sizeof(float) * dimensions)); /* Fill with random data */ while (centers->length < centers->maxlen) { Pointer center = VectorArrayGet(centers, centers->length); for (int i = 0; i < dimensions; i++) { - x[i] = static_castRandomDouble(); + x[i] = static_cast(RandomDouble()); } typeInfo->updateCenter(center, dimensions, x); -- Gitee From 1a28f4f8c0ec839a43a0bcd2e9d5a39d8c14c04e Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 10:54:45 +0800 Subject: [PATCH 30/67] clean code --- src/common/backend/utils/adt/sparsevec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/backend/utils/adt/sparsevec.cpp b/src/common/backend/utils/adt/sparsevec.cpp index 86f3b908c0..c0d4d0db52 100644 --- a/src/common/backend/utils/adt/sparsevec.cpp +++ b/src/common/backend/utils/adt/sparsevec.cpp @@ -144,11 +144,11 @@ static inline bool SparsevecIsspace(char ch) */ static int CompareIndices(const void *a, const void *b) { - if ((dynamic_cast(a))->index < (dynamic_cast(b))->index) { + if (((SparseInputElement *)a)->index < ((SparseInputElement *)b)->index) { return -1; } - if ((dynamic_cast(a))->index > (dynamic_cast(b))->index) { + if (((SparseInputElement *)a)->index > ((SparseInputElement *)b)->index) { return 1; } -- Gitee From d06ec25d5706c3c1f56c99a37f124c96fc415156 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 11:08:21 +0800 Subject: [PATCH 31/67] clean code --- src/gausskernel/storage/access/datavec/hnsw.cpp | 4 ++-- src/include/catalog/pg_opclass.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/hnsw.cpp b/src/gausskernel/storage/access/datavec/hnsw.cpp index a736b7a35b..a2ad61e056 100644 --- a/src/gausskernel/storage/access/datavec/hnsw.cpp +++ b/src/gausskernel/storage/access/datavec/hnsw.cpp @@ -206,7 +206,7 @@ Datum hnswinsert(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); Datum *values = (Datum *)PG_GETARG_POINTER(1); - bool *isnull = static_cast(PG_GETARG_POINTER(2)); + bool *isnull = reinterpret_cast(PG_GETARG_POINTER(2)); ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); Relation heaprel = (Relation)PG_GETARG_POINTER(4); IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); @@ -246,7 +246,7 @@ Datum hnswcostestimate(PG_FUNCTION_ARGS) Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); - double *correlation = static_cast(PG_GETARG_POINTER(6)); + double *correlation = reinterpret_cast(PG_GETARG_POINTER(6)); hnswcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); PG_RETURN_VOID(); diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index dc8b32f49c..4e7a2b253a 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -395,7 +395,7 @@ DATA(insert OID = 8913 (8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 t 0)); DATA(insert OID = 8914 (8301 vector_l2_ops PGNSP PGUID 8385 8305 t 0)); DATA(insert OID = 8915 (8301 vector_ip_ops PGNSP PGUID 8386 8305 t 0)); DATA(insert OID = 8916 (8301 vector_cosine_ops PGNSP PGUID 8387 8305 t 0)); -DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0 )); +DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0)); DATA(insert OID = 8918 (8301 halfvec_l2_ops PGNSP PGUID 8389 8306 t 0)); DATA(insert OID = 8919 (8301 halfvec_ip_ops PGNSP PGUID 8390 8306 t 0)); -- Gitee From 29b742e0c1364a3bbff97eb04d1c0c06def9f2c6 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 11:37:24 +0800 Subject: [PATCH 32/67] clean code --- src/gausskernel/storage/access/datavec/ivfflat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index fabc4f1d4d..1c2b9e0ca5 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -223,7 +223,7 @@ Datum ivfflatinsert(PG_FUNCTION_ARGS) { Relation rel = (Relation)PG_GETARG_POINTER(0); Datum *values = (Datum *)PG_GETARG_POINTER(1); - bool *isnull = static_cast(PG_GETARG_POINTER(2)); + bool *isnull = reinterpret_cast(PG_GETARG_POINTER(2)); ItemPointer ht_ctid = (ItemPointer)PG_GETARG_POINTER(3); Relation heaprel = (Relation)PG_GETARG_POINTER(4); IndexUniqueCheck checkunique = (IndexUniqueCheck)PG_GETARG_INT32(5); @@ -263,7 +263,7 @@ Datum ivfflatcostestimate(PG_FUNCTION_ARGS) Cost *startupcost = (Cost *)PG_GETARG_POINTER(3); Cost *totalcost = (Cost *)PG_GETARG_POINTER(4); Selectivity *selectivity = (Selectivity *)PG_GETARG_POINTER(5); - double *correlation = static_cast(PG_GETARG_POINTER(6)); + double *correlation = reinterpret_cast(PG_GETARG_POINTER(6)); ivfflatcostestimate_internal(root, path, loopcount, startupcost, totalcost, selectivity, correlation); PG_RETURN_VOID(); -- Gitee From 2c92e36866c364b41cc661b026e51dc2212d07b5 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 14:17:30 +0800 Subject: [PATCH 33/67] clean code --- src/include/catalog/pg_amproc.h | 70 ++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index b321e9be0e..28102861fc 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -656,59 +656,59 @@ DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); //hnsw //vector_l2_ops -DATA(insert OID = 8924 ( 8371 8305 8305 1 8431 )); +DATA(insert OID = 8924 (8371 8305 8305 1 8431)); //vector_ip_ops -DATA(insert OID = 8925 ( 8372 8305 8305 1 8434 )); +DATA(insert OID = 8925 (8372 8305 8305 1 8434)); //vector_cosine_ops -DATA(insert OID = 8926 ( 8373 8305 8305 1 8434 )); -DATA(insert OID = 8947 ( 8373 8305 8305 2 8438 )); +DATA(insert OID = 8926 (8373 8305 8305 1 8434)); +DATA(insert OID = 8947 (8373 8305 8305 2 8438)); //vector_l1_ops -DATA(insert OID = 8927 ( 8374 8305 8305 1 8436 )); +DATA(insert OID = 8927 (8374 8305 8305 1 8436)); -DATA(insert OID = 8928 ( 8375 8306 8306 1 8451 )); -DATA(insert OID = 8929 ( 8376 8306 8306 1 8451 )); -DATA(insert OID = 8930 ( 8377 8306 8306 1 8451 )); -DATA(insert OID = 8931 ( 8378 8306 8306 1 8451 )); +DATA(insert OID = 8928 (8375 8306 8306 1 8451)); +DATA(insert OID = 8929 (8376 8306 8306 1 8451)); +DATA(insert OID = 8930 (8377 8306 8306 1 8451)); +DATA(insert OID = 8931 (8378 8306 8306 1 8451)); -DATA(insert OID = 8932 ( 8379 1560 1560 1 8462 )); -DATA(insert OID = 8933 ( 8380 1560 1560 1 8462 )); +DATA(insert OID = 8932 (8379 1560 1560 1 8462)); +DATA(insert OID = 8933 (8380 1560 1560 1 8462)); -DATA(insert OID = 8934 ( 8381 8307 8307 1 8470 )); -DATA(insert OID = 8954 ( 8381 8307 8307 3 8479 )); +DATA(insert OID = 8934 (8381 8307 8307 1 8470)); +DATA(insert OID = 8954 (8381 8307 8307 3 8479)); -DATA(insert OID = 8935 ( 8382 8307 8307 1 8463 )); -DATA(insert OID = 8955 ( 8382 8307 8307 3 8479 )); +DATA(insert OID = 8935 (8382 8307 8307 1 8463)); +DATA(insert OID = 8955 (8382 8307 8307 3 8479)); -DATA(insert OID = 8936 ( 8383 8307 8307 1 8463 )); -DATA(insert OID = 8956 ( 8383 8307 8307 2 8478 )); -DATA(insert OID = 8957 ( 8383 8307 8307 3 8479 )); +DATA(insert OID = 8936 (8383 8307 8307 1 8463)); +DATA(insert OID = 8956 (8383 8307 8307 2 8478)); +DATA(insert OID = 8957 (8383 8307 8307 3 8479)); -DATA(insert OID = 8937 ( 8384 8307 8307 1 8467 )); -DATA(insert OID = 8958 ( 8384 8307 8307 3 8479 )); +DATA(insert OID = 8937 (8384 8307 8307 1 8467)); +DATA(insert OID = 8958 (8384 8307 8307 3 8479)); //ivfflat //vector_l2_ops -DATA(insert OID = 8938 ( 8385 8305 8305 1 8431 )); -DATA(insert OID = 8939 ( 8385 8305 8305 3 8433 )); +DATA(insert OID = 8938 (8385 8305 8305 1 8431)); +DATA(insert OID = 8939 (8385 8305 8305 3 8433)); //vector_ip_ops -DATA(insert OID = 8940 ( 8386 8305 8305 1 8434 )); -DATA(insert OID = 8941 ( 8386 8305 8305 3 8432 )); -DATA(insert OID = 8942 ( 8386 8305 8305 4 8438 )); +DATA(insert OID = 8940 (8386 8305 8305 1 8434)); +DATA(insert OID = 8941 (8386 8305 8305 3 8432)); +DATA(insert OID = 8942 (8386 8305 8305 4 8438)); //vector_cosine_ops -DATA(insert OID = 8943 ( 8387 8305 8305 1 8434 )); -DATA(insert OID = 8944 ( 8387 8305 8305 2 8438 )); -DATA(insert OID = 8945 ( 8387 8305 8305 3 8432 )); -DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); +DATA(insert OID = 8943 (8387 8305 8305 1 8434)); +DATA(insert OID = 8944 (8387 8305 8305 2 8438)); +DATA(insert OID = 8945 (8387 8305 8305 3 8432)); +DATA(insert OID = 8946 (8387 8305 8305 4 8438)); //vector_l1_ops //DATA(insert OID = 8942 ( 8388 8305 8305 1 8450 )); -DATA(insert OID = 8948 ( 8389 8306 8306 1 8451 )); -DATA(insert OID = 8949 ( 8390 8306 8306 1 8451 )); -DATA(insert OID = 8950 ( 8391 8306 8306 1 8451 )); -DATA(insert OID = 8951 ( 8392 8306 8306 1 8451 )); +DATA(insert OID = 8948 (8389 8306 8306 1 8451)); +DATA(insert OID = 8949 (8390 8306 8306 1 8451)); +DATA(insert OID = 8950 (8391 8306 8306 1 8451)); +DATA(insert OID = 8951 (8392 8306 8306 1 8451)); -DATA(insert OID = 8952 ( 8393 1560 1560 1 8462 )); -DATA(insert OID = 8953 ( 8394 1560 1560 1 8462 )); +DATA(insert OID = 8952 (8393 1560 1560 1 8462)); +DATA(insert OID = 8953 (8394 1560 1560 1 8462)); #endif /* PG_AMPROC_H */ -- Gitee From 2a31a0627d743bd4badf752b3ceab330d2cf4845 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 14:43:29 +0800 Subject: [PATCH 34/67] clean code --- src/common/backend/utils/adt/halfvec.cpp | 2 +- src/common/backend/utils/adt/vector.cpp | 4 ++-- .../storage/access/datavec/hnswutils.cpp | 6 ++--- .../storage/access/datavec/ivfbuild.cpp | 2 +- src/include/access/datavec/hnsw.h | 4 ++-- src/include/access/datavec/ivfflat.h | 2 +- src/include/access/datavec/vector.h | 2 +- src/include/catalog/pg_amproc.h | 22 ++++++++----------- src/include/catalog/pg_opfamily.h | 2 +- 9 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/common/backend/utils/adt/halfvec.cpp b/src/common/backend/utils/adt/halfvec.cpp index 523b905427..c03616cd94 100644 --- a/src/common/backend/utils/adt/halfvec.cpp +++ b/src/common/backend/utils/adt/halfvec.cpp @@ -24,7 +24,7 @@ #endif #define STATE_DIMS(x) (ARR_DIMS(x)[0] - 1) -#define CreateStateDatums(dim) palloc(sizeof(Datum) * (dim + 1)) +#define CreateStateDatums(dim) palloc(sizeof(Datum) * ((dim) + 1)) /* * Get a half from a message buffer diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 4ba879dcfd..389f503296 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -32,7 +32,7 @@ #endif #define STATE_DIMS(x) (ARR_DIMS(x)[0] - 1) -#define CreateStateDatums(dim) palloc(sizeof(Datum) * (dim + 1)) +#define CreateStateDatums(dim) palloc(sizeof(Datum) * ((dim) + 1)) #if defined(USE_TARGET_CLONES) && !defined(__FMA__) #define VECTOR_TARGET_CLONES __attribute__((target_clones("default", "fma"))) @@ -1372,7 +1372,7 @@ int PlanCreateIndexWorkers(Relation heapRelation, IndexInfo *indexInfo) parallelWorkers = 0; } - /* disable parallel building index for system table*/ + /* disable parallel building index for system table */ if (IsCatalogRelation(heapRelation)) { parallelWorkers = 0; } diff --git a/src/gausskernel/storage/access/datavec/hnswutils.cpp b/src/gausskernel/storage/access/datavec/hnswutils.cpp index 9577cd0731..67db50e6ef 100644 --- a/src/gausskernel/storage/access/datavec/hnswutils.cpp +++ b/src/gausskernel/storage/access/datavec/hnswutils.cpp @@ -58,7 +58,7 @@ static uint32 hash_tid(ItemPointerData tid) #define SH_KEY_TYPE ItemPointerData #define SH_KEY tid #define SH_HASH_KEY(tb, key) hash_tid(key) -#define SH_EQUAL(tb, a, b) ItemPointerEquals(&a, &b) +#define SH_EQUAL(tb, a, b) ItemPointerEquals(&(a), &(b)) #define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" @@ -78,7 +78,7 @@ static uint32 hash_pointer(uintptr_t ptr) #define SH_KEY_TYPE uintptr_t #define SH_KEY ptr #define SH_HASH_KEY(tb, key) hash_pointer(key) -#define SH_EQUAL(tb, a, b) (a == b) +#define SH_EQUAL(tb, a, b) ((a) == (b)) #define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" @@ -98,7 +98,7 @@ static uint32 hash_offset(Size offset) #define SH_KEY_TYPE Size #define SH_KEY offset #define SH_HASH_KEY(tb, key) hash_offset(key) -#define SH_EQUAL(tb, a, b) (a == b) +#define SH_EQUAL(tb, a, b) ((a) == (b)) #define SH_SCOPE extern #define SH_DEFINE #include "lib/simplehash.h" diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index 2f25b622c6..659135cc8e 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -532,7 +532,7 @@ static double ParallelHeapScan(IvfflatBuildState *buildstate) BgworkerListWaitFinish(&buildstate->ivfleader->nparticipanttuplesorts); pg_memory_barrier(); - /*all done, update to the actual number of participants*/ + /* all done, update to the actual number of participants */ if (ivfshared->sharedsort != NULL) { ivfshared->sharedsort->actualParticipants = buildstate->ivfleader->nparticipanttuplesorts; } diff --git a/src/include/access/datavec/hnsw.h b/src/include/access/datavec/hnsw.h index 422ab54295..cb2bd468bd 100644 --- a/src/include/access/datavec/hnsw.h +++ b/src/include/access/datavec/hnsw.h @@ -122,7 +122,7 @@ qsort(list_arr, len, sizeof(ListCell *), cmp); \ \ new_list = (List *)palloc(sizeof(List)); \ - new_list->type = list->type; \ + new_list->type = (list->type); \ new_list->length = len; \ new_list->head = list_arr[len - 1]; \ new_list->tail = list_arr[0]; \ @@ -140,7 +140,7 @@ #define HnswIsNeighborTuple(tup) ((tup)->type == HNSW_NEIGHBOR_TUPLE_TYPE) /* 2 * M connections for ground layer */ -#define HnswGetLayerM(m, layer) (layer == 0 ? (m) * 2 : (m)) +#define HnswGetLayerM(m, layer) ((layer == 0) ? (m) * 2 : (m)) /* Optimal ML from paper */ #define HnswGetMl(m) (1 / log(m)) diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h index dab90c733d..d57c7e61be 100644 --- a/src/include/access/datavec/ivfflat.h +++ b/src/include/access/datavec/ivfflat.h @@ -51,7 +51,7 @@ #define PROGRESS_IVFFLAT_PHASE_ASSIGN 3 #define PROGRESS_IVFFLAT_PHASE_LOAD 4 -#define IVFFLAT_LIST_SIZE(size) (offsetof(IvfflatListData, center) + size) +#define IVFFLAT_LIST_SIZE(size) (offsetof(IvfflatListData, center) + (size)) #define IvfflatPageGetOpaque(page) ((IvfflatPageOpaque)PageGetSpecialPointer(page)) #define IvfflatPageGetMeta(page) ((IvfflatMetaPageData *)PageGetContents(page)) diff --git a/src/include/access/datavec/vector.h b/src/include/access/datavec/vector.h index 09160abef5..74c16feae7 100644 --- a/src/include/access/datavec/vector.h +++ b/src/include/access/datavec/vector.h @@ -8,7 +8,7 @@ #define DatumGetVector(x) ((Vector *)PG_DETOAST_DATUM(x)) #define PG_GETARG_VECTOR_P(x) DatumGetVector(PG_GETARG_DATUM(x)) #define PG_RETURN_VECTOR_P(x) PG_RETURN_POINTER(x) -#define UpdateProgress(index, val) ((void)val) +#define UpdateProgress(index, val) ((void)(val)) typedef struct Vector { int32 vl_len_; /* varlena header (do not touch directly!) */ diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 28102861fc..46c4312f51 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -654,15 +654,15 @@ DATA(insert ( 9570 9003 9003 1 5586 )); DATA(insert ( 8901 3831 3831 1 3870 )); DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); -//hnsw -//vector_l2_ops +/* hnsw */ +/* vector_l2_ops */ DATA(insert OID = 8924 (8371 8305 8305 1 8431)); -//vector_ip_ops +/* vector_ip_ops */ DATA(insert OID = 8925 (8372 8305 8305 1 8434)); -//vector_cosine_ops +/* vector_cosine_ops */ DATA(insert OID = 8926 (8373 8305 8305 1 8434)); DATA(insert OID = 8947 (8373 8305 8305 2 8438)); -//vector_l1_ops +/* vector_l1_ops */ DATA(insert OID = 8927 (8374 8305 8305 1 8436)); DATA(insert OID = 8928 (8375 8306 8306 1 8451)); @@ -686,23 +686,19 @@ DATA(insert OID = 8957 (8383 8307 8307 3 8479)); DATA(insert OID = 8937 (8384 8307 8307 1 8467)); DATA(insert OID = 8958 (8384 8307 8307 3 8479)); -//ivfflat -//vector_l2_ops +/* ivfflat */ +/* vector_l2_ops */ DATA(insert OID = 8938 (8385 8305 8305 1 8431)); DATA(insert OID = 8939 (8385 8305 8305 3 8433)); -//vector_ip_ops +/* vector_ip_ops */ DATA(insert OID = 8940 (8386 8305 8305 1 8434)); DATA(insert OID = 8941 (8386 8305 8305 3 8432)); DATA(insert OID = 8942 (8386 8305 8305 4 8438)); -//vector_cosine_ops +/* vector_cosine_ops */ DATA(insert OID = 8943 (8387 8305 8305 1 8434)); DATA(insert OID = 8944 (8387 8305 8305 2 8438)); DATA(insert OID = 8945 (8387 8305 8305 3 8432)); DATA(insert OID = 8946 (8387 8305 8305 4 8438)); -//vector_l1_ops -//DATA(insert OID = 8942 ( 8388 8305 8305 1 8450 )); - - DATA(insert OID = 8948 (8389 8306 8306 1 8451)); DATA(insert OID = 8949 (8390 8306 8306 1 8451)); diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 9d8bba0e5d..172235c1ba 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -199,7 +199,7 @@ DATA(insert OID = 4262 (4239 int1_ops PGNSP PGUID)); DATA(insert OID = 4263 (4239 bool_ops PGNSP PGUID)); DATA(insert OID = 4264 (4239 smalldatetime_ops PGNSP PGUID)); -/*datavec index ops*/ +/* datavec index ops */ DATA(insert OID = 8371 (8300 vector_l2_ops PGNSP PGUID)); DATA(insert OID = 8372 (8300 vector_ip_ops PGNSP PGUID)); DATA(insert OID = 8373 (8300 vector_cosine_ops PGNSP PGUID)); -- Gitee From 3d2581819983f1b42f8281e6934cb8c0b8abc996 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 15:00:47 +0800 Subject: [PATCH 35/67] clean code --- .../storage/access/datavec/hnswbuild.cpp | 3 ++- .../storage/access/datavec/ivfbuild.cpp | 11 ++++++++--- .../storage/access/datavec/ivfscan.cpp | 13 +++++++++---- src/include/access/datavec/ivfflat.h | 3 ++- src/include/access/datavec/ryu_common.h | 15 +++++++++++---- 5 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/gausskernel/storage/access/datavec/hnswbuild.cpp b/src/gausskernel/storage/access/datavec/hnswbuild.cpp index c8708ae3c4..af04d6f6ca 100644 --- a/src/gausskernel/storage/access/datavec/hnswbuild.cpp +++ b/src/gausskernel/storage/access/datavec/hnswbuild.cpp @@ -621,7 +621,8 @@ static bool InsertTuple(Relation index, Datum *values, const bool *isnull, ItemP LWLockRelease(&graph->allocatorLock); /* Copy the datum */ - memcpy(valuePtr, DatumGetPointer(value), valueSize); + errno_t rc = memcpy_s(valuePtr, valueSize, DatumGetPointer(value), valueSize); + securec_check(rc, "\0", "\0"); HnswPtrStore(base, element->value, valuePtr); /* Create a lock for the element */ diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index 659135cc8e..3c4a8f4323 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -442,6 +442,7 @@ static void CreateListPages(Relation index, VectorArray centers, int dimensions, GenericXLogState *state; Size listSize; IvfflatList list; + errno_t rc = EOK; listSize = MAXALIGN(IVFFLAT_LIST_SIZE(centers->itemsize)); list = (IvfflatList)palloc0(listSize); @@ -458,7 +459,8 @@ static void CreateListPages(Relation index, VectorArray centers, int dimensions, /* Load list */ list->startPage = InvalidBlockNumber; list->insertPage = InvalidBlockNumber; - memcpy(&list->center, VectorArrayGet(centers, i), VARSIZE_ANY(VectorArrayGet(centers, i))); + rc = memcpy_s(&list->center, VARSIZE_ANY(VectorArrayGet(centers, i)), VectorArrayGet(centers, i), VARSIZE_ANY(VectorArrayGet(centers, i))); + securec_check(rc, "\0", "\0"); /* Ensure free space */ if (PageGetFreeSpace(page) < listSize) @@ -556,6 +558,7 @@ static void IvfflatParallelScanAndSort(IvfflatSpool *ivfspool, IvfflatShared *iv TableScanDesc scan; double reltuples; IndexInfo *indexInfo; + errno_t rc = EOK; /* Sort options, which must match AssignTuples */ AttrNumber attNums[] = {1}; @@ -575,7 +578,8 @@ static void IvfflatParallelScanAndSort(IvfflatSpool *ivfspool, IvfflatShared *iv indexInfo = BuildIndexInfo(ivfspool->index); indexInfo->ii_Concurrent = false; InitBuildState(&buildstate, ivfspool->heap, ivfspool->index, indexInfo); - memcpy(buildstate.centers->items, ivfcenters, VECTOR_SIZE(buildstate.centers->dim) * buildstate.centers->maxlen); + rc = memcpy_s(buildstate.centers->items, VECTOR_SIZE(buildstate.centers->dim) * buildstate.centers->maxlen, ivfcenters, VECTOR_SIZE(buildstate.centers->dim) * buildstate.centers->maxlen); + securec_check(rc, "\0", "\0"); buildstate.centers->length = buildstate.centers->maxlen; ivfspool->sortstate = tuplesort_begin_heap(buildstate.tupdesc, 1, attNums, sortOperators, sortCollations, nullsFirstFlags, sortmem, false, 0, 0, 1, coordinate); @@ -681,7 +685,8 @@ static IvfflatShared *IvfflatParallelInitshared(IvfflatBuildState *buildstate, i estcenters = VECTOR_SIZE(buildstate->dimensions) * buildstate->lists; ivfcenters = (char *)MemoryContextAllocZero(INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), estcenters); - memcpy(ivfcenters, buildstate->centers->items, estcenters); + errno_t rc = memcpy_s(ivfcenters, estcenters, buildstate->centers->items, estcenters); + securec_check(rc, "\0", "\0"); ivfshared->ivfcenters = (Vector *)ivfcenters; return ivfshared; diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index ce8815bd9f..f495230310 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -262,6 +262,7 @@ IndexScanDesc ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys) { IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; + errno_t rc = EOK; #if PG_VERSION_NUM >= 130000 if (!so->first) @@ -271,11 +272,15 @@ void ivfflatrescan_internal(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey so->first = true; pairingheap_reset(so->listQueue); - if (keys && scan->numberOfKeys > 0) - memmove(scan->keyData, keys, scan->numberOfKeys * sizeof(ScanKeyData)); + if (keys && scan->numberOfKeys > 0) { + rc = memmove_s(scan->keyData, scan->numberOfKeys * sizeof(ScanKeyData), keys, scan->numberOfKeys * sizeof(ScanKeyData)); + securec_check(rc, "\0", "\0"); + } - if (orderbys && scan->numberOfOrderBys > 0) - memmove(scan->orderByData, orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); + if (orderbys && scan->numberOfOrderBys > 0) { + rc = memmove_s(scan->orderByData, scan->numberOfOrderBys * sizeof(ScanKeyData), orderbys, scan->numberOfOrderBys * sizeof(ScanKeyData)); + securec_check(rc, "\0", "\0"); + } } /* diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h index d57c7e61be..c722709b23 100644 --- a/src/include/access/datavec/ivfflat.h +++ b/src/include/access/datavec/ivfflat.h @@ -262,7 +262,8 @@ static inline Pointer VectorArrayGet(VectorArray arr, int offset) static inline void VectorArraySet(VectorArray arr, int offset, Pointer val) { - memcpy(VectorArrayGet(arr, offset), val, VARSIZE_ANY(val)); + errno_t rc = memcpy_s(VectorArrayGet(arr, offset), VARSIZE_ANY(val), val, VARSIZE_ANY(val)); + securec_check(rc, "\0", "\0"); } /* Methods */ diff --git a/src/include/access/datavec/ryu_common.h b/src/include/access/datavec/ryu_common.h index 8713d39474..db983c5474 100644 --- a/src/include/access/datavec/ryu_common.h +++ b/src/include/access/datavec/ryu_common.h @@ -105,15 +105,18 @@ static inline int32 log10Pow5(const int32 e) static inline int copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) { + errno_t rc = EOK; if (mantissa) { - memcpy(result, "NaN", 3); + rc = memcpy_s(result, 3, "NaN", 3); + securec_check(rc, "\0", "\0"); return 3; } if (sign) { result[0] = '-'; } if (exponent) { - memcpy(result + sign, "Infinity", 8); + rc = memcpy_s(result + sign, 8, "Infinity", 8); + securec_check(rc, "\0", "\0"); return sign + 8; } result[sign] = '0'; @@ -123,16 +126,20 @@ static inline int copy_special_str(char *const result, const bool sign, const bo static inline uint32 float_to_bits(const float f) { uint32 bits = 0; + errno_t rc = EOK; - memcpy(&bits, &f, sizeof(float)); + rc = memcpy_s(&bits, sizeof(float), &f, sizeof(float)); + securec_check(rc, "\0", "\0"); return bits; } static inline uint64 double_to_bits(const double d) { uint64 bits = 0; + errno_t rc = EOK; - memcpy(&bits, &d, sizeof(double)); + rc = memcpy(&bits, sizeof(double), &d, sizeof(double)); + securec_check(rc, "\0", "\0"); return bits; } -- Gitee From 2d8fc9a2142b64f457ee6fa84f6afa889e747996 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Sat, 2 Nov 2024 15:29:55 +0800 Subject: [PATCH 36/67] =?UTF-8?q?halfvec=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 94 +++++++++++++- src/include/catalog/pg_amop.data | 42 ++---- src/include/catalog/pg_amproc.h | 130 +++++++++++-------- src/include/catalog/pg_opclass.h | 4 +- src/include/catalog/pg_opfamily.h | 3 +- 5 files changed, 179 insertions(+), 94 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index abf43152a5..c5fcc76245 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13323,31 +13323,31 @@ AddFuncGroup( ), AddFuncGroup( "halfvec_cmp", 1, - AddBuiltinFunc(_0(8451), _1("halfvec_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8451), _1("halfvec_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_in", 1, - AddBuiltinFunc(_0(8452), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8452), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_out", 1, - AddBuiltinFunc(_0(8453), _1("halfvec_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8453), _1("halfvec_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_typmod_in", 1, - AddBuiltinFunc(_0(8454), _1("halfvec_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8454), _1("halfvec_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_recv", 1, - AddBuiltinFunc(_0(8455), _1("halfvec_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8455), _1("halfvec_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_send", 1, - AddBuiltinFunc(_0(8456), _1("halfvec_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8456), _1("halfvec_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_negative_inner_product", 1, - AddBuiltinFunc(_0(8457), _1("halfvec_negative_inner_product"), _2(1), _3(true), _4(false), _5(halfvec_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8457), _1("halfvec_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_in", 1, @@ -13437,3 +13437,83 @@ AddFuncGroup( "hnsw_sparsevec_support", 1, AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(3), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + + AddFuncGroup( + "halfvec_l2_squared_distance", 1, + AddBuiltinFunc(_0(8480), _1("halfvec_l2_squared_distance"), _2(1), _3(true), _4(false), _5(vector_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_spherical_distance", 1, + AddBuiltinFunc(_0(8481), _1("halfvec_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "l2_distance", 1, + AddBuiltinFunc(_0(8482), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "l1_distance", 1, + AddBuiltinFunc(_0(8483), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "inner_product", 1, + AddBuiltinFunc(_0(8484), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "l2_norm", 1, + AddBuiltinFunc(_0(8485), _1("l2_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "hnsw_halfvec_support", 1, + AddBuiltinFunc(_0(8486), _1("hnsw_halfvec_support"), _2(3), _3(true), _4(false), _5(hnsw_halfvec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_halfvec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflat_halfvec_support", 1, + AddBuiltinFunc(_0(8487), _1("ivfflat_halfvec_support"), _2(3), _3(true), _4(false), _5(ivfflat_halfvec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_halfvec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + AddFuncGroup( + "halfvec_add", 1, + AddBuiltinFunc(_0(8488), _1("halfvec_add"), _2(1), _3(true), _4(false), _5(vector_add), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_add"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_sub", 1, + AddBuiltinFunc(_0(8489), _1("halfvec_sub"), _2(1), _3(true), _4(false), _5(vector_sub), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_lt", 1, + AddBuiltinFunc(_0(8490), _1("halfvec_lt"), _2(1), _3(true), _4(false), _5(vector_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_le", 1, + AddBuiltinFunc(_0(8491), _1("halfvec_le"), _2(1), _3(true), _4(false), _5(vector_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_eq", 1, + AddBuiltinFunc(_0(8493), _1("halfvec_eq"), _2(1), _3(true), _4(false), _5(vector_eq), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_ne", 1, + AddBuiltinFunc(_0(8494), _1("halfvec_ne"), _2(1), _3(true), _4(false), _5(vector_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_ge", 1, + AddBuiltinFunc(_0(8495), _1("halfvec_ge"), _2(1), _3(true), _4(false), _5(vector_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_gt", 1, + AddBuiltinFunc(_0(8496), _1("halfvec_gt"), _2(1), _3(true), _4(false), _5(vector_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_accum", 1, + AddBuiltinFunc(_0(8497), _1("halfvec_accum"), _2(1), _3(true), _4(false), _5(vector_accum), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_combine", 1, + AddBuiltinFunc(_0(8498), _1("halfvec_combine"), _2(1), _3(true), _4(false), _5(vector_combine), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_avg", 1, + AddBuiltinFunc(_0(8499), _1("halfvec_avg"), _2(1), _3(true), _4(false), _5(vector_avg), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), \ No newline at end of file diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 51d7ca5ea1..8fb93a58e3 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1605,21 +1605,12 @@ DATA(insert OID = 6061 ( 8374 8305 8305 1 o 8314 8300 1970 )); DATA(insert OID = 6036 ( 8375 8306 8306 1 o 8315 8300 1970 )); -DATA(insert OID = 6136 ( 8375 8306 8306 2 o 8316 8300 1970 )); -DATA(insert OID = 6236 ( 8375 8306 8306 3 o 8317 8300 1970 )); -DATA(insert OID = 6336 ( 8375 8306 8306 4 o 8318 8300 1970 )); -DATA(insert OID = 6046 ( 8376 8306 8306 1 o 8315 8300 1970 )); -DATA(insert OID = 6146 ( 8376 8306 8306 2 o 8316 8300 1970 )); -DATA(insert OID = 6246 ( 8376 8306 8306 3 o 8317 8300 1970 )); -DATA(insert OID = 6346 ( 8376 8306 8306 4 o 8318 8300 1970 )); -DATA(insert OID = 6056 ( 8377 8306 8306 1 o 8315 8300 1970 )); -DATA(insert OID = 6156 ( 8377 8306 8306 2 o 8316 8300 1970 )); -DATA(insert OID = 6256 ( 8377 8306 8306 3 o 8317 8300 1970 )); -DATA(insert OID = 6356 ( 8377 8306 8306 4 o 8318 8300 1970 )); -DATA(insert OID = 6066 ( 8378 8306 8306 1 o 8315 8300 1970 )); -DATA(insert OID = 6166 ( 8378 8306 8306 2 o 8316 8300 1970 )); -DATA(insert OID = 6266 ( 8378 8306 8306 3 o 8317 8300 1970 )); -DATA(insert OID = 6366 ( 8378 8306 8306 4 o 8318 8300 424 )); + +DATA(insert OID = 6046 ( 8376 8306 8306 1 o 8316 8300 1970 )); + +DATA(insert OID = 6056 ( 8377 8306 8306 1 o 8317 8300 1970 )); + +DATA(insert OID = 6066 ( 8378 8306 8306 1 o 8318 8300 1970 )); DATA(insert OID = 6091 ( 8381 8307 8307 1 o 8319 8300 1970 )); @@ -1657,21 +1648,12 @@ DATA(insert OID = 6119 ( 8387 8305 8305 1 o 8313 8301 1970 )); DATA(insert OID = 6127 ( 8389 8306 8306 1 o 8315 8301 1970 )); -DATA(insert OID = 6128 ( 8389 8306 8306 2 o 8316 8301 1970 )); -DATA(insert OID = 6129 ( 8389 8306 8306 3 o 8317 8301 1970 )); -DATA(insert OID = 6130 ( 8389 8306 8306 4 o 8318 8301 1970 )); -DATA(insert OID = 6131 ( 8390 8306 8306 1 o 8315 8301 1970 )); -DATA(insert OID = 6132 ( 8390 8306 8306 2 o 8316 8301 1970 )); -DATA(insert OID = 6133 ( 8390 8306 8306 3 o 8317 8301 1970 )); -DATA(insert OID = 6134 ( 8390 8306 8306 4 o 8318 8301 1970 )); -DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8315 8301 1970 )); -DATA(insert OID = 6137 ( 8391 8306 8306 2 o 8316 8301 1970 )); -DATA(insert OID = 6138 ( 8391 8306 8306 3 o 8317 8301 1970 )); -DATA(insert OID = 6139 ( 8391 8306 8306 4 o 8318 8301 1970 )); -DATA(insert OID = 6140 ( 8392 8306 8306 1 o 8315 8301 1970 )); -DATA(insert OID = 6141 ( 8392 8306 8306 2 o 8316 8301 1970 )); -DATA(insert OID = 6142 ( 8392 8306 8306 3 o 8317 8301 1970 )); -DATA(insert OID = 6143 ( 8392 8306 8306 4 o 8318 8301 1970 )); + +DATA(insert OID = 6131 ( 8390 8306 8306 1 o 8316 8301 1970 )); + +DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8317 8301 1970 )); + + diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 46c4312f51..1e7c50c00d 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -654,57 +654,81 @@ DATA(insert ( 9570 9003 9003 1 5586 )); DATA(insert ( 8901 3831 3831 1 3870 )); DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); -/* hnsw */ -/* vector_l2_ops */ -DATA(insert OID = 8924 (8371 8305 8305 1 8431)); -/* vector_ip_ops */ -DATA(insert OID = 8925 (8372 8305 8305 1 8434)); -/* vector_cosine_ops */ -DATA(insert OID = 8926 (8373 8305 8305 1 8434)); -DATA(insert OID = 8947 (8373 8305 8305 2 8438)); -/* vector_l1_ops */ -DATA(insert OID = 8927 (8374 8305 8305 1 8436)); - -DATA(insert OID = 8928 (8375 8306 8306 1 8451)); -DATA(insert OID = 8929 (8376 8306 8306 1 8451)); -DATA(insert OID = 8930 (8377 8306 8306 1 8451)); -DATA(insert OID = 8931 (8378 8306 8306 1 8451)); - -DATA(insert OID = 8932 (8379 1560 1560 1 8462)); -DATA(insert OID = 8933 (8380 1560 1560 1 8462)); - -DATA(insert OID = 8934 (8381 8307 8307 1 8470)); -DATA(insert OID = 8954 (8381 8307 8307 3 8479)); - -DATA(insert OID = 8935 (8382 8307 8307 1 8463)); -DATA(insert OID = 8955 (8382 8307 8307 3 8479)); - -DATA(insert OID = 8936 (8383 8307 8307 1 8463)); -DATA(insert OID = 8956 (8383 8307 8307 2 8478)); -DATA(insert OID = 8957 (8383 8307 8307 3 8479)); - -DATA(insert OID = 8937 (8384 8307 8307 1 8467)); -DATA(insert OID = 8958 (8384 8307 8307 3 8479)); - -/* ivfflat */ -/* vector_l2_ops */ -DATA(insert OID = 8938 (8385 8305 8305 1 8431)); -DATA(insert OID = 8939 (8385 8305 8305 3 8433)); -/* vector_ip_ops */ -DATA(insert OID = 8940 (8386 8305 8305 1 8434)); -DATA(insert OID = 8941 (8386 8305 8305 3 8432)); -DATA(insert OID = 8942 (8386 8305 8305 4 8438)); -/* vector_cosine_ops */ -DATA(insert OID = 8943 (8387 8305 8305 1 8434)); -DATA(insert OID = 8944 (8387 8305 8305 2 8438)); -DATA(insert OID = 8945 (8387 8305 8305 3 8432)); -DATA(insert OID = 8946 (8387 8305 8305 4 8438)); - -DATA(insert OID = 8948 (8389 8306 8306 1 8451)); -DATA(insert OID = 8949 (8390 8306 8306 1 8451)); -DATA(insert OID = 8950 (8391 8306 8306 1 8451)); -DATA(insert OID = 8951 (8392 8306 8306 1 8451)); - -DATA(insert OID = 8952 (8393 1560 1560 1 8462)); -DATA(insert OID = 8953 (8394 1560 1560 1 8462)); +//hnsw +//vector_l2_ops +DATA(insert OID = 8924 ( 8371 8305 8305 1 8431 )); +//vector_ip_ops +DATA(insert OID = 8925 ( 8372 8305 8305 1 8434 )); +//vector_cosine_ops +DATA(insert OID = 8926 ( 8373 8305 8305 1 8434 )); +DATA(insert OID = 8947 ( 8373 8305 8305 2 8438 )); +//vector_l1_ops +DATA(insert OID = 8927 ( 8374 8305 8305 1 8436 )); + +DATA(insert OID = 8928 ( 8375 8306 8306 1 8480 )); +DATA(insert OID = 8959 ( 8375 8306 8306 3 8486 )); + +DATA(insert OID = 8929 ( 8376 8306 8306 1 8457 )); +DATA(insert OID = 8960 ( 8376 8306 8306 3 8486 )); + +DATA(insert OID = 8930 ( 8377 8306 8306 1 8457 )); +DATA(insert OID = 8961 ( 8377 8306 8306 2 8485 )); +DATA(insert OID = 8962 ( 8377 8306 8306 3 8486 )); + +DATA(insert OID = 8931 ( 8378 8306 8306 1 8483 )); +DATA(insert OID = 8963 ( 8378 8306 8306 3 8486 )); + +DATA(insert OID = 8932 ( 8379 1560 1560 1 8462 )); +DATA(insert OID = 8933 ( 8380 1560 1560 1 8462 )); + +DATA(insert OID = 8934 ( 8381 8307 8307 1 8470 )); +DATA(insert OID = 8954 ( 8381 8307 8307 3 8479 )); + +DATA(insert OID = 8935 ( 8382 8307 8307 1 8463 )); +DATA(insert OID = 8955 ( 8382 8307 8307 3 8479 )); + +DATA(insert OID = 8936 ( 8383 8307 8307 1 8463 )); +DATA(insert OID = 8956 ( 8383 8307 8307 2 8478 )); +DATA(insert OID = 8957 ( 8383 8307 8307 3 8479 )); + +DATA(insert OID = 8937 ( 8384 8307 8307 1 8467 )); +DATA(insert OID = 8958 ( 8384 8307 8307 3 8479 )); + +//ivfflat +//vector_l2_ops +DATA(insert OID = 8938 ( 8385 8305 8305 1 8431 )); +DATA(insert OID = 8939 ( 8385 8305 8305 3 8433 )); +//vector_ip_ops +DATA(insert OID = 8940 ( 8386 8305 8305 1 8434 )); +DATA(insert OID = 8941 ( 8386 8305 8305 3 8432 )); +DATA(insert OID = 8942 ( 8386 8305 8305 4 8438 )); +//vector_cosine_ops +DATA(insert OID = 8943 ( 8387 8305 8305 1 8434 )); +DATA(insert OID = 8944 ( 8387 8305 8305 2 8438 )); +DATA(insert OID = 8945 ( 8387 8305 8305 3 8432 )); +DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); +//vector_l1_ops +//DATA(insert OID = 8942 ( 8388 8305 8305 1 8450 )); + + + +DATA(insert OID = 8948 ( 8389 8306 8306 1 8480 )); +DATA(insert OID = 8964 ( 8389 8306 8306 3 8482 )); +DATA(insert OID = 8965 ( 8389 8306 8306 5 8487 )); + +DATA(insert OID = 8949 ( 8390 8306 8306 1 8457 )); +DATA(insert OID = 8966 ( 8390 8306 8306 3 8481 )); +DATA(insert OID = 8967 ( 8390 8306 8306 4 8485 )); +DATA(insert OID = 8968 ( 8390 8306 8306 5 8487 )); + +DATA(insert OID = 8950 ( 8391 8306 8306 1 8457 )); +DATA(insert OID = 8969 ( 8391 8306 8306 2 8485 )); +DATA(insert OID = 8970 ( 8391 8306 8306 3 8481 )); +DATA(insert OID = 8971 ( 8391 8306 8306 4 8485 )); +DATA(insert OID = 8972 ( 8391 8306 8306 5 8487 )); + + + +DATA(insert OID = 8952 ( 8393 1560 1560 1 8462 )); +DATA(insert OID = 8953 ( 8394 1560 1560 1 8462 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 4e7a2b253a..6b332d0539 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -379,6 +379,7 @@ DATA(insert OID = 8900 (8300 vector_l2_ops PGNSP PGUID 8371 8305 t 0)); DATA(insert OID = 8999 (8300 vector_ip_ops PGNSP PGUID 8372 8305 t 0)); DATA(insert OID = 8902 (8300 vector_cosine_ops PGNSP PGUID 8373 8305 t 0)); DATA(insert OID = 8903 (8300 vector_l1_ops PGNSP PGUID 8374 8305 t 0)); + DATA(insert OID = 8904 (8300 halfvec_l2_ops PGNSP PGUID 8375 8306 t 0)); DATA(insert OID = 8905 (8300 halfvec_ip_ops PGNSP PGUID 8376 8306 t 0)); DATA(insert OID = 8906 (8300 halfvec_cosine_ops PGNSP PGUID 8377 8306 t 0)); @@ -395,12 +396,11 @@ DATA(insert OID = 8913 (8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 t 0)); DATA(insert OID = 8914 (8301 vector_l2_ops PGNSP PGUID 8385 8305 t 0)); DATA(insert OID = 8915 (8301 vector_ip_ops PGNSP PGUID 8386 8305 t 0)); DATA(insert OID = 8916 (8301 vector_cosine_ops PGNSP PGUID 8387 8305 t 0)); -DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0)); +DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0 )); DATA(insert OID = 8918 (8301 halfvec_l2_ops PGNSP PGUID 8389 8306 t 0)); DATA(insert OID = 8919 (8301 halfvec_ip_ops PGNSP PGUID 8390 8306 t 0)); DATA(insert OID = 8920 (8301 halfvec_cosine_ops PGNSP PGUID 8391 8306 t 0)); -DATA(insert OID = 8921 (8301 halfvec_l1_ops PGNSP PGUID 8392 8306 t 0)); DATA(insert OID = 8922 (8301 bit_jaccard_ops PGNSP PGUID 8393 1560 t 0)); DATA(insert OID = 8923 (8301 bit_hamming_ops PGNSP PGUID 8394 1560 t 0)); diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 172235c1ba..433df5528e 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -199,7 +199,7 @@ DATA(insert OID = 4262 (4239 int1_ops PGNSP PGUID)); DATA(insert OID = 4263 (4239 bool_ops PGNSP PGUID)); DATA(insert OID = 4264 (4239 smalldatetime_ops PGNSP PGUID)); -/* datavec index ops */ +/*datavec index ops*/ DATA(insert OID = 8371 (8300 vector_l2_ops PGNSP PGUID)); DATA(insert OID = 8372 (8300 vector_ip_ops PGNSP PGUID)); DATA(insert OID = 8373 (8300 vector_cosine_ops PGNSP PGUID)); @@ -226,7 +226,6 @@ DATA(insert OID = 8388 (8301 vector_l1_ops PGNSP PGUID)); DATA(insert OID = 8389 (8301 halfvec_l2_ops PGNSP PGUID)); DATA(insert OID = 8390 (8301 halfvec_ip_ops PGNSP PGUID)); DATA(insert OID = 8391 (8301 halfvec_cosine_ops PGNSP PGUID)); -DATA(insert OID = 8392 (8301 halfvec_l1_ops PGNSP PGUID)); DATA(insert OID = 8393 (8301 bit_jaccard_ops PGNSP PGUID)); DATA(insert OID = 8394 (8301 bit_hamming_ops PGNSP PGUID)); -- Gitee From 147c50206f1fa16e46cd9895fda4efd8f9b1bcc4 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Sat, 2 Nov 2024 15:34:59 +0800 Subject: [PATCH 37/67] clean code --- src/include/access/datavec/ryu_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/access/datavec/ryu_common.h b/src/include/access/datavec/ryu_common.h index db983c5474..3d61a5c06b 100644 --- a/src/include/access/datavec/ryu_common.h +++ b/src/include/access/datavec/ryu_common.h @@ -138,7 +138,7 @@ static inline uint64 double_to_bits(const double d) uint64 bits = 0; errno_t rc = EOK; - rc = memcpy(&bits, sizeof(double), &d, sizeof(double)); + rc = memcpy_s(&bits, sizeof(double), &d, sizeof(double)); securec_check(rc, "\0", "\0"); return bits; } -- Gitee From bfefcd4e71d828e30f2fa961ef7317829f8e1600 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Sat, 2 Nov 2024 20:47:09 +0800 Subject: [PATCH 38/67] =?UTF-8?q?=E5=8E=BB=E9=87=8D=EF=BC=8C=E5=8A=A0build?= =?UTF-8?q?in=E5=87=BD=E6=95=B0=EF=BC=8C=E6=95=B4=E7=90=86bit=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 125 ++++++++++++------- src/include/catalog/pg_amop.data | 8 +- src/include/catalog/pg_amproc.h | 12 +- src/include/catalog/pg_operator.data | 48 ++++--- 4 files changed, 126 insertions(+), 67 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index c5fcc76245..f3227329e7 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13250,24 +13250,28 @@ AddFuncGroup( AddBuiltinFunc(_0(8432), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l2_distance", 1, - AddBuiltinFunc(_0(8433), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "l2_distance", 2, + AddBuiltinFunc(_0(8433), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8465), _1("l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_negative_inner_product", 1, AddBuiltinFunc(_0(8434), _1("vector_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "cosine_distance", 1, - AddBuiltinFunc(_0(8435), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "cosine_distance", 2, + AddBuiltinFunc(_0(8435), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8466), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l1_distance", 1, - AddBuiltinFunc(_0(8436), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "l1_distance", 2, + AddBuiltinFunc(_0(8436), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8467), _1("l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "inner_product", 1, - AddBuiltinFunc(_0(8437), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "inner_product", 2, + AddBuiltinFunc(_0(8437), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8471), _1("inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_norm", 1, @@ -13377,34 +13381,19 @@ AddFuncGroup( "sparsevec_cmp", 1, AddBuiltinFunc(_0(8464), _1("sparsevec_cmp"), _2(1), _3(true), _4(false), _5(sparsevec_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "sparsevec_l2_distance", 1, - AddBuiltinFunc(_0(8465), _1("sparsevec_l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "sparsevec_cosine_distance", 1, - AddBuiltinFunc(_0(8466), _1("sparsevec_cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "sparsevec_l1_distance", 1, - AddBuiltinFunc(_0(8467), _1("sparsevec_l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), + AddFuncGroup( "jaccard_distance", 1, - AddBuiltinFunc(_0(8468), _1("jaccard_distance"), _2(1), _3(true), _4(false), _5(jaccard_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8468), _1("jaccard_distance"), _2(2), _3(true), _4(false), _5(jaccard_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("jaccard_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "hamming_distance", 1, - AddBuiltinFunc(_0(8469), _1("hamming_distance"), _2(1), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8469), _1("hamming_distance"), _2(2), _3(true), _4(false), _5(hamming_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 1560, 1560), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hamming_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "sparsevec_l2_squared_distance", 1, AddBuiltinFunc(_0(8470), _1("sparsevec_l2_squared_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "sparsevec_inner_product", 1, - AddBuiltinFunc(_0(8471), _1("sparsevec_inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), AddFuncGroup( "sparsevec_lt", 1, AddBuiltinFunc(_0(8472), _1("sparsevec_lt"), _2(1), _3(true), _4(false), _5(sparsevec_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13429,13 +13418,10 @@ AddFuncGroup( "sparsevec_gt", 1, AddBuiltinFunc(_0(8477), _1("sparsevec_gt"), _2(1), _3(true), _4(false), _5(sparsevec_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "sparsevec_l2_norm", 1, - AddBuiltinFunc(_0(8478), _1("sparsevec_l2_norm"), _2(1), _3(true), _4(false), _5(sparsevec_l2_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), + AddFuncGroup( "hnsw_sparsevec_support", 1, - AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(3), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(0), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13447,22 +13433,10 @@ AddFuncGroup( AddBuiltinFunc(_0(8481), _1("halfvec_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l2_distance", 1, - AddBuiltinFunc(_0(8482), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "l1_distance", 1, - AddBuiltinFunc(_0(8483), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "inner_product", 1, - AddBuiltinFunc(_0(8484), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "l2_norm", 2, + AddBuiltinFunc(_0(8485), _1("l2_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8478), _1("l2_norm"), _2(1), _3(true), _4(false), _5(sparsevec_l2_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "l2_norm", 1, - AddBuiltinFunc(_0(8485), _1("l2_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( "hnsw_halfvec_support", 1, AddBuiltinFunc(_0(8486), _1("hnsw_halfvec_support"), _2(3), _3(true), _4(false), _5(hnsw_halfvec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_halfvec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13516,4 +13490,63 @@ AddFuncGroup( AddFuncGroup( "halfvec_avg", 1, AddBuiltinFunc(_0(8499), _1("halfvec_avg"), _2(1), _3(true), _4(false), _5(vector_avg), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + AddFuncGroup( + "l2_normalize", 2, + AddBuiltinFunc(_0(8200), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(l2_normalize), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8200), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(sparsevec_l2_normalize), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "binary_quantize", 1, + AddBuiltinFunc(_0(8201), _1("binary_quantize"), _2(3), _3(true), _4(false), _5(binary_quantize), _6(1562), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8305, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("binary_quantize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "subvector", 1, + AddBuiltinFunc(_0(8202), _1("subvector"), _2(1), _3(true), _4(false), _5(subvector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8305, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("subvector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_mul", 1, + AddBuiltinFunc(_0(8203), _1("vector_mul"), _2(1), _3(true), _4(false), _5(vector_mul), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_mul"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_concat", 1, + AddBuiltinFunc(_0(8204), _1("vector_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflatvalidate", 1, + AddBuiltinFunc(_0(8205), _1("ivfflatvalidate"), _2(1), _3(true), _4(false), _5(ivfflatvalidate), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 26), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflatvalidate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflathandler", 1, + AddBuiltinFunc(_0(8206), _1("ivfflathandler"), _2(0), _3(true), _4(false), _5(ivfflathandler), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflathandler"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswvalidate", 1, + AddBuiltinFunc(_0(8207), _1("hnswvalidate"), _2(1), _3(true), _4(false), _5(hnswvalidate), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 26), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswvalidate"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnswhandler", 1, + AddBuiltinFunc(_0(8208), _1("hnswhandler"), _2(0), _3(true), _4(false), _5(hnswhandler), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnswhandler"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "hnsw_bit_support", 1, + AddBuiltinFunc(_0(8209), _1("hnsw_bit_support"), _2(1), _3(true), _4(false), _5(hnsw_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "ivfflat_bit_support", 1, + AddBuiltinFunc(_0(8210), _1("ivfflat_bit_support"), _2(1), _3(true), _4(false), _5(ivfflat_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_dims", 1, + AddBuiltinFunc(_0(8428), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_mul", 1, + AddBuiltinFunc(_0(8203), _1("halfvec_mul"), _2(1), _3(true), _4(false), _5(vector_mul), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_mul"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_concat", 1, + AddBuiltinFunc(_0(8204), _1("halfvec_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), \ No newline at end of file diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 8fb93a58e3..fe446ef8e3 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1625,10 +1625,11 @@ DATA(insert OID = 6103 ( 8384 8307 8307 1 o 8322 8300 1970 )); -DATA(insert OID = 6107 ( 8379 1560 1560 1 o 8323 8300 1970 )); -DATA(insert OID = 6108 ( 8379 1560 1560 2 o 8324 8300 1970 )); +DATA(insert OID = 6107 ( 8379 1560 1560 1 o 8324 8300 1970 )); + + DATA(insert OID = 6109 ( 8380 1560 1560 1 o 8323 8300 1970 )); -DATA(insert OID = 6110 ( 8380 1560 1560 2 o 8324 8300 1970 )); + @@ -1663,4 +1664,3 @@ DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8317 8301 1970 )); DATA(insert OID = 6144 ( 8393 1560 1560 1 o 8323 8301 1970 )); DATA(insert OID = 6145 ( 8393 1560 1560 2 o 8324 8301 1970 )); DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); -DATA(insert OID = 6148 ( 8394 1560 1560 2 o 8324 8301 1970 )); diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 1e7c50c00d..1c4f307ec5 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -678,8 +678,11 @@ DATA(insert OID = 8962 ( 8377 8306 8306 3 8486 )); DATA(insert OID = 8931 ( 8378 8306 8306 1 8483 )); DATA(insert OID = 8963 ( 8378 8306 8306 3 8486 )); -DATA(insert OID = 8932 ( 8379 1560 1560 1 8462 )); -DATA(insert OID = 8933 ( 8380 1560 1560 1 8462 )); +DATA(insert OID = 8932 ( 8379 1560 1560 1 8468 )); +DATA(insert OID = 8975 ( 8379 1560 1560 1 8209 )); + +DATA(insert OID = 8933 ( 8380 1560 1560 1 8469 )); +DATA(insert OID = 8976 ( 8380 1560 1560 3 8209 )); DATA(insert OID = 8934 ( 8381 8307 8307 1 8470 )); DATA(insert OID = 8954 ( 8381 8307 8307 3 8479 )); @@ -730,5 +733,8 @@ DATA(insert OID = 8972 ( 8391 8306 8306 5 8487 )); DATA(insert OID = 8952 ( 8393 1560 1560 1 8462 )); -DATA(insert OID = 8953 ( 8394 1560 1560 1 8462 )); + +DATA(insert OID = 8953 ( 8394 1560 1560 1 8469 )); +DATA(insert OID = 8973 ( 8394 1560 1560 3 8469 )); +DATA(insert OID = 8974 ( 8394 1560 1560 5 8210 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index d64d418490..731211a20b 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1926,6 +1926,8 @@ DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 cosin DESCR("cosine_distance"); DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 l1_distance - -)); DESCR("l1_distance"); +DATA(insert OID = 8339 ("||" PGNSP PGUID b f f 8305 8305 8305 8204 0 vector_concat - -)); +DESCR("l1_distance"); DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 l2_distance - -)); DESCR("l2_distance"); @@ -1935,6 +1937,8 @@ DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 cosin DESCR("cosine_distance"); DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 l1_distance - -)); DESCR("l1_distance"); +DATA(insert OID = 8340 ("||" PGNSP PGUID b f f 8306 8306 8306 8204 0 halfvec_concat - -)); +DESCR("l1_distance"); DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 sparsevec_l2_distance - -)); DESCR("sparsevec_l2_distance"); @@ -1945,41 +1949,57 @@ DESCR("sparsevec_cosine_distance"); DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 sparsevec_l1_distance - -)); DESCR("sparsevec_l1_distance"); -DATA(insert OID = 8323 ("<~>" PGNSP PGUID b f f 1560 1560 701 8323 0 jaccard_distance - -)); +DATA(insert OID = 8323 ("<~>" PGNSP PGUID b f f 1560 1560 701 8323 0 hamming_distance - -)); DESCR("jaccard_distance"); -DATA(insert OID = 8324 ("<%>" PGNSP PGUID b f f 1560 1560 701 8324 0 hamming_distance - -)); +DATA(insert OID = 8324 ("<%>" PGNSP PGUID b f f 1560 1560 701 8324 0 jaccard_distance - -)); DESCR("hamming_distance"); DATA(insert OID = 8325 ("+" PGNSP PGUID b f f 8305 8305 8305 8325 0 vector_add 0 0)); DESCR("vector_add"); DATA(insert OID = 8326 ("-" PGNSP PGUID b f f 8305 8305 8305 8326 0 vector_sub 0 0)); DESCR("vector_sub"); -DATA(insert OID = 8327 ("<" PGNSP PGUID b f f 8305 8305 16 6164 6165 vector_lt scalarltsel scalarltjoinsel)); +DATA(insert OID = 8327 ("<" PGNSP PGUID b f f 8305 8305 16 8327 8328 vector_lt scalarltsel scalarltjoinsel)); DESCR("vector less than"); -DATA(insert OID = 8328 ("<=" PGNSP PGUID b f f 8305 8305 16 6165 6164 vector_le scalarltsel scalarltjoinsel)); +DATA(insert OID = 8328 ("<=" PGNSP PGUID b f f 8305 8305 16 8328 8327 vector_le scalarltsel scalarltjoinsel)); DESCR("vector less than or equal"); -DATA(insert OID = 8329 (">" PGNSP PGUID b f f 8305 8305 16 6167 6168 vector_gt scalargtsel scalargtjoinsel)); +DATA(insert OID = 8329 (">" PGNSP PGUID b f f 8305 8305 16 8329 8330 vector_gt scalargtsel scalargtjoinsel)); DESCR("vector greater than"); -DATA(insert OID = 8330 (">=" PGNSP PGUID b f f 8305 8305 16 6168 6167 vector_ge scalargtsel scalargtjoinsel)); +DATA(insert OID = 8330 (">=" PGNSP PGUID b f f 8305 8305 16 8330 8329 vector_ge scalargtsel scalargtjoinsel)); DESCR("vector greater than or equal"); -DATA(insert OID = 8331 ("=" PGNSP PGUID b f t 8305 8305 16 6169 6170 vector_eq eqsel eqjoinsel)); +DATA(insert OID = 8331 ("=" PGNSP PGUID b f t 8305 8305 16 8331 8332 vector_eq eqsel eqjoinsel)); DESCR("vector equal"); -DATA(insert OID = 8332 ("<>" PGNSP PGUID b f f 8305 8305 16 6170 6169 vector_ne neqsel neqjoinsel)); +DATA(insert OID = 8332 ("<>" PGNSP PGUID b f f 8305 8305 16 8332 8331 vector_ne neqsel neqjoinsel)); DESCR("vector unequal"); -DATA(insert OID = 8333 ("<" PGNSP PGUID b f f 8307 8307 16 6164 6165 sparsevec_lt scalarltsel scalarltjoinsel)); +DATA(insert OID = 8333 ("<" PGNSP PGUID b f f 8307 8307 16 8335 8336 sparsevec_lt scalarltsel scalarltjoinsel)); DESCR("sparsevec less than"); -DATA(insert OID = 8334 ("<=" PGNSP PGUID b f f 8307 8307 16 6165 6164 sparsevec_le scalarltsel scalarltjoinsel)); +DATA(insert OID = 8334 ("<=" PGNSP PGUID b f f 8307 8307 16 8336 8335 sparsevec_le scalarltsel scalarltjoinsel)); DESCR("sparsevec less than or equal"); -DATA(insert OID = 8335 (">" PGNSP PGUID b f f 8307 8307 16 6167 6168 sparsevec_gt scalargtsel scalargtjoinsel)); +DATA(insert OID = 8335 (">" PGNSP PGUID b f f 8307 8307 16 8333 8334 sparsevec_gt scalargtsel scalargtjoinsel)); DESCR("sparsevec greater than"); -DATA(insert OID = 8336 (">=" PGNSP PGUID b f f 8307 8307 16 6168 6167 sparsevec_ge scalargtsel scalargtjoinsel)); +DATA(insert OID = 8336 (">=" PGNSP PGUID b f f 8307 8307 16 8334 8333 sparsevec_ge scalargtsel scalargtjoinsel)); DESCR("sparsevec greater than or equal"); -DATA(insert OID = 8337 ("=" PGNSP PGUID b f t 8307 8307 16 6169 6170 sparsevec_eq eqsel eqjoinsel)); +DATA(insert OID = 8337 ("=" PGNSP PGUID b f t 8307 8307 16 8337 8338 sparsevec_eq eqsel eqjoinsel)); DESCR("sparsevec equal"); -DATA(insert OID = 8338 ("<>" PGNSP PGUID b f f 8307 8307 16 6170 6169 sparsevec_ne neqsel neqjoinsel)); +DATA(insert OID = 8338 ("<>" PGNSP PGUID b f f 8307 8307 16 8338 8337 sparsevec_ne neqsel neqjoinsel)); DESCR("sparsevec unequal"); +DATA(insert OID = 8341 ("+" PGNSP PGUID b f f 8306 8306 8306 8325 0 halfvec_add 0 0)); +DESCR("halfvec_add"); +DATA(insert OID = 8342 ("-" PGNSP PGUID b f f 8306 8306 8306 8326 0 halfvec_sub 0 0)); +DESCR("halfvec_sub"); +DATA(insert OID = 8343 ("<" PGNSP PGUID b f f 8306 8306 16 8327 8328 halfvec_lt scalarltsel scalarltjoinsel)); +DESCR("halfvec less than"); +DATA(insert OID = 8344 ("<=" PGNSP PGUID b f f 8306 8306 16 8328 8327 halfvec_le scalarltsel scalarltjoinsel)); +DESCR("halfvec less than or equal"); +DATA(insert OID = 8345 (">" PGNSP PGUID b f f 8306 8306 16 8329 8330 halfvec_gt scalargtsel scalargtjoinsel)); +DESCR("halfvec greater than"); +DATA(insert OID = 8346 (">=" PGNSP PGUID b f f 8306 8306 16 8330 8329 halfvec_ge scalargtsel scalargtjoinsel)); +DESCR("halfvec greater than or equal"); +DATA(insert OID = 8347 ("=" PGNSP PGUID b f t 8306 8306 16 8331 8332 halfvec_eq eqsel eqjoinsel)); +DESCR("halfvec equal"); +DATA(insert OID = 8348 ("<>" PGNSP PGUID b f f 8306 8306 16 8332 8331 halfvec_ne neqsel neqjoinsel)); +DESCR("halfvec unequal"); /* * function prototypes */ \ No newline at end of file -- Gitee From 5a04b8da74319286cb32881e014d992bfbc00ed2 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Sat, 2 Nov 2024 20:59:33 +0800 Subject: [PATCH 39/67] =?UTF-8?q?=E5=8E=BB=E9=87=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index f3227329e7..c6777cb34e 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13496,7 +13496,7 @@ AddFuncGroup( AddFuncGroup( "l2_normalize", 2, AddBuiltinFunc(_0(8200), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(l2_normalize), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8200), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(sparsevec_l2_normalize), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8211), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(sparsevec_l2_normalize), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "binary_quantize", 1, @@ -13538,15 +13538,11 @@ AddFuncGroup( "ivfflat_bit_support", 1, AddBuiltinFunc(_0(8210), _1("ivfflat_bit_support"), _2(1), _3(true), _4(false), _5(ivfflat_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "vector_dims", 1, - AddBuiltinFunc(_0(8428), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), AddFuncGroup( "halfvec_mul", 1, - AddBuiltinFunc(_0(8203), _1("halfvec_mul"), _2(1), _3(true), _4(false), _5(vector_mul), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_mul"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8212), _1("halfvec_mul"), _2(1), _3(true), _4(false), _5(vector_mul), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_mul"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "halfvec_concat", 1, - AddBuiltinFunc(_0(8204), _1("halfvec_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), \ No newline at end of file + AddBuiltinFunc(_0(8213), _1("halfvec_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), -- Gitee From b7ee2496cfb3d228966df73c9173af14800fbcae Mon Sep 17 00:00:00 2001 From: h30054849 Date: Sun, 3 Nov 2024 09:36:54 +0800 Subject: [PATCH 40/67] [bug fix] remove duplicate amproc & replace function name with oid --- src/include/catalog/pg_amproc.h | 2 +- src/include/catalog/pg_operator.data | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 1c4f307ec5..38875858a6 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -679,7 +679,7 @@ DATA(insert OID = 8931 ( 8378 8306 8306 1 8483 )); DATA(insert OID = 8963 ( 8378 8306 8306 3 8486 )); DATA(insert OID = 8932 ( 8379 1560 1560 1 8468 )); -DATA(insert OID = 8975 ( 8379 1560 1560 1 8209 )); +DATA(insert OID = 8975 ( 8379 1560 1560 3 8209 )); DATA(insert OID = 8933 ( 8380 1560 1560 1 8469 )); DATA(insert OID = 8976 ( 8380 1560 1560 3 8209 )); diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index 731211a20b..a1272aa46e 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1918,35 +1918,35 @@ DESCR("greater than or equal"); DATA(insert OID = 6565 ("-" PGNSP PGUID l f f 0 16 16 0 0 boolum - -)); DESCR("negate"); -DATA(insert OID = 8311 ("<->" PGNSP PGUID b f f 8305 8305 701 8311 0 l2_distance - -)); +DATA(insert OID = 8311 ("<->" PGNSP PGUID b f f 8305 8305 701 8311 0 8433 - -)); DESCR("l2_distance"); DATA(insert OID = 8312 ("<#>" PGNSP PGUID b f f 8305 8305 701 8312 0 vector_negative_inner_product - -)); DESCR("vector_negative_inner_product"); -DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 cosine_distance - -)); +DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 8435 - -)); DESCR("cosine_distance"); -DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 l1_distance - -)); +DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 8436 - -)); DESCR("l1_distance"); DATA(insert OID = 8339 ("||" PGNSP PGUID b f f 8305 8305 8305 8204 0 vector_concat - -)); DESCR("l1_distance"); -DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 l2_distance - -)); +DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 8433 - -)); DESCR("l2_distance"); DATA(insert OID = 8316 ("<#>" PGNSP PGUID b f f 8306 8306 701 8312 0 halfvec_negative_inner_product - -)); DESCR("halfvec_negative_inner_product"); -DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 cosine_distance - -)); +DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 8435 - -)); DESCR("cosine_distance"); -DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 l1_distance - -)); +DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 8436 - -)); DESCR("l1_distance"); DATA(insert OID = 8340 ("||" PGNSP PGUID b f f 8306 8306 8306 8204 0 halfvec_concat - -)); DESCR("l1_distance"); -DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 sparsevec_l2_distance - -)); +DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 8465 - -)); DESCR("sparsevec_l2_distance"); DATA(insert OID = 8320 ("<#>" PGNSP PGUID b f f 8307 8307 701 8320 0 sparsevec_negative_inner_product - -)); DESCR("sparsevec_negative_inner_product"); -DATA(insert OID = 8321 ("<=>" PGNSP PGUID b f f 8307 8307 701 8321 0 sparsevec_cosine_distance - -)); +DATA(insert OID = 8321 ("<=>" PGNSP PGUID b f f 8307 8307 701 8321 0 8466 - -)); DESCR("sparsevec_cosine_distance"); -DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 sparsevec_l1_distance - -)); +DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 8467 - -)); DESCR("sparsevec_l1_distance"); DATA(insert OID = 8323 ("<~>" PGNSP PGUID b f f 1560 1560 701 8323 0 hamming_distance - -)); -- Gitee From 2f7fff0ebf2e0ab3217d7efc1256c128690e0022 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Sun, 3 Nov 2024 12:34:56 +0800 Subject: [PATCH 41/67] add datavec GUC --- src/common/backend/utils/misc/guc/guc_sql.cpp | 28 +++++++++++++++++++ .../process/threadpool/knl_session.cpp | 6 ++++ .../storage/access/datavec/hnswscan.cpp | 2 +- .../storage/access/datavec/ivfflat.cpp | 2 +- .../storage/access/datavec/ivfscan.cpp | 2 +- src/include/knl/knl_session.h | 7 +++++ 6 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/common/backend/utils/misc/guc/guc_sql.cpp b/src/common/backend/utils/misc/guc/guc_sql.cpp index 48f46f2f6a..6c5fdffe9c 100755 --- a/src/common/backend/utils/misc/guc/guc_sql.cpp +++ b/src/common/backend/utils/misc/guc/guc_sql.cpp @@ -148,6 +148,8 @@ #include "utils/xml.h" #include "workload/cpwlm.h" #include "workload/workload.h" +#include "access/datavec/hnsw.h" +#include "access/datavec/ivfflat.h" #include "utils/guc_sql.h" #define DEFAULT_USTATS_TRACKER_NAPTIME 20 @@ -2564,6 +2566,32 @@ static void InitSqlConfigureNamesInt() NULL, NULL, NULL}, + {{"hnsw.ef_search", + PGC_USERSET, + NODE_ALL, + QUERY_TUNING_OTHER, + gettext_noop("Sets the size of the dynamic candidate list for search"), + gettext_noop("Valid range is 1..1000.")}, + &u_sess->datavec_ctx.hnsw_ef_search, + HNSW_DEFAULT_EF_SEARCH, + HNSW_MIN_EF_SEARCH, + HNSW_MAX_EF_SEARCH, + NULL, + NULL, + NULL}, + {{"ivfflat.probes", + PGC_USERSET, + NODE_ALL, + QUERY_TUNING_OTHER, + gettext_noop("Sets the number of probes"), + gettext_noop("Valid range is 1..lists."),}, + &u_sess->datavec_ctx.ivfflat_probes, + IVFFLAT_DEFAULT_PROBES, + IVFFLAT_MIN_LISTS, + IVFFLAT_MAX_LISTS, + NULL, + NULL, + NULL}, #endif /* End-of-list marker */ {{NULL, diff --git a/src/gausskernel/process/threadpool/knl_session.cpp b/src/gausskernel/process/threadpool/knl_session.cpp index 7891194c08..da08250ed4 100755 --- a/src/gausskernel/process/threadpool/knl_session.cpp +++ b/src/gausskernel/process/threadpool/knl_session.cpp @@ -1476,6 +1476,12 @@ static void knl_u_libsw_init(knl_u_libsw_context* libsw_cxt) libsw_cxt->redirect_manager = New(CurrentMemoryContext) RedirectManager(); } +static void knl_u_datavec_init(knl_u_datavec_context* datavec_cxt) +{ + datavec_cxt->hnsw_ef_search = 0; + datavec_cxt->ivfflat_probes = 0; +} + void knl_session_init(knl_session_context* sess_cxt) { Assert (0 != strncmp(CurrentMemoryContext->name, "ErrorContext", sizeof("ErrorContext"))); diff --git a/src/gausskernel/storage/access/datavec/hnswscan.cpp b/src/gausskernel/storage/access/datavec/hnswscan.cpp index 8776133367..fb919d60ae 100644 --- a/src/gausskernel/storage/access/datavec/hnswscan.cpp +++ b/src/gausskernel/storage/access/datavec/hnswscan.cpp @@ -35,7 +35,7 @@ static List *GetScanItems(IndexScanDesc scan, Datum q) ep = w; } - int hnsw_ef_search = get_session_context()->hnsw_ef_search; + int hnsw_ef_search = u_sess->datavec_ctx.hnsw_ef_search; return HnswSearchLayer(base, q, ep, hnsw_ef_search, 0, index, procinfo, collation, m, false, NULL, scan); } diff --git a/src/gausskernel/storage/access/datavec/ivfflat.cpp b/src/gausskernel/storage/access/datavec/ivfflat.cpp index 1c2b9e0ca5..b81cd522b6 100644 --- a/src/gausskernel/storage/access/datavec/ivfflat.cpp +++ b/src/gausskernel/storage/access/datavec/ivfflat.cpp @@ -52,7 +52,7 @@ static void ivfflatcostestimate_internal(PlannerInfo *root, IndexPath *path, dou index_close(index, NoLock); /* Get the ratio of lists that we need to visit */ - ratio = (static_cast(get_session_context()->ivfflat_probes)) / lists; + ratio = (static_cast(u_sess->datavec_ctx.ivfflat_probes)) / lists; if (ratio > 1.0) { ratio = 1.0; } diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index f495230310..d24f7979f9 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -213,7 +213,7 @@ IndexScanDesc ivfflatbeginscan_internal(Relation index, int nkeys, int norderbys Oid sortOperators[] = {FLOAT8LTOID}; Oid sortCollations[] = {InvalidOid}; bool nullsFirstFlags[] = {false}; - int probes = get_session_context()->ivfflat_probes; + int probes = u_sess->datavec_ctx.ivfflat_probes; int natts = 2; int attDistance = 1; int attHeaptid = 2; diff --git a/src/include/knl/knl_session.h b/src/include/knl/knl_session.h index 663efea7e1..41195ca7b0 100644 --- a/src/include/knl/knl_session.h +++ b/src/include/knl/knl_session.h @@ -3008,6 +3008,11 @@ typedef struct knl_u_ndp_context { char *crl_path; } knl_u_ndp_context; +typedef struct knl_u_datavec_context { + int hnsw_ef_search; + int ivfflat_probes; +} knl_u_datavec_context; + typedef struct knl_session_context { volatile knl_session_status status; /* used for threadworker, elem in m_readySessionList */ @@ -3162,6 +3167,8 @@ typedef struct knl_session_context { /* standby write. */ knl_u_libsw_context libsw_cxt; + knl_u_datavec_context datavec_ctx; + } knl_session_context; enum stp_xact_err_type { -- Gitee From 580330daab39c68017c756fa87dec651cbefba60 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Sun, 3 Nov 2024 13:25:03 +0800 Subject: [PATCH 42/67] [bug fix] incorrect function 1 oid in half_l1_ops --- src/include/catalog/pg_amproc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 38875858a6..3f00bfd476 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -675,7 +675,7 @@ DATA(insert OID = 8930 ( 8377 8306 8306 1 8457 )); DATA(insert OID = 8961 ( 8377 8306 8306 2 8485 )); DATA(insert OID = 8962 ( 8377 8306 8306 3 8486 )); -DATA(insert OID = 8931 ( 8378 8306 8306 1 8483 )); +DATA(insert OID = 8931 ( 8378 8306 8306 1 8436 )); DATA(insert OID = 8963 ( 8378 8306 8306 3 8486 )); DATA(insert OID = 8932 ( 8379 1560 1560 1 8468 )); -- Gitee From bfc1818bf7c35461ee3a77d342f7108ba5b5f0c9 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Sun, 3 Nov 2024 13:45:03 +0800 Subject: [PATCH 43/67] [bug fix] incorrect function 1 oid in ivfflat halfvec_l2_ops --- src/include/catalog/pg_amproc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 3f00bfd476..c14732055e 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -716,7 +716,7 @@ DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); DATA(insert OID = 8948 ( 8389 8306 8306 1 8480 )); -DATA(insert OID = 8964 ( 8389 8306 8306 3 8482 )); +DATA(insert OID = 8964 ( 8389 8306 8306 3 8433 )); DATA(insert OID = 8965 ( 8389 8306 8306 5 8487 )); DATA(insert OID = 8949 ( 8390 8306 8306 1 8457 )); -- Gitee From 58c5ea71890aabb5b09e4bce6757db8a20f6799e Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Mon, 4 Nov 2024 09:21:38 +0800 Subject: [PATCH 44/67] add btree --- src/common/backend/catalog/builtin_funcs.ini | 1 + src/include/catalog/pg_amop.data | 18 ++++++++++++++++++ src/include/catalog/pg_amproc.h | 8 +++++++- src/include/catalog/pg_opclass.h | 7 ++++++- src/include/catalog/pg_operator.data | 18 +++++++++--------- src/include/catalog/pg_opfamily.h | 10 +++++++++- 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index c6777cb34e..27d9e75060 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13546,3 +13546,4 @@ AddFuncGroup( "halfvec_concat", 1, AddBuiltinFunc(_0(8213), _1("halfvec_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index fe446ef8e3..84d2844456 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1664,3 +1664,21 @@ DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8317 8301 1970 )); DATA(insert OID = 6144 ( 8393 1560 1560 1 o 8323 8301 1970 )); DATA(insert OID = 6145 ( 8393 1560 1560 2 o 8324 8301 1970 )); DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); + +DATA(insert OID = 8980 ( 8392 8305 8305 1 o 8327 403 1970 )); +DATA(insert OID = 8981 ( 8392 8305 8305 2 o 8328 403 1970 )); +DATA(insert OID = 8982 ( 8392 8305 8305 3 o 8331 403 1970 )); +DATA(insert OID = 8983 ( 8392 8305 8305 4 o 8330 403 1970 )); +DATA(insert OID = 8984 ( 8392 8305 8305 5 o 8329 403 1970 )); + +DATA(insert OID = 8986 ( 8395 8306 8306 1 o 8343 403 1970 )); +DATA(insert OID = 8987 ( 8395 8306 8306 2 o 8344 403 1970 )); +DATA(insert OID = 8988 ( 8395 8306 8306 3 o 8347 403 1970 )); +DATA(insert OID = 8989 ( 8395 8306 8306 4 o 8346 403 1970 )); +DATA(insert OID = 8991 ( 8395 8306 8306 5 o 8345 403 1970 )); + +DATA(insert OID = 8993 ( 8397 8307 8307 1 o 8333 403 1970 )); +DATA(insert OID = 8994 ( 8397 8307 8307 2 o 8334 403 1970 )); +DATA(insert OID = 8995 ( 8397 8307 8307 3 o 8337 403 1970 )); +DATA(insert OID = 8996 ( 8397 8307 8307 4 o 8336 403 1970 )); +DATA(insert OID = 8997 ( 8397 8307 8307 5 o 8335 403 1970 )); diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index c14732055e..d15ce0075e 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -679,7 +679,7 @@ DATA(insert OID = 8931 ( 8378 8306 8306 1 8436 )); DATA(insert OID = 8963 ( 8378 8306 8306 3 8486 )); DATA(insert OID = 8932 ( 8379 1560 1560 1 8468 )); -DATA(insert OID = 8975 ( 8379 1560 1560 3 8209 )); +DATA(insert OID = 8975 ( 8379 1560 1560 1 8209 )); DATA(insert OID = 8933 ( 8380 1560 1560 1 8469 )); DATA(insert OID = 8976 ( 8380 1560 1560 3 8209 )); @@ -737,4 +737,10 @@ DATA(insert OID = 8952 ( 8393 1560 1560 1 8462 )); DATA(insert OID = 8953 ( 8394 1560 1560 1 8469 )); DATA(insert OID = 8973 ( 8394 1560 1560 3 8469 )); DATA(insert OID = 8974 ( 8394 1560 1560 5 8210 )); + +DATA(insert OID = 8985 ( 8392 8035 8035 1 8450 )); + +DATA(insert OID = 8992 ( 8395 8036 8036 1 8451 )); + +DATA(insert OID = 8998 ( 8397 8037 8037 1 8464 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 6b332d0539..36f9ff6af0 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -402,8 +402,13 @@ DATA(insert OID = 8918 (8301 halfvec_l2_ops PGNSP PGUID 8389 8306 t 0)); DATA(insert OID = 8919 (8301 halfvec_ip_ops PGNSP PGUID 8390 8306 t 0)); DATA(insert OID = 8920 (8301 halfvec_cosine_ops PGNSP PGUID 8391 8306 t 0)); -DATA(insert OID = 8922 (8301 bit_jaccard_ops PGNSP PGUID 8393 1560 t 0)); DATA(insert OID = 8923 (8301 bit_hamming_ops PGNSP PGUID 8394 1560 t 0)); +DATA(insert OID = 8977 (403 vector_ops PGNSP PGUID 8392 8305 t 0)); + +DATA(insert OID = 8978 (403 halfvec_ops PGNSP PGUID 8395 8306 t 0)); + +DATA(insert OID = 8979 (403 sparsevec_ops PGNSP PGUID 8397 8307 t 0)); + #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index a1272aa46e..731211a20b 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1918,35 +1918,35 @@ DESCR("greater than or equal"); DATA(insert OID = 6565 ("-" PGNSP PGUID l f f 0 16 16 0 0 boolum - -)); DESCR("negate"); -DATA(insert OID = 8311 ("<->" PGNSP PGUID b f f 8305 8305 701 8311 0 8433 - -)); +DATA(insert OID = 8311 ("<->" PGNSP PGUID b f f 8305 8305 701 8311 0 l2_distance - -)); DESCR("l2_distance"); DATA(insert OID = 8312 ("<#>" PGNSP PGUID b f f 8305 8305 701 8312 0 vector_negative_inner_product - -)); DESCR("vector_negative_inner_product"); -DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 8435 - -)); +DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 cosine_distance - -)); DESCR("cosine_distance"); -DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 8436 - -)); +DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 l1_distance - -)); DESCR("l1_distance"); DATA(insert OID = 8339 ("||" PGNSP PGUID b f f 8305 8305 8305 8204 0 vector_concat - -)); DESCR("l1_distance"); -DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 8433 - -)); +DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 l2_distance - -)); DESCR("l2_distance"); DATA(insert OID = 8316 ("<#>" PGNSP PGUID b f f 8306 8306 701 8312 0 halfvec_negative_inner_product - -)); DESCR("halfvec_negative_inner_product"); -DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 8435 - -)); +DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 cosine_distance - -)); DESCR("cosine_distance"); -DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 8436 - -)); +DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 l1_distance - -)); DESCR("l1_distance"); DATA(insert OID = 8340 ("||" PGNSP PGUID b f f 8306 8306 8306 8204 0 halfvec_concat - -)); DESCR("l1_distance"); -DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 8465 - -)); +DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 sparsevec_l2_distance - -)); DESCR("sparsevec_l2_distance"); DATA(insert OID = 8320 ("<#>" PGNSP PGUID b f f 8307 8307 701 8320 0 sparsevec_negative_inner_product - -)); DESCR("sparsevec_negative_inner_product"); -DATA(insert OID = 8321 ("<=>" PGNSP PGUID b f f 8307 8307 701 8321 0 8466 - -)); +DATA(insert OID = 8321 ("<=>" PGNSP PGUID b f f 8307 8307 701 8321 0 sparsevec_cosine_distance - -)); DESCR("sparsevec_cosine_distance"); -DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 8467 - -)); +DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 sparsevec_l1_distance - -)); DESCR("sparsevec_l1_distance"); DATA(insert OID = 8323 ("<~>" PGNSP PGUID b f f 1560 1560 701 8323 0 hamming_distance - -)); diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 433df5528e..33f7ba29ad 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -227,9 +227,17 @@ DATA(insert OID = 8389 (8301 halfvec_l2_ops PGNSP PGUID)); DATA(insert OID = 8390 (8301 halfvec_ip_ops PGNSP PGUID)); DATA(insert OID = 8391 (8301 halfvec_cosine_ops PGNSP PGUID)); -DATA(insert OID = 8393 (8301 bit_jaccard_ops PGNSP PGUID)); DATA(insert OID = 8394 (8301 bit_hamming_ops PGNSP PGUID)); +DATA(insert OID = 8392 (8301 vector_ops PGNSP PGUID)); +//DATA(insert OID = 8393 (8301 vector_ops PGNSP PGUID)); + +DATA(insert OID = 8395 (8301 halfvec_ops PGNSP PGUID)); +//DATA(insert OID = 8396 (8301 bit_hamming_ops PGNSP PGUID)); + +DATA(insert OID = 8397 (8301 sparsevec_ops PGNSP PGUID)); +//DATA(insert OID = 8398 (8301 bit_hamming_ops PGNSP PGUID)); + /* ubtree index */ #define BTREE_UBTREE_FAM_OID_DIFF 5000 #define BTREE_UBTREE_FAM_OID_SPECIAL_DIFF 4000 -- Gitee From 659554c39f0fe73e2457859aefc131ac957d96f4 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Mon, 4 Nov 2024 09:39:14 +0800 Subject: [PATCH 45/67] [bug fix] incorrect oid --- src/common/backend/catalog/builtin_funcs.ini | 1 - src/include/catalog/pg_amproc.h | 2 +- src/include/catalog/pg_operator.data | 18 +++++++++--------- src/include/catalog/pg_opfamily.h | 6 +++--- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 27d9e75060..c6777cb34e 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13546,4 +13546,3 @@ AddFuncGroup( "halfvec_concat", 1, AddBuiltinFunc(_0(8213), _1("halfvec_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index d15ce0075e..645d474996 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -679,7 +679,7 @@ DATA(insert OID = 8931 ( 8378 8306 8306 1 8436 )); DATA(insert OID = 8963 ( 8378 8306 8306 3 8486 )); DATA(insert OID = 8932 ( 8379 1560 1560 1 8468 )); -DATA(insert OID = 8975 ( 8379 1560 1560 1 8209 )); +DATA(insert OID = 8975 ( 8379 1560 1560 3 8209 )); DATA(insert OID = 8933 ( 8380 1560 1560 1 8469 )); DATA(insert OID = 8976 ( 8380 1560 1560 3 8209 )); diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index 731211a20b..a1272aa46e 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1918,35 +1918,35 @@ DESCR("greater than or equal"); DATA(insert OID = 6565 ("-" PGNSP PGUID l f f 0 16 16 0 0 boolum - -)); DESCR("negate"); -DATA(insert OID = 8311 ("<->" PGNSP PGUID b f f 8305 8305 701 8311 0 l2_distance - -)); +DATA(insert OID = 8311 ("<->" PGNSP PGUID b f f 8305 8305 701 8311 0 8433 - -)); DESCR("l2_distance"); DATA(insert OID = 8312 ("<#>" PGNSP PGUID b f f 8305 8305 701 8312 0 vector_negative_inner_product - -)); DESCR("vector_negative_inner_product"); -DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 cosine_distance - -)); +DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 8435 - -)); DESCR("cosine_distance"); -DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 l1_distance - -)); +DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 8436 - -)); DESCR("l1_distance"); DATA(insert OID = 8339 ("||" PGNSP PGUID b f f 8305 8305 8305 8204 0 vector_concat - -)); DESCR("l1_distance"); -DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 l2_distance - -)); +DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 8433 - -)); DESCR("l2_distance"); DATA(insert OID = 8316 ("<#>" PGNSP PGUID b f f 8306 8306 701 8312 0 halfvec_negative_inner_product - -)); DESCR("halfvec_negative_inner_product"); -DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 cosine_distance - -)); +DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 8435 - -)); DESCR("cosine_distance"); -DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 l1_distance - -)); +DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 8436 - -)); DESCR("l1_distance"); DATA(insert OID = 8340 ("||" PGNSP PGUID b f f 8306 8306 8306 8204 0 halfvec_concat - -)); DESCR("l1_distance"); -DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 sparsevec_l2_distance - -)); +DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 8465 - -)); DESCR("sparsevec_l2_distance"); DATA(insert OID = 8320 ("<#>" PGNSP PGUID b f f 8307 8307 701 8320 0 sparsevec_negative_inner_product - -)); DESCR("sparsevec_negative_inner_product"); -DATA(insert OID = 8321 ("<=>" PGNSP PGUID b f f 8307 8307 701 8321 0 sparsevec_cosine_distance - -)); +DATA(insert OID = 8321 ("<=>" PGNSP PGUID b f f 8307 8307 701 8321 0 8466 - -)); DESCR("sparsevec_cosine_distance"); -DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 sparsevec_l1_distance - -)); +DATA(insert OID = 8322 ("<+>" PGNSP PGUID b f f 8307 8307 701 8322 0 8467 - -)); DESCR("sparsevec_l1_distance"); DATA(insert OID = 8323 ("<~>" PGNSP PGUID b f f 1560 1560 701 8323 0 hamming_distance - -)); diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 33f7ba29ad..2a82ec3b87 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -229,13 +229,13 @@ DATA(insert OID = 8391 (8301 halfvec_cosine_ops PGNSP PGUID)); DATA(insert OID = 8394 (8301 bit_hamming_ops PGNSP PGUID)); -DATA(insert OID = 8392 (8301 vector_ops PGNSP PGUID)); +DATA(insert OID = 8392 (403 vector_ops PGNSP PGUID)); //DATA(insert OID = 8393 (8301 vector_ops PGNSP PGUID)); -DATA(insert OID = 8395 (8301 halfvec_ops PGNSP PGUID)); +DATA(insert OID = 8395 (403 halfvec_ops PGNSP PGUID)); //DATA(insert OID = 8396 (8301 bit_hamming_ops PGNSP PGUID)); -DATA(insert OID = 8397 (8301 sparsevec_ops PGNSP PGUID)); +DATA(insert OID = 8397 (403 sparsevec_ops PGNSP PGUID)); //DATA(insert OID = 8398 (8301 bit_hamming_ops PGNSP PGUID)); /* ubtree index */ -- Gitee From cd76cb4162a5a38349b6838ee96da928780e6e21 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Mon, 4 Nov 2024 17:19:01 +0800 Subject: [PATCH 46/67] =?UTF-8?q?=E5=A2=9E=E6=B7=BBcast=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E4=BA=9B=E5=B0=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 102 +++++++++++++++---- src/include/catalog/pg_amop.data | 3 +- src/include/catalog/pg_amproc.h | 2 +- src/include/catalog/pg_cast.h | 24 +++++ src/include/catalog/pg_operator.data | 2 + 5 files changed, 110 insertions(+), 23 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index c6777cb34e..cff8bbd19f 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13230,17 +13230,11 @@ AddFuncGroup( AddBuiltinFunc(_0(8427), _1("vector_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_dims", 1, - AddBuiltinFunc(_0(8428), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "array_to_vector", 1, - AddBuiltinFunc(_0(8429), _1("array_to_vector"), _2(1), _3(true), _4(false), _5(array_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "vector_to_float4", 1, - AddBuiltinFunc(_0(8430), _1("vector_to_float4"), _2(1), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "vector_dims", 2, + AddBuiltinFunc(_0(8428), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8233), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + AddFuncGroup( "vector_l2_squared_distance", 1, AddBuiltinFunc(_0(8431), _1("vector_l2_squared_distance"), _2(1), _3(true), _4(false), _5(vector_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13250,8 +13244,9 @@ AddFuncGroup( AddBuiltinFunc(_0(8432), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l2_distance", 2, + "l2_distance", 3, AddBuiltinFunc(_0(8433), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8234), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8465), _1("l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13259,18 +13254,21 @@ AddFuncGroup( AddBuiltinFunc(_0(8434), _1("vector_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "cosine_distance", 2, + "cosine_distance", 3, AddBuiltinFunc(_0(8435), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8236), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8466), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l1_distance", 2, + "l1_distance", 3, AddBuiltinFunc(_0(8436), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8237), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8467), _1("l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "inner_product", 2, + "inner_product", 3, AddBuiltinFunc(_0(8437), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8235), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8471), _1("inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13434,7 +13432,7 @@ AddFuncGroup( ), AddFuncGroup( "l2_norm", 2, - AddBuiltinFunc(_0(8485), _1("l2_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8485), _1("l2_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8478), _1("l2_norm"), _2(1), _3(true), _4(false), _5(sparsevec_l2_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13494,17 +13492,20 @@ AddFuncGroup( AddFuncGroup( - "l2_normalize", 2, + "l2_normalize", 3, AddBuiltinFunc(_0(8200), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(l2_normalize), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8238), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(l2_normalize), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8211), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(sparsevec_l2_normalize), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "binary_quantize", 1, - AddBuiltinFunc(_0(8201), _1("binary_quantize"), _2(3), _3(true), _4(false), _5(binary_quantize), _6(1562), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8305, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("binary_quantize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "binary_quantize", 2, + AddBuiltinFunc(_0(8201), _1("binary_quantize"), _2(1), _3(true), _4(false), _5(binary_quantize), _6(1562), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("binary_quantize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8239), _1("binary_quantize"), _2(1), _3(true), _4(false), _5(binary_quantize), _6(1562), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("binary_quantize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "subvector", 1, - AddBuiltinFunc(_0(8202), _1("subvector"), _2(1), _3(true), _4(false), _5(subvector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8305, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("subvector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + "subvector", 2, + AddBuiltinFunc(_0(8202), _1("subvector"), _2(1), _3(true), _4(false), _5(subvector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8305, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("subvector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8240), _1("subvector"), _2(1), _3(true), _4(false), _5(subvector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8306, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("subvector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_mul", 1, @@ -13546,3 +13547,64 @@ AddFuncGroup( "halfvec_concat", 1, AddBuiltinFunc(_0(8213), _1("halfvec_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + AddFuncGroup( + "vector", 1, + AddBuiltinFunc(_0(8214), _1("vector"), _2(3), _3(true), _4(false), _5(vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8305, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "array_to_vector", 4, + AddBuiltinFunc(_0(8215), _1("array_to_vector"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1007, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8216), _1("array_to_vector"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1021, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8217), _1("array_to_vector"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1022, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8218), _1("array_to_vector"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1231, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_to_float4", 1, + AddBuiltinFunc(_0(8219), _1("vector_to_float4"), _2(3), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8305, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + + AddFuncGroup( + "halfvec", 1, + AddBuiltinFunc(_0(8220), _1("halfvec"), _2(3), _3(true), _4(false), _5(vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "array_to_halfvec", 4, + AddBuiltinFunc(_0(8221), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1007, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8222), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1021, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8223), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1022, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8224), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1231, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_to_float4", 1, + AddBuiltinFunc(_0(8225), _1("halfvec_to_float4"), _2(3), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_to_vector", 1, + AddBuiltinFunc(_0(8226), _1("halfvec_to_vector"), _2(3), _3(true), _4(false), _5(halfvec_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_to_halfvec", 1, + AddBuiltinFunc(_0(8227), _1("vector_to_halfvec"), _2(3), _3(true), _4(false), _5(vector_to_halfvec), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8305, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_halfvec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + + AddFuncGroup( + "sparsevec", 1, + AddBuiltinFunc(_0(8228), _1("sparsevec"), _2(3), _3(true), _4(false), _5(sparsevec), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8307, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "vector_to_sparsevec", 1, + AddBuiltinFunc(_0(8229), _1("vector_to_sparsevec"), _2(3), _3(true), _4(false), _5(vector_to_sparsevec), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8305, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_sparsevec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_to_vector", 1, + AddBuiltinFunc(_0(8230), _1("sparsevec_to_vector"), _2(3), _3(true), _4(false), _5(sparsevec_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8307, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "halfvec_to_sparsevec", 1, + AddBuiltinFunc(_0(8231), _1("halfvec_to_sparsevec"), _2(3), _3(true), _4(false), _5(halfvec_to_sparsevec), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_to_sparsevec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "sparsevec_to_halfvec", 1, + AddBuiltinFunc(_0(8232), _1("sparsevec_to_halfvec"), _2(3), _3(true), _4(false), _5(sparsevec_to_halfvec), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8307, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_to_halfvec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 84d2844456..e6a188cbdf 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1661,8 +1661,7 @@ DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8317 8301 1970 )); -DATA(insert OID = 6144 ( 8393 1560 1560 1 o 8323 8301 1970 )); -DATA(insert OID = 6145 ( 8393 1560 1560 2 o 8324 8301 1970 )); + DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); DATA(insert OID = 8980 ( 8392 8305 8305 1 o 8327 403 1970 )); diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 645d474996..b10588b092 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -732,7 +732,7 @@ DATA(insert OID = 8972 ( 8391 8306 8306 5 8487 )); -DATA(insert OID = 8952 ( 8393 1560 1560 1 8462 )); + DATA(insert OID = 8953 ( 8394 1560 1560 1 8469 )); DATA(insert OID = 8973 ( 8394 1560 1560 3 8469 )); diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index e2532011f3..dfc359296e 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -596,4 +596,28 @@ DATA(insert ( 1042 3272 3314 i f _null_)); DATA(insert ( 3272 3969 3323 i f _null_)); DATA(insert ( 3969 3272 3321 i f _null_)); +/* vector <-> int[],float4[],float8[],numeric[] */ +DATA(insert OID = 8299 ( 8305 8305 8214 i f _null_)); +DATA(insert OID = 8298 ( 1007 8305 8215 a f _null_)); +DATA(insert OID = 8297 ( 1021 8305 8216 a f _null_)); +DATA(insert OID = 8296 ( 1022 8305 8217 a f _null_)); +DATA(insert OID = 8295 ( 1231 8305 8218 a f _null_)); +DATA(insert OID = 8294 ( 8305 1021 8219 i f _null_)); + +/* halfvector <-> int[],float4[],float8[],numeric[] vector*/ +DATA(insert OID = 8293 ( 8306 8306 8220 i f _null_)); +DATA(insert OID = 8292 ( 1007 8306 8221 a f _null_)); +DATA(insert OID = 8291 ( 1021 8306 8222 a f _null_)); +DATA(insert OID = 8290 ( 1022 8306 8223 a f _null_)); +DATA(insert OID = 8289 ( 1231 8306 8224 a f _null_)); +DATA(insert OID = 8288 ( 8306 1021 8225 a f _null_)); +DATA(insert OID = 8287 ( 8306 8305 8226 a f _null_)); +DATA(insert OID = 8286 ( 8305 8306 8227 i f _null_)); + +/* sparsevec <-> int[],float4[],float8[],numeric[] halfvector,vector*/ +DATA(insert OID = 8285 ( 8307 8307 8228 i f _null_)); +DATA(insert OID = 8284 ( 8305 8307 8229 i f _null_)); +DATA(insert OID = 8283 ( 8307 8305 8230 a f _null_)); +DATA(insert OID = 8282 ( 8306 8307 8231 i f _null_)); +DATA(insert OID = 8281 ( 8307 8306 8232 a f _null_)); #endif /* PG_CAST_H */ diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index a1272aa46e..b39806c4a2 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1958,6 +1958,8 @@ DATA(insert OID = 8325 ("+" PGNSP PGUID b f f 8305 8305 8305 8325 0 vector DESCR("vector_add"); DATA(insert OID = 8326 ("-" PGNSP PGUID b f f 8305 8305 8305 8326 0 vector_sub 0 0)); DESCR("vector_sub"); +DATA(insert OID = 8349 ("*" PGNSP PGUID b f f 8305 8305 8305 8349 0 8203 0 0)); +DESCR("vector_mul"); DATA(insert OID = 8327 ("<" PGNSP PGUID b f f 8305 8305 16 8327 8328 vector_lt scalarltsel scalarltjoinsel)); DESCR("vector less than"); DATA(insert OID = 8328 ("<=" PGNSP PGUID b f f 8305 8305 16 8328 8327 vector_le scalarltsel scalarltjoinsel)); -- Gitee From 18a6486b15311c8a18a25b494276940cac654b79 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Mon, 4 Nov 2024 19:16:09 +0800 Subject: [PATCH 47/67] [bug fix] incorrect data type oid in btree amproc --- src/include/catalog/pg_amproc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index b10588b092..3d52c40980 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -738,9 +738,9 @@ DATA(insert OID = 8953 ( 8394 1560 1560 1 8469 )); DATA(insert OID = 8973 ( 8394 1560 1560 3 8469 )); DATA(insert OID = 8974 ( 8394 1560 1560 5 8210 )); -DATA(insert OID = 8985 ( 8392 8035 8035 1 8450 )); +DATA(insert OID = 8985 ( 8392 8305 8305 1 8450 )); -DATA(insert OID = 8992 ( 8395 8036 8036 1 8451 )); +DATA(insert OID = 8992 ( 8395 8306 8306 1 8451 )); -DATA(insert OID = 8998 ( 8397 8037 8037 1 8464 )); +DATA(insert OID = 8998 ( 8397 8307 8307 1 8464 )); #endif /* PG_AMPROC_H */ -- Gitee From 768244b0bf00e2751b4eaad6d98a40193e3e7bf6 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Mon, 4 Nov 2024 19:45:48 +0800 Subject: [PATCH 48/67] cleancode --- src/test/regress/pg_regress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/pg_regress.cpp b/src/test/regress/pg_regress.cpp index 825c7ef19e..8701807d0d 100644 --- a/src/test/regress/pg_regress.cpp +++ b/src/test/regress/pg_regress.cpp @@ -5467,7 +5467,7 @@ static void CheckCleanCodeWarningInfo(const int baseNum, const int currentNum, return; } -#define BASE_GLOBAL_VARIABLE_NUM 237 +#define BASE_GLOBAL_VARIABLE_NUM 240 #define CMAKE_CMD_BUF_LEN 1000 -- Gitee From f7f6d37862e7427bee3fbea6130f85fb35d6f19a Mon Sep 17 00:00:00 2001 From: h30054849 Date: Mon, 4 Nov 2024 19:51:47 +0800 Subject: [PATCH 49/67] [bug fix] proper typmod for an index expression column --- src/common/backend/catalog/index.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/backend/catalog/index.cpp b/src/common/backend/catalog/index.cpp index 41a8c6ac00..fc9d449773 100644 --- a/src/common/backend/catalog/index.cpp +++ b/src/common/backend/catalog/index.cpp @@ -416,7 +416,7 @@ static TupleDesc ConstructTupleDescriptor(Relation heapRelation, IndexInfo* inde to->attalign = typeTup->typalign; to->attstattarget = -1; to->attcacheoff = -1; - to->atttypmod = -1; + to->atttypmod = exprTypmod(indexkey); to->attislocal = true; to->attcollation = (i < numkeyatts) ? collationObjectId[i] : InvalidOid; -- Gitee From 6b09dd8c21b3da89e1623025a6e5a11b58d4b6ce Mon Sep 17 00:00:00 2001 From: jiwenke Date: Mon, 4 Nov 2024 19:55:58 +0800 Subject: [PATCH 50/67] cleancode --- src/include/catalog/pg_amop.data | 53 +------------------------------ src/include/catalog/pg_amproc.h | 22 ++----------- src/include/catalog/pg_opfamily.h | 6 ---- 3 files changed, 4 insertions(+), 77 deletions(-) diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index e6a188cbdf..d1851fa20f 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1594,90 +1594,39 @@ DATA(insert OID = 7272 ( 9570 9003 9003 2 s 5553 4439 0 )); DATA(insert OID = 7273 ( 9570 9003 9003 3 s 5550 4439 0 )); DATA(insert OID = 7274 ( 9570 9003 9003 4 s 5549 4439 0 )); DATA(insert OID = 7275 ( 9570 9003 9003 5 s 5554 4439 0 )); - DATA(insert OID = 6031 ( 8371 8305 8305 1 o 8311 8300 1970 )); - DATA(insert OID = 6041 ( 8372 8305 8305 1 o 8312 8300 1970 )); - DATA(insert OID = 6051 ( 8373 8305 8305 1 o 8313 8300 1970 )); - DATA(insert OID = 6061 ( 8374 8305 8305 1 o 8314 8300 1970 )); - - DATA(insert OID = 6036 ( 8375 8306 8306 1 o 8315 8300 1970 )); - DATA(insert OID = 6046 ( 8376 8306 8306 1 o 8316 8300 1970 )); - DATA(insert OID = 6056 ( 8377 8306 8306 1 o 8317 8300 1970 )); - DATA(insert OID = 6066 ( 8378 8306 8306 1 o 8318 8300 1970 )); - DATA(insert OID = 6091 ( 8381 8307 8307 1 o 8319 8300 1970 )); - - DATA(insert OID = 6095 ( 8382 8307 8307 1 o 8320 8300 1970 )); - - DATA(insert OID = 6101 ( 8383 8307 8307 1 o 8321 8300 1970 )); - - DATA(insert OID = 6103 ( 8384 8307 8307 1 o 8322 8300 1970 )); - - - DATA(insert OID = 6107 ( 8379 1560 1560 1 o 8324 8300 1970 )); - - DATA(insert OID = 6109 ( 8380 1560 1560 1 o 8323 8300 1970 )); - - - - - - - DATA(insert OID = 6111 ( 8385 8305 8305 1 o 8311 8301 1970 )); - - - DATA(insert OID = 6115 ( 8386 8305 8305 1 o 8312 8301 1970 )); - - DATA(insert OID = 6119 ( 8387 8305 8305 1 o 8313 8301 1970 )); - - - - DATA(insert OID = 6127 ( 8389 8306 8306 1 o 8315 8301 1970 )); - DATA(insert OID = 6131 ( 8390 8306 8306 1 o 8316 8301 1970 )); - DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8317 8301 1970 )); - - - - - - - - - DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); - DATA(insert OID = 8980 ( 8392 8305 8305 1 o 8327 403 1970 )); DATA(insert OID = 8981 ( 8392 8305 8305 2 o 8328 403 1970 )); DATA(insert OID = 8982 ( 8392 8305 8305 3 o 8331 403 1970 )); DATA(insert OID = 8983 ( 8392 8305 8305 4 o 8330 403 1970 )); DATA(insert OID = 8984 ( 8392 8305 8305 5 o 8329 403 1970 )); - DATA(insert OID = 8986 ( 8395 8306 8306 1 o 8343 403 1970 )); DATA(insert OID = 8987 ( 8395 8306 8306 2 o 8344 403 1970 )); DATA(insert OID = 8988 ( 8395 8306 8306 3 o 8347 403 1970 )); DATA(insert OID = 8989 ( 8395 8306 8306 4 o 8346 403 1970 )); DATA(insert OID = 8991 ( 8395 8306 8306 5 o 8345 403 1970 )); - DATA(insert OID = 8993 ( 8397 8307 8307 1 o 8333 403 1970 )); DATA(insert OID = 8994 ( 8397 8307 8307 2 o 8334 403 1970 )); DATA(insert OID = 8995 ( 8397 8307 8307 3 o 8337 403 1970 )); DATA(insert OID = 8996 ( 8397 8307 8307 4 o 8336 403 1970 )); -DATA(insert OID = 8997 ( 8397 8307 8307 5 o 8335 403 1970 )); +DATA(insert OID = 8997 ( 8397 8307 8307 5 o 8335 403 1970 )); \ No newline at end of file diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 3d52c40980..0e04f939d8 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -654,15 +654,11 @@ DATA(insert ( 9570 9003 9003 1 5586 )); DATA(insert ( 8901 3831 3831 1 3870 )); DATA(insert ( 8626 3614 3614 1 3622 )); DATA(insert ( 8683 3615 3615 1 3668 )); -//hnsw -//vector_l2_ops + DATA(insert OID = 8924 ( 8371 8305 8305 1 8431 )); -//vector_ip_ops DATA(insert OID = 8925 ( 8372 8305 8305 1 8434 )); -//vector_cosine_ops DATA(insert OID = 8926 ( 8373 8305 8305 1 8434 )); DATA(insert OID = 8947 ( 8373 8305 8305 2 8438 )); -//vector_l1_ops DATA(insert OID = 8927 ( 8374 8305 8305 1 8436 )); DATA(insert OID = 8928 ( 8375 8306 8306 1 8480 )); @@ -697,22 +693,17 @@ DATA(insert OID = 8957 ( 8383 8307 8307 3 8479 )); DATA(insert OID = 8937 ( 8384 8307 8307 1 8467 )); DATA(insert OID = 8958 ( 8384 8307 8307 3 8479 )); -//ivfflat -//vector_l2_ops DATA(insert OID = 8938 ( 8385 8305 8305 1 8431 )); DATA(insert OID = 8939 ( 8385 8305 8305 3 8433 )); -//vector_ip_ops + DATA(insert OID = 8940 ( 8386 8305 8305 1 8434 )); DATA(insert OID = 8941 ( 8386 8305 8305 3 8432 )); DATA(insert OID = 8942 ( 8386 8305 8305 4 8438 )); -//vector_cosine_ops + DATA(insert OID = 8943 ( 8387 8305 8305 1 8434 )); DATA(insert OID = 8944 ( 8387 8305 8305 2 8438 )); DATA(insert OID = 8945 ( 8387 8305 8305 3 8432 )); DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); -//vector_l1_ops -//DATA(insert OID = 8942 ( 8388 8305 8305 1 8450 )); - DATA(insert OID = 8948 ( 8389 8306 8306 1 8480 )); @@ -730,17 +721,10 @@ DATA(insert OID = 8970 ( 8391 8306 8306 3 8481 )); DATA(insert OID = 8971 ( 8391 8306 8306 4 8485 )); DATA(insert OID = 8972 ( 8391 8306 8306 5 8487 )); - - - - DATA(insert OID = 8953 ( 8394 1560 1560 1 8469 )); DATA(insert OID = 8973 ( 8394 1560 1560 3 8469 )); DATA(insert OID = 8974 ( 8394 1560 1560 5 8210 )); - DATA(insert OID = 8985 ( 8392 8305 8305 1 8450 )); - DATA(insert OID = 8992 ( 8395 8306 8306 1 8451 )); - DATA(insert OID = 8998 ( 8397 8307 8307 1 8464 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 2a82ec3b87..1a86e5e33a 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -228,15 +228,9 @@ DATA(insert OID = 8390 (8301 halfvec_ip_ops PGNSP PGUID)); DATA(insert OID = 8391 (8301 halfvec_cosine_ops PGNSP PGUID)); DATA(insert OID = 8394 (8301 bit_hamming_ops PGNSP PGUID)); - DATA(insert OID = 8392 (403 vector_ops PGNSP PGUID)); -//DATA(insert OID = 8393 (8301 vector_ops PGNSP PGUID)); - DATA(insert OID = 8395 (403 halfvec_ops PGNSP PGUID)); -//DATA(insert OID = 8396 (8301 bit_hamming_ops PGNSP PGUID)); - DATA(insert OID = 8397 (403 sparsevec_ops PGNSP PGUID)); -//DATA(insert OID = 8398 (8301 bit_hamming_ops PGNSP PGUID)); /* ubtree index */ #define BTREE_UBTREE_FAM_OID_DIFF 5000 -- Gitee From be2a141d28506544144973b93345660448e38d53 Mon Sep 17 00:00:00 2001 From: rumengchun <1172336222@qq.com> Date: Mon, 4 Nov 2024 22:14:40 +0800 Subject: [PATCH 51/67] =?UTF-8?q?=E6=B7=BB=E5=8A=A0halfvec=5Fmul,=E5=90=91?= =?UTF-8?q?=E9=87=8F=E6=95=B0=E7=BB=84,sum=E8=81=9A=E9=9B=86=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/catalog/builtin_funcs.ini | 10 ++++++---- src/include/catalog/pg_aggregate.h | 4 +++- src/include/catalog/pg_operator.data | 2 ++ src/include/catalog/pg_type.h | 15 ++++++++++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index cff8bbd19f..0ac21d03cd 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -494,7 +494,7 @@ AddBuiltinFunc(_0(1504), _1("attach"), _2(2), _3(true), _4(true), _5(debug_client_attatch), _6(2249), _7(PG_PLDEBUG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 25, 23), _21(6, 25, 23, 26, 25, 23, 25), _22(6, 'i', 'i', 'o', 'o', 'o', 'o'), _23(6, "nodename", "port", "funcoid", "funcname", "lineno", "query"), _24(NULL), _25("debug_client_attatch"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), ), AddFuncGroup( - "avg", 8, + "avg", 9, AddBuiltinFunc(_0(2100), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 20), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2101), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2102), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 21), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), @@ -502,7 +502,8 @@ AddBuiltinFunc(_0(2104), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 700), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2105), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 701), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2106), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1186), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1186), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(5537), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 5545), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(5537), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 5545), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8241), _1("avg"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("concatenate aggregate input into an array"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "backtrace", 1, @@ -11234,7 +11235,7 @@ AddFuncGroup( AddBuiltinFunc(_0(9463), _1("subtype_recv"), _2(3), _3(false), _4(false), _5(subtype_recv), _6(2276), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("subtype_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0), _41(NULL)) ), AddFuncGroup( - "sum", 8, + "sum", 9, AddBuiltinFunc(_0(2107), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 20), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2108), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(20), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2109), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(20), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 21), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), @@ -11242,7 +11243,8 @@ AddFuncGroup( AddBuiltinFunc(_0(2111), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 701), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2112), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(790), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 790), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(2113), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1186), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1186), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(2114), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1700), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(2114), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(1700), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1700), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + AddBuiltinFunc(_0(8242), _1("sum"), _2(1), _3(false), _4(false), _5(aggregate_dummy), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(true), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("aggregate_dummy"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("the average (arithmetic mean) as numeric of all bigint values"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "suppress_redundant_updates_trigger", 1, diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index 6cd0082ebd..c9bfcafb8a 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -485,7 +485,9 @@ DATA(insert ( 9990 tdigest_merge tdigest_merge_to_one calculate_quantile_of DATA(insert ( 9986 tdigest_mergep tdigest_merge_to_one calculate_value_at 0 4406 _null_ _null_ n 0)); #define ADDTDIGESTMERGEPOID 9986 - +/*vector aggregate function*/ +DATA(insert ( 8241 vector_accum vector_combine vector_avg 0 8305 _null_ "{0}" n 0)); +DATA(insert ( 8242 vector_add vector_add - 0 8305 _null_ _null_ n 0)); /* * prototypes for functions in pg_aggregate.c */ diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index b39806c4a2..a4e013a903 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1990,6 +1990,8 @@ DATA(insert OID = 8341 ("+" PGNSP PGUID b f f 8306 8306 8306 8325 0 halfve DESCR("halfvec_add"); DATA(insert OID = 8342 ("-" PGNSP PGUID b f f 8306 8306 8306 8326 0 halfvec_sub 0 0)); DESCR("halfvec_sub"); +DATA(insert OID = 8350 ("*" PGNSP PGUID b f f 8306 8306 8306 8349 0 8203 0 0)); +DESCR("halfvec_mul"); DATA(insert OID = 8343 ("<" PGNSP PGUID b f f 8306 8306 16 8327 8328 halfvec_lt scalarltsel scalarltjoinsel)); DESCR("halfvec less than"); DATA(insert OID = 8344 ("<=" PGNSP PGUID b f f 8306 8306 16 8328 8327 halfvec_le scalarltsel scalarltjoinsel)); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 8b020c61a9..892b3ccc4d 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -823,15 +823,24 @@ DATA(insert OID = 4408 ( undefined PGNSP PGUID -2 f u W f t \054 0 0 0 undefin DESCR("undefined objects as PLSQL compilation time"); #define UNDEFINEDOID 4408 -DATA(insert OID = 8305 (vector PGNSP PGUID -1 f b U f t \054 0 0 0 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); +DATA(insert OID = 8305 (vector PGNSP PGUID -1 f b U f t \054 0 0 8308 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define VECTOROID 8305 -DATA(insert OID = 8306 (halfvec PGNSP PGUID -1 f b U f t \054 0 0 0 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); +DATA(insert OID = 8306 (halfvec PGNSP PGUID -1 f b U f t \054 0 0 8309 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define FLOATVECTOROID 8306 -DATA(insert OID = 8307 (sparsevec PGNSP PGUID -1 f b U f t \054 0 0 0 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); +DATA(insert OID = 8307 (sparsevec PGNSP PGUID -1 f b U f t \054 0 0 8310 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define SPARSEVECTOROID 8307 +DATA(insert OID = 8308 ( _vector PGNSP PGUID -1 f b A f t \054 0 8305 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +#define VECTORARRAYOID 8308 + +DATA(insert OID = 8309 ( _halfvec PGNSP PGUID -1 f b A f t \054 0 8306 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +#define HALFVECARRAYOID 8309 + +DATA(insert OID = 8310 ( _sparsevec PGNSP PGUID -1 f b A f t \054 0 8307 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +#define SPARSEVECARRAYOID 8310 + /* * macros */ -- Gitee From 9f2e7002b2e7afd149946dc36a2c8f56677a2b08 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Mon, 4 Nov 2024 22:52:02 +0800 Subject: [PATCH 52/67] remove halfvec --- src/common/backend/catalog/builtin_funcs.ini | 166 ++----------------- src/include/catalog/pg_amop.data | 12 -- src/include/catalog/pg_amproc.h | 30 ---- src/include/catalog/pg_cast.h | 12 -- src/include/catalog/pg_opclass.h | 11 -- src/include/catalog/pg_operator.data | 29 ---- src/include/catalog/pg_opfamily.h | 10 -- src/include/catalog/pg_type.h | 6 - 8 files changed, 11 insertions(+), 265 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 0ac21d03cd..f61a406302 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13232,9 +13232,8 @@ AddFuncGroup( AddBuiltinFunc(_0(8427), _1("vector_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "vector_dims", 2, + "vector_dims", 1, AddBuiltinFunc(_0(8428), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8233), _1("vector_dims"), _2(1), _3(true), _4(false), _5(vector_dims), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_dims"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13246,9 +13245,8 @@ AddFuncGroup( AddBuiltinFunc(_0(8432), _1("vector_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l2_distance", 3, + "l2_distance", 2, AddBuiltinFunc(_0(8433), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8234), _1("l2_distance"), _2(1), _3(true), _4(false), _5(l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8465), _1("l2_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l2_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13256,21 +13254,18 @@ AddFuncGroup( AddBuiltinFunc(_0(8434), _1("vector_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "cosine_distance", 3, + "cosine_distance", 2, AddBuiltinFunc(_0(8435), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8236), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8466), _1("cosine_distance"), _2(1), _3(true), _4(false), _5(sparsevec_cosine_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_cosine_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "l1_distance", 3, + "l1_distance", 2, AddBuiltinFunc(_0(8436), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8237), _1("l1_distance"), _2(1), _3(true), _4(false), _5(l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8467), _1("l1_distance"), _2(1), _3(true), _4(false), _5(sparsevec_l1_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l1_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "inner_product", 3, + "inner_product", 2, AddBuiltinFunc(_0(8437), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8235), _1("inner_product"), _2(1), _3(true), _4(false), _5(inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8306, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8471), _1("inner_product"), _2(1), _3(true), _4(false), _5(sparsevec_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8307, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( @@ -13325,34 +13320,6 @@ AddFuncGroup( "vector_cmp", 1, AddBuiltinFunc(_0(8450), _1("vector_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "halfvec_cmp", 1, - AddBuiltinFunc(_0(8451), _1("halfvec_cmp"), _2(1), _3(true), _4(false), _5(vector_cmp), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_cmp"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_in", 1, - AddBuiltinFunc(_0(8452), _1("halfvec_in"), _2(3), _3(true), _4(false), _5(vector_in), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_out", 1, - AddBuiltinFunc(_0(8453), _1("halfvec_out"), _2(1), _3(true), _4(false), _5(vector_out), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_out"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_typmod_in", 1, - AddBuiltinFunc(_0(8454), _1("halfvec_typmod_in"), _2(1), _3(true), _4(false), _5(vector_typmod_in), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 1263), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_typmod_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false),_33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_recv", 1, - AddBuiltinFunc(_0(8455), _1("halfvec_recv"), _2(3), _3(true), _4(false), _5(vector_recv), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2281, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_recv"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_send", 1, - AddBuiltinFunc(_0(8456), _1("halfvec_send"), _2(1), _3(true), _4(false), _5(vector_send), _6(17), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_send"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_negative_inner_product", 1, - AddBuiltinFunc(_0(8457), _1("halfvec_negative_inner_product"), _2(1), _3(true), _4(false), _5(vector_negative_inner_product), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_negative_inner_product"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), AddFuncGroup( "sparsevec_in", 1, AddBuiltinFunc(_0(8458), _1("sparsevec_in"), _2(3), _3(true), _4(false), _5(sparsevec_in), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 2275, 26, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_in"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("I/O"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13423,91 +13390,22 @@ AddFuncGroup( "hnsw_sparsevec_support", 1, AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(0), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - AddFuncGroup( - "halfvec_l2_squared_distance", 1, - AddBuiltinFunc(_0(8480), _1("halfvec_l2_squared_distance"), _2(1), _3(true), _4(false), _5(vector_l2_squared_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_l2_squared_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_spherical_distance", 1, - AddBuiltinFunc(_0(8481), _1("halfvec_spherical_distance"), _2(1), _3(true), _4(false), _5(vector_spherical_distance), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL),_25("vector_spherical_distance"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), AddFuncGroup( - "l2_norm", 2, - AddBuiltinFunc(_0(8485), _1("l2_norm"), _2(1), _3(true), _4(false), _5(vector_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), + "l2_norm", 1, AddBuiltinFunc(_0(8478), _1("l2_norm"), _2(1), _3(true), _4(false), _5(sparsevec_l2_norm), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_norm"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "hnsw_halfvec_support", 1, - AddBuiltinFunc(_0(8486), _1("hnsw_halfvec_support"), _2(3), _3(true), _4(false), _5(hnsw_halfvec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_halfvec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "ivfflat_halfvec_support", 1, - AddBuiltinFunc(_0(8487), _1("ivfflat_halfvec_support"), _2(3), _3(true), _4(false), _5(ivfflat_halfvec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_halfvec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - - - AddFuncGroup( - "halfvec_add", 1, - AddBuiltinFunc(_0(8488), _1("halfvec_add"), _2(1), _3(true), _4(false), _5(vector_add), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_add"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_sub", 1, - AddBuiltinFunc(_0(8489), _1("halfvec_sub"), _2(1), _3(true), _4(false), _5(vector_sub), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_lt", 1, - AddBuiltinFunc(_0(8490), _1("halfvec_lt"), _2(1), _3(true), _4(false), _5(vector_lt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_lt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_le", 1, - AddBuiltinFunc(_0(8491), _1("halfvec_le"), _2(1), _3(true), _4(false), _5(vector_le), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_le"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_eq", 1, - AddBuiltinFunc(_0(8493), _1("halfvec_eq"), _2(1), _3(true), _4(false), _5(vector_eq), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_eq"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_ne", 1, - AddBuiltinFunc(_0(8494), _1("halfvec_ne"), _2(1), _3(true), _4(false), _5(vector_ne), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ne"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_ge", 1, - AddBuiltinFunc(_0(8495), _1("halfvec_ge"), _2(1), _3(true), _4(false), _5(vector_ge), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_ge"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_gt", 1, - AddBuiltinFunc(_0(8496), _1("halfvec_gt"), _2(1), _3(true), _4(false), _5(vector_gt), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_gt"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_accum", 1, - AddBuiltinFunc(_0(8497), _1("halfvec_accum"), _2(1), _3(true), _4(false), _5(vector_accum), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_accum"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_combine", 1, - AddBuiltinFunc(_0(8498), _1("halfvec_combine"), _2(1), _3(true), _4(false), _5(vector_combine), _6(2277), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 2277, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_combine"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_avg", 1, - AddBuiltinFunc(_0(8499), _1("halfvec_avg"), _2(1), _3(true), _4(false), _5(vector_avg), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2277), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_avg"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - - - AddFuncGroup( - "l2_normalize", 3, + "l2_normalize", 2, AddBuiltinFunc(_0(8200), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(l2_normalize), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8238), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(l2_normalize), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), AddBuiltinFunc(_0(8211), _1("l2_normalize"), _2(1), _3(true), _4(false), _5(sparsevec_l2_normalize), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8307), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_l2_normalize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "binary_quantize", 2, + "binary_quantize", 1, AddBuiltinFunc(_0(8201), _1("binary_quantize"), _2(1), _3(true), _4(false), _5(binary_quantize), _6(1562), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("binary_quantize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8239), _1("binary_quantize"), _2(1), _3(true), _4(false), _5(binary_quantize), _6(1562), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 8306), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("binary_quantize"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( - "subvector", 2, + "subvector", 1, AddBuiltinFunc(_0(8202), _1("subvector"), _2(1), _3(true), _4(false), _5(subvector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8305, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("subvector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8240), _1("subvector"), _2(1), _3(true), _4(false), _5(subvector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 8306, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("subvector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector_mul", 1, @@ -13541,15 +13439,7 @@ AddFuncGroup( "ivfflat_bit_support", 1, AddBuiltinFunc(_0(8210), _1("ivfflat_bit_support"), _2(1), _3(true), _4(false), _5(ivfflat_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - AddFuncGroup( - "halfvec_mul", 1, - AddBuiltinFunc(_0(8212), _1("halfvec_mul"), _2(1), _3(true), _4(false), _5(vector_mul), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_mul"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_concat", 1, - AddBuiltinFunc(_0(8213), _1("halfvec_concat"), _2(1), _3(true), _4(false), _5(vector_concat), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(2, 8305, 8305), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_concat"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( + AddFuncGroup( "vector", 1, AddBuiltinFunc(_0(8214), _1("vector"), _2(3), _3(true), _4(false), _5(vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8305, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), @@ -13564,32 +13454,6 @@ AddFuncGroup( "vector_to_float4", 1, AddBuiltinFunc(_0(8219), _1("vector_to_float4"), _2(3), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8305, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), - - - AddFuncGroup( - "halfvec", 1, - AddBuiltinFunc(_0(8220), _1("halfvec"), _2(3), _3(true), _4(false), _5(vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "array_to_halfvec", 4, - AddBuiltinFunc(_0(8221), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1007, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8222), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1021, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8223), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1022, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)), - AddBuiltinFunc(_0(8224), _1("array_to_halfvec"), _2(3), _3(true), _4(false), _5(array_to_vector), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 1231, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("array_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_to_float4", 1, - AddBuiltinFunc(_0(8225), _1("halfvec_to_float4"), _2(3), _3(true), _4(false), _5(vector_to_float4), _6(1021), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_float4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_to_vector", 1, - AddBuiltinFunc(_0(8226), _1("halfvec_to_vector"), _2(3), _3(true), _4(false), _5(halfvec_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "vector_to_halfvec", 1, - AddBuiltinFunc(_0(8227), _1("vector_to_halfvec"), _2(3), _3(true), _4(false), _5(vector_to_halfvec), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8305, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("vector_to_halfvec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( "sparsevec", 1, AddBuiltinFunc(_0(8228), _1("sparsevec"), _2(3), _3(true), _4(false), _5(sparsevec), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8307, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) @@ -13601,12 +13465,4 @@ AddFuncGroup( AddFuncGroup( "sparsevec_to_vector", 1, AddBuiltinFunc(_0(8230), _1("sparsevec_to_vector"), _2(3), _3(true), _4(false), _5(sparsevec_to_vector), _6(8305), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8307, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_to_vector"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "halfvec_to_sparsevec", 1, - AddBuiltinFunc(_0(8231), _1("halfvec_to_sparsevec"), _2(3), _3(true), _4(false), _5(halfvec_to_sparsevec), _6(8307), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8306, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("halfvec_to_sparsevec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), - AddFuncGroup( - "sparsevec_to_halfvec", 1, - AddBuiltinFunc(_0(8232), _1("sparsevec_to_halfvec"), _2(3), _3(true), _4(false), _5(sparsevec_to_halfvec), _6(8306), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(3, 8307, 23, 16), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("sparsevec_to_halfvec"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) - ), + ), \ No newline at end of file diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index d1851fa20f..7b05837e0e 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1598,10 +1598,6 @@ DATA(insert OID = 6031 ( 8371 8305 8305 1 o 8311 8300 1970 )); DATA(insert OID = 6041 ( 8372 8305 8305 1 o 8312 8300 1970 )); DATA(insert OID = 6051 ( 8373 8305 8305 1 o 8313 8300 1970 )); DATA(insert OID = 6061 ( 8374 8305 8305 1 o 8314 8300 1970 )); -DATA(insert OID = 6036 ( 8375 8306 8306 1 o 8315 8300 1970 )); -DATA(insert OID = 6046 ( 8376 8306 8306 1 o 8316 8300 1970 )); -DATA(insert OID = 6056 ( 8377 8306 8306 1 o 8317 8300 1970 )); -DATA(insert OID = 6066 ( 8378 8306 8306 1 o 8318 8300 1970 )); DATA(insert OID = 6091 ( 8381 8307 8307 1 o 8319 8300 1970 )); DATA(insert OID = 6095 ( 8382 8307 8307 1 o 8320 8300 1970 )); DATA(insert OID = 6101 ( 8383 8307 8307 1 o 8321 8300 1970 )); @@ -1611,20 +1607,12 @@ DATA(insert OID = 6109 ( 8380 1560 1560 1 o 8323 8300 1970 )); DATA(insert OID = 6111 ( 8385 8305 8305 1 o 8311 8301 1970 )); DATA(insert OID = 6115 ( 8386 8305 8305 1 o 8312 8301 1970 )); DATA(insert OID = 6119 ( 8387 8305 8305 1 o 8313 8301 1970 )); -DATA(insert OID = 6127 ( 8389 8306 8306 1 o 8315 8301 1970 )); -DATA(insert OID = 6131 ( 8390 8306 8306 1 o 8316 8301 1970 )); -DATA(insert OID = 6135 ( 8391 8306 8306 1 o 8317 8301 1970 )); DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); DATA(insert OID = 8980 ( 8392 8305 8305 1 o 8327 403 1970 )); DATA(insert OID = 8981 ( 8392 8305 8305 2 o 8328 403 1970 )); DATA(insert OID = 8982 ( 8392 8305 8305 3 o 8331 403 1970 )); DATA(insert OID = 8983 ( 8392 8305 8305 4 o 8330 403 1970 )); DATA(insert OID = 8984 ( 8392 8305 8305 5 o 8329 403 1970 )); -DATA(insert OID = 8986 ( 8395 8306 8306 1 o 8343 403 1970 )); -DATA(insert OID = 8987 ( 8395 8306 8306 2 o 8344 403 1970 )); -DATA(insert OID = 8988 ( 8395 8306 8306 3 o 8347 403 1970 )); -DATA(insert OID = 8989 ( 8395 8306 8306 4 o 8346 403 1970 )); -DATA(insert OID = 8991 ( 8395 8306 8306 5 o 8345 403 1970 )); DATA(insert OID = 8993 ( 8397 8307 8307 1 o 8333 403 1970 )); DATA(insert OID = 8994 ( 8397 8307 8307 2 o 8334 403 1970 )); DATA(insert OID = 8995 ( 8397 8307 8307 3 o 8337 403 1970 )); diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 0e04f939d8..73755d729c 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -661,19 +661,6 @@ DATA(insert OID = 8926 ( 8373 8305 8305 1 8434 )); DATA(insert OID = 8947 ( 8373 8305 8305 2 8438 )); DATA(insert OID = 8927 ( 8374 8305 8305 1 8436 )); -DATA(insert OID = 8928 ( 8375 8306 8306 1 8480 )); -DATA(insert OID = 8959 ( 8375 8306 8306 3 8486 )); - -DATA(insert OID = 8929 ( 8376 8306 8306 1 8457 )); -DATA(insert OID = 8960 ( 8376 8306 8306 3 8486 )); - -DATA(insert OID = 8930 ( 8377 8306 8306 1 8457 )); -DATA(insert OID = 8961 ( 8377 8306 8306 2 8485 )); -DATA(insert OID = 8962 ( 8377 8306 8306 3 8486 )); - -DATA(insert OID = 8931 ( 8378 8306 8306 1 8436 )); -DATA(insert OID = 8963 ( 8378 8306 8306 3 8486 )); - DATA(insert OID = 8932 ( 8379 1560 1560 1 8468 )); DATA(insert OID = 8975 ( 8379 1560 1560 3 8209 )); @@ -705,26 +692,9 @@ DATA(insert OID = 8944 ( 8387 8305 8305 2 8438 )); DATA(insert OID = 8945 ( 8387 8305 8305 3 8432 )); DATA(insert OID = 8946 ( 8387 8305 8305 4 8438 )); - -DATA(insert OID = 8948 ( 8389 8306 8306 1 8480 )); -DATA(insert OID = 8964 ( 8389 8306 8306 3 8433 )); -DATA(insert OID = 8965 ( 8389 8306 8306 5 8487 )); - -DATA(insert OID = 8949 ( 8390 8306 8306 1 8457 )); -DATA(insert OID = 8966 ( 8390 8306 8306 3 8481 )); -DATA(insert OID = 8967 ( 8390 8306 8306 4 8485 )); -DATA(insert OID = 8968 ( 8390 8306 8306 5 8487 )); - -DATA(insert OID = 8950 ( 8391 8306 8306 1 8457 )); -DATA(insert OID = 8969 ( 8391 8306 8306 2 8485 )); -DATA(insert OID = 8970 ( 8391 8306 8306 3 8481 )); -DATA(insert OID = 8971 ( 8391 8306 8306 4 8485 )); -DATA(insert OID = 8972 ( 8391 8306 8306 5 8487 )); - DATA(insert OID = 8953 ( 8394 1560 1560 1 8469 )); DATA(insert OID = 8973 ( 8394 1560 1560 3 8469 )); DATA(insert OID = 8974 ( 8394 1560 1560 5 8210 )); DATA(insert OID = 8985 ( 8392 8305 8305 1 8450 )); -DATA(insert OID = 8992 ( 8395 8306 8306 1 8451 )); DATA(insert OID = 8998 ( 8397 8307 8307 1 8464 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index dfc359296e..40eef589a4 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -604,20 +604,8 @@ DATA(insert OID = 8296 ( 1022 8305 8217 a f _null_)); DATA(insert OID = 8295 ( 1231 8305 8218 a f _null_)); DATA(insert OID = 8294 ( 8305 1021 8219 i f _null_)); -/* halfvector <-> int[],float4[],float8[],numeric[] vector*/ -DATA(insert OID = 8293 ( 8306 8306 8220 i f _null_)); -DATA(insert OID = 8292 ( 1007 8306 8221 a f _null_)); -DATA(insert OID = 8291 ( 1021 8306 8222 a f _null_)); -DATA(insert OID = 8290 ( 1022 8306 8223 a f _null_)); -DATA(insert OID = 8289 ( 1231 8306 8224 a f _null_)); -DATA(insert OID = 8288 ( 8306 1021 8225 a f _null_)); -DATA(insert OID = 8287 ( 8306 8305 8226 a f _null_)); -DATA(insert OID = 8286 ( 8305 8306 8227 i f _null_)); - /* sparsevec <-> int[],float4[],float8[],numeric[] halfvector,vector*/ DATA(insert OID = 8285 ( 8307 8307 8228 i f _null_)); DATA(insert OID = 8284 ( 8305 8307 8229 i f _null_)); DATA(insert OID = 8283 ( 8307 8305 8230 a f _null_)); -DATA(insert OID = 8282 ( 8306 8307 8231 i f _null_)); -DATA(insert OID = 8281 ( 8307 8306 8232 a f _null_)); #endif /* PG_CAST_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 36f9ff6af0..9e279b6894 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -380,11 +380,6 @@ DATA(insert OID = 8999 (8300 vector_ip_ops PGNSP PGUID 8372 8305 t 0)); DATA(insert OID = 8902 (8300 vector_cosine_ops PGNSP PGUID 8373 8305 t 0)); DATA(insert OID = 8903 (8300 vector_l1_ops PGNSP PGUID 8374 8305 t 0)); -DATA(insert OID = 8904 (8300 halfvec_l2_ops PGNSP PGUID 8375 8306 t 0)); -DATA(insert OID = 8905 (8300 halfvec_ip_ops PGNSP PGUID 8376 8306 t 0)); -DATA(insert OID = 8906 (8300 halfvec_cosine_ops PGNSP PGUID 8377 8306 t 0)); -DATA(insert OID = 8907 (8300 halfvec_l1_ops PGNSP PGUID 8378 8306 t 0)); - DATA(insert OID = 8908 (8300 bit_jaccard_ops PGNSP PGUID 8379 1560 t 0)); DATA(insert OID = 8909 (8300 bit_hamming_ops PGNSP PGUID 8380 1560 t 0)); @@ -398,16 +393,10 @@ DATA(insert OID = 8915 (8301 vector_ip_ops PGNSP PGUID 8386 8305 t 0)); DATA(insert OID = 8916 (8301 vector_cosine_ops PGNSP PGUID 8387 8305 t 0)); DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0 )); -DATA(insert OID = 8918 (8301 halfvec_l2_ops PGNSP PGUID 8389 8306 t 0)); -DATA(insert OID = 8919 (8301 halfvec_ip_ops PGNSP PGUID 8390 8306 t 0)); -DATA(insert OID = 8920 (8301 halfvec_cosine_ops PGNSP PGUID 8391 8306 t 0)); - DATA(insert OID = 8923 (8301 bit_hamming_ops PGNSP PGUID 8394 1560 t 0)); DATA(insert OID = 8977 (403 vector_ops PGNSP PGUID 8392 8305 t 0)); -DATA(insert OID = 8978 (403 halfvec_ops PGNSP PGUID 8395 8306 t 0)); - DATA(insert OID = 8979 (403 sparsevec_ops PGNSP PGUID 8397 8307 t 0)); #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index a4e013a903..fd62090248 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1929,17 +1929,6 @@ DESCR("l1_distance"); DATA(insert OID = 8339 ("||" PGNSP PGUID b f f 8305 8305 8305 8204 0 vector_concat - -)); DESCR("l1_distance"); -DATA(insert OID = 8315 ("<->" PGNSP PGUID b f f 8306 8306 701 8311 0 8433 - -)); -DESCR("l2_distance"); -DATA(insert OID = 8316 ("<#>" PGNSP PGUID b f f 8306 8306 701 8312 0 halfvec_negative_inner_product - -)); -DESCR("halfvec_negative_inner_product"); -DATA(insert OID = 8317 ("<=>" PGNSP PGUID b f f 8306 8306 701 8313 0 8435 - -)); -DESCR("cosine_distance"); -DATA(insert OID = 8318 ("<+>" PGNSP PGUID b f f 8306 8306 701 8314 0 8436 - -)); -DESCR("l1_distance"); -DATA(insert OID = 8340 ("||" PGNSP PGUID b f f 8306 8306 8306 8204 0 halfvec_concat - -)); -DESCR("l1_distance"); - DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 8465 - -)); DESCR("sparsevec_l2_distance"); DATA(insert OID = 8320 ("<#>" PGNSP PGUID b f f 8307 8307 701 8320 0 sparsevec_negative_inner_product - -)); @@ -1986,24 +1975,6 @@ DESCR("sparsevec equal"); DATA(insert OID = 8338 ("<>" PGNSP PGUID b f f 8307 8307 16 8338 8337 sparsevec_ne neqsel neqjoinsel)); DESCR("sparsevec unequal"); -DATA(insert OID = 8341 ("+" PGNSP PGUID b f f 8306 8306 8306 8325 0 halfvec_add 0 0)); -DESCR("halfvec_add"); -DATA(insert OID = 8342 ("-" PGNSP PGUID b f f 8306 8306 8306 8326 0 halfvec_sub 0 0)); -DESCR("halfvec_sub"); -DATA(insert OID = 8350 ("*" PGNSP PGUID b f f 8306 8306 8306 8349 0 8203 0 0)); -DESCR("halfvec_mul"); -DATA(insert OID = 8343 ("<" PGNSP PGUID b f f 8306 8306 16 8327 8328 halfvec_lt scalarltsel scalarltjoinsel)); -DESCR("halfvec less than"); -DATA(insert OID = 8344 ("<=" PGNSP PGUID b f f 8306 8306 16 8328 8327 halfvec_le scalarltsel scalarltjoinsel)); -DESCR("halfvec less than or equal"); -DATA(insert OID = 8345 (">" PGNSP PGUID b f f 8306 8306 16 8329 8330 halfvec_gt scalargtsel scalargtjoinsel)); -DESCR("halfvec greater than"); -DATA(insert OID = 8346 (">=" PGNSP PGUID b f f 8306 8306 16 8330 8329 halfvec_ge scalargtsel scalargtjoinsel)); -DESCR("halfvec greater than or equal"); -DATA(insert OID = 8347 ("=" PGNSP PGUID b f t 8306 8306 16 8331 8332 halfvec_eq eqsel eqjoinsel)); -DESCR("halfvec equal"); -DATA(insert OID = 8348 ("<>" PGNSP PGUID b f f 8306 8306 16 8332 8331 halfvec_ne neqsel neqjoinsel)); -DESCR("halfvec unequal"); /* * function prototypes */ \ No newline at end of file diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 1a86e5e33a..61855d445d 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -205,11 +205,6 @@ DATA(insert OID = 8372 (8300 vector_ip_ops PGNSP PGUID)); DATA(insert OID = 8373 (8300 vector_cosine_ops PGNSP PGUID)); DATA(insert OID = 8374 (8300 vector_l1_ops PGNSP PGUID)); -DATA(insert OID = 8375 (8300 halfvec_l2_ops PGNSP PGUID)); -DATA(insert OID = 8376 (8300 halfvec_ip_ops PGNSP PGUID)); -DATA(insert OID = 8377 (8300 halfvec_cosine_ops PGNSP PGUID)); -DATA(insert OID = 8378 (8300 halfvec_l1_ops PGNSP PGUID)); - DATA(insert OID = 8379 (8300 bit_jaccard_ops PGNSP PGUID)); DATA(insert OID = 8380 (8300 bit_hamming_ops PGNSP PGUID)); @@ -223,13 +218,8 @@ DATA(insert OID = 8386 (8301 vector_ip_ops PGNSP PGUID)); DATA(insert OID = 8387 (8301 vector_cosine_ops PGNSP PGUID)); DATA(insert OID = 8388 (8301 vector_l1_ops PGNSP PGUID)); -DATA(insert OID = 8389 (8301 halfvec_l2_ops PGNSP PGUID)); -DATA(insert OID = 8390 (8301 halfvec_ip_ops PGNSP PGUID)); -DATA(insert OID = 8391 (8301 halfvec_cosine_ops PGNSP PGUID)); - DATA(insert OID = 8394 (8301 bit_hamming_ops PGNSP PGUID)); DATA(insert OID = 8392 (403 vector_ops PGNSP PGUID)); -DATA(insert OID = 8395 (403 halfvec_ops PGNSP PGUID)); DATA(insert OID = 8397 (403 sparsevec_ops PGNSP PGUID)); /* ubtree index */ diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 892b3ccc4d..8a89dc3fbb 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -826,18 +826,12 @@ DESCR("undefined objects as PLSQL compilation time"); DATA(insert OID = 8305 (vector PGNSP PGUID -1 f b U f t \054 0 0 8308 vector_in vector_out vector_recv vector_send vector_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define VECTOROID 8305 -DATA(insert OID = 8306 (halfvec PGNSP PGUID -1 f b U f t \054 0 0 8309 halfvec_in halfvec_out halfvec_recv halfvec_send halfvec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); -#define FLOATVECTOROID 8306 - DATA(insert OID = 8307 (sparsevec PGNSP PGUID -1 f b U f t \054 0 0 8310 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define SPARSEVECTOROID 8307 DATA(insert OID = 8308 ( _vector PGNSP PGUID -1 f b A f t \054 0 8305 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); #define VECTORARRAYOID 8308 -DATA(insert OID = 8309 ( _halfvec PGNSP PGUID -1 f b A f t \054 0 8306 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); -#define HALFVECARRAYOID 8309 - DATA(insert OID = 8310 ( _sparsevec PGNSP PGUID -1 f b A f t \054 0 8307 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); #define SPARSEVECARRAYOID 8310 -- Gitee From 10000339c8502cadf49e9a3a6965ed4571c73a10 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Mon, 4 Nov 2024 23:02:49 +0800 Subject: [PATCH 53/67] 8204->0 --- src/include/catalog/pg_operator.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index fd62090248..88582f283c 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1926,7 +1926,7 @@ DATA(insert OID = 8313 ("<=>" PGNSP PGUID b f f 8305 8305 701 8313 0 8435 DESCR("cosine_distance"); DATA(insert OID = 8314 ("<+>" PGNSP PGUID b f f 8305 8305 701 8314 0 8436 - -)); DESCR("l1_distance"); -DATA(insert OID = 8339 ("||" PGNSP PGUID b f f 8305 8305 8305 8204 0 vector_concat - -)); +DATA(insert OID = 8339 ("||" PGNSP PGUID b f f 8305 8305 8305 0 0 vector_concat - -)); DESCR("l1_distance"); DATA(insert OID = 8319 ("<->" PGNSP PGUID b f f 8307 8307 701 8319 0 8465 - -)); -- Gitee From 1130a805f00dc1e908e83e4266661284dffb8537 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 09:12:35 +0800 Subject: [PATCH 54/67] [bug fix] only 1 default ops for an index type & typein = typeout = typelement --- src/include/catalog/pg_opclass.h | 28 ++++++++++++++-------------- src/include/catalog/pg_type.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 9e279b6894..5cc55cf580 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -375,25 +375,25 @@ DATA(insert ( 405 settext_ops PGNSP PGUID 1995 3272 f 0 )); DATA(insert ( 4439 setasint_ops PGNSP PGUID 6976 3272 t 0 )); DATA(insert ( 405 set_ops PGNSP PGUID 8646 3272 t 0 )); -DATA(insert OID = 8900 (8300 vector_l2_ops PGNSP PGUID 8371 8305 t 0)); -DATA(insert OID = 8999 (8300 vector_ip_ops PGNSP PGUID 8372 8305 t 0)); -DATA(insert OID = 8902 (8300 vector_cosine_ops PGNSP PGUID 8373 8305 t 0)); -DATA(insert OID = 8903 (8300 vector_l1_ops PGNSP PGUID 8374 8305 t 0)); +DATA(insert OID = 8900 (8300 vector_l2_ops PGNSP PGUID 8371 8305 f 0)); +DATA(insert OID = 8999 (8300 vector_ip_ops PGNSP PGUID 8372 8305 f 0)); +DATA(insert OID = 8902 (8300 vector_cosine_ops PGNSP PGUID 8373 8305 f 0)); +DATA(insert OID = 8903 (8300 vector_l1_ops PGNSP PGUID 8374 8305 f 0)); -DATA(insert OID = 8908 (8300 bit_jaccard_ops PGNSP PGUID 8379 1560 t 0)); -DATA(insert OID = 8909 (8300 bit_hamming_ops PGNSP PGUID 8380 1560 t 0)); +DATA(insert OID = 8908 (8300 bit_jaccard_ops PGNSP PGUID 8379 1560 f 0)); +DATA(insert OID = 8909 (8300 bit_hamming_ops PGNSP PGUID 8380 1560 f 0)); -DATA(insert OID = 8910 (8300 sparsevec_l2_ops PGNSP PGUID 8381 8307 t 0)); -DATA(insert OID = 8911 (8300 sparsevec_ip_ops PGNSP PGUID 8382 8307 t 0)); -DATA(insert OID = 8912 (8300 sparsevec_cosine_ops PGNSP PGUID 8383 8307 t 0)); -DATA(insert OID = 8913 (8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 t 0)); +DATA(insert OID = 8910 (8300 sparsevec_l2_ops PGNSP PGUID 8381 8307 f 0)); +DATA(insert OID = 8911 (8300 sparsevec_ip_ops PGNSP PGUID 8382 8307 f 0)); +DATA(insert OID = 8912 (8300 sparsevec_cosine_ops PGNSP PGUID 8383 8307 f 0)); +DATA(insert OID = 8913 (8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 f 0)); DATA(insert OID = 8914 (8301 vector_l2_ops PGNSP PGUID 8385 8305 t 0)); -DATA(insert OID = 8915 (8301 vector_ip_ops PGNSP PGUID 8386 8305 t 0)); -DATA(insert OID = 8916 (8301 vector_cosine_ops PGNSP PGUID 8387 8305 t 0)); -DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 t 0 )); +DATA(insert OID = 8915 (8301 vector_ip_ops PGNSP PGUID 8386 8305 f 0)); +DATA(insert OID = 8916 (8301 vector_cosine_ops PGNSP PGUID 8387 8305 f 0)); +DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 f 0 )); -DATA(insert OID = 8923 (8301 bit_hamming_ops PGNSP PGUID 8394 1560 t 0)); +DATA(insert OID = 8923 (8301 bit_hamming_ops PGNSP PGUID 8394 1560 f 0)); DATA(insert OID = 8977 (403 vector_ops PGNSP PGUID 8392 8305 t 0)); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 8a89dc3fbb..4a1e153063 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -829,10 +829,10 @@ DATA(insert OID = 8305 (vector PGNSP PGUID -1 f b U f t \054 0 0 8308 vector_i DATA(insert OID = 8307 (sparsevec PGNSP PGUID -1 f b U f t \054 0 0 8310 sparsevec_in sparsevec_out sparsevec_recv sparsevec_send sparsevec_typmod_in - - i e f 0 -1 0 0 _null_ _null_ _null_)); #define SPARSEVECTOROID 8307 -DATA(insert OID = 8308 ( _vector PGNSP PGUID -1 f b A f t \054 0 8305 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 8308 ( _vector PGNSP PGUID -1 f b A f t \054 0 8305 0 array_in array_out array_recv array_send vector_typmod_in - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); #define VECTORARRAYOID 8308 -DATA(insert OID = 8310 ( _sparsevec PGNSP PGUID -1 f b A f t \054 0 8307 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 8310 ( _sparsevec PGNSP PGUID -1 f b A f t \054 0 8307 0 array_in array_out array_recv array_send sparsevec_typmod_in - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); #define SPARSEVECARRAYOID 8310 /* -- Gitee From 6652c0dc800326f75c7ec45a42cc9a8093ee2845 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 09:19:32 +0800 Subject: [PATCH 55/67] new vector operator '<=>' --- .../regress/expected/single_node_test_null_operator.out | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/regress/expected/single_node_test_null_operator.out b/src/test/regress/expected/single_node_test_null_operator.out index bc2b1f3404..6218306bf6 100644 --- a/src/test/regress/expected/single_node_test_null_operator.out +++ b/src/test/regress/expected/single_node_test_null_operator.out @@ -5,15 +5,15 @@ LINE 1: SELECT 1 <=> 1; ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. SELECT '' <=> NULL; -ERROR: operator does not exist: unknown <=> unknown +ERROR: operator is not unique: unknown <=> unknown LINE 1: SELECT '' <=> NULL; ^ -HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +HINT: Could not choose a best candidate operator. You might need to add explicit type casts. SELECT NULL <=> NULL; -ERROR: operator does not exist: unknown <=> unknown +ERROR: operator is not unique: unknown <=> unknown LINE 1: SELECT NULL <=> NULL; ^ -HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +HINT: Could not choose a best candidate operator. You might need to add explicit type casts. SELECT (1,2) <=> (1,2); ERROR: operator does not exist: integer <=> integer LINE 1: SELECT (1,2) <=> (1,2); -- Gitee From c16d7f5760acf924dcf4c8c0de34edb860538aa9 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 09:29:29 +0800 Subject: [PATCH 56/67] correct oprcom & oprnegate for vector operators --- src/include/catalog/pg_operator.data | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/include/catalog/pg_operator.data b/src/include/catalog/pg_operator.data index 88582f283c..9e17ea18e4 100644 --- a/src/include/catalog/pg_operator.data +++ b/src/include/catalog/pg_operator.data @@ -1949,13 +1949,13 @@ DATA(insert OID = 8326 ("-" PGNSP PGUID b f f 8305 8305 8305 8326 0 vector DESCR("vector_sub"); DATA(insert OID = 8349 ("*" PGNSP PGUID b f f 8305 8305 8305 8349 0 8203 0 0)); DESCR("vector_mul"); -DATA(insert OID = 8327 ("<" PGNSP PGUID b f f 8305 8305 16 8327 8328 vector_lt scalarltsel scalarltjoinsel)); +DATA(insert OID = 8327 ("<" PGNSP PGUID b f f 8305 8305 16 8329 8330 vector_lt scalarltsel scalarltjoinsel)); DESCR("vector less than"); -DATA(insert OID = 8328 ("<=" PGNSP PGUID b f f 8305 8305 16 8328 8327 vector_le scalarltsel scalarltjoinsel)); +DATA(insert OID = 8328 ("<=" PGNSP PGUID b f f 8305 8305 16 8330 8329 vector_le scalarltsel scalarltjoinsel)); DESCR("vector less than or equal"); -DATA(insert OID = 8329 (">" PGNSP PGUID b f f 8305 8305 16 8329 8330 vector_gt scalargtsel scalargtjoinsel)); +DATA(insert OID = 8329 (">" PGNSP PGUID b f f 8305 8305 16 8327 8328 vector_gt scalargtsel scalargtjoinsel)); DESCR("vector greater than"); -DATA(insert OID = 8330 (">=" PGNSP PGUID b f f 8305 8305 16 8330 8329 vector_ge scalargtsel scalargtjoinsel)); +DATA(insert OID = 8330 (">=" PGNSP PGUID b f f 8305 8305 16 8328 8327 vector_ge scalargtsel scalargtjoinsel)); DESCR("vector greater than or equal"); DATA(insert OID = 8331 ("=" PGNSP PGUID b f t 8305 8305 16 8331 8332 vector_eq eqsel eqjoinsel)); DESCR("vector equal"); -- Gitee From 879aa7ae3b6986e730afa0958e2a8de9d576afaf Mon Sep 17 00:00:00 2001 From: jiwenke Date: Tue, 5 Nov 2024 10:49:23 +0800 Subject: [PATCH 57/67] avg --- src/include/catalog/pg_aggregate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index c9bfcafb8a..69b5258671 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -486,7 +486,7 @@ DATA(insert ( 9990 tdigest_merge tdigest_merge_to_one calculate_quantile_of DATA(insert ( 9986 tdigest_mergep tdigest_merge_to_one calculate_value_at 0 4406 _null_ _null_ n 0)); #define ADDTDIGESTMERGEPOID 9986 /*vector aggregate function*/ -DATA(insert ( 8241 vector_accum vector_combine vector_avg 0 8305 _null_ "{0}" n 0)); +DATA(insert ( 8241 vector_accum vector_combine vector_avg 0 1022 "{0,0,0}" "{0,0,0}" n 0)); DATA(insert ( 8242 vector_add vector_add - 0 8305 _null_ _null_ n 0)); /* * prototypes for functions in pg_aggregate.c -- Gitee From f2d59c20047738b875f4584e0f0fde0133d441d0 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Tue, 5 Nov 2024 11:06:32 +0800 Subject: [PATCH 58/67] amop --- src/test/regress/expected/opr_sanity_2.out | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/regress/expected/opr_sanity_2.out b/src/test/regress/expected/opr_sanity_2.out index c065a44183..78cda3ac18 100644 --- a/src/test/regress/expected/opr_sanity_2.out +++ b/src/test/regress/expected/opr_sanity_2.out @@ -261,7 +261,17 @@ ORDER BY 1, 2, 3; 4439 | 5 | ~>~ 4444 | 1 | @@ 4444 | 2 | @@@ -(80 rows) + 8300 | 1 | <#> + 8300 | 1 | <%> + 8300 | 1 | <+> + 8300 | 1 | <-> + 8300 | 1 | <=> + 8300 | 1 | <~> + 8301 | 1 | <#> + 8301 | 1 | <-> + 8301 | 1 | <=> + 8301 | 1 | <~> +(90 rows) -- Check that all opclass search operators have selectivity estimators. -- This is not absolutely required, but it seems a reasonable thing -- Gitee From 2ce3d2d4320da1dc111a4494b965243fdd874c92 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 11:21:58 +0800 Subject: [PATCH 59/67] remove ivf l1 & fix argument count & add range of support func numfor hnsw and ivfflat index --- src/common/backend/catalog/builtin_funcs.ini | 4 ++-- src/include/catalog/pg_amop.data | 20 ++++++++++---------- src/include/catalog/pg_opclass.h | 1 - src/include/catalog/pg_opfamily.h | 1 - src/test/regress/expected/opr_sanity_2.out | 3 ++- src/test/regress/sql/opr_sanity_2.sql | 3 ++- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index f61a406302..379345bc51 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13433,11 +13433,11 @@ AddFuncGroup( ), AddFuncGroup( "hnsw_bit_support", 1, - AddBuiltinFunc(_0(8209), _1("hnsw_bit_support"), _2(1), _3(true), _4(false), _5(hnsw_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8209), _1("hnsw_bit_support"), _2(0), _3(true), _4(false), _5(hnsw_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflat_bit_support", 1, - AddBuiltinFunc(_0(8210), _1("ivfflat_bit_support"), _2(1), _3(true), _4(false), _5(ivfflat_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8210), _1("ivfflat_bit_support"), _2(0), _3(true), _4(false), _5(ivfflat_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector", 1, diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index 7b05837e0e..ccd3d42d31 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1608,13 +1608,13 @@ DATA(insert OID = 6111 ( 8385 8305 8305 1 o 8311 8301 1970 )); DATA(insert OID = 6115 ( 8386 8305 8305 1 o 8312 8301 1970 )); DATA(insert OID = 6119 ( 8387 8305 8305 1 o 8313 8301 1970 )); DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); -DATA(insert OID = 8980 ( 8392 8305 8305 1 o 8327 403 1970 )); -DATA(insert OID = 8981 ( 8392 8305 8305 2 o 8328 403 1970 )); -DATA(insert OID = 8982 ( 8392 8305 8305 3 o 8331 403 1970 )); -DATA(insert OID = 8983 ( 8392 8305 8305 4 o 8330 403 1970 )); -DATA(insert OID = 8984 ( 8392 8305 8305 5 o 8329 403 1970 )); -DATA(insert OID = 8993 ( 8397 8307 8307 1 o 8333 403 1970 )); -DATA(insert OID = 8994 ( 8397 8307 8307 2 o 8334 403 1970 )); -DATA(insert OID = 8995 ( 8397 8307 8307 3 o 8337 403 1970 )); -DATA(insert OID = 8996 ( 8397 8307 8307 4 o 8336 403 1970 )); -DATA(insert OID = 8997 ( 8397 8307 8307 5 o 8335 403 1970 )); \ No newline at end of file +DATA(insert OID = 8980 ( 8392 8305 8305 1 s 8327 403 1970 )); +DATA(insert OID = 8981 ( 8392 8305 8305 2 s 8328 403 1970 )); +DATA(insert OID = 8982 ( 8392 8305 8305 3 s 8331 403 1970 )); +DATA(insert OID = 8983 ( 8392 8305 8305 4 s 8330 403 1970 )); +DATA(insert OID = 8984 ( 8392 8305 8305 5 s 8329 403 1970 )); +DATA(insert OID = 8993 ( 8397 8307 8307 1 s 8333 403 1970 )); +DATA(insert OID = 8994 ( 8397 8307 8307 2 s 8334 403 1970 )); +DATA(insert OID = 8995 ( 8397 8307 8307 3 s 8337 403 1970 )); +DATA(insert OID = 8996 ( 8397 8307 8307 4 s 8336 403 1970 )); +DATA(insert OID = 8997 ( 8397 8307 8307 5 s 8335 403 1970 )); \ No newline at end of file diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 5cc55cf580..e566732b60 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -391,7 +391,6 @@ DATA(insert OID = 8913 (8300 sparsevec_l1_ops PGNSP PGUID 8384 8307 f 0)); DATA(insert OID = 8914 (8301 vector_l2_ops PGNSP PGUID 8385 8305 t 0)); DATA(insert OID = 8915 (8301 vector_ip_ops PGNSP PGUID 8386 8305 f 0)); DATA(insert OID = 8916 (8301 vector_cosine_ops PGNSP PGUID 8387 8305 f 0)); -DATA(insert OID = 8917 (8301 vector_l1_ops PGNSP PGUID 8388 8305 f 0 )); DATA(insert OID = 8923 (8301 bit_hamming_ops PGNSP PGUID 8394 1560 f 0)); diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 61855d445d..9f2013d839 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -216,7 +216,6 @@ DATA(insert OID = 8384 (8300 sparsevec_l1_ops PGNSP PGUID)); DATA(insert OID = 8385 (8301 vector_l2_ops PGNSP PGUID)); DATA(insert OID = 8386 (8301 vector_ip_ops PGNSP PGUID)); DATA(insert OID = 8387 (8301 vector_cosine_ops PGNSP PGUID)); -DATA(insert OID = 8388 (8301 vector_l1_ops PGNSP PGUID)); DATA(insert OID = 8394 (8301 bit_hamming_ops PGNSP PGUID)); DATA(insert OID = 8392 (403 vector_ops PGNSP PGUID)); diff --git a/src/test/regress/expected/opr_sanity_2.out b/src/test/regress/expected/opr_sanity_2.out index 78cda3ac18..650e9e61f7 100644 --- a/src/test/regress/expected/opr_sanity_2.out +++ b/src/test/regress/expected/opr_sanity_2.out @@ -429,7 +429,8 @@ WHERE p2.opfmethod = p1.oid AND p3.amprocfamily = p2.oid AND p4.amprocrighttype = p3.amprocrighttype) NOT BETWEEN (CASE WHEN p1.amname IN ('gist', 'gin') THEN p1.amsupport - 1 - WHEN p1.amname IN ('btree', 'ubtree') THEN p1.amsupport - 2 + WHEN p1.amname IN ('btree', 'ubtree', 'hnsw') THEN p1.amsupport - 2 + WHEN p1.amname = 'ivfflat' THEN p1.amsupport - 3 ELSE p1.amsupport END) AND p1.amsupport; amname | opfname | amproclefttype | amprocrighttype diff --git a/src/test/regress/sql/opr_sanity_2.sql b/src/test/regress/sql/opr_sanity_2.sql index 8fc4d2a7aa..266030da98 100644 --- a/src/test/regress/sql/opr_sanity_2.sql +++ b/src/test/regress/sql/opr_sanity_2.sql @@ -286,7 +286,8 @@ WHERE p2.opfmethod = p1.oid AND p3.amprocfamily = p2.oid AND p4.amprocrighttype = p3.amprocrighttype) NOT BETWEEN (CASE WHEN p1.amname IN ('gist', 'gin') THEN p1.amsupport - 1 - WHEN p1.amname IN ('btree', 'ubtree') THEN p1.amsupport - 2 + WHEN p1.amname IN ('btree', 'ubtree', 'hnsw') THEN p1.amsupport - 2 + WHEN p1.amname = 'ivfflat' THEN p1.amsupport - 3 ELSE p1.amsupport END) AND p1.amsupport; -- Gitee From 82a7567f17ad2d3dd26b4e79b23eab2d2541fec5 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Tue, 5 Nov 2024 11:26:50 +0800 Subject: [PATCH 60/67] v to i --- src/common/backend/catalog/builtin_funcs.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index 379345bc51..af1a5b8e4d 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13388,7 +13388,7 @@ AddFuncGroup( AddFuncGroup( "hnsw_sparsevec_support", 1, - AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(0), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(0), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "l2_norm", 1, @@ -13433,11 +13433,11 @@ AddFuncGroup( ), AddFuncGroup( "hnsw_bit_support", 1, - AddBuiltinFunc(_0(8209), _1("hnsw_bit_support"), _2(0), _3(true), _4(false), _5(hnsw_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8209), _1("hnsw_bit_support"), _2(0), _3(true), _4(false), _5(hnsw_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "ivfflat_bit_support", 1, - AddBuiltinFunc(_0(8210), _1("ivfflat_bit_support"), _2(0), _3(true), _4(false), _5(ivfflat_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8210), _1("ivfflat_bit_support"), _2(0), _3(true), _4(false), _5(ivfflat_bit_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("ivfflat_bit_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "vector", 1, -- Gitee From 534a63e2ece3c5c9dc578e7ce710ad9afbb93739 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 11:54:05 +0800 Subject: [PATCH 61/67] add suport function range for hnsw and ivfflat --- src/test/regress/expected/opr_sanity_2.out | 1 + src/test/regress/sql/opr_sanity_2.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/src/test/regress/expected/opr_sanity_2.out b/src/test/regress/expected/opr_sanity_2.out index 650e9e61f7..f8ab87dbeb 100644 --- a/src/test/regress/expected/opr_sanity_2.out +++ b/src/test/regress/expected/opr_sanity_2.out @@ -445,6 +445,7 @@ FROM pg_am am JOIN pg_opclass op ON opcmethod = am.oid LEFT JOIN pg_amproc p ON amprocfamily = opcfamily AND amproclefttype = amprocrighttype AND amproclefttype = opcintype WHERE am.amname <> 'btree' AND am.amname <> 'gist' AND am.amname <> 'gin' AND am.amname <> 'ubtree' + AND am.amname <> 'hnsw' AND am.amname <> 'ivfflat' GROUP BY amname, amsupport, opcname, amprocfamily HAVING count(*) != amsupport OR amprocfamily IS NULL; amname | opcname | count diff --git a/src/test/regress/sql/opr_sanity_2.sql b/src/test/regress/sql/opr_sanity_2.sql index 266030da98..cac6c5d43d 100644 --- a/src/test/regress/sql/opr_sanity_2.sql +++ b/src/test/regress/sql/opr_sanity_2.sql @@ -300,6 +300,7 @@ FROM pg_am am JOIN pg_opclass op ON opcmethod = am.oid LEFT JOIN pg_amproc p ON amprocfamily = opcfamily AND amproclefttype = amprocrighttype AND amproclefttype = opcintype WHERE am.amname <> 'btree' AND am.amname <> 'gist' AND am.amname <> 'gin' AND am.amname <> 'ubtree' + AND am.amname <> 'hnsw' AND am.amname <> 'ivfflat' GROUP BY amname, amsupport, opcname, amprocfamily HAVING count(*) != amsupport OR amprocfamily IS NULL; -- Gitee From 5b4b4dc30a47bf982e44fecad6b1d02a16adea2e Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 12:04:07 +0800 Subject: [PATCH 62/67] searching: 1970 -> 0 --- src/include/catalog/pg_amop.data | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/include/catalog/pg_amop.data b/src/include/catalog/pg_amop.data index ccd3d42d31..183993ea5b 100644 --- a/src/include/catalog/pg_amop.data +++ b/src/include/catalog/pg_amop.data @@ -1608,13 +1608,13 @@ DATA(insert OID = 6111 ( 8385 8305 8305 1 o 8311 8301 1970 )); DATA(insert OID = 6115 ( 8386 8305 8305 1 o 8312 8301 1970 )); DATA(insert OID = 6119 ( 8387 8305 8305 1 o 8313 8301 1970 )); DATA(insert OID = 6147 ( 8394 1560 1560 1 o 8323 8301 1970 )); -DATA(insert OID = 8980 ( 8392 8305 8305 1 s 8327 403 1970 )); -DATA(insert OID = 8981 ( 8392 8305 8305 2 s 8328 403 1970 )); -DATA(insert OID = 8982 ( 8392 8305 8305 3 s 8331 403 1970 )); -DATA(insert OID = 8983 ( 8392 8305 8305 4 s 8330 403 1970 )); -DATA(insert OID = 8984 ( 8392 8305 8305 5 s 8329 403 1970 )); -DATA(insert OID = 8993 ( 8397 8307 8307 1 s 8333 403 1970 )); -DATA(insert OID = 8994 ( 8397 8307 8307 2 s 8334 403 1970 )); -DATA(insert OID = 8995 ( 8397 8307 8307 3 s 8337 403 1970 )); -DATA(insert OID = 8996 ( 8397 8307 8307 4 s 8336 403 1970 )); -DATA(insert OID = 8997 ( 8397 8307 8307 5 s 8335 403 1970 )); \ No newline at end of file +DATA(insert OID = 8980 ( 8392 8305 8305 1 s 8327 403 0 )); +DATA(insert OID = 8981 ( 8392 8305 8305 2 s 8328 403 0 )); +DATA(insert OID = 8982 ( 8392 8305 8305 3 s 8331 403 0 )); +DATA(insert OID = 8983 ( 8392 8305 8305 4 s 8330 403 0 )); +DATA(insert OID = 8984 ( 8392 8305 8305 5 s 8329 403 0 )); +DATA(insert OID = 8993 ( 8397 8307 8307 1 s 8333 403 0 )); +DATA(insert OID = 8994 ( 8397 8307 8307 2 s 8334 403 0 )); +DATA(insert OID = 8995 ( 8397 8307 8307 3 s 8337 403 0 )); +DATA(insert OID = 8996 ( 8397 8307 8307 4 s 8336 403 0 )); +DATA(insert OID = 8997 ( 8397 8307 8307 5 s 8335 403 0 )); \ No newline at end of file -- Gitee From 066e255d29bf796eb62b2c1f676fe92094a81057 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Tue, 5 Nov 2024 12:29:54 +0800 Subject: [PATCH 63/67] space --- src/test/regress/expected/opr_sanity_2.out | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/regress/expected/opr_sanity_2.out b/src/test/regress/expected/opr_sanity_2.out index 650e9e61f7..09e7752095 100644 --- a/src/test/regress/expected/opr_sanity_2.out +++ b/src/test/regress/expected/opr_sanity_2.out @@ -261,16 +261,16 @@ ORDER BY 1, 2, 3; 4439 | 5 | ~>~ 4444 | 1 | @@ 4444 | 2 | @@@ - 8300 | 1 | <#> - 8300 | 1 | <%> - 8300 | 1 | <+> - 8300 | 1 | <-> - 8300 | 1 | <=> - 8300 | 1 | <~> - 8301 | 1 | <#> - 8301 | 1 | <-> - 8301 | 1 | <=> - 8301 | 1 | <~> + 8300 | 1 | <#> + 8300 | 1 | <%> + 8300 | 1 | <+> + 8300 | 1 | <-> + 8300 | 1 | <=> + 8300 | 1 | <~> + 8301 | 1 | <#> + 8301 | 1 | <-> + 8301 | 1 | <=> + 8301 | 1 | <~> (90 rows) -- Check that all opclass search operators have selectivity estimators. -- Gitee From 11d3ee788ade8a8fd1b5a11a633a0a2b6c4486ea Mon Sep 17 00:00:00 2001 From: jiwenke Date: Tue, 5 Nov 2024 12:31:17 +0800 Subject: [PATCH 64/67] avg --- src/include/catalog/pg_aggregate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index 69b5258671..c362b96411 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -486,7 +486,7 @@ DATA(insert ( 9990 tdigest_merge tdigest_merge_to_one calculate_quantile_of DATA(insert ( 9986 tdigest_mergep tdigest_merge_to_one calculate_value_at 0 4406 _null_ _null_ n 0)); #define ADDTDIGESTMERGEPOID 9986 /*vector aggregate function*/ -DATA(insert ( 8241 vector_accum vector_combine vector_avg 0 1022 "{0,0,0}" "{0,0,0}" n 0)); +DATA(insert ( 8241 vector_accum vector_combine vector_avg 0 1022 "{0}" "{0}" n 0)); DATA(insert ( 8242 vector_add vector_add - 0 8305 _null_ _null_ n 0)); /* * prototypes for functions in pg_aggregate.c -- Gitee From 2db944609c1457609e2a60a1c98ef95dce3fda20 Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 12:37:21 +0800 Subject: [PATCH 65/67] sql indentation --- src/test/regress/sql/opr_sanity_2.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/sql/opr_sanity_2.sql b/src/test/regress/sql/opr_sanity_2.sql index cac6c5d43d..97edf33c2b 100644 --- a/src/test/regress/sql/opr_sanity_2.sql +++ b/src/test/regress/sql/opr_sanity_2.sql @@ -300,7 +300,7 @@ FROM pg_am am JOIN pg_opclass op ON opcmethod = am.oid LEFT JOIN pg_amproc p ON amprocfamily = opcfamily AND amproclefttype = amprocrighttype AND amproclefttype = opcintype WHERE am.amname <> 'btree' AND am.amname <> 'gist' AND am.amname <> 'gin' AND am.amname <> 'ubtree' - AND am.amname <> 'hnsw' AND am.amname <> 'ivfflat' + AND am.amname <> 'hnsw' AND am.amname <> 'ivfflat' GROUP BY amname, amsupport, opcname, amprocfamily HAVING count(*) != amsupport OR amprocfamily IS NULL; -- Gitee From 811b3875633d3e19f8ebb7bdd11d57788f3a002e Mon Sep 17 00:00:00 2001 From: h30054849 Date: Tue, 5 Nov 2024 13:03:45 +0800 Subject: [PATCH 66/67] fix wrong input --- src/common/backend/catalog/builtin_funcs.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index af1a5b8e4d..2815fe25cd 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -13388,7 +13388,7 @@ AddFuncGroup( AddFuncGroup( "hnsw_sparsevec_support", 1, - AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(0), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + AddBuiltinFunc(_0(8479), _1("hnsw_sparsevec_support"), _2(0), _3(true), _4(false), _5(hnsw_sparsevec_support), _6(2281), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 2281), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("hnsw_sparsevec_support"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("NULL"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), AddFuncGroup( "l2_norm", 1, -- Gitee From 1ad098854eecd0da66886f4fb4fe077da9e84665 Mon Sep 17 00:00:00 2001 From: jiwenke Date: Tue, 5 Nov 2024 14:53:32 +0800 Subject: [PATCH 67/67] max dims --- src/common/backend/utils/adt/halfvec.cpp | 3 +-- src/common/backend/utils/adt/vector.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/common/backend/utils/adt/halfvec.cpp b/src/common/backend/utils/adt/halfvec.cpp index c03616cd94..3ee57c1cf7 100644 --- a/src/common/backend/utils/adt/halfvec.cpp +++ b/src/common/backend/utils/adt/halfvec.cpp @@ -132,8 +132,7 @@ static inline bool HalfvecIsspace(char ch) */ static float8 *CheckStateArray(ArrayType *statearray, const char *caller) { - if (ARR_NDIM(statearray) != 1 || ARR_DIMS(statearray)[0] < 1 || ARR_HASNULL(statearray) || - ARR_ELEMTYPE(statearray) != FLOAT8OID) + if (ARR_NDIM(statearray) != 1 || ARR_DIMS(statearray)[0] < 1 || ARR_HASNULL(statearray)) elog(ERROR, "%s: expected state array", caller); return (float8 *)ARR_DATA_PTR(statearray); } diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 389f503296..0daff7aee6 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -158,8 +158,7 @@ static inline bool VectorIsspace(char ch) */ static float8 *CheckStateArray(ArrayType *statearray, const char *caller) { - if (ARR_NDIM(statearray) != 1 || ARR_DIMS(statearray)[0] < 1 || ARR_HASNULL(statearray) || - ARR_ELEMTYPE(statearray) != FLOAT8OID) + if (ARR_NDIM(statearray) != 1 || ARR_DIMS(statearray)[0] < 1 || ARR_HASNULL(statearray)) elog(ERROR, "%s: expected state array", caller); return (float8 *)ARR_DATA_PTR(statearray); } -- Gitee