| 362 | */ |
| 363 | PG_FUNCTION_INFO_V1(array_to_floatvector); |
| 364 | Datum array_to_floatvector(PG_FUNCTION_ARGS) |
| 365 | { |
| 366 | ArrayType *array = PG_GETARG_ARRAYTYPE_P(0); |
| 367 | int32 typmod = PG_GETARG_INT32(1); |
| 368 | |
| 369 | if (ARR_NDIM(array) > 1) { |
| 370 | ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), |
| 371 | errmsg("array must be 1-D"))); |
| 372 | } |
| 373 | |
| 374 | if (ARR_HASNULL(array) && array_contains_nulls(array)) { |
| 375 | ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 376 | errmsg("array must not contain nulls"))); |
| 377 | } |
| 378 | |
| 379 | bool typbyval; |
| 380 | char typalign; |
| 381 | int16 typlen; |
| 382 | int nelemsp; |
| 383 | Datum *elemsp; |
| 384 | get_typlenbyvalalign(ARR_ELEMTYPE(array), &typlen, &typbyval, &typalign); |
| 385 | deconstruct_array(array, ARR_ELEMTYPE(array), typlen, typbyval, typalign, &elemsp, NULL, &nelemsp); |
| 386 | |
| 387 | CheckDim(nelemsp); |
| 388 | CheckExpectedDim(typmod, nelemsp); |
| 389 | |
| 390 | FloatVector *result = InitFloatVector(nelemsp); |
| 391 | if (ARR_ELEMTYPE(array) == INT4OID) { |
| 392 | for (int i = 0; i < nelemsp; ++i) { |
| 393 | result->x[i] = DatumGetInt32(elemsp[i]); |
| 394 | } |
| 395 | } else if (ARR_ELEMTYPE(array) == FLOAT8OID) { |
| 396 | for (int i = 0; i < nelemsp; ++i) { |
| 397 | result->x[i] = DatumGetFloat8(elemsp[i]); |
| 398 | } |
| 399 | } else if (ARR_ELEMTYPE(array) == FLOAT4OID) { |
| 400 | for (int i = 0; i < nelemsp; ++i) |
| 401 | result->x[i] = DatumGetFloat4(elemsp[i]); |
| 402 | } else if (ARR_ELEMTYPE(array) == NUMERICOID) { |
| 403 | /* FLOAT4OID = 700 是类型 OID,不是函数 OID;OidFunctionCall1 第一参数 |
| 404 | * 必须是 pg_proc.oid。原代码会触发 `cache lookup failed for function 700`。 |
| 405 | * 用 numeric_float4 C 符号经 DirectFunctionCall1 直接转换。 */ |
| 406 | for (int i = 0; i < nelemsp; ++i) { |
| 407 | result->x[i] = DatumGetFloat4(DirectFunctionCall1(numeric_float4, elemsp[i])); |
| 408 | } |
| 409 | } else { |
| 410 | ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), |
| 411 | errmsg("unsupported array type"))); |
| 412 | } |
| 413 | |
| 414 | /* |
| 415 | * Free allocation from deconstruct_array. Do not free individual elements |
| 416 | * when pass-by-reference since they point to original array. |
| 417 | */ |
| 418 | pfree(elemsp); |
| 419 | |
| 420 | /* Check elements */ |
| 421 | for (int i = 0; i < result->dim; ++i) { |
nothing calls this directly
no test coverage detected