PostgreSQL Source Code  git master
array.h File Reference
#include "fmgr.h"
#include "utils/expandeddatum.h"
Include dependency graph for array.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ArrayType
 
struct  ExpandedArrayHeader
 
union  AnyArrayType
 
struct  ArrayBuildState
 
struct  ArrayBuildStateArr
 
struct  ArrayBuildStateAny
 
struct  ArrayMetaState
 
struct  ArrayMapState
 

Macros

#define MAXDIM   6
 
#define EA_MAGIC   689375833 /* ID for debugging crosschecks */
 
#define DatumGetArrayTypeP(X)   ((ArrayType *) PG_DETOAST_DATUM(X))
 
#define DatumGetArrayTypePCopy(X)   ((ArrayType *) PG_DETOAST_DATUM_COPY(X))
 
#define PG_GETARG_ARRAYTYPE_P(n)   DatumGetArrayTypeP(PG_GETARG_DATUM(n))
 
#define PG_GETARG_ARRAYTYPE_P_COPY(n)   DatumGetArrayTypePCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_ARRAYTYPE_P(x)   PG_RETURN_POINTER(x)
 
#define PG_GETARG_EXPANDED_ARRAY(n)   DatumGetExpandedArray(PG_GETARG_DATUM(n))
 
#define PG_GETARG_EXPANDED_ARRAYX(n, metacache)   DatumGetExpandedArrayX(PG_GETARG_DATUM(n), metacache)
 
#define PG_RETURN_EXPANDED_ARRAY(x)   PG_RETURN_DATUM(EOHPGetRWDatum(&(x)->hdr))
 
#define PG_GETARG_ANY_ARRAY_P(n)   DatumGetAnyArrayP(PG_GETARG_DATUM(n))
 
#define ARR_SIZE(a)   VARSIZE(a)
 
#define ARR_NDIM(a)   ((a)->ndim)
 
#define ARR_HASNULL(a)   ((a)->dataoffset != 0)
 
#define ARR_ELEMTYPE(a)   ((a)->elemtype)
 
#define ARR_DIMS(a)   ((int *) (((char *) (a)) + sizeof(ArrayType)))
 
#define ARR_LBOUND(a)
 
#define ARR_NULLBITMAP(a)
 
#define ARR_OVERHEAD_NONULLS(ndims)   MAXALIGN(sizeof(ArrayType) + 2 * sizeof(int) * (ndims))
 
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
 
#define ARR_DATA_OFFSET(a)   (ARR_HASNULL(a) ? (a)->dataoffset : ARR_OVERHEAD_NONULLS(ARR_NDIM(a)))
 
#define ARR_DATA_PTR(a)   (((char *) (a)) + ARR_DATA_OFFSET(a))
 
#define AARR_NDIM(a)
 
#define AARR_HASNULL(a)
 
#define AARR_ELEMTYPE(a)
 
#define AARR_DIMS(a)
 
#define AARR_LBOUND(a)
 

Typedefs

typedef struct ArrayType ArrayType
 
typedef struct ExpandedArrayHeader ExpandedArrayHeader
 
typedef union AnyArrayType AnyArrayType
 
typedef struct ArrayBuildState ArrayBuildState
 
typedef struct ArrayBuildStateArr ArrayBuildStateArr
 
typedef struct ArrayBuildStateAny ArrayBuildStateAny
 
typedef struct ArrayMetaState ArrayMetaState
 
typedef struct ArrayMapState ArrayMapState
 
typedef struct ArrayIteratorDataArrayIterator
 

Functions

void CopyArrayEls (ArrayType *array, Datum *values, bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)
 
Datum array_get_element (Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
 
Datum array_set_element (Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_get_slice (Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_set_slice (Datum arraydatum, int nSubscripts, int *upperIndx, int *lowerIndx, bool *upperProvided, bool *lowerProvided, Datum srcArrayDatum, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_ref (ArrayType *array, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
 
ArrayTypearray_set (ArrayType *array, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
 
Datum array_map (Datum arrayd, struct ExprState *exprstate, struct ExprContext *econtext, Oid retType, ArrayMapState *amstate)
 
void array_bitmap_copy (bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
 
ArrayTypeconstruct_array (Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
 
ArrayTypeconstruct_md_array (Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
 
ArrayTypeconstruct_empty_array (Oid elmtype)
 
ExpandedArrayHeaderconstruct_empty_expanded_array (Oid element_type, MemoryContext parentcontext, ArrayMetaState *metacache)
 
void deconstruct_array (ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
 
bool array_contains_nulls (ArrayType *array)
 
ArrayBuildStateinitArrayResult (Oid element_type, MemoryContext rcontext, bool subcontext)
 
ArrayBuildStateaccumArrayResult (ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
 
Datum makeArrayResult (ArrayBuildState *astate, MemoryContext rcontext)
 
Datum makeMdArrayResult (ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
 
ArrayBuildStateArrinitArrayResultArr (Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)
 
ArrayBuildStateArraccumArrayResultArr (ArrayBuildStateArr *astate, Datum dvalue, bool disnull, Oid array_type, MemoryContext rcontext)
 
Datum makeArrayResultArr (ArrayBuildStateArr *astate, MemoryContext rcontext, bool release)
 
ArrayBuildStateAnyinitArrayResultAny (Oid input_type, MemoryContext rcontext, bool subcontext)
 
ArrayBuildStateAnyaccumArrayResultAny (ArrayBuildStateAny *astate, Datum dvalue, bool disnull, Oid input_type, MemoryContext rcontext)
 
Datum makeArrayResultAny (ArrayBuildStateAny *astate, MemoryContext rcontext, bool release)
 
ArrayIterator array_create_iterator (ArrayType *arr, int slice_ndim, ArrayMetaState *mstate)
 
bool array_iterate (ArrayIterator iterator, Datum *value, bool *isnull)
 
void array_free_iterator (ArrayIterator iterator)
 
int ArrayGetOffset (int n, const int *dim, const int *lb, const int *indx)
 
int ArrayGetOffset0 (int n, const int *tup, const int *scale)
 
int ArrayGetNItems (int ndim, const int *dims)
 
void ArrayCheckBounds (int ndim, const int *dims, const int *lb)
 
void mda_get_range (int n, int *span, const int *st, const int *endp)
 
void mda_get_prod (int n, const int *range, int *prod)
 
void mda_get_offset_values (int n, int *dist, const int *prod, const int *span)
 
int mda_next_tuple (int n, int *curr, const int *span)
 
int32ArrayGetIntegerTypmods (ArrayType *arr, int *n)
 
Datum expand_array (Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
 
ExpandedArrayHeaderDatumGetExpandedArray (Datum d)
 
ExpandedArrayHeaderDatumGetExpandedArrayX (Datum d, ArrayMetaState *metacache)
 
AnyArrayTypeDatumGetAnyArrayP (Datum d)
 
void deconstruct_expanded_array (ExpandedArrayHeader *eah)
 

Variables

bool Array_nulls
 

Macro Definition Documentation

◆ AARR_DIMS

#define AARR_DIMS (   a)

◆ AARR_ELEMTYPE

#define AARR_ELEMTYPE (   a)
Value:
(a)->xpn.element_type : ARR_ELEMTYPE((ArrayType *) (a)))
#define VARATT_IS_EXPANDED_HEADER(PTR)
#define ARR_ELEMTYPE(a)
Definition: array.h:285

Definition at line 328 of file array.h.

Referenced by array_cmp(), array_contain_compare(), array_eq(), array_map(), array_out(), array_send(), array_unnest(), hash_array(), and hash_array_extended().

◆ AARR_HASNULL

#define AARR_HASNULL (   a)
Value:
((a)->xpn.dvalues != NULL ? (a)->xpn.dnulls != NULL : ARR_HASNULL((a)->xpn.fvalue)) : \
#define ARR_HASNULL(a)
Definition: array.h:284
#define VARATT_IS_EXPANDED_HEADER(PTR)

Definition at line 324 of file array.h.

Referenced by array_send().

◆ AARR_LBOUND

#define AARR_LBOUND (   a)
Value:
(a)->xpn.lbound : ARR_LBOUND((ArrayType *) (a)))
#define ARR_LBOUND(a)
Definition: array.h:289
#define VARATT_IS_EXPANDED_HEADER(PTR)

Definition at line 334 of file array.h.

Referenced by array_cmp(), array_dims(), array_eq(), array_lower(), array_map(), array_out(), array_send(), array_upper(), and generate_subscripts().

◆ AARR_NDIM

#define AARR_NDIM (   a)

◆ ARR_DATA_OFFSET

#define ARR_DATA_OFFSET (   a)    (ARR_HASNULL(a) ? (a)->dataoffset : ARR_OVERHEAD_NONULLS(ARR_NDIM(a)))

◆ ARR_DATA_PTR

#define ARR_DATA_PTR (   a)    (((char *) (a)) + ARR_DATA_OFFSET(a))

Definition at line 315 of file array.h.

Referenced by _arrq_cons(), _lca(), _lt_q_regex(), _ltree_compress(), accumArrayResultArr(), AlterPolicy(), array_cat(), array_create_iterator(), array_extract_slice(), array_fill_internal(), array_get_element(), array_get_slice(), array_insert_slice(), array_iter_setup(), array_iterator(), array_replace_internal(), array_set_element(), array_set_slice(), array_to_text_internal(), arrq_cons(), build_function_result_tupdesc_d(), check_float8_array(), check_role_for_policy(), CopyArrayEls(), cube_subset(), deconstruct_array(), DeconstructFkConstraintRow(), equalPolicy(), ExecEvalArrayExpr(), ExecEvalHashedScalarArrayOp(), ExecEvalScalarArrayOp(), expand_array(), expand_function_arguments(), extension_config_remove(), fetch_statentries_for_relation(), FuncnameGetCandidates(), generateClonedExtStatsStmt(), get_attstatsslot(), get_func_arg_info(), get_func_input_arg_names(), get_func_result_name(), get_func_trftypes(), get_primary_key_attnos(), get_relation_constraint_attnos(), get_text_array_contents(), getWeights(), heap_force_common(), int2_avg_accum(), int2_avg_accum_inv(), int2int4_sum(), int4_avg_accum(), int4_avg_accum_inv(), int4_avg_combine(), int8_avg(), lt_q_regex(), makeArrayResultArr(), pg_extension_config_dump(), pg_get_statisticsobj_worker(), pg_isolation_test_session_is_blocked(), PLyList_FromArray(), ProcedureCreate(), RelationGetExclusionInfo(), RemoveRoleFromObjectPolicy(), transformCallStmt(), TryReuseForeignKey(), width_bucket_array_fixed(), width_bucket_array_float8(), and width_bucket_array_variable().

◆ ARR_DIMS

#define ARR_DIMS (   a)    ((int *) (((char *) (a)) + sizeof(ArrayType)))

Definition at line 287 of file array.h.

Referenced by _arrq_cons(), _lca(), _lt_q_regex(), _ltree_compress(), accumArrayResultArr(), aclnewowner(), aclupdate(), allocacl(), AlterPolicy(), array_cat(), array_contains_nulls(), array_create_iterator(), array_fill_internal(), array_get_element(), array_get_slice(), array_in(), array_insert_slice(), array_iterator(), array_map(), array_recv(), array_replace_internal(), array_set_element(), array_set_slice(), array_to_json_internal(), array_to_jsonb_internal(), array_to_text_internal(), arrq_cons(), build_function_result_tupdesc_d(), check_float8_array(), check_role_for_policy(), clause_is_strict_for(), construct_md_array(), convert_saop_to_hashed_saop_walker(), count_nulls(), create_array_envelope(), deconstruct_array(), DeconstructFkConstraintRow(), EA_flatten_into(), equalPolicy(), estimate_array_length(), ExecEvalArrayExpr(), ExecEvalHashedScalarArrayOp(), ExecEvalScalarArrayOp(), expand_array(), expand_function_arguments(), extension_config_remove(), fetch_statentries_for_relation(), FuncnameGetCandidates(), generateClonedExtStatsStmt(), get_attstatsslot(), get_func_arg_info(), get_func_input_arg_names(), get_func_result_name(), get_func_trftypes(), get_primary_key_attnos(), get_relation_constraint_attnos(), get_text_array_contents(), getWeights(), GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), hstore_from_array(), hstore_from_arrays(), hstore_slice_to_array(), int2vectorrecv(), is_strict_saop(), json_object(), jsonb_object(), lt_q_regex(), makeArrayResultArr(), new_intArrayType(), oidvectorrecv(), percentile_cont_multi_final_common(), percentile_disc_multi_final(), pg_extension_config_dump(), pg_get_functiondef(), pg_get_statisticsobj_worker(), pg_isolation_test_session_is_blocked(), plperl_ref_from_pg_array(), PLyList_FromArray(), predicate_classify(), ProcedureCreate(), ProcessGUCArray(), RelationGetExclusionInfo(), RemoveRoleFromObjectPolicy(), resize_intArrayType(), sanity_check_tid_array(), SPI_sql_row_to_xmlelement(), transformCallStmt(), trim_array(), TryReuseForeignKey(), width_bucket_array_fixed(), width_bucket_array_float8(), and width_bucket_array_variable().

◆ ARR_ELEMTYPE

#define ARR_ELEMTYPE (   a)    ((a)->elemtype)

Definition at line 285 of file array.h.

Referenced by _bt_preprocess_array_keys(), array_cat(), array_create_iterator(), array_get_slice(), array_iterate(), array_position_common(), array_positions(), array_replace_internal(), array_set_element(), array_set_slice(), array_to_json_internal(), array_to_jsonb_internal(), array_to_text_internal(), arrayconst_startup_fn(), ArrayGetIntegerTypmods(), build_function_result_tupdesc_d(), check_acl(), check_float8_array(), compute_array_stats(), DecodeTextArrayToBitmapset(), deconstruct_array(), DeconstructFkConstraintRow(), exec_stmt_foreach_a(), ExecEvalArrayCoerce(), ExecEvalArrayExpr(), ExecEvalHashedScalarArrayOp(), ExecEvalScalarArrayOp(), ExecIndexEvalArrayKeys(), expand_array(), expand_function_arguments(), extension_config_remove(), extract_variadic_args(), fetch_statentries_for_relation(), FuncnameGetCandidates(), generateClonedExtStatsStmt(), get_attstatsslot(), get_func_arg_info(), get_func_input_arg_names(), get_func_result_name(), get_func_trftypes(), get_primary_key_attnos(), get_relation_constraint_attnos(), get_text_array_contents(), ginarrayextract(), gincost_scalararrayopexpr(), ginqueryarrayextract(), GUCArrayAdd(), hstore_from_array(), hstore_from_arrays(), int2vectorrecv(), map_sql_value_to_xml_value(), match_clause_to_partition_key(), mcv_get_match_bitmap(), multirange_constructor2(), new_intArrayType(), oidvectorrecv(), pg_extension_config_dump(), pg_get_functiondef(), pg_get_statisticsobj_worker(), pg_isolation_test_session_is_blocked(), pg_logical_slot_get_changes_guts(), plperl_ref_from_pg_array(), ProcedureCreate(), ProcessGUCArray(), RelationGetExclusionInfo(), satisfies_hash_partition(), scalararraysel(), SPI_sql_row_to_xmlelement(), text_format(), transformCallStmt(), trim_array(), TryReuseForeignKey(), and width_bucket_array().

◆ ARR_HASNULL

◆ ARR_LBOUND

◆ ARR_NDIM

#define ARR_NDIM (   a)    ((a)->ndim)

Definition at line 283 of file array.h.

Referenced by _arrq_cons(), _lca(), _lt_q_regex(), _ltree_compress(), accumArrayResultArr(), array_cat(), array_contains_nulls(), array_create_iterator(), array_fill_internal(), array_get_element(), array_get_slice(), array_insert_slice(), array_iterator(), array_position_common(), array_positions(), array_replace_internal(), array_set_element(), array_set_slice(), array_to_json_internal(), array_to_jsonb_internal(), array_to_text_internal(), ArrayGetIntegerTypmods(), arrq_cons(), build_function_result_tupdesc_d(), check_acl(), check_float8_array(), clause_is_strict_for(), convert_saop_to_hashed_saop_walker(), count_nulls(), DecodeTextArrayToBitmapset(), deconstruct_array(), DeconstructFkConstraintRow(), estimate_array_length(), exec_stmt_foreach_a(), ExecEvalArrayExpr(), ExecEvalHashedScalarArrayOp(), ExecEvalScalarArrayOp(), expand_array(), expand_function_arguments(), extension_config_remove(), fetch_statentries_for_relation(), FuncnameGetCandidates(), generateClonedExtStatsStmt(), get_attstatsslot(), get_func_arg_info(), get_func_input_arg_names(), get_func_result_name(), get_func_trftypes(), get_primary_key_attnos(), get_relation_constraint_attnos(), get_text_array_contents(), getWeights(), GUCArrayAdd(), hstore_from_array(), hstore_from_arrays(), hstore_slice_to_array(), int2vectorrecv(), is_strict_saop(), json_object(), json_object_two_arg(), jsonb_delete_array(), jsonb_delete_path(), jsonb_insert(), jsonb_object(), jsonb_object_two_arg(), jsonb_set(), lt_q_regex(), multirange_constructor2(), new_intArrayType(), oidvectorrecv(), parse_key_value_arrays(), percentile_cont_multi_final_common(), percentile_disc_multi_final(), pg_extension_config_dump(), pg_get_functiondef(), pg_get_statisticsobj_worker(), pg_isolation_test_session_is_blocked(), pg_logical_slot_get_changes_guts(), plperl_ref_from_pg_array(), PLyList_FromArray(), predicate_classify(), ProcedureCreate(), ProcessGUCArray(), RelationGetExclusionInfo(), resize_intArrayType(), sanity_check_tid_array(), SPI_sql_row_to_xmlelement(), transformCallStmt(), TryReuseForeignKey(), width_bucket_array(), width_bucket_array_fixed(), width_bucket_array_float8(), and width_bucket_array_variable().

◆ ARR_NULLBITMAP

◆ ARR_OVERHEAD_NONULLS

◆ ARR_OVERHEAD_WITHNULLS

#define ARR_OVERHEAD_WITHNULLS (   ndims,
  nitems 
)

◆ ARR_SIZE

◆ DatumGetArrayTypeP

#define DatumGetArrayTypeP (   X)    ((ArrayType *) PG_DETOAST_DATUM(X))

Definition at line 254 of file array.h.

Referenced by _bt_preprocess_array_keys(), _ltree_compress(), accumArrayResultArr(), AlterFunction(), AlterSetting(), ApplySetting(), array_get_element(), array_get_slice(), array_set(), array_set_element(), array_set_slice(), array_to_json_internal(), array_to_jsonb_internal(), arrayconst_startup_fn(), build_function_result_tupdesc_d(), calc_arraycontsel(), clause_is_strict_for(), compute_array_stats(), DecodeTextArrayToBitmapset(), decompile_column_index_array(), DeconstructFkConstraintRow(), estimate_array_length(), ExecEvalArrayExpr(), ExecEvalHashedScalarArrayOp(), ExecEvalScalarArrayOp(), ExecIndexEvalArrayKeys(), expand_function_arguments(), extension_config_remove(), fetch_statentries_for_relation(), FuncnameGetCandidates(), g_int_compress(), g_int_decompress(), g_intbig_compress(), generateClonedExtStatsStmt(), generateClonedIndexStmt(), get_func_arg_info(), get_func_input_arg_names(), get_func_result_name(), get_func_trftypes(), get_primary_key_attnos(), get_relation_constraint_attnos(), get_reloptions(), GetSubscription(), gincost_scalararrayopexpr(), is_strict_saop(), map_sql_value_to_xml_value(), match_clause_to_partition_key(), mcv_get_match_bitmap(), oid_array_to_list(), parseRelOptionsInternal(), pg_extension_config_dump(), pg_get_constraintdef_worker(), pg_get_functiondef(), pg_get_statisticsobj_worker(), pg_isolation_test_session_is_blocked(), plperl_ref_from_pg_array(), PLyList_FromArray(), predicate_classify(), RelationGetExclusionInfo(), scalararraysel(), TidListEval(), transformCallStmt(), transformRelOptions(), TryReuseForeignKey(), and untransformRelOptions().

◆ DatumGetArrayTypePCopy

◆ EA_MAGIC

#define EA_MAGIC   689375833 /* ID for debugging crosschecks */

◆ MAXDIM

◆ PG_GETARG_ANY_ARRAY_P

◆ PG_GETARG_ARRAYTYPE_P

#define PG_GETARG_ARRAYTYPE_P (   n)    DatumGetArrayTypeP(PG_GETARG_DATUM(n))

Definition at line 256 of file array.h.

Referenced by _lca(), _lt_q_regex(), _ltq_extract_regex(), _ltq_regex(), _ltree_extract_isparent(), _ltree_extract_risparent(), _ltree_isparent(), _ltree_risparent(), _ltxtq_exec(), _ltxtq_extract_exec(), array_cat(), array_fill(), array_fill_with_lower_bounds(), array_position_common(), array_positions(), array_remove(), array_replace(), array_to_text(), array_to_text_null(), array_to_tsvector(), binary_upgrade_create_empty_extension(), bittypmodin(), bpchartypmodin(), concat_internal(), count_nulls(), cube_a_f8(), cube_a_f8_f8(), cube_subset(), dblink_build_sql_delete(), dblink_build_sql_insert(), dblink_build_sql_update(), extract_variadic_args(), float4_accum(), float8_accum(), float8_avg(), float8_combine(), float8_corr(), float8_covar_pop(), float8_covar_samp(), float8_regr_accum(), float8_regr_avgx(), float8_regr_avgy(), float8_regr_combine(), float8_regr_intercept(), float8_regr_r2(), float8_regr_slope(), float8_regr_sxx(), float8_regr_sxy(), float8_regr_syy(), float8_stddev_pop(), float8_stddev_samp(), float8_var_pop(), float8_var_samp(), g_int_same(), g_intbig_consistent(), get_jsonb_path_all(), get_path_all(), ghstore_consistent(), gin_extract_hstore_query(), gin_extract_jsonb_query(), ginint4_queryextract(), hstore_delete_array(), hstore_exists_all(), hstore_exists_any(), hstore_from_array(), hstore_from_arrays(), hstore_slice_to_array(), hstore_slice_to_hstore(), icount(), idx(), int2_avg_accum(), int2_avg_accum_inv(), int2int4_sum(), int4_avg_accum(), int4_avg_accum_inv(), int4_avg_combine(), int8_avg(), intarray_push_array(), intarray_push_elem(), interval_accum(), interval_accum_inv(), interval_avg(), interval_combine(), intervaltypmodin(), intset_union_elem(), json_object(), json_object_two_arg(), jsonb_delete_array(), jsonb_delete_path(), jsonb_exists_all(), jsonb_exists_any(), jsonb_insert(), jsonb_object(), jsonb_object_two_arg(), jsonb_set(), lt_q_regex(), ltree_consistent(), multirange_constructor2(), numerictypmodin(), percentile_cont_multi_final_common(), percentile_disc_multi_final(), pg_armor(), pg_get_object_address(), pg_isolation_test_session_is_blocked(), pg_logical_slot_get_changes_guts(), satisfies_hash_partition(), subarray(), text_format(), timestamptypmodin(), timestamptztypmodin(), timetypmodin(), timetztypmodin(), trim_array(), tsvector_delete_arr(), tsvector_filter(), tsvector_setweight_by_filter(), varbittypmodin(), varchartypmodin(), width_bucket_array(), xpath(), and xpath_exists().

◆ PG_GETARG_ARRAYTYPE_P_COPY

◆ PG_GETARG_EXPANDED_ARRAY

#define PG_GETARG_EXPANDED_ARRAY (   n)    DatumGetExpandedArray(PG_GETARG_DATUM(n))

Definition at line 261 of file array.h.

◆ PG_GETARG_EXPANDED_ARRAYX

#define PG_GETARG_EXPANDED_ARRAYX (   n,
  metacache 
)    DatumGetExpandedArrayX(PG_GETARG_DATUM(n), metacache)

Definition at line 262 of file array.h.

Referenced by fetch_array_arg_replace_nulls().

◆ PG_RETURN_ARRAYTYPE_P

◆ PG_RETURN_EXPANDED_ARRAY

#define PG_RETURN_EXPANDED_ARRAY (   x)    PG_RETURN_DATUM(EOHPGetRWDatum(&(x)->hdr))

Definition at line 264 of file array.h.

Typedef Documentation

◆ AnyArrayType

typedef union AnyArrayType AnyArrayType

◆ ArrayBuildState

◆ ArrayBuildStateAny

◆ ArrayBuildStateArr

◆ ArrayIterator

Definition at line 251 of file array.h.

◆ ArrayMapState

typedef struct ArrayMapState ArrayMapState

◆ ArrayMetaState

◆ ArrayType

typedef struct ArrayType ArrayType

◆ ExpandedArrayHeader

Function Documentation

◆ accumArrayResult()

ArrayBuildState* accumArrayResult ( ArrayBuildState astate,
Datum  dvalue,
bool  disnull,
Oid  element_type,
MemoryContext  rcontext 
)

Definition at line 5122 of file arrayfuncs.c.

References ArrayBuildState::alen, Assert, datumCopy(), ArrayBuildState::dnulls, ArrayBuildState::dvalues, ArrayBuildState::element_type, initArrayResult(), ArrayBuildState::mcontext, MemoryContextSwitchTo(), ArrayBuildState::nelems, PG_DETOAST_DATUM_COPY, PointerGetDatum, repalloc(), ArrayBuildState::typbyval, and ArrayBuildState::typlen.

Referenced by accumArrayResultAny(), array_agg_transfn(), array_positions(), array_to_datum_internal(), brin_minmax_multi_summary_out(), dblink_get_connections(), get_altertable_subcmdtypes(), optionListToArray(), parse_ident(), pg_get_statisticsobjdef_expressions(), pg_stats_ext_mcvlist_items(), populate_array_element(), range_agg_transfn(), regexp_split_to_array(), serialize_expr_stats(), SPI_sql_row_to_xmlelement(), split_text_accum_result(), transformRelOptions(), and tuple_data_split_internal().

5126 {
5127  MemoryContext oldcontext;
5128 
5129  if (astate == NULL)
5130  {
5131  /* First time through --- initialize */
5132  astate = initArrayResult(element_type, rcontext, true);
5133  }
5134  else
5135  {
5136  Assert(astate->element_type == element_type);
5137  }
5138 
5139  oldcontext = MemoryContextSwitchTo(astate->mcontext);
5140 
5141  /* enlarge dvalues[]/dnulls[] if needed */
5142  if (astate->nelems >= astate->alen)
5143  {
5144  astate->alen *= 2;
5145  astate->dvalues = (Datum *)
5146  repalloc(astate->dvalues, astate->alen * sizeof(Datum));
5147  astate->dnulls = (bool *)
5148  repalloc(astate->dnulls, astate->alen * sizeof(bool));
5149  }
5150 
5151  /*
5152  * Ensure pass-by-ref stuff is copied into mcontext; and detoast it too if
5153  * it's varlena. (You might think that detoasting is not needed here
5154  * because construct_md_array can detoast the array elements later.
5155  * However, we must not let construct_md_array modify the ArrayBuildState
5156  * because that would mean array_agg_finalfn damages its input, which is
5157  * verboten. Also, this way frequently saves one copying step.)
5158  */
5159  if (!disnull && !astate->typbyval)
5160  {
5161  if (astate->typlen == -1)
5162  dvalue = PointerGetDatum(PG_DETOAST_DATUM_COPY(dvalue));
5163  else
5164  dvalue = datumCopy(dvalue, astate->typbyval, astate->typlen);
5165  }
5166 
5167  astate->dvalues[astate->nelems] = dvalue;
5168  astate->dnulls[astate->nelems] = disnull;
5169  astate->nelems++;
5170 
5171  MemoryContextSwitchTo(oldcontext);
5172 
5173  return astate;
5174 }
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:242
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5083
#define PointerGetDatum(X)
Definition: postgres.h:600
Datum * dvalues
Definition: array.h:183
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool typbyval
Definition: array.h:189
Oid element_type
Definition: array.h:187
bool * dnulls
Definition: array.h:184
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:131
uintptr_t Datum
Definition: postgres.h:411
#define Assert(condition)
Definition: c.h:804
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
MemoryContext mcontext
Definition: array.h:182
int16 typlen
Definition: array.h:188

◆ accumArrayResultAny()

ArrayBuildStateAny* accumArrayResultAny ( ArrayBuildStateAny astate,
Datum  dvalue,
bool  disnull,
Oid  input_type,
MemoryContext  rcontext 
)

Definition at line 5593 of file arrayfuncs.c.

References accumArrayResult(), accumArrayResultArr(), ArrayBuildStateAny::arraystate, initArrayResultAny(), and ArrayBuildStateAny::scalarstate.

Referenced by ExecScanSubPlan(), and ExecSetParamPlan().

5597 {
5598  if (astate == NULL)
5599  astate = initArrayResultAny(input_type, rcontext, true);
5600 
5601  if (astate->scalarstate)
5602  (void) accumArrayResult(astate->scalarstate,
5603  dvalue, disnull,
5604  input_type, rcontext);
5605  else
5606  (void) accumArrayResultArr(astate->arraystate,
5607  dvalue, disnull,
5608  input_type, rcontext);
5609 
5610  return astate;
5611 }
ArrayBuildStateAny * initArrayResultAny(Oid input_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5548
ArrayBuildState * scalarstate
Definition: array.h:222
ArrayBuildStateArr * accumArrayResultArr(ArrayBuildStateArr *astate, Datum dvalue, bool disnull, Oid array_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5316
ArrayBuildStateArr * arraystate
Definition: array.h:223
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5122

◆ accumArrayResultArr()

ArrayBuildStateArr* accumArrayResultArr ( ArrayBuildStateArr astate,
Datum  dvalue,
bool  disnull,
Oid  array_type,
MemoryContext  rcontext 
)

Definition at line 5316 of file arrayfuncs.c.

References ArrayBuildStateArr::abytes, ArrayBuildStateArr::aitems, arg, ARR_DATA_OFFSET, ARR_DATA_PTR, ARR_DIMS, ARR_HASNULL, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_SIZE, array_bitmap_copy(), ArrayBuildStateArr::array_type, ArrayGetNItems(), Assert, ArrayBuildStateArr::data, DatumGetArrayTypeP, DatumGetPointer, ArrayBuildStateArr::dims, ereport, errcode(), errmsg(), ERROR, i, initArrayResultArr(), InvalidOid, ArrayBuildStateArr::lbs, Max, MAXDIM, ArrayBuildStateArr::mcontext, MemoryContextSwitchTo(), ArrayBuildStateArr::nbytes, ArrayBuildStateArr::ndims, ArrayIteratorData::nitems, ArrayBuildStateArr::nitems, ArrayBuildStateArr::nullbitmap, palloc(), pfree(), pg_nextpower2_32(), and repalloc().

Referenced by accumArrayResultAny(), and array_agg_array_transfn().

5320 {
5321  ArrayType *arg;
5322  MemoryContext oldcontext;
5323  int *dims,
5324  *lbs,
5325  ndims,
5326  nitems,
5327  ndatabytes;
5328  char *data;
5329  int i;
5330 
5331  /*
5332  * We disallow accumulating null subarrays. Another plausible definition
5333  * is to ignore them, but callers that want that can just skip calling
5334  * this function.
5335  */
5336  if (disnull)
5337  ereport(ERROR,
5338  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5339  errmsg("cannot accumulate null arrays")));
5340 
5341  /* Detoast input array in caller's context */
5342  arg = DatumGetArrayTypeP(dvalue);
5343 
5344  if (astate == NULL)
5345  astate = initArrayResultArr(array_type, InvalidOid, rcontext, true);
5346  else
5347  Assert(astate->array_type == array_type);
5348 
5349  oldcontext = MemoryContextSwitchTo(astate->mcontext);
5350 
5351  /* Collect this input's dimensions */
5352  ndims = ARR_NDIM(arg);
5353  dims = ARR_DIMS(arg);
5354  lbs = ARR_LBOUND(arg);
5355  data = ARR_DATA_PTR(arg);
5356  nitems = ArrayGetNItems(ndims, dims);
5357  ndatabytes = ARR_SIZE(arg) - ARR_DATA_OFFSET(arg);
5358 
5359  if (astate->ndims == 0)
5360  {
5361  /* First input; check/save the dimensionality info */
5362 
5363  /* Should we allow empty inputs and just produce an empty output? */
5364  if (ndims == 0)
5365  ereport(ERROR,
5366  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5367  errmsg("cannot accumulate empty arrays")));
5368  if (ndims + 1 > MAXDIM)
5369  ereport(ERROR,
5370  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5371  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
5372  ndims + 1, MAXDIM)));
5373 
5374  /*
5375  * The output array will have n+1 dimensions, with the ones after the
5376  * first matching the input's dimensions.
5377  */
5378  astate->ndims = ndims + 1;
5379  astate->dims[0] = 0;
5380  memcpy(&astate->dims[1], dims, ndims * sizeof(int));
5381  astate->lbs[0] = 1;
5382  memcpy(&astate->lbs[1], lbs, ndims * sizeof(int));
5383 
5384  /* Allocate at least enough data space for this item */
5385  astate->abytes = pg_nextpower2_32(Max(1024, ndatabytes + 1));
5386  astate->data = (char *) palloc(astate->abytes);
5387  }
5388  else
5389  {
5390  /* Second or later input: must match first input's dimensionality */
5391  if (astate->ndims != ndims + 1)
5392  ereport(ERROR,
5393  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5394  errmsg("cannot accumulate arrays of different dimensionality")));
5395  for (i = 0; i < ndims; i++)
5396  {
5397  if (astate->dims[i + 1] != dims[i] || astate->lbs[i + 1] != lbs[i])
5398  ereport(ERROR,
5399  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5400  errmsg("cannot accumulate arrays of different dimensionality")));
5401  }
5402 
5403  /* Enlarge data space if needed */
5404  if (astate->nbytes + ndatabytes > astate->abytes)
5405  {
5406  astate->abytes = Max(astate->abytes * 2,
5407  astate->nbytes + ndatabytes);
5408  astate->data = (char *) repalloc(astate->data, astate->abytes);
5409  }
5410  }
5411 
5412  /*
5413  * Copy the data portion of the sub-array. Note we assume that the
5414  * advertised data length of the sub-array is properly aligned. We do not
5415  * have to worry about detoasting elements since whatever's in the
5416  * sub-array should be OK already.
5417  */
5418  memcpy(astate->data + astate->nbytes, data, ndatabytes);
5419  astate->nbytes += ndatabytes;
5420 
5421  /* Deal with null bitmap if needed */
5422  if (astate->nullbitmap || ARR_HASNULL(arg))
5423  {
5424  int newnitems = astate->nitems + nitems;
5425 
5426  if (astate->nullbitmap == NULL)
5427  {
5428  /*
5429  * First input with nulls; we must retrospectively handle any
5430  * previous inputs by marking all their items non-null.
5431  */
5432  astate->aitems = pg_nextpower2_32(Max(256, newnitems + 1));
5433  astate->nullbitmap = (bits8 *) palloc((astate->aitems + 7) / 8);
5434  array_bitmap_copy(astate->nullbitmap, 0,
5435  NULL, 0,
5436  astate->nitems);
5437  }
5438  else if (newnitems > astate->aitems)
5439  {
5440  astate->aitems = Max(astate->aitems * 2, newnitems);
5441  astate->nullbitmap = (bits8 *)
5442  repalloc(astate->nullbitmap, (astate->aitems + 7) / 8);
5443  }
5444  array_bitmap_copy(astate->nullbitmap, astate->nitems,
5445  ARR_NULLBITMAP(arg), 0,
5446  nitems);
5447  }
5448 
5449  astate->nitems += nitems;
5450  astate->dims[0] += 1;
5451 
5452  MemoryContextSwitchTo(oldcontext);
5453 
5454  /* Release detoasted copy if any */
5455  if ((Pointer) arg != DatumGetPointer(dvalue))
5456  pfree(arg);
5457 
5458  return astate;
5459 }
#define ARR_SIZE(a)
Definition: array.h:282
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4756
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:698
ArrayBuildStateArr * initArrayResultArr(Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5270
#define ARR_DATA_OFFSET(a)
Definition: array.h:309
#define ARR_LBOUND(a)
Definition: array.h:289
bits8 * nullbitmap
Definition: array.h:202
void pfree(void *pointer)
Definition: mcxt.c:1169
char * Pointer
Definition: c.h:418
#define ERROR
Definition: elog.h:46
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define MAXDIM
Definition: array.h:75
static uint32 pg_nextpower2_32(uint32 num)
Definition: pg_bitutils.h:146
#define ARR_HASNULL(a)
Definition: array.h:284
uint8 bits8
Definition: c.h:448
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
int lbs[MAXDIM]
Definition: array.h:209
#define Max(x, y)
Definition: c.h:980
#define Assert(condition)
Definition: c.h:804
#define ARR_NDIM(a)
Definition: array.h:283
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
#define DatumGetPointer(X)
Definition: postgres.h:593
int dims[MAXDIM]
Definition: array.h:208
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
void * arg
#define ARR_NULLBITMAP(a)
Definition: array.h:293
MemoryContext mcontext
Definition: array.h:200
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ array_bitmap_copy()

void array_bitmap_copy ( bits8 destbitmap,
int  destoffset,
const bits8 srcbitmap,
int  srcoffset,
int  nitems 
)

Definition at line 4756 of file arrayfuncs.c.

References Assert.

Referenced by accumArrayResultArr(), array_cat(), array_extract_slice(), array_insert_slice(), array_set_element(), array_set_slice(), ExecEvalArrayExpr(), and makeArrayResultArr().

4759 {
4760  int destbitmask,
4761  destbitval,
4762  srcbitmask,
4763  srcbitval;
4764 
4765  Assert(destbitmap);
4766  if (nitems <= 0)
4767  return; /* don't risk fetch off end of memory */
4768  destbitmap += destoffset / 8;
4769  destbitmask = 1 << (destoffset % 8);
4770  destbitval = *destbitmap;
4771  if (srcbitmap)
4772  {
4773  srcbitmap += srcoffset / 8;
4774  srcbitmask = 1 << (srcoffset % 8);
4775  srcbitval = *srcbitmap;
4776  while (nitems-- > 0)
4777  {
4778  if (srcbitval & srcbitmask)
4779  destbitval |= destbitmask;
4780  else
4781  destbitval &= ~destbitmask;
4782  destbitmask <<= 1;
4783  if (destbitmask == 0x100)
4784  {
4785  *destbitmap++ = destbitval;
4786  destbitmask = 1;
4787  if (nitems > 0)
4788  destbitval = *destbitmap;
4789  }
4790  srcbitmask <<= 1;
4791  if (srcbitmask == 0x100)
4792  {
4793  srcbitmap++;
4794  srcbitmask = 1;
4795  if (nitems > 0)
4796  srcbitval = *srcbitmap;
4797  }
4798  }
4799  if (destbitmask != 1)
4800  *destbitmap = destbitval;
4801  }
4802  else
4803  {
4804  while (nitems-- > 0)
4805  {
4806  destbitval |= destbitmask;
4807  destbitmask <<= 1;
4808  if (destbitmask == 0x100)
4809  {
4810  *destbitmap++ = destbitval;
4811  destbitmask = 1;
4812  if (nitems > 0)
4813  destbitval = *destbitmap;
4814  }
4815  }
4816  if (destbitmask != 1)
4817  *destbitmap = destbitval;
4818  }
4819 }
#define Assert(condition)
Definition: c.h:804

◆ array_contains_nulls()

bool array_contains_nulls ( ArrayType array)

Definition at line 3558 of file arrayfuncs.c.

References ARR_DIMS, ARR_HASNULL, ARR_NDIM, ARR_NULLBITMAP, and ArrayGetNItems().

Referenced by _arrq_cons(), _lca(), _lt_q_regex(), _ltree_compress(), array_fill_internal(), array_iterator(), array_position_common(), array_positions(), ArrayGetIntegerTypmods(), arrq_cons(), cube_a_f8(), cube_a_f8_f8(), cube_subset(), get_jsonb_path_all(), get_path_all(), getWeights(), lt_q_regex(), pg_isolation_test_session_is_blocked(), pg_logical_slot_get_changes_guts(), sanity_check_tid_array(), and width_bucket_array().

3559 {
3560  int nelems;
3561  bits8 *bitmap;
3562  int bitmask;
3563 
3564  /* Easy answer if there's no null bitmap */
3565  if (!ARR_HASNULL(array))
3566  return false;
3567 
3568  nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
3569 
3570  bitmap = ARR_NULLBITMAP(array);
3571 
3572  /* check whole bytes of the bitmap byte-at-a-time */
3573  while (nelems >= 8)
3574  {
3575  if (*bitmap != 0xFF)
3576  return true;
3577  bitmap++;
3578  nelems -= 8;
3579  }
3580 
3581  /* check last partial byte */
3582  bitmask = 1;
3583  while (nelems > 0)
3584  {
3585  if ((*bitmap & bitmask) == 0)
3586  return true;
3587  bitmask <<= 1;
3588  nelems--;
3589  }
3590 
3591  return false;
3592 }
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_HASNULL(a)
Definition: array.h:284
uint8 bits8
Definition: c.h:448
#define ARR_NDIM(a)
Definition: array.h:283
#define ARR_NULLBITMAP(a)
Definition: array.h:293

◆ array_create_iterator()

ArrayIterator array_create_iterator ( ArrayType arr,
int  slice_ndim,
ArrayMetaState mstate 
)

Definition at line 4387 of file arrayfuncs.c.

References ArrayIteratorData::arr, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), Assert, ArrayIteratorData::current_item, ArrayIteratorData::data_ptr, ArrayMetaState::element_type, elog, ERROR, get_typlenbyvalalign(), ArrayIteratorData::nitems, ArrayIteratorData::nullbitmap, palloc(), palloc0(), PointerIsValid, ArrayIteratorData::slice_dims, ArrayIteratorData::slice_lbound, ArrayIteratorData::slice_len, ArrayIteratorData::slice_ndim, ArrayIteratorData::slice_nulls, ArrayIteratorData::slice_values, ArrayIteratorData::typalign, ArrayMetaState::typalign, ArrayIteratorData::typbyval, ArrayMetaState::typbyval, ArrayIteratorData::typlen, and ArrayMetaState::typlen.

Referenced by array_position_common(), array_positions(), and exec_stmt_foreach_a().

4388 {
4389  ArrayIterator iterator = palloc0(sizeof(ArrayIteratorData));
4390 
4391  /*
4392  * Sanity-check inputs --- caller should have got this right already
4393  */
4394  Assert(PointerIsValid(arr));
4395  if (slice_ndim < 0 || slice_ndim > ARR_NDIM(arr))
4396  elog(ERROR, "invalid arguments to array_create_iterator");
4397 
4398  /*
4399  * Remember basic info about the array and its element type
4400  */
4401  iterator->arr = arr;
4402  iterator->nullbitmap = ARR_NULLBITMAP(arr);
4403  iterator->nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
4404 
4405  if (mstate != NULL)
4406  {
4407  Assert(mstate->element_type == ARR_ELEMTYPE(arr));
4408 
4409  iterator->typlen = mstate->typlen;
4410  iterator->typbyval = mstate->typbyval;
4411  iterator->typalign = mstate->typalign;
4412  }
4413  else
4415  &iterator->typlen,
4416  &iterator->typbyval,
4417  &iterator->typalign);
4418 
4419  /*
4420  * Remember the slicing parameters.
4421  */
4422  iterator->slice_ndim = slice_ndim;
4423 
4424  if (slice_ndim > 0)
4425  {
4426  /*
4427  * Get pointers into the array's dims and lbound arrays to represent
4428  * the dims/lbound arrays of a slice. These are the same as the
4429  * rightmost N dimensions of the array.
4430  */
4431  iterator->slice_dims = ARR_DIMS(arr) + ARR_NDIM(arr) - slice_ndim;
4432  iterator->slice_lbound = ARR_LBOUND(arr) + ARR_NDIM(arr) - slice_ndim;
4433 
4434  /*
4435  * Compute number of elements in a slice.
4436  */
4437  iterator->slice_len = ArrayGetNItems(slice_ndim,
4438  iterator->slice_dims);
4439 
4440  /*
4441  * Create workspace for building sub-arrays.
4442  */
4443  iterator->slice_values = (Datum *)
4444  palloc(iterator->slice_len * sizeof(Datum));
4445  iterator->slice_nulls = (bool *)
4446  palloc(iterator->slice_len * sizeof(bool));
4447  }
4448 
4449  /*
4450  * Initialize our data pointer and linear element number. These will
4451  * advance through the array during array_iterate().
4452  */
4453  iterator->data_ptr = ARR_DATA_PTR(arr);
4454  iterator->current_item = 0;
4455 
4456  return iterator;
4457 }
bits8 * nullbitmap
Definition: arrayfuncs.c:73
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2218
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
#define ARR_LBOUND(a)
Definition: array.h:289
bool typbyval
Definition: array.h:233
bool * slice_nulls
Definition: arrayfuncs.c:85
#define ERROR
Definition: elog.h:46
Datum * slice_values
Definition: arrayfuncs.c:84
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
int16 typlen
Definition: array.h:232
void * palloc0(Size size)
Definition: mcxt.c:1093
uintptr_t Datum
Definition: postgres.h:411
#define Assert(condition)
Definition: c.h:804
#define ARR_NDIM(a)
Definition: array.h:283
char typalign
Definition: array.h:234
void * palloc(Size size)
Definition: mcxt.c:1062
#define elog(elevel,...)
Definition: elog.h:232
Oid element_type
Definition: array.h:231
#define PointerIsValid(pointer)
Definition: c.h:698
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_NULLBITMAP(a)
Definition: array.h:293
ArrayType * arr
Definition: arrayfuncs.c:72

◆ array_free_iterator()

void array_free_iterator ( ArrayIterator  iterator)

Definition at line 4549 of file arrayfuncs.c.

References pfree(), ArrayIteratorData::slice_ndim, ArrayIteratorData::slice_nulls, and ArrayIteratorData::slice_values.

Referenced by array_position_common(), and array_positions().

4550 {
4551  if (iterator->slice_ndim > 0)
4552  {
4553  pfree(iterator->slice_values);
4554  pfree(iterator->slice_nulls);
4555  }
4556  pfree(iterator);
4557 }
bool * slice_nulls
Definition: arrayfuncs.c:85
void pfree(void *pointer)
Definition: mcxt.c:1169
Datum * slice_values
Definition: arrayfuncs.c:84

◆ array_get_element()

Datum array_get_element ( Datum  arraydatum,
int  nSubscripts,
int *  indx,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign,
bool isNull 
)

Definition at line 1831 of file arrayfuncs.c.

References ARR_DATA_PTR, ARR_DIMS, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, array_get_element_expanded(), array_get_isnull(), array_seek(), ArrayCast(), ArrayGetOffset(), DatumGetArrayTypeP, DatumGetPointer, i, MAXDIM, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by array_ref(), array_subscript_fetch(), array_subscript_fetch_old(), ATExecAlterColumnType(), and RelationBuildTupleDesc().

1839 {
1840  int i,
1841  ndim,
1842  *dim,
1843  *lb,
1844  offset,
1845  fixedDim[1],
1846  fixedLb[1];
1847  char *arraydataptr,
1848  *retptr;
1849  bits8 *arraynullsptr;
1850 
1851  if (arraytyplen > 0)
1852  {
1853  /*
1854  * fixed-length arrays -- these are assumed to be 1-d, 0-based
1855  */
1856  ndim = 1;
1857  fixedDim[0] = arraytyplen / elmlen;
1858  fixedLb[0] = 0;
1859  dim = fixedDim;
1860  lb = fixedLb;
1861  arraydataptr = (char *) DatumGetPointer(arraydatum);
1862  arraynullsptr = NULL;
1863  }
1864  else if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(arraydatum)))
1865  {
1866  /* expanded array: let's do this in a separate function */
1867  return array_get_element_expanded(arraydatum,
1868  nSubscripts,
1869  indx,
1870  arraytyplen,
1871  elmlen,
1872  elmbyval,
1873  elmalign,
1874  isNull);
1875  }
1876  else
1877  {
1878  /* detoast array if necessary, producing normal varlena input */
1879  ArrayType *array = DatumGetArrayTypeP(arraydatum);
1880 
1881  ndim = ARR_NDIM(array);
1882  dim = ARR_DIMS(array);
1883  lb = ARR_LBOUND(array);
1884  arraydataptr = ARR_DATA_PTR(array);
1885  arraynullsptr = ARR_NULLBITMAP(array);
1886  }
1887 
1888  /*
1889  * Return NULL for invalid subscript
1890  */
1891  if (ndim != nSubscripts || ndim <= 0 || ndim > MAXDIM)
1892  {
1893  *isNull = true;
1894  return (Datum) 0;
1895  }
1896  for (i = 0; i < ndim; i++)
1897  {
1898  if (indx[i] < lb[i] || indx[i] >= (dim[i] + lb[i]))
1899  {
1900  *isNull = true;
1901  return (Datum) 0;
1902  }
1903  }
1904 
1905  /*
1906  * Calculate the element number
1907  */
1908  offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
1909 
1910  /*
1911  * Check for NULL array element
1912  */
1913  if (array_get_isnull(arraynullsptr, offset))
1914  {
1915  *isNull = true;
1916  return (Datum) 0;
1917  }
1918 
1919  /*
1920  * OK, get the element
1921  */
1922  *isNull = false;
1923  retptr = array_seek(arraydataptr, 0, arraynullsptr, offset,
1924  elmlen, elmbyval, elmalign);
1925  return ArrayCast(retptr, elmbyval, elmlen);
1926 }
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:335
int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx)
Definition: arrayutils.c:32
#define ARR_LBOUND(a)
Definition: array.h:289
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
static Datum array_get_element_expanded(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
Definition: arrayfuncs.c:1932
#define MAXDIM
Definition: array.h:75
uint8 bits8
Definition: c.h:448
uintptr_t Datum
Definition: postgres.h:411
static char * array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
Definition: arrayfuncs.c:4656
static Datum ArrayCast(char *value, bool byval, int len)
Definition: arrayfuncs.c:4606
static bool array_get_isnull(const bits8 *nullbitmap, int offset)
Definition: arrayfuncs.c:4571
#define ARR_NDIM(a)
Definition: array.h:283
#define DatumGetPointer(X)
Definition: postgres.h:593
int i
#define ARR_NULLBITMAP(a)
Definition: array.h:293
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ array_get_slice()

Datum array_get_slice ( Datum  arraydatum,
int  nSubscripts,
int *  upperIndx,
int *  lowerIndx,
bool upperProvided,
bool lowerProvided,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign 
)

Definition at line 2041 of file arrayfuncs.c.

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, array_extract_slice(), array_slice_size(), ArrayGetNItems(), generate_unaccent_rules::bytes(), construct_empty_array(), ArrayType::dataoffset, DatumGetArrayTypeP, DatumGetPointer, ArrayType::elemtype, ereport, errcode(), errmsg(), ERROR, i, InvalidOid, MAXDIM, mda_get_range(), ArrayType::ndim, palloc0(), PointerGetDatum, and SET_VARSIZE.

Referenced by array_subscript_fetch_old_slice(), array_subscript_fetch_slice(), and trim_array().

2051 {
2052  ArrayType *array;
2053  ArrayType *newarray;
2054  int i,
2055  ndim,
2056  *dim,
2057  *lb,
2058  *newlb;
2059  int fixedDim[1],
2060  fixedLb[1];
2061  Oid elemtype;
2062  char *arraydataptr;
2063  bits8 *arraynullsptr;
2064  int32 dataoffset;
2065  int bytes,
2066  span[MAXDIM];
2067 
2068  if (arraytyplen > 0)
2069  {
2070  /*
2071  * fixed-length arrays -- currently, cannot slice these because parser
2072  * labels output as being of the fixed-length array type! Code below
2073  * shows how we could support it if the parser were changed to label
2074  * output as a suitable varlena array type.
2075  */
2076  ereport(ERROR,
2077  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2078  errmsg("slices of fixed-length arrays not implemented")));
2079 
2080  /*
2081  * fixed-length arrays -- these are assumed to be 1-d, 0-based
2082  *
2083  * XXX where would we get the correct ELEMTYPE from?
2084  */
2085  ndim = 1;
2086  fixedDim[0] = arraytyplen / elmlen;
2087  fixedLb[0] = 0;
2088  dim = fixedDim;
2089  lb = fixedLb;
2090  elemtype = InvalidOid; /* XXX */
2091  arraydataptr = (char *) DatumGetPointer(arraydatum);
2092  arraynullsptr = NULL;
2093  }
2094  else
2095  {
2096  /* detoast input array if necessary */
2097  array = DatumGetArrayTypeP(arraydatum);
2098 
2099  ndim = ARR_NDIM(array);
2100  dim = ARR_DIMS(array);
2101  lb = ARR_LBOUND(array);
2102  elemtype = ARR_ELEMTYPE(array);
2103  arraydataptr = ARR_DATA_PTR(array);
2104  arraynullsptr = ARR_NULLBITMAP(array);
2105  }
2106 
2107  /*
2108  * Check provided subscripts. A slice exceeding the current array limits
2109  * is silently truncated to the array limits. If we end up with an empty
2110  * slice, return an empty array.
2111  */
2112  if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
2113  return PointerGetDatum(construct_empty_array(elemtype));
2114 
2115  for (i = 0; i < nSubscripts; i++)
2116  {
2117  if (!lowerProvided[i] || lowerIndx[i] < lb[i])
2118  lowerIndx[i] = lb[i];
2119  if (!upperProvided[i] || upperIndx[i] >= (dim[i] + lb[i]))
2120  upperIndx[i] = dim[i] + lb[i] - 1;
2121  if (lowerIndx[i] > upperIndx[i])
2122  return PointerGetDatum(construct_empty_array(elemtype));
2123  }
2124  /* fill any missing subscript positions with full array range */
2125  for (; i < ndim; i++)
2126  {
2127  lowerIndx[i] = lb[i];
2128  upperIndx[i] = dim[i] + lb[i] - 1;
2129  if (lowerIndx[i] > upperIndx[i])
2130  return PointerGetDatum(construct_empty_array(elemtype));
2131  }
2132 
2133  mda_get_range(ndim, span, lowerIndx, upperIndx);
2134 
2135  bytes = array_slice_size(arraydataptr, arraynullsptr,
2136  ndim, dim, lb,
2137  lowerIndx, upperIndx,
2138  elmlen, elmbyval, elmalign);
2139 
2140  /*
2141  * Currently, we put a null bitmap in the result if the source has one;
2142  * could be smarter ...
2143  */
2144  if (arraynullsptr)
2145  {
2146  dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, ArrayGetNItems(ndim, span));
2147  bytes += dataoffset;
2148  }
2149  else
2150  {
2151  dataoffset = 0; /* marker for no null bitmap */
2152  bytes += ARR_OVERHEAD_NONULLS(ndim);
2153  }
2154 
2155  newarray = (ArrayType *) palloc0(bytes);
2156  SET_VARSIZE(newarray, bytes);
2157  newarray->ndim = ndim;
2158  newarray->dataoffset = dataoffset;
2159  newarray->elemtype = elemtype;
2160  memcpy(ARR_DIMS(newarray), span, ndim * sizeof(int));
2161 
2162  /*
2163  * Lower bounds of the new array are set to 1. Formerly (before 7.3) we
2164  * copied the given lowerIndx values ... but that seems confusing.
2165  */
2166  newlb = ARR_LBOUND(newarray);
2167  for (i = 0; i < ndim; i++)
2168  newlb[i] = 1;
2169 
2170  array_extract_slice(newarray,
2171  ndim, dim, lb,
2172  arraydataptr, arraynullsptr,
2173  lowerIndx, upperIndx,
2174  elmlen, elmbyval, elmalign);
2175 
2176  return PointerGetDatum(newarray);
2177 }
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:303
#define PointerGetDatum(X)
Definition: postgres.h:600
def bytes(source, encoding='ascii', errors='strict')
int32 dataoffset
Definition: array.h:89
static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)
Definition: arrayfuncs.c:4827
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
int errcode(int sqlerrcode)
Definition: elog.c:698
static void array_extract_slice(ArrayType *newarray, int ndim, int *dim, int *lb, char *arraydataptr, bits8 *arraynullsptr, int *st, int *endp, int typlen, bool typbyval, char typalign)
Definition: arrayfuncs.c:4887
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3440
unsigned int Oid
Definition: postgres_ext.h:31
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:305
signed int int32
Definition: c.h:429
#define ARR_LBOUND(a)
Definition: array.h:289
#define ERROR
Definition: elog.h:46
Oid elemtype
Definition: array.h:90
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define MAXDIM
Definition: array.h:75
uint8 bits8
Definition: c.h:448
void * palloc0(Size size)
Definition: mcxt.c:1093
void mda_get_range(int n, int *span, const int *st, const int *endp)
Definition: arrayutils.c:151
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:157
#define ARR_NDIM(a)
Definition: array.h:283
#define DatumGetPointer(X)
Definition: postgres.h:593
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_NULLBITMAP(a)
Definition: array.h:293
int ndim
Definition: array.h:88
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ array_iterate()

bool array_iterate ( ArrayIterator  iterator,
Datum value,
bool isnull 
)

Definition at line 4466 of file arrayfuncs.c.

References ArrayIteratorData::arr, ARR_ELEMTYPE, array_get_isnull(), att_addlength_pointer, att_align_nominal, construct_md_array(), ArrayIteratorData::current_item, ArrayIteratorData::data_ptr, fetch_att, i, ArrayIteratorData::nitems, ArrayIteratorData::nullbitmap, PointerGetDatum, ArrayIteratorData::slice_dims, ArrayIteratorData::slice_lbound, ArrayIteratorData::slice_len, ArrayIteratorData::slice_ndim, ArrayIteratorData::slice_nulls, ArrayIteratorData::slice_values, ArrayIteratorData::typalign, ArrayIteratorData::typbyval, ArrayIteratorData::typlen, and values.

Referenced by array_position_common(), array_positions(), and exec_stmt_foreach_a().

4467 {
4468  /* Done if we have reached the end of the array */
4469  if (iterator->current_item >= iterator->nitems)
4470  return false;
4471 
4472  if (iterator->slice_ndim == 0)
4473  {
4474  /*
4475  * Scalar case: return one element.
4476  */
4477  if (array_get_isnull(iterator->nullbitmap, iterator->current_item++))
4478  {
4479  *isnull = true;
4480  *value = (Datum) 0;
4481  }
4482  else
4483  {
4484  /* non-NULL, so fetch the individual Datum to return */
4485  char *p = iterator->data_ptr;
4486 
4487  *isnull = false;
4488  *value = fetch_att(p, iterator->typbyval, iterator->typlen);
4489 
4490  /* Move our data pointer forward to the next element */
4491  p = att_addlength_pointer(p, iterator->typlen, p);
4492  p = (char *) att_align_nominal(p, iterator->typalign);
4493  iterator->data_ptr = p;
4494  }
4495  }
4496  else
4497  {
4498  /*
4499  * Slice case: build and return an array of the requested size.
4500  */
4501  ArrayType *result;
4502  Datum *values = iterator->slice_values;
4503  bool *nulls = iterator->slice_nulls;
4504  char *p = iterator->data_ptr;
4505  int i;
4506 
4507  for (i = 0; i < iterator->slice_len; i++)
4508  {
4509  if (array_get_isnull(iterator->nullbitmap,
4510  iterator->current_item++))
4511  {
4512  nulls[i] = true;
4513  values[i] = (Datum) 0;
4514  }
4515  else
4516  {
4517  nulls[i] = false;
4518  values[i] = fetch_att(p, iterator->typbyval, iterator->typlen);
4519 
4520  /* Move our data pointer forward to the next element */
4521  p = att_addlength_pointer(p, iterator->typlen, p);
4522  p = (char *) att_align_nominal(p, iterator->typalign);
4523  }
4524  }
4525 
4526  iterator->data_ptr = p;
4527 
4528  result = construct_md_array(values,
4529  nulls,
4530  iterator->slice_ndim,
4531  iterator->slice_dims,
4532  iterator->slice_lbound,
4533  ARR_ELEMTYPE(iterator->arr),
4534  iterator->typlen,
4535  iterator->typbyval,
4536  iterator->typalign);
4537 
4538  *isnull = false;
4539  *value = PointerGetDatum(result);
4540  }
4541 
4542  return true;
4543 }
bits8 * nullbitmap
Definition: arrayfuncs.c:73
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
#define PointerGetDatum(X)
Definition: postgres.h:600
bool * slice_nulls
Definition: arrayfuncs.c:85
Datum * slice_values
Definition: arrayfuncs.c:84
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
uintptr_t Datum
Definition: postgres.h:411
static struct @143 value
static bool array_get_isnull(const bits8 *nullbitmap, int offset)
Definition: arrayfuncs.c:4571
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:75
int i
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3354
#define ARR_ELEMTYPE(a)
Definition: array.h:285
ArrayType * arr
Definition: arrayfuncs.c:72

◆ array_map()

Datum array_map ( Datum  arrayd,
struct ExprState exprstate,
struct ExprContext econtext,
Oid  retType,
ArrayMapState amstate 
)

Definition at line 3159 of file arrayfuncs.c.

References AARR_DIMS, AARR_ELEMTYPE, AARR_LBOUND, AARR_NDIM, AllocSizeIsValid, ARR_DIMS, ARR_LBOUND, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, array_iter_next(), array_iter_setup(), ArrayGetNItems(), att_addlength_datum, att_align_nominal, construct_empty_array(), CopyArrayEls(), ArrayType::dataoffset, DatumGetAnyArrayP(), ArrayMetaState::element_type, ArrayType::elemtype, ereport, errcode(), errmsg(), ERROR, ExecEvalExpr(), get_typlenbyvalalign(), i, ExprState::innermost_casenull, ExprState::innermost_caseval, ArrayMapState::inp_extra, MaxAllocSize, ArrayType::ndim, ArrayIteratorData::nitems, palloc(), palloc0(), pfree(), PG_DETOAST_DATUM, PointerGetDatum, ArrayMapState::ret_extra, SET_VARSIZE, ArrayIteratorData::typalign, ArrayMetaState::typalign, ArrayIteratorData::typbyval, ArrayMetaState::typbyval, ArrayIteratorData::typlen, ArrayMetaState::typlen, and values.

Referenced by ExecEvalArrayCoerce().

3162 {
3163  AnyArrayType *v = DatumGetAnyArrayP(arrayd);
3164  ArrayType *result;
3165  Datum *values;
3166  bool *nulls;
3167  int *dim;
3168  int ndim;
3169  int nitems;
3170  int i;
3171  int32 nbytes = 0;
3172  int32 dataoffset;
3173  bool hasnulls;
3174  Oid inpType;
3175  int inp_typlen;
3176  bool inp_typbyval;
3177  char inp_typalign;
3178  int typlen;
3179  bool typbyval;
3180  char typalign;
3181  array_iter iter;
3182  ArrayMetaState *inp_extra;
3183  ArrayMetaState *ret_extra;
3184  Datum *transform_source = exprstate->innermost_caseval;
3185  bool *transform_source_isnull = exprstate->innermost_casenull;
3186 
3187  inpType = AARR_ELEMTYPE(v);
3188  ndim = AARR_NDIM(v);
3189  dim = AARR_DIMS(v);
3190  nitems = ArrayGetNItems(ndim, dim);
3191 
3192  /* Check for empty array */
3193  if (nitems <= 0)
3194  {
3195  /* Return empty array */
3196  return PointerGetDatum(construct_empty_array(retType));
3197  }
3198 
3199  /*
3200  * We arrange to look up info about input and return element types only
3201  * once per series of calls, assuming the element type doesn't change
3202  * underneath us.
3203  */
3204  inp_extra = &amstate->inp_extra;
3205  ret_extra = &amstate->ret_extra;
3206 
3207  if (inp_extra->element_type != inpType)
3208  {
3209  get_typlenbyvalalign(inpType,
3210  &inp_extra->typlen,
3211  &inp_extra->typbyval,
3212  &inp_extra->typalign);
3213  inp_extra->element_type = inpType;
3214  }
3215  inp_typlen = inp_extra->typlen;
3216  inp_typbyval = inp_extra->typbyval;
3217  inp_typalign = inp_extra->typalign;
3218 
3219  if (ret_extra->element_type != retType)
3220  {
3221  get_typlenbyvalalign(retType,
3222  &ret_extra->typlen,
3223  &ret_extra->typbyval,
3224  &ret_extra->typalign);
3225  ret_extra->element_type = retType;
3226  }
3227  typlen = ret_extra->typlen;
3228  typbyval = ret_extra->typbyval;
3229  typalign = ret_extra->typalign;
3230 
3231  /* Allocate temporary arrays for new values */
3232  values = (Datum *) palloc(nitems * sizeof(Datum));
3233  nulls = (bool *) palloc(nitems * sizeof(bool));
3234 
3235  /* Loop over source data */
3236  array_iter_setup(&iter, v);
3237  hasnulls = false;
3238 
3239  for (i = 0; i < nitems; i++)
3240  {
3241  /* Get source element, checking for NULL */
3242  *transform_source =
3243  array_iter_next(&iter, transform_source_isnull, i,
3244  inp_typlen, inp_typbyval, inp_typalign);
3245 
3246  /* Apply the given expression to source element */
3247  values[i] = ExecEvalExpr(exprstate, econtext, &nulls[i]);
3248 
3249  if (nulls[i])
3250  hasnulls = true;
3251  else
3252  {
3253  /* Ensure data is not toasted */
3254  if (typlen == -1)
3255  values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
3256  /* Update total result size */
3257  nbytes = att_addlength_datum(nbytes, typlen, values[i]);
3258  nbytes = att_align_nominal(nbytes, typalign);
3259  /* check for overflow of total request */
3260  if (!AllocSizeIsValid(nbytes))
3261  ereport(ERROR,
3262  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3263  errmsg("array size exceeds the maximum allowed (%d)",
3264  (int) MaxAllocSize)));
3265  }
3266  }
3267 
3268  /* Allocate and fill the result array */
3269  if (hasnulls)
3270  {
3271  dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems);
3272  nbytes += dataoffset;
3273  }
3274  else
3275  {
3276  dataoffset = 0; /* marker for no null bitmap */
3277  nbytes += ARR_OVERHEAD_NONULLS(ndim);
3278  }
3279  result = (ArrayType *) palloc0(nbytes);
3280  SET_VARSIZE(result, nbytes);
3281  result->ndim = ndim;
3282  result->dataoffset = dataoffset;
3283  result->elemtype = retType;
3284  memcpy(ARR_DIMS(result), AARR_DIMS(v), ndim * sizeof(int));
3285  memcpy(ARR_LBOUND(result), AARR_LBOUND(v), ndim * sizeof(int));
3286 
3287  CopyArrayEls(result,
3288  values, nulls, nitems,
3289  typlen, typbyval, typalign,
3290  false);
3291 
3292  /*
3293  * Note: do not risk trying to pfree the results of the called expression
3294  */
3295  pfree(values);
3296  pfree(nulls);
3297 
3298  return PointerGetDatum(result);
3299 }
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:303
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
static Datum array_iter_next(array_iter *it, bool *isnull, int i, int elmlen, bool elmbyval, char elmalign)
Definition: arrayaccess.h:81
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2218
#define PointerGetDatum(X)
Definition: postgres.h:600
bool * innermost_casenull
Definition: execnodes.h:112
int32 dataoffset
Definition: array.h:89
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
int errcode(int sqlerrcode)
Definition: elog.c:698
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3440
unsigned int Oid
Definition: postgres_ext.h:31
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:305
signed int int32
Definition: c.h:429
AnyArrayType * DatumGetAnyArrayP(Datum d)
#define ARR_LBOUND(a)
Definition: array.h:289
bool typbyval
Definition: array.h:233
void pfree(void *pointer)
Definition: mcxt.c:1169
char typalign
Definition: pg_type.h:176
#define ERROR
Definition: elog.h:46
Oid elemtype
Definition: array.h:90
#define ARR_DIMS(a)
Definition: array.h:287
ArrayMetaState inp_extra
Definition: array.h:246
int16 typlen
Definition: array.h:232
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:316
static void array_iter_setup(array_iter *it, AnyArrayType *a)
Definition: arrayaccess.h:49
Datum * innermost_caseval
Definition: execnodes.h:111
#define AllocSizeIsValid(size)
Definition: memutils.h:42
#define MaxAllocSize
Definition: memutils.h:40
void * palloc0(Size size)
Definition: mcxt.c:1093
uintptr_t Datum
Definition: postgres.h:411
#define AARR_DIMS(a)
Definition: array.h:331
#define AARR_ELEMTYPE(a)
Definition: array.h:328
#define ereport(elevel,...)
Definition: elog.h:157
#define AARR_LBOUND(a)
Definition: array.h:334
#define AARR_NDIM(a)
Definition: array.h:321
ArrayMetaState ret_extra
Definition: array.h:247
void CopyArrayEls(ArrayType *array, Datum *values, bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)
Definition: arrayfuncs.c:961
char typalign
Definition: array.h:234
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:164
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
Oid element_type
Definition: array.h:231
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
int ndim
Definition: array.h:88

◆ array_ref()

Datum array_ref ( ArrayType array,
int  nSubscripts,
int *  indx,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign,
bool isNull 
)

Definition at line 3104 of file arrayfuncs.c.

References array_get_element(), and PointerGetDatum.

Referenced by GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), pg_get_functiondef(), and ProcessGUCArray().

3107 {
3108  return array_get_element(PointerGetDatum(array), nSubscripts, indx,
3109  arraytyplen, elmlen, elmbyval, elmalign,
3110  isNull);
3111 }
#define PointerGetDatum(X)
Definition: postgres.h:600
Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, bool *isNull)
Definition: arrayfuncs.c:1831

◆ array_set()

ArrayType* array_set ( ArrayType array,
int  nSubscripts,
int *  indx,
Datum  dataValue,
bool  isNull,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign 
)

Definition at line 3121 of file arrayfuncs.c.

References array_set_element(), DatumGetArrayTypeP, and PointerGetDatum.

Referenced by GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), and pg_extension_config_dump().

3124 {
3126  nSubscripts, indx,
3127  dataValue, isNull,
3128  arraytyplen,
3129  elmlen, elmbyval, elmalign));
3130 }
#define PointerGetDatum(X)
Definition: postgres.h:600
Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:2212
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ array_set_element()

Datum array_set_element ( Datum  arraydatum,
int  nSubscripts,
int *  indx,
Datum  dataValue,
bool  isNull,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign 
)

Definition at line 2212 of file arrayfuncs.c.

References ARR_DATA_OFFSET, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, ARR_SIZE, array_bitmap_copy(), array_get_isnull(), array_seek(), array_set_element_expanded(), array_set_isnull(), ArrayCastAndSet(), ArrayCheckBounds(), ArrayGetNItems(), ArrayGetOffset(), att_addlength_datum, att_addlength_pointer, att_align_nominal, construct_md_array(), ArrayType::dataoffset, DatumGetArrayTypeP, DatumGetPointer, ArrayType::elemtype, ereport, errcode(), errmsg(), ERROR, i, MAXDIM, MemSet, ArrayType::ndim, palloc(), palloc0(), PG_DETOAST_DATUM, PointerGetDatum, SET_VARSIZE, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by array_append(), array_prepend(), array_set(), and array_subscript_assign().

2221 {
2222  ArrayType *array;
2223  ArrayType *newarray;
2224  int i,
2225  ndim,
2226  dim[MAXDIM],
2227  lb[MAXDIM],
2228  offset;
2229  char *elt_ptr;
2230  bool newhasnulls;
2231  bits8 *oldnullbitmap;
2232  int oldnitems,
2233  newnitems,
2234  olddatasize,
2235  newsize,
2236  olditemlen,
2237  newitemlen,
2238  overheadlen,
2239  oldoverheadlen,
2240  addedbefore,
2241  addedafter,
2242  lenbefore,
2243  lenafter;
2244 
2245  if (arraytyplen > 0)
2246  {
2247  /*
2248  * fixed-length arrays -- these are assumed to be 1-d, 0-based. We
2249  * cannot extend them, either.
2250  */
2251  char *resultarray;
2252 
2253  if (nSubscripts != 1)
2254  ereport(ERROR,
2255  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2256  errmsg("wrong number of array subscripts")));
2257 
2258  if (indx[0] < 0 || indx[0] >= arraytyplen / elmlen)
2259  ereport(ERROR,
2260  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2261  errmsg("array subscript out of range")));
2262 
2263  if (isNull)
2264  ereport(ERROR,
2265  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2266  errmsg("cannot assign null value to an element of a fixed-length array")));
2267 
2268  resultarray = (char *) palloc(arraytyplen);
2269  memcpy(resultarray, DatumGetPointer(arraydatum), arraytyplen);
2270  elt_ptr = (char *) resultarray + indx[0] * elmlen;
2271  ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
2272  return PointerGetDatum(resultarray);
2273  }
2274 
2275  if (nSubscripts <= 0 || nSubscripts > MAXDIM)
2276  ereport(ERROR,
2277  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2278  errmsg("wrong number of array subscripts")));
2279 
2280  /* make sure item to be inserted is not toasted */
2281  if (elmlen == -1 && !isNull)
2282  dataValue = PointerGetDatum(PG_DETOAST_DATUM(dataValue));
2283 
2285  {
2286  /* expanded array: let's do this in a separate function */
2287  return array_set_element_expanded(arraydatum,
2288  nSubscripts,
2289  indx,
2290  dataValue,
2291  isNull,
2292  arraytyplen,
2293  elmlen,
2294  elmbyval,
2295  elmalign);
2296  }
2297 
2298  /* detoast input array if necessary */
2299  array = DatumGetArrayTypeP(arraydatum);
2300 
2301  ndim = ARR_NDIM(array);
2302 
2303  /*
2304  * if number of dims is zero, i.e. an empty array, create an array with
2305  * nSubscripts dimensions, and set the lower bounds to the supplied
2306  * subscripts
2307  */
2308  if (ndim == 0)
2309  {
2310  Oid elmtype = ARR_ELEMTYPE(array);
2311 
2312  for (i = 0; i < nSubscripts; i++)
2313  {
2314  dim[i] = 1;
2315  lb[i] = indx[i];
2316  }
2317 
2318  return PointerGetDatum(construct_md_array(&dataValue, &isNull,
2319  nSubscripts, dim, lb,
2320  elmtype,
2321  elmlen, elmbyval, elmalign));
2322  }
2323 
2324  if (ndim != nSubscripts)
2325  ereport(ERROR,
2326  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2327  errmsg("wrong number of array subscripts")));
2328 
2329  /* copy dim/lb since we may modify them */
2330  memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
2331  memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
2332 
2333  newhasnulls = (ARR_HASNULL(array) || isNull);
2334  addedbefore = addedafter = 0;
2335 
2336  /*
2337  * Check subscripts
2338  */
2339  if (ndim == 1)
2340  {
2341  if (indx[0] < lb[0])
2342  {
2343  addedbefore = lb[0] - indx[0];
2344  dim[0] += addedbefore;
2345  lb[0] = indx[0];
2346  if (addedbefore > 1)
2347  newhasnulls = true; /* will insert nulls */
2348  }
2349  if (indx[0] >= (dim[0] + lb[0]))
2350  {
2351  addedafter = indx[0] - (dim[0] + lb[0]) + 1;
2352  dim[0] += addedafter;
2353  if (addedafter > 1)
2354  newhasnulls = true; /* will insert nulls */
2355  }
2356  }
2357  else
2358  {
2359  /*
2360  * XXX currently we do not support extending multi-dimensional arrays
2361  * during assignment
2362  */
2363  for (i = 0; i < ndim; i++)
2364  {
2365  if (indx[i] < lb[i] ||
2366  indx[i] >= (dim[i] + lb[i]))
2367  ereport(ERROR,
2368  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2369  errmsg("array subscript out of range")));
2370  }
2371  }
2372 
2373  /* This checks for overflow of the array dimensions */
2374  newnitems = ArrayGetNItems(ndim, dim);
2375  ArrayCheckBounds(ndim, dim, lb);
2376 
2377  /*
2378  * Compute sizes of items and areas to copy
2379  */
2380  if (newhasnulls)
2381  overheadlen = ARR_OVERHEAD_WITHNULLS(ndim, newnitems);
2382  else
2383  overheadlen = ARR_OVERHEAD_NONULLS(ndim);
2384  oldnitems = ArrayGetNItems(ndim, ARR_DIMS(array));
2385  oldnullbitmap = ARR_NULLBITMAP(array);
2386  oldoverheadlen = ARR_DATA_OFFSET(array);
2387  olddatasize = ARR_SIZE(array) - oldoverheadlen;
2388  if (addedbefore)
2389  {
2390  offset = 0;
2391  lenbefore = 0;
2392  olditemlen = 0;
2393  lenafter = olddatasize;
2394  }
2395  else if (addedafter)
2396  {
2397  offset = oldnitems;
2398  lenbefore = olddatasize;
2399  olditemlen = 0;
2400  lenafter = 0;
2401  }
2402  else
2403  {
2404  offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
2405  elt_ptr = array_seek(ARR_DATA_PTR(array), 0, oldnullbitmap, offset,
2406  elmlen, elmbyval, elmalign);
2407  lenbefore = (int) (elt_ptr - ARR_DATA_PTR(array));
2408  if (array_get_isnull(oldnullbitmap, offset))
2409  olditemlen = 0;
2410  else
2411  {
2412  olditemlen = att_addlength_pointer(0, elmlen, elt_ptr);
2413  olditemlen = att_align_nominal(olditemlen, elmalign);
2414  }
2415  lenafter = (int) (olddatasize - lenbefore - olditemlen);
2416  }
2417 
2418  if (isNull)
2419  newitemlen = 0;
2420  else
2421  {
2422  newitemlen = att_addlength_datum(0, elmlen, dataValue);
2423  newitemlen = att_align_nominal(newitemlen, elmalign);
2424  }
2425 
2426  newsize = overheadlen + lenbefore + newitemlen + lenafter;
2427 
2428  /*
2429  * OK, create the new array and fill in header/dimensions
2430  */
2431  newarray = (ArrayType *) palloc0(newsize);
2432  SET_VARSIZE(newarray, newsize);
2433  newarray->ndim = ndim;
2434  newarray->dataoffset = newhasnulls ? overheadlen : 0;
2435  newarray->elemtype = ARR_ELEMTYPE(array);
2436  memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
2437  memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
2438 
2439  /*
2440  * Fill in data
2441  */
2442  memcpy((char *) newarray + overheadlen,
2443  (char *) array + oldoverheadlen,
2444  lenbefore);
2445  if (!isNull)
2446  ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign,
2447  (char *) newarray + overheadlen + lenbefore);
2448  memcpy((char *) newarray + overheadlen + lenbefore + newitemlen,
2449  (char *) array + oldoverheadlen + lenbefore + olditemlen,
2450  lenafter);
2451 
2452  /*
2453  * Fill in nulls bitmap if needed
2454  *
2455  * Note: it's possible we just replaced the last NULL with a non-NULL, and
2456  * could get rid of the bitmap. Seems not worth testing for though.
2457  */
2458  if (newhasnulls)
2459  {
2460  bits8 *newnullbitmap = ARR_NULLBITMAP(newarray);
2461 
2462  /* Zero the bitmap to take care of marking inserted positions null */
2463  MemSet(newnullbitmap, 0, (newnitems + 7) / 8);
2464  /* Fix the inserted value */
2465  if (addedafter)
2466  array_set_isnull(newnullbitmap, newnitems - 1, isNull);
2467  else
2468  array_set_isnull(newnullbitmap, offset, isNull);
2469  /* Fix the copied range(s) */
2470  if (addedbefore)
2471  array_bitmap_copy(newnullbitmap, addedbefore,
2472  oldnullbitmap, 0,
2473  oldnitems);
2474  else
2475  {
2476  array_bitmap_copy(newnullbitmap, 0,
2477  oldnullbitmap, 0,
2478  offset);
2479  if (addedafter == 0)
2480  array_bitmap_copy(newnullbitmap, offset + 1,
2481  oldnullbitmap, offset + 1,
2482  oldnitems - offset - 1);
2483  }
2484  }
2485 
2486  return PointerGetDatum(newarray);
2487 }
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:303
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
#define ARR_SIZE(a)
Definition: array.h:282
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:335
int ArrayGetOffset(int n, const int *dim, const int *lb, const int *indx)
Definition: arrayutils.c:32
static int ArrayCastAndSet(Datum src, int typlen, bool typbyval, char typalign, char *dest)
Definition: arrayfuncs.c:4617
#define PointerGetDatum(X)
Definition: postgres.h:600
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4756
int32 dataoffset
Definition: array.h:89
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
unsigned int Oid
Definition: postgres_ext.h:31
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:305
#define ARR_DATA_OFFSET(a)
Definition: array.h:309
#define ARR_LBOUND(a)
Definition: array.h:289
#define ERROR
Definition: elog.h:46
Oid elemtype
Definition: array.h:90
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
static Datum array_set_element_expanded(Datum arraydatum, int nSubscripts, int *indx, Datum dataValue, bool isNull, int arraytyplen, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:2497
#define MAXDIM
Definition: array.h:75
#define ARR_HASNULL(a)
Definition: array.h:284
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
void ArrayCheckBounds(int ndim, const int *dims, const int *lb)
Definition: arrayutils.c:128
uint8 bits8
Definition: c.h:448
void * palloc0(Size size)
Definition: mcxt.c:1093
static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull)
Definition: arrayfuncs.c:4588
#define ereport(elevel,...)
Definition: elog.h:157
static char * array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
Definition: arrayfuncs.c:4656
static bool array_get_isnull(const bits8 *nullbitmap, int offset)
Definition: arrayfuncs.c:4571
#define ARR_NDIM(a)
Definition: array.h:283
#define DatumGetPointer(X)
Definition: postgres.h:593
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:164
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3354
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_NULLBITMAP(a)
Definition: array.h:293
int ndim
Definition: array.h:88
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ array_set_slice()

Datum array_set_slice ( Datum  arraydatum,
int  nSubscripts,
int *  upperIndx,
int *  lowerIndx,
bool upperProvided,
bool lowerProvided,
Datum  srcArrayDatum,
bool  isNull,
int  arraytyplen,
int  elmlen,
bool  elmbyval,
char  elmalign 
)

Definition at line 2786 of file arrayfuncs.c.

References ARR_DATA_OFFSET, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_LBOUND, ARR_NDIM, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, ARR_SIZE, array_bitmap_copy(), array_insert_slice(), array_nelems_size(), array_slice_size(), ArrayCheckBounds(), ArrayGetNItems(), Assert, construct_md_array(), ArrayType::dataoffset, DatumGetArrayTypeP, deconstruct_array(), ArrayType::elemtype, ereport, errcode(), errdetail(), errmsg(), ERROR, i, Max, MAXDIM, mda_get_range(), MemSet, Min, ArrayType::ndim, ArrayIteratorData::nitems, palloc0(), PointerGetDatum, and SET_VARSIZE.

Referenced by array_subscript_assign_slice().

2798 {
2799  ArrayType *array;
2800  ArrayType *srcArray;
2801  ArrayType *newarray;
2802  int i,
2803  ndim,
2804  dim[MAXDIM],
2805  lb[MAXDIM],
2806  span[MAXDIM];
2807  bool newhasnulls;
2808  int nitems,
2809  nsrcitems,
2810  olddatasize,
2811  newsize,
2812  olditemsize,
2813  newitemsize,
2814  overheadlen,
2815  oldoverheadlen,
2816  addedbefore,
2817  addedafter,
2818  lenbefore,
2819  lenafter,
2820  itemsbefore,
2821  itemsafter,
2822  nolditems;
2823 
2824  /* Currently, assignment from a NULL source array is a no-op */
2825  if (isNull)
2826  return arraydatum;
2827 
2828  if (arraytyplen > 0)
2829  {
2830  /*
2831  * fixed-length arrays -- not got round to doing this...
2832  */
2833  ereport(ERROR,
2834  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2835  errmsg("updates on slices of fixed-length arrays not implemented")));
2836  }
2837 
2838  /* detoast arrays if necessary */
2839  array = DatumGetArrayTypeP(arraydatum);
2840  srcArray = DatumGetArrayTypeP(srcArrayDatum);
2841 
2842  /* note: we assume srcArray contains no toasted elements */
2843 
2844  ndim = ARR_NDIM(array);
2845 
2846  /*
2847  * if number of dims is zero, i.e. an empty array, create an array with
2848  * nSubscripts dimensions, and set the upper and lower bounds to the
2849  * supplied subscripts
2850  */
2851  if (ndim == 0)
2852  {
2853  Datum *dvalues;
2854  bool *dnulls;
2855  int nelems;
2856  Oid elmtype = ARR_ELEMTYPE(array);
2857 
2858  deconstruct_array(srcArray, elmtype, elmlen, elmbyval, elmalign,
2859  &dvalues, &dnulls, &nelems);
2860 
2861  for (i = 0; i < nSubscripts; i++)
2862  {
2863  if (!upperProvided[i] || !lowerProvided[i])
2864  ereport(ERROR,
2865  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2866  errmsg("array slice subscript must provide both boundaries"),
2867  errdetail("When assigning to a slice of an empty array value,"
2868  " slice boundaries must be fully specified.")));
2869 
2870  dim[i] = 1 + upperIndx[i] - lowerIndx[i];
2871  lb[i] = lowerIndx[i];
2872  }
2873 
2874  /* complain if too few source items; we ignore extras, however */
2875  if (nelems < ArrayGetNItems(nSubscripts, dim))
2876  ereport(ERROR,
2877  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2878  errmsg("source array too small")));
2879 
2880  return PointerGetDatum(construct_md_array(dvalues, dnulls, nSubscripts,
2881  dim, lb, elmtype,
2882  elmlen, elmbyval, elmalign));
2883  }
2884 
2885  if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
2886  ereport(ERROR,
2887  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2888  errmsg("wrong number of array subscripts")));
2889 
2890  /* copy dim/lb since we may modify them */
2891  memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
2892  memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
2893 
2894  newhasnulls = (ARR_HASNULL(array) || ARR_HASNULL(srcArray));
2895  addedbefore = addedafter = 0;
2896 
2897  /*
2898  * Check subscripts
2899  */
2900  if (ndim == 1)
2901  {
2902  Assert(nSubscripts == 1);
2903  if (!lowerProvided[0])
2904  lowerIndx[0] = lb[0];
2905  if (!upperProvided[0])
2906  upperIndx[0] = dim[0] + lb[0] - 1;
2907  if (lowerIndx[0] > upperIndx[0])
2908  ereport(ERROR,
2909  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2910  errmsg("upper bound cannot be less than lower bound")));
2911  if (lowerIndx[0] < lb[0])
2912  {
2913  if (upperIndx[0] < lb[0] - 1)
2914  newhasnulls = true; /* will insert nulls */
2915  addedbefore = lb[0] - lowerIndx[0];
2916  dim[0] += addedbefore;
2917  lb[0] = lowerIndx[0];
2918  }
2919  if (upperIndx[0] >= (dim[0] + lb[0]))
2920  {
2921  if (lowerIndx[0] > (dim[0] + lb[0]))
2922  newhasnulls = true; /* will insert nulls */
2923  addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
2924  dim[0] += addedafter;
2925  }
2926  }
2927  else
2928  {
2929  /*
2930  * XXX currently we do not support extending multi-dimensional arrays
2931  * during assignment
2932  */
2933  for (i = 0; i < nSubscripts; i++)
2934  {
2935  if (!lowerProvided[i])
2936  lowerIndx[i] = lb[i];
2937  if (!upperProvided[i])
2938  upperIndx[i] = dim[i] + lb[i] - 1;
2939  if (lowerIndx[i] > upperIndx[i])
2940  ereport(ERROR,
2941  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2942  errmsg("upper bound cannot be less than lower bound")));
2943  if (lowerIndx[i] < lb[i] ||
2944  upperIndx[i] >= (dim[i] + lb[i]))
2945  ereport(ERROR,
2946  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2947  errmsg("array subscript out of range")));
2948  }
2949  /* fill any missing subscript positions with full array range */
2950  for (; i < ndim; i++)
2951  {
2952  lowerIndx[i] = lb[i];
2953  upperIndx[i] = dim[i] + lb[i] - 1;
2954  if (lowerIndx[i] > upperIndx[i])
2955  ereport(ERROR,
2956  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2957  errmsg("upper bound cannot be less than lower bound")));
2958  }
2959  }
2960 
2961  /* Do this mainly to check for overflow */
2962  nitems = ArrayGetNItems(ndim, dim);
2963  ArrayCheckBounds(ndim, dim, lb);
2964 
2965  /*
2966  * Make sure source array has enough entries. Note we ignore the shape of
2967  * the source array and just read entries serially.
2968  */
2969  mda_get_range(ndim, span, lowerIndx, upperIndx);
2970  nsrcitems = ArrayGetNItems(ndim, span);
2971  if (nsrcitems > ArrayGetNItems(ARR_NDIM(srcArray), ARR_DIMS(srcArray)))
2972  ereport(ERROR,
2973  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2974  errmsg("source array too small")));
2975 
2976  /*
2977  * Compute space occupied by new entries, space occupied by replaced
2978  * entries, and required space for new array.
2979  */
2980  if (newhasnulls)
2981  overheadlen = ARR_OVERHEAD_WITHNULLS(ndim, nitems);
2982  else
2983  overheadlen = ARR_OVERHEAD_NONULLS(ndim);
2984  newitemsize = array_nelems_size(ARR_DATA_PTR(srcArray), 0,
2985  ARR_NULLBITMAP(srcArray), nsrcitems,
2986  elmlen, elmbyval, elmalign);
2987  oldoverheadlen = ARR_DATA_OFFSET(array);
2988  olddatasize = ARR_SIZE(array) - oldoverheadlen;
2989  if (ndim > 1)
2990  {
2991  /*
2992  * here we do not need to cope with extension of the array; it would
2993  * be a lot more complicated if we had to do so...
2994  */
2995  olditemsize = array_slice_size(ARR_DATA_PTR(array),
2996  ARR_NULLBITMAP(array),
2997  ndim, dim, lb,
2998  lowerIndx, upperIndx,
2999  elmlen, elmbyval, elmalign);
3000  lenbefore = lenafter = 0; /* keep compiler quiet */
3001  itemsbefore = itemsafter = nolditems = 0;
3002  }
3003  else
3004  {
3005  /*
3006  * here we must allow for possibility of slice larger than orig array
3007  * and/or not adjacent to orig array subscripts
3008  */
3009  int oldlb = ARR_LBOUND(array)[0];
3010  int oldub = oldlb + ARR_DIMS(array)[0] - 1;
3011  int slicelb = Max(oldlb, lowerIndx[0]);
3012  int sliceub = Min(oldub, upperIndx[0]);
3013  char *oldarraydata = ARR_DATA_PTR(array);
3014  bits8 *oldarraybitmap = ARR_NULLBITMAP(array);
3015 
3016  /* count/size of old array entries that will go before the slice */
3017  itemsbefore = Min(slicelb, oldub + 1) - oldlb;
3018  lenbefore = array_nelems_size(oldarraydata, 0, oldarraybitmap,
3019  itemsbefore,
3020  elmlen, elmbyval, elmalign);
3021  /* count/size of old array entries that will be replaced by slice */
3022  if (slicelb > sliceub)
3023  {
3024  nolditems = 0;
3025  olditemsize = 0;
3026  }
3027  else
3028  {
3029  nolditems = sliceub - slicelb + 1;
3030  olditemsize = array_nelems_size(oldarraydata + lenbefore,
3031  itemsbefore, oldarraybitmap,
3032  nolditems,
3033  elmlen, elmbyval, elmalign);
3034  }
3035  /* count/size of old array entries that will go after the slice */
3036  itemsafter = oldub + 1 - Max(sliceub + 1, oldlb);
3037  lenafter = olddatasize - lenbefore - olditemsize;
3038  }
3039 
3040  newsize = overheadlen + olddatasize - olditemsize + newitemsize;
3041 
3042  newarray = (ArrayType *) palloc0(newsize);
3043  SET_VARSIZE(newarray, newsize);
3044  newarray->ndim = ndim;
3045  newarray->dataoffset = newhasnulls ? overheadlen : 0;
3046  newarray->elemtype = ARR_ELEMTYPE(array);
3047  memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
3048  memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
3049 
3050  if (ndim > 1)
3051  {
3052  /*
3053  * here we do not need to cope with extension of the array; it would
3054  * be a lot more complicated if we had to do so...
3055  */
3056  array_insert_slice(newarray, array, srcArray,
3057  ndim, dim, lb,
3058  lowerIndx, upperIndx,
3059  elmlen, elmbyval, elmalign);
3060  }
3061  else
3062  {
3063  /* fill in data */
3064  memcpy((char *) newarray + overheadlen,
3065  (char *) array + oldoverheadlen,
3066  lenbefore);
3067  memcpy((char *) newarray + overheadlen + lenbefore,
3068  ARR_DATA_PTR(srcArray),
3069  newitemsize);
3070  memcpy((char *) newarray + overheadlen + lenbefore + newitemsize,
3071  (char *) array + oldoverheadlen + lenbefore + olditemsize,
3072  lenafter);
3073  /* fill in nulls bitmap if needed */
3074  if (newhasnulls)
3075  {
3076  bits8 *newnullbitmap = ARR_NULLBITMAP(newarray);
3077  bits8 *oldnullbitmap = ARR_NULLBITMAP(array);
3078 
3079  /* Zero the bitmap to handle marking inserted positions null */
3080  MemSet(newnullbitmap, 0, (nitems + 7) / 8);
3081  array_bitmap_copy(newnullbitmap, addedbefore,
3082  oldnullbitmap, 0,
3083  itemsbefore);
3084  array_bitmap_copy(newnullbitmap, lowerIndx[0] - lb[0],
3085  ARR_NULLBITMAP(srcArray), 0,
3086  nsrcitems);
3087  array_bitmap_copy(newnullbitmap, addedbefore + itemsbefore + nolditems,
3088  oldnullbitmap, itemsbefore + nolditems,
3089  itemsafter);
3090  }
3091  }
3092 
3093  return PointerGetDatum(newarray);
3094 }
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:303
#define ARR_SIZE(a)
Definition: array.h:282
#define PointerGetDatum(X)
Definition: postgres.h:600
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4756
int32 dataoffset
Definition: array.h:89
static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)
Definition: arrayfuncs.c:4827
#define Min(x, y)
Definition: c.h:986
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
unsigned int Oid
Definition: postgres_ext.h:31
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:305
#define ARR_DATA_OFFSET(a)
Definition: array.h:309
#define ARR_LBOUND(a)
Definition: array.h:289
#define ERROR
Definition: elog.h:46
Oid elemtype
Definition: array.h:90
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define MAXDIM
Definition: array.h:75
int errdetail(const char *fmt,...)
Definition: elog.c:1042
#define ARR_HASNULL(a)
Definition: array.h:284
void ArrayCheckBounds(int ndim, const int *dims, const int *lb)
Definition: arrayutils.c:128
uint8 bits8
Definition: c.h:448
void * palloc0(Size size)
Definition: mcxt.c:1093
uintptr_t Datum
Definition: postgres.h:411
void mda_get_range(int n, int *span, const int *st, const int *endp)
Definition: arrayutils.c:151
#define ereport(elevel,...)
Definition: elog.h:157
#define Max(x, y)
Definition: c.h:980
#define Assert(condition)
Definition: c.h:804
static void array_insert_slice(ArrayType *destArray, ArrayType *origArray, ArrayType *srcArray, int ndim, int *dim, int *lb, int *st, int *endp, int typlen, bool typbyval, char typalign)
Definition: arrayfuncs.c:4960
#define ARR_NDIM(a)
Definition: array.h:283
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
static int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems, int typlen, bool typbyval, char typalign)
Definition: arrayfuncs.c:4704
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3354
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_NULLBITMAP(a)
Definition: array.h:293
int ndim
Definition: array.h:88
#define DatumGetArrayTypeP(X)
Definition: array.h:254

◆ ArrayCheckBounds()

void ArrayCheckBounds ( int  ndim,
const int *  dims,
const int *  lb 
)

Definition at line 128 of file arrayutils.c.

References ereport, errcode(), errmsg(), ERROR, i, pg_add_s32_overflow(), and PG_USED_FOR_ASSERTS_ONLY.

Referenced by array_cat(), array_fill_internal(), array_in(), array_recv(), array_set_element(), array_set_element_expanded(), array_set_slice(), construct_md_array(), ExecEvalArrayExpr(), and makeArrayResultArr().

129 {
130  int i;
131 
132  for (i = 0; i < ndim; i++)
133  {
134  /* PG_USED_FOR_ASSERTS_ONLY prevents variable-isn't-read warnings */
136 
137  if (pg_add_s32_overflow(dims[i], lb[i], &sum))
138  ereport(ERROR,
139  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
140  errmsg("array lower bound is too large: %d",
141  lb[i])));
142  }
143 }
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:155

◆ ArrayGetIntegerTypmods()

int32* ArrayGetIntegerTypmods ( ArrayType arr,
int *  n 
)

Definition at line 231 of file arrayutils.c.

References ARR_ELEMTYPE, ARR_NDIM, array_contains_nulls(), DatumGetCString, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, i, palloc(), pfree(), and pg_strtoint32().

Referenced by anybit_typmodin(), anychar_typmodin(), anytime_typmodin(), anytimestamp_typmodin(), intervaltypmodin(), and numerictypmodin().

232 {
233  int32 *result;
234  Datum *elem_values;
235  int i;
236 
237  if (ARR_ELEMTYPE(arr) != CSTRINGOID)
238  ereport(ERROR,
239  (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
240  errmsg("typmod array must be type cstring[]")));
241 
242  if (ARR_NDIM(arr) != 1)
243  ereport(ERROR,
244  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
245  errmsg("typmod array must be one-dimensional")));
246 
247  if (array_contains_nulls(arr))
248  ereport(ERROR,
249  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
250  errmsg("typmod array must not contain nulls")));
251 
252  /* hardwired knowledge about cstring's representation details here */
253  deconstruct_array(arr, CSTRINGOID,
254  -2, false, TYPALIGN_CHAR,
255  &elem_values, NULL, n);
256 
257  result = (int32 *) palloc(*n * sizeof(int32));
258 
259  for (i = 0; i < *n; i++)
260  result[i] = pg_strtoint32(DatumGetCString(elem_values[i]));
261 
262  pfree(elem_values);
263 
264  return result;
265 }
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
#define DatumGetCString(X)
Definition: postgres.h:610
uintptr_t Datum
Definition: postgres.h:411
#define ereport(elevel,...)
Definition: elog.h:157
#define ARR_NDIM(a)
Definition: array.h:283
int32 pg_strtoint32(const char *s)
Definition: numutils.c:263
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
bool array_contains_nulls(ArrayType *array)
Definition: arrayfuncs.c:3558
#define ARR_ELEMTYPE(a)
Definition: array.h:285

◆ ArrayGetNItems()

int ArrayGetNItems ( int  ndim,
const int *  dims 
)

Definition at line 76 of file arrayutils.c.

References Assert, ereport, errcode(), errmsg(), ERROR, i, and MaxArraySize.

Referenced by _arrq_cons(), _lca(), _lt_q_regex(), _ltree_compress(), accumArrayResultArr(), array_cardinality(), array_cat(), array_cmp(), array_contain_compare(), array_contains_nulls(), array_create_iterator(), array_eq(), array_fill_internal(), array_get_slice(), array_in(), array_insert_slice(), array_iterator(), array_map(), array_out(), array_recv(), array_replace_internal(), array_send(), array_set_element(), array_set_element_expanded(), array_set_slice(), array_slice_size(), array_to_json_internal(), array_to_jsonb_internal(), array_to_text_internal(), array_unnest(), arrq_cons(), clause_is_strict_for(), construct_md_array(), convert_saop_to_hashed_saop_walker(), count_nulls(), deconstruct_array(), EA_get_flat_size(), estimate_array_length(), ExecEvalArrayExpr(), ExecEvalHashedScalarArrayOp(), ExecEvalScalarArrayOp(), get_text_array_contents(), getWeights(), hash_array(), hash_array_extended(), is_strict_saop(), lt_q_regex(), makeArrayResultArr(), pg_isolation_test_session_is_blocked(), predicate_classify(), sanity_check_tid_array(), width_bucket_array_fixed(), width_bucket_array_float8(), and width_bucket_array_variable().

77 {
78  int32 ret;
79  int i;
80 
81 #define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum)))
82 
83  if (ndim <= 0)
84  return 0;
85  ret = 1;
86  for (i = 0; i < ndim; i++)
87  {
88  int64 prod;
89 
90  /* A negative dimension implies that UB-LB overflowed ... */
91  if (dims[i] < 0)
92  ereport(ERROR,
93  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
94  errmsg("array size exceeds the maximum allowed (%d)",
95  (int) MaxArraySize)));
96 
97  prod = (int64) ret * (int64) dims[i];
98 
99  ret = (int32) prod;
100  if ((int64) ret != prod)
101  ereport(ERROR,
102  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
103  errmsg("array size exceeds the maximum allowed (%d)",
104  (int) MaxArraySize)));
105  }
106  Assert(ret >= 0);
107  if ((Size) ret > MaxArraySize)
108  ereport(ERROR,
109  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
110  errmsg("array size exceeds the maximum allowed (%d)",
111  (int) MaxArraySize)));
112  return (int) ret;
113 }
#define MaxArraySize
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
size_t Size
Definition: c.h:540
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i

◆ ArrayGetOffset()

int ArrayGetOffset ( int  n,
const int *  dim,
const int *  lb,
const int *  indx 
)

Definition at line 32 of file arrayutils.c.

References i, and scale.

Referenced by array_extract_slice(), array_get_element(), array_get_element_expanded(), array_insert_slice(), array_set_element(), array_set_element_expanded(), and array_slice_size().

33 {
34  int i,
35  scale = 1,
36  offset = 0;
37 
38  for (i = n - 1; i >= 0; i--)
39  {
40  offset += (indx[i] - lb[i]) * scale;
41  scale *= dim[i];
42  }
43  return offset;
44 }
int scale
Definition: pgbench.c:191
int i

◆ ArrayGetOffset0()

int ArrayGetOffset0 ( int  n,
const int *  tup,
const int *  scale 
)

Definition at line 51 of file arrayutils.c.

References i.

Referenced by ReadArrayStr().

52 {
53  int i,
54  lin = 0;
55 
56  for (i = 0; i < n; i++)
57  lin += tup[i] * scale[i];
58  return lin;
59 }
int scale
Definition: pgbench.c:191
int i

◆ construct_array()

ArrayType* construct_array ( Datum elems,
int  nelems,
Oid  elmtype,
int  elmlen,
bool  elmbyval,
char  elmalign 
)

Definition at line 3319 of file arrayfuncs.c.

References construct_md_array().

Referenced by AlterPolicy(), ATExecAlterColumnType(), bt_page_print_tuples(), build_regtype_array(), convert_requires_to_datum(), CreateConstraintEntry(), CreateFunction(), CreatePolicy(), CreateStatistics(), current_schemas(), enum_range_internal(), extension_config_remove(), filter_list_to_array(), float4_accum(), float8_accum(), float8_combine(), float8_regr_accum(), float8_regr_combine(), gethba_options(), gin_leafpage_items(), gin_page_opaque_info(), gist_page_opaque_info(), GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), hash_metapage_info(), heap_tuple_infomask_flags(), hstore_akeys(), interpret_function_parameter_list(), interval_accum(), interval_accum_inv(), interval_combine(), makeMultirangeConstructors(), pg_blocking_pids(), pg_extension_config_dump(), pg_safe_snapshot_blocking_pids(), publicationListToArray(), RemoveRoleFromObjectPolicy(), serialize_expr_stats(), show_trgm(), StoreAttrDefault(), test_rls_hooks_permissive(), test_rls_hooks_restrictive(), ts_lexize(), tsvector_to_array(), tsvector_unnest(), typenameTypeMod(), and update_attstats().

3322 {
3323  int dims[1];
3324  int lbs[1];
3325 
3326  dims[0] = nelems;
3327  lbs[0] = 1;
3328 
3329  return construct_md_array(elems, NULL, 1, dims, lbs,
3330  elmtype, elmlen, elmbyval, elmalign);
3331 }
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3354

◆ construct_empty_array()

◆ construct_empty_expanded_array()

ExpandedArrayHeader* construct_empty_expanded_array ( Oid  element_type,
MemoryContext  parentcontext,
ArrayMetaState metacache 
)

Definition at line 3457 of file arrayfuncs.c.

References construct_empty_array(), DatumGetEOHP(), expand_array(), pfree(), and PointerGetDatum.

Referenced by fetch_array_arg_replace_nulls().

3460 {
3461  ArrayType *array = construct_empty_array(element_type);
3462  Datum d;
3463 
3464  d = expand_array(PointerGetDatum(array), parentcontext, metacache);
3465  pfree(array);
3466  return (ExpandedArrayHeader *) DatumGetEOHP(d);
3467 }
#define PointerGetDatum(X)
Definition: postgres.h:600
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3440
void pfree(void *pointer)
Definition: mcxt.c:1169
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
uintptr_t Datum
Definition: postgres.h:411

◆ construct_md_array()

ArrayType* construct_md_array ( Datum elems,
bool nulls,
int  ndims,
int *  dims,
int *  lbs,
Oid  elmtype,
int  elmlen,
bool  elmbyval,
char  elmalign 
)

Definition at line 3354 of file arrayfuncs.c.

References AllocSizeIsValid, ARR_DIMS, ARR_LBOUND, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, ArrayCheckBounds(), ArrayGetNItems(), att_addlength_datum, att_align_nominal, construct_empty_array(), CopyArrayEls(), ArrayType::dataoffset, ArrayType::elemtype, ereport, errcode(), errmsg(), ERROR, i, MaxAllocSize, MAXDIM, ArrayType::ndim, palloc0(), PG_DETOAST_DATUM, PointerGetDatum, and SET_VARSIZE.

Referenced by array_iterate(), array_set_element(), array_set_slice(), build_regexp_match_result(), build_test_info_result(), build_test_match_result(), construct_array(), ExecEvalArrayExpr(), hstore_avals(), hstore_slice_to_array(), hstore_to_array_internal(), makeMdArrayResult(), percentile_cont_multi_final_common(), percentile_disc_multi_final(), plpgsql_fulfill_promise(), PLySequence_ToArray(), and strlist_to_textarray().

3360 {
3361  ArrayType *result;
3362  bool hasnulls;
3363  int32 nbytes;
3364  int32 dataoffset;
3365  int i;
3366  int nelems;
3367 
3368  if (ndims < 0) /* we do allow zero-dimension arrays */
3369  ereport(ERROR,
3370  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3371  errmsg("invalid number of dimensions: %d", ndims)));
3372  if (ndims > MAXDIM)
3373  ereport(ERROR,
3374  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3375  errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
3376  ndims, MAXDIM)));
3377 
3378  /* This checks for overflow of the array dimensions */
3379  nelems = ArrayGetNItems(ndims, dims);
3380  ArrayCheckBounds(ndims, dims, lbs);
3381 
3382  /* if ndims <= 0 or any dims[i] == 0, return empty array */
3383  if (nelems <= 0)
3384  return construct_empty_array(elmtype);
3385 
3386  /* compute required space */
3387  nbytes = 0;
3388  hasnulls = false;
3389  for (i = 0; i < nelems; i++)
3390  {
3391  if (nulls && nulls[i])
3392  {
3393  hasnulls = true;
3394  continue;
3395  }
3396  /* make sure data is not toasted */
3397  if (elmlen == -1)
3398  elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
3399  nbytes = att_addlength_datum(nbytes, elmlen, elems[i]);
3400  nbytes = att_align_nominal(nbytes, elmalign);
3401  /* check for overflow of total request */
3402  if (!AllocSizeIsValid(nbytes))
3403  ereport(ERROR,
3404  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3405  errmsg("array size exceeds the maximum allowed (%d)",
3406  (int) MaxAllocSize)));
3407  }
3408 
3409  /* Allocate and initialize result array */
3410  if (hasnulls)
3411  {
3412  dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nelems);
3413  nbytes += dataoffset;
3414  }
3415  else
3416  {
3417  dataoffset = 0; /* marker for no null bitmap */
3418  nbytes += ARR_OVERHEAD_NONULLS(ndims);
3419  }
3420  result = (ArrayType *) palloc0(nbytes);
3421  SET_VARSIZE(result, nbytes);
3422  result->ndim = ndims;
3423  result->dataoffset = dataoffset;
3424  result->elemtype = elmtype;
3425  memcpy(ARR_DIMS(result), dims, ndims * sizeof(int));
3426  memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int));
3427 
3428  CopyArrayEls(result,
3429  elems, nulls, nelems,
3430  elmlen, elmbyval, elmalign,
3431  false);
3432 
3433  return result;
3434 }
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:303
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
#define PointerGetDatum(X)
Definition: postgres.h:600
int32 dataoffset
Definition: array.h:89
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
int errcode(int sqlerrcode)
Definition: elog.c:698
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3440
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:305
signed int int32
Definition: c.h:429
#define ARR_LBOUND(a)
Definition: array.h:289
#define ERROR
Definition: elog.h:46
Oid elemtype
Definition: array.h:90
#define ARR_DIMS(a)
Definition: array.h:287
#define MAXDIM
Definition: array.h:75
#define AllocSizeIsValid(size)
Definition: memutils.h:42
#define MaxAllocSize
Definition: memutils.h:40
void ArrayCheckBounds(int ndim, const int *dims, const int *lb)
Definition: arrayutils.c:128
void * palloc0(Size size)
Definition: mcxt.c:1093
#define ereport(elevel,...)
Definition: elog.h:157
void CopyArrayEls(ArrayType *array, Datum *values, bool *nulls, int nitems, int typlen, bool typbyval, char typalign, bool freedata)
Definition: arrayfuncs.c:961
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:164
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
int ndim
Definition: array.h:88

◆ CopyArrayEls()

void CopyArrayEls ( ArrayType array,
Datum values,
bool nulls,
int  nitems,
int  typlen,
bool  typbyval,
char  typalign,
bool  freedata 
)

Definition at line 961 of file arrayfuncs.c.

References ARR_DATA_PTR, ARR_NULLBITMAP, ArrayCastAndSet(), DatumGetPointer, elog, ERROR, i, ArrayIteratorData::nitems, and pfree().

Referenced by array_in(), array_map(), array_recv(), array_replace_internal(), construct_md_array(), and EA_flatten_into().

969 {
970  char *p = ARR_DATA_PTR(array);
971  bits8 *bitmap = ARR_NULLBITMAP(array);
972  int bitval = 0;
973  int bitmask = 1;
974  int i;
975 
976  if (typbyval)
977  freedata = false;
978 
979  for (i = 0; i < nitems; i++)
980  {
981  if (nulls && nulls[i])
982  {
983  if (!bitmap) /* shouldn't happen */
984  elog(ERROR, "null array element where not supported");
985  /* bitmap bit stays 0 */
986  }
987  else
988  {
989  bitval |= bitmask;
990  p += ArrayCastAndSet(values[i], typlen, typbyval, typalign, p);
991  if (freedata)
993  }
994  if (bitmap)
995  {
996  bitmask <<= 1;
997  if (bitmask == 0x100)
998  {
999  *bitmap++ = bitval;
1000  bitval = 0;
1001  bitmask = 1;
1002  }
1003  }
1004  }
1005 
1006  if (bitmap && bitmask != 1)
1007  *bitmap = bitval;
1008 }
static int ArrayCastAndSet(Datum src, int typlen, bool typbyval, char typalign, char *dest)
Definition: arrayfuncs.c:4617
void pfree(void *pointer)
Definition: mcxt.c:1169
char typalign
Definition: pg_type.h:176
#define ERROR
Definition: elog.h:46
#define ARR_DATA_PTR(a)
Definition: array.h:315
uint8 bits8
Definition: c.h:448
#define DatumGetPointer(X)
Definition: postgres.h:593
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define elog(elevel,...)
Definition: elog.h:232
int i
#define ARR_NULLBITMAP(a)
Definition: array.h:293

◆ DatumGetAnyArrayP()

AnyArrayType* DatumGetAnyArrayP ( Datum  d)

Definition at line 401 of file array_expanded.c.

References Assert, DatumGetEOHP(), DatumGetPointer, EA_MAGIC, ExpandedArrayHeader::ea_magic, PG_DETOAST_DATUM, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by array_map().

402 {
403  ExpandedArrayHeader *eah;
404 
405  /*
406  * If it's an expanded array (RW or RO), return the header pointer.
407  */
409  {
410  eah = (ExpandedArrayHeader *) DatumGetEOHP(d);
411  Assert(eah->ea_magic == EA_MAGIC);
412  return (AnyArrayType *) eah;
413  }
414 
415  /* Else do regular detoasting as needed */
416  return (AnyArrayType *) PG_DETOAST_DATUM(d);
417 }
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:335
#define EA_MAGIC
Definition: array.h:106
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
#define Assert(condition)
Definition: c.h:804
#define DatumGetPointer(X)
Definition: postgres.h:593
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240

◆ DatumGetExpandedArray()

ExpandedArrayHeader* DatumGetExpandedArray ( Datum  d)

Definition at line 352 of file array_expanded.c.

References Assert, CurrentMemoryContext, DatumGetEOHP(), DatumGetPointer, EA_MAGIC, ExpandedArrayHeader::ea_magic, expand_array(), and VARATT_IS_EXTERNAL_EXPANDED_RW.

Referenced by array_set_element_expanded(), and statext_expressions_load().

353 {
354  /* If it's a writable expanded array already, just return it */
356  {
358 
359  Assert(eah->ea_magic == EA_MAGIC);
360  return eah;
361  }
362 
363  /* Else expand the hard way */
364  d = expand_array(d, CurrentMemoryContext, NULL);
365  return (ExpandedArrayHeader *) DatumGetEOHP(d);
366 }
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
#define EA_MAGIC
Definition: array.h:106
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
#define Assert(condition)
Definition: c.h:804
#define DatumGetPointer(X)
Definition: postgres.h:593
#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR)
Definition: postgres.h:333

◆ DatumGetExpandedArrayX()

ExpandedArrayHeader* DatumGetExpandedArrayX ( Datum  d,
ArrayMetaState metacache 
)

Definition at line 372 of file array_expanded.c.

References Assert, CurrentMemoryContext, DatumGetEOHP(), DatumGetPointer, EA_MAGIC, ExpandedArrayHeader::ea_magic, ExpandedArrayHeader::element_type, ArrayMetaState::element_type, expand_array(), ExpandedArrayHeader::typalign, ArrayMetaState::typalign, ExpandedArrayHeader::typbyval, ArrayMetaState::typbyval, ExpandedArrayHeader::typlen, ArrayMetaState::typlen, and VARATT_IS_EXTERNAL_EXPANDED_RW.

373 {
374  /* If it's a writable expanded array already, just return it */
376  {
378 
379  Assert(eah->ea_magic == EA_MAGIC);
380  /* Update cache if provided */
381  if (metacache)
382  {
383  metacache->element_type = eah->element_type;
384  metacache->typlen = eah->typlen;
385  metacache->typbyval = eah->typbyval;
386  metacache->typalign = eah->typalign;
387  }
388  return eah;
389  }
390 
391  /* Else expand using caller's cache if any */
392  d = expand_array(d, CurrentMemoryContext, metacache);
393  return (ExpandedArrayHeader *) DatumGetEOHP(d);
394 }
Datum expand_array(Datum arraydatum, MemoryContext parentcontext, ArrayMetaState *metacache)
#define EA_MAGIC
Definition: array.h:106
bool typbyval
Definition: array.h:233
int16 typlen
Definition: array.h:232
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
#define Assert(condition)
Definition: c.h:804
#define DatumGetPointer(X)
Definition: postgres.h:593
char typalign
Definition: array.h:234
Oid element_type
Definition: array.h:231
#define VARATT_IS_EXTERNAL_EXPANDED_RW(PTR)
Definition: postgres.h:333

◆ deconstruct_array()

void deconstruct_array ( ArrayType array,
Oid  elmtype,
int  elmlen,
bool  elmbyval,
char  elmalign,
Datum **  elemsp,
bool **  nullsp,
int *  nelemsp 
)

Definition at line 3491 of file arrayfuncs.c.

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), Assert, att_addlength_pointer, att_align_nominal, ereport, errcode(), errmsg(), ERROR, fetch_att, i, palloc(), and palloc0().

Referenced by _bt_preprocess_array_keys(), array_contain_compare(), array_set_slice(), array_to_json_internal(), array_to_jsonb_internal(), array_to_tsvector(), arrayconst_startup_fn(), ArrayGetIntegerTypmods(), binary_upgrade_create_empty_extension(), build_function_result_tupdesc_d(), compute_array_stats(), DecodeTextArrayToBitmapset(), decompile_column_index_array(), deconstruct_expanded_array(), ExecIndexEvalArrayKeys(), extension_config_remove(), extract_variadic_args(), generateClonedIndexStmt(), get_attstatsslot(), get_func_arg_info(), get_func_input_arg_names(), get_func_result_name(), get_jsonb_path_all(), get_path_all(), get_reloptions(), ghstore_consistent(), gin_extract_hstore_query(), gin_extract_jsonb_query(), ginarrayextract(), gincost_scalararrayopexpr(), ginqueryarrayextract(), hstore_from_array(), hstore_from_arrays(), hstore_slice_to_array(), hstoreArrayToPairs(), interval_accum(), interval_accum_inv(), interval_avg(), interval_combine(), json_object(), json_object_two_arg(), jsonb_delete_array(), jsonb_delete_path(), jsonb_exists_all(), jsonb_exists_any(), jsonb_insert(), jsonb_object(), jsonb_object_two_arg(), jsonb_set(), map_sql_value_to_xml_value(), match_clause_to_partition_key(), mcelem_array_selec(), mcv_get_match_bitmap(), multirange_constructor2(), oid_array_to_list(), parse_key_value_arrays(), parseRelOptionsInternal(), percentile_cont_multi_final_common(), percentile_disc_multi_final(), pg_get_constraintdef_worker(), pg_get_object_address(), pg_logical_slot_get_changes_guts(), plperl_ref_from_pg_array(), satisfies_hash_partition(), scalararraysel(), SPI_sql_row_to_xmlelement(), text_format(), textarray_to_stringlist(), textarray_to_strvaluelist(), TidListEval(), transformRelOptions(), tsvector_delete_arr(), tsvector_filter(), tsvector_setweight_by_filter(), and untransformRelOptions().

3495 {
3496  Datum *elems;
3497  bool *nulls;
3498  int nelems;
3499  char *p;
3500  bits8 *bitmap;
3501  int bitmask;
3502  int i;
3503 
3504  Assert(ARR_ELEMTYPE(array) == elmtype);
3505 
3506  nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
3507  *elemsp = elems = (Datum *) palloc(nelems * sizeof(Datum));
3508  if (nullsp)
3509  *nullsp = nulls = (bool *) palloc0(nelems * sizeof(bool));
3510  else
3511  nulls = NULL;
3512  *nelemsp = nelems;
3513 
3514  p = ARR_DATA_PTR(array);
3515  bitmap = ARR_NULLBITMAP(array);
3516  bitmask = 1;
3517 
3518  for (i = 0; i < nelems; i++)
3519  {
3520  /* Get source element, checking for NULL */
3521  if (bitmap && (*bitmap & bitmask) == 0)
3522  {
3523  elems[i] = (Datum) 0;
3524  if (nulls)
3525  nulls[i] = true;
3526  else
3527  ereport(ERROR,
3528  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
3529  errmsg("null array element not allowed in this context")));
3530  }
3531  else
3532  {
3533  elems[i] = fetch_att(p, elmbyval, elmlen);
3534  p = att_addlength_pointer(p, elmlen, p);
3535  p = (char *) att_align_nominal(p, elmalign);
3536  }
3537 
3538  /* advance bitmap pointer if any */
3539  if (bitmap)
3540  {
3541  bitmask <<= 1;
3542  if (bitmask == 0x100)
3543  {
3544  bitmap++;
3545  bitmask = 1;
3546  }
3547  }
3548  }
3549 }
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
uint8 bits8
Definition: c.h:448
void * palloc0(Size size)
Definition: mcxt.c:1093
uintptr_t Datum
Definition: postgres.h:411
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
#define ARR_NDIM(a)
Definition: array.h:283
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:75
int i
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_NULLBITMAP(a)
Definition: array.h:293

◆ deconstruct_expanded_array()

void deconstruct_expanded_array ( ExpandedArrayHeader eah)

Definition at line 424 of file array_expanded.c.

References ARR_HASNULL, deconstruct_array(), ExpandedArrayHeader::dnulls, ExpandedArrayHeader::dvalues, ExpandedArrayHeader::dvalueslen, ExpandedArrayHeader::element_type, ExpandedObjectHeader::eoh_context, ExpandedArrayHeader::fvalue, ExpandedArrayHeader::hdr, MemoryContextSwitchTo(), ExpandedArrayHeader::nelems, ExpandedArrayHeader::typalign, ExpandedArrayHeader::typbyval, and ExpandedArrayHeader::typlen.

Referenced by array_contain_compare(), array_get_element_expanded(), array_set_element_expanded(), and statext_expressions_load().

425 {
426  if (eah->dvalues == NULL)
427  {
429  Datum *dvalues;
430  bool *dnulls;
431  int nelems;
432 
433  dnulls = NULL;
435  eah->element_type,
436  eah->typlen, eah->typbyval, eah->typalign,
437  &dvalues,
438  ARR_HASNULL(eah->fvalue) ? &dnulls : NULL,
439  &nelems);
440 
441  /*
442  * Update header only after successful completion of this step. If
443  * deconstruct_array fails partway through, worst consequence is some
444  * leaked memory in the object's context. If the caller fails at a
445  * later point, that's fine, since the deconstructed representation is
446  * valid anyhow.
447  */
448  eah->dvalues = dvalues;
449  eah->dnulls = dnulls;
450  eah->dvalueslen = eah->nelems = nelems;
451  MemoryContextSwitchTo(oldcxt);
452  }
453 }
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum * dvalues
Definition: array.h:139
ExpandedObjectHeader hdr
Definition: array.h:111
#define ARR_HASNULL(a)
Definition: array.h:284
ArrayType * fvalue
Definition: array.h:158
uintptr_t Datum
Definition: postgres.h:411
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
MemoryContext eoh_context

◆ expand_array()

Datum expand_array ( Datum  arraydatum,
MemoryContext  parentcontext,
ArrayMetaState metacache 
)

Definition at line 50 of file array_expanded.c.

References ALLOCSET_START_SMALL_SIZES, AllocSetContextCreate, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, ARR_SIZE, Assert, copy_byval_expanded_array(), DatumGetArrayTypePCopy, DatumGetEOHP(), DatumGetPointer, ExpandedArrayHeader::dims, ExpandedArrayHeader::dnulls, ExpandedArrayHeader::dvalues, ExpandedArrayHeader::dvalueslen, EA_MAGIC, ExpandedArrayHeader::ea_magic, ExpandedArrayHeader::element_type, ArrayMetaState::element_type, EOH_init_header(), EOHPGetRWDatum, ExpandedArrayHeader::fendptr, ExpandedArrayHeader::flat_size, ExpandedArrayHeader::fstartptr, ExpandedArrayHeader::fvalue, get_typlenbyvalalign(), ExpandedArrayHeader::hdr, ExpandedArrayHeader::lbound, MemoryContextAlloc(), MemoryContextSwitchTo(), ExpandedArrayHeader::ndims, ExpandedArrayHeader::nelems, ExpandedArrayHeader::typalign, ArrayMetaState::typalign, ExpandedArrayHeader::typbyval, ArrayMetaState::typbyval, ExpandedArrayHeader::typlen, ArrayMetaState::typlen, and VARATT_IS_EXTERNAL_EXPANDED.

Referenced by construct_empty_expanded_array(), DatumGetExpandedArray(), DatumGetExpandedArrayX(), exec_assign_value(), and plpgsql_exec_function().

52 {
53  ArrayType *array;
55  MemoryContext objcxt;
56  MemoryContext oldcxt;
57  ArrayMetaState fakecache;
58 
59  /*
60  * Allocate private context for expanded object. We start by assuming
61  * that the array won't be very large; but if it does grow a lot, don't
62  * constrain aset.c's large-context behavior.
63  */
64  objcxt = AllocSetContextCreate(parentcontext,
65  "expanded array",
67 
68  /* Set up expanded array header */
69  eah = (ExpandedArrayHeader *)
70  MemoryContextAlloc(objcxt, sizeof(ExpandedArrayHeader));
71 
72  EOH_init_header(&eah->hdr, &EA_methods, objcxt);
73  eah->ea_magic = EA_MAGIC;
74 
75  /* If the source is an expanded array, we may be able to optimize */
77  {
78  ExpandedArrayHeader *oldeah = (ExpandedArrayHeader *) DatumGetEOHP(arraydatum);
79 
80  Assert(oldeah->ea_magic == EA_MAGIC);
81 
82  /*
83  * Update caller's cache if provided; we don't need it this time, but
84  * next call might be for a non-expanded source array. Furthermore,
85  * if the caller didn't provide a cache area, use some local storage
86  * to cache anyway, thereby avoiding a catalog lookup in the case
87  * where we fall through to the flat-copy code path.
88  */
89  if (metacache == NULL)
90  metacache = &fakecache;
91  metacache->element_type = oldeah->element_type;
92  metacache->typlen = oldeah->typlen;
93  metacache->typbyval = oldeah->typbyval;
94  metacache->typalign = oldeah->typalign;
95 
96  /*
97  * If element type is pass-by-value and we have a Datum-array
98  * representation, just copy the source's metadata and Datum/isnull
99  * arrays. The original flat array, if present at all, adds no
100  * additional information so we need not copy it.
101  */
102  if (oldeah->typbyval && oldeah->dvalues != NULL)
103  {
104  copy_byval_expanded_array(eah, oldeah);
105  /* return a R/W pointer to the expanded array */
106  return EOHPGetRWDatum(&eah->hdr);
107  }
108 
109  /*
110  * Otherwise, either we have only a flat representation or the
111  * elements are pass-by-reference. In either case, the best thing
112  * seems to be to copy the source as a flat representation and then
113  * deconstruct that later if necessary. For the pass-by-ref case, we
114  * could perhaps save some cycles with custom code that generates the
115  * deconstructed representation in parallel with copying the values,
116  * but it would be a lot of extra code for fairly marginal gain. So,
117  * fall through into the flat-source code path.
118  */
119  }
120 
121  /*
122  * Detoast and copy source array into private context, as a flat array.
123  *
124  * Note that this coding risks leaking some memory in the private context
125  * if we have to fetch data from a TOAST table; however, experimentation
126  * says that the leak is minimal. Doing it this way saves a copy step,
127  * which seems worthwhile, especially if the array is large enough to need
128  * external storage.
129  */
130  oldcxt = MemoryContextSwitchTo(objcxt);
131  array = DatumGetArrayTypePCopy(arraydatum);
132  MemoryContextSwitchTo(oldcxt);
133 
134  eah->ndims = ARR_NDIM(array);
135  /* note these pointers point into the fvalue header! */
136  eah->dims = ARR_DIMS(array);
137  eah->lbound = ARR_LBOUND(array);
138 
139  /* Save array's element-type data for possible use later */
140  eah->element_type = ARR_ELEMTYPE(array);
141  if (metacache && metacache->element_type == eah->element_type)
142  {
143  /* We have a valid cache of representational data */
144  eah->typlen = metacache->typlen;
145  eah->typbyval = metacache->typbyval;
146  eah->typalign = metacache->typalign;
147  }
148  else
149  {
150  /* No, so look it up */
152  &eah->typlen,
153  &eah->typbyval,
154  &eah->typalign);
155  /* Update cache if provided */
156  if (metacache)
157  {
158  metacache->element_type = eah->element_type;
159  metacache->typlen = eah->typlen;
160  metacache->typbyval = eah->typbyval;
161  metacache->typalign = eah->typalign;
162  }
163  }
164 
165  /* we don't make a deconstructed representation now */
166  eah->dvalues = NULL;
167  eah->dnulls = NULL;
168  eah->dvalueslen = 0;
169  eah->nelems = 0;
170  eah->flat_size = 0;
171 
172  /* remember we have a flat representation */
173  eah->fvalue = array;
174  eah->fstartptr = ARR_DATA_PTR(array);
175  eah->fendptr = ((char *) array) + ARR_SIZE(array);
176 
177  /* return a R/W pointer to the expanded array */
178  return EOHPGetRWDatum(&eah->hdr);
179 }
static const ExpandedObjectMethods EA_methods
#define AllocSetContextCreate
Definition: memutils.h:173
static void copy_byval_expanded_array(ExpandedArrayHeader *eah, ExpandedArrayHeader *oldeah)
#define ARR_SIZE(a)
Definition: array.h:282
#define VARATT_IS_EXTERNAL_EXPANDED(PTR)
Definition: postgres.h:335
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2218
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum * dvalues
Definition: array.h:139
char * fendptr
Definition: array.h:160
#define EA_MAGIC
Definition: array.h:106
#define ARR_LBOUND(a)
Definition: array.h:289
bool typbyval
Definition: array.h:233
ExpandedObjectHeader hdr
Definition: array.h:111
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
int16 typlen
Definition: array.h:232
void EOH_init_header(ExpandedObjectHeader *eohptr, const ExpandedObjectMethods *methods, MemoryContext obj_context)
Definition: expandeddatum.c:48
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
ArrayType * fvalue
Definition: array.h:158
#define DatumGetArrayTypePCopy(X)
Definition: array.h:255
#define Assert(condition)
Definition: c.h:804
#define ARR_NDIM(a)
Definition: array.h:283
#define DatumGetPointer(X)
Definition: postgres.h:593
char typalign
Definition: array.h:234
#define EOHPGetRWDatum(eohptr)
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
char * fstartptr
Definition: array.h:159
Oid element_type
Definition: array.h:231
#define ALLOCSET_START_SMALL_SIZES
Definition: memutils.h:212
#define ARR_ELEMTYPE(a)
Definition: array.h:285

◆ initArrayResult()

ArrayBuildState* initArrayResult ( Oid  element_type,
MemoryContext  rcontext,
bool  subcontext 
)

Definition at line 5083 of file arrayfuncs.c.

References ArrayBuildState::alen, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ArrayBuildState::dnulls, ArrayBuildState::dvalues, ArrayBuildState::element_type, get_typlenbyvalalign(), ArrayBuildState::mcontext, MemoryContextAlloc(), ArrayBuildState::nelems, ArrayBuildState::private_cxt, ArrayBuildState::typalign, ArrayBuildState::typbyval, and ArrayBuildState::typlen.

Referenced by accumArrayResult(), array_agg_transfn(), array_positions(), initArrayResultAny(), plperl_array_to_datum(), populate_array(), range_agg_transfn(), tuple_data_split_internal(), and xpath().

5084 {
5085  ArrayBuildState *astate;
5086  MemoryContext arr_context = rcontext;
5087 
5088  /* Make a temporary context to hold all the junk */
5089  if (subcontext)
5090  arr_context = AllocSetContextCreate(rcontext,
5091  "accumArrayResult",
5093 
5094  astate = (ArrayBuildState *)
5095  MemoryContextAlloc(arr_context, sizeof(ArrayBuildState));
5096  astate->mcontext = arr_context;
5097  astate->private_cxt = subcontext;
5098  astate->alen = (subcontext ? 64 : 8); /* arbitrary starting array size */
5099  astate->dvalues = (Datum *)
5100  MemoryContextAlloc(arr_context, astate->alen * sizeof(Datum));
5101  astate->dnulls = (bool *)
5102  MemoryContextAlloc(arr_context, astate->alen * sizeof(bool));
5103  astate->nelems = 0;
5104  astate->element_type = element_type;
5105  get_typlenbyvalalign(element_type,
5106  &astate->typlen,
5107  &astate->typbyval,
5108  &astate->typalign);
5109 
5110  return astate;
5111 }
#define AllocSetContextCreate
Definition: memutils.h:173
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2218
Datum * dvalues
Definition: array.h:183
bool typbyval
Definition: array.h:189
Oid element_type
Definition: array.h:187
bool private_cxt
Definition: array.h:191
bool * dnulls
Definition: array.h:184
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
char typalign
Definition: array.h:190
uintptr_t Datum
Definition: postgres.h:411
MemoryContext mcontext
Definition: array.h:182
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
int16 typlen
Definition: array.h:188

◆ initArrayResultAny()

ArrayBuildStateAny* initArrayResultAny ( Oid  input_type,
MemoryContext  rcontext,
bool  subcontext 
)

Definition at line 5548 of file arrayfuncs.c.

References ArrayBuildStateAny::arraystate, Assert, get_array_type(), get_element_type(), initArrayResult(), initArrayResultArr(), InvalidOid, ArrayBuildState::mcontext, ArrayBuildStateArr::mcontext, MemoryContextAlloc(), OidIsValid, and ArrayBuildStateAny::scalarstate.

Referenced by accumArrayResultAny(), ExecScanSubPlan(), and ExecSetParamPlan().

5549 {
5550  ArrayBuildStateAny *astate;
5551  Oid element_type = get_element_type(input_type);
5552 
5553  if (OidIsValid(element_type))
5554  {
5555  /* Array case */
5556  ArrayBuildStateArr *arraystate;
5557 
5558  arraystate = initArrayResultArr(input_type, InvalidOid, rcontext, subcontext);
5559  astate = (ArrayBuildStateAny *)
5560  MemoryContextAlloc(arraystate->mcontext,
5561  sizeof(ArrayBuildStateAny));
5562  astate->scalarstate = NULL;
5563  astate->arraystate = arraystate;
5564  }
5565  else
5566  {
5567  /* Scalar case */
5568  ArrayBuildState *scalarstate;
5569 
5570  /* Let's just check that we have a type that can be put into arrays */
5571  Assert(OidIsValid(get_array_type(input_type)));
5572 
5573  scalarstate = initArrayResult(input_type, rcontext, subcontext);
5574  astate = (ArrayBuildStateAny *)
5575  MemoryContextAlloc(scalarstate->mcontext,
5576  sizeof(ArrayBuildStateAny));
5577  astate->scalarstate = scalarstate;
5578  astate->arraystate = NULL;
5579  }
5580 
5581  return astate;
5582 }
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5083
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2706
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2734
unsigned int Oid
Definition: postgres_ext.h:31
ArrayBuildState * scalarstate
Definition: array.h:222
#define OidIsValid(objectId)
Definition: c.h:710
ArrayBuildStateArr * initArrayResultArr(Oid array_type, Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5270
ArrayBuildStateArr * arraystate
Definition: array.h:223
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:804
MemoryContext mcontext
Definition: array.h:182
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
MemoryContext mcontext
Definition: array.h:200

◆ initArrayResultArr()

ArrayBuildStateArr* initArrayResultArr ( Oid  array_type,
Oid  element_type,
MemoryContext  rcontext,
bool  subcontext 
)

Definition at line 5270 of file arrayfuncs.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, ArrayBuildStateArr::array_type, ArrayBuildStateArr::element_type, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_element_type(), ArrayBuildStateArr::mcontext, MemoryContextAllocZero(), OidIsValid, and ArrayBuildStateArr::private_cxt.

Referenced by accumArrayResultArr(), array_agg_array_transfn(), and initArrayResultAny().

5272 {
5273  ArrayBuildStateArr *astate;
5274  MemoryContext arr_context = rcontext; /* by default use the parent ctx */
5275 
5276  /* Lookup element type, unless element_type already provided */
5277  if (!OidIsValid(element_type))
5278  {
5279  element_type = get_element_type(array_type);
5280 
5281  if (!OidIsValid(element_type))
5282  ereport(ERROR,
5283  (errcode(ERRCODE_DATATYPE_MISMATCH),
5284  errmsg("data type %s is not an array type",
5285  format_type_be(array_type))));
5286  }
5287 
5288  /* Make a temporary context to hold all the junk */
5289  if (subcontext)
5290  arr_context = AllocSetContextCreate(rcontext,
5291  "accumArrayResultArr",
5293 
5294  /* Note we initialize all fields to zero */
5295  astate = (ArrayBuildStateArr *)
5296  MemoryContextAllocZero(arr_context, sizeof(ArrayBuildStateArr));
5297  astate->mcontext = arr_context;
5298  astate->private_cxt = subcontext;
5299 
5300  /* Save relevant datatype information */
5301  astate->array_type = array_type;
5302  astate->element_type = element_type;
5303 
5304  return astate;
5305 }
#define AllocSetContextCreate
Definition: memutils.h:173
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2706
int errcode(int sqlerrcode)
Definition: elog.c:698
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
bool private_cxt
Definition: array.h:212
MemoryContext mcontext
Definition: array.h:200

◆ makeArrayResult()

Datum makeArrayResult ( ArrayBuildState astate,
MemoryContext  rcontext 
)

Definition at line 5186 of file arrayfuncs.c.

References makeMdArrayResult(), ArrayBuildState::nelems, and ArrayBuildState::private_cxt.

Referenced by array_positions(), brin_minmax_multi_summary_out(), dblink_get_connections(), get_altertable_subcmdtypes(), optionListToArray(), parse_ident(), pg_get_statisticsobjdef_expressions(), pg_stats_ext_mcvlist_items(), regexp_split_to_array(), serialize_expr_stats(), text_to_array(), transformRelOptions(), tuple_data_split_internal(), and xpath().

5188 {
5189  int ndims;
5190  int dims[1];
5191  int lbs[1];
5192 
5193  /* If no elements were presented, we want to create an empty array */
5194  ndims = (astate->nelems > 0) ? 1 : 0;
5195  dims[0] = astate->nelems;
5196  lbs[0] = 1;
5197 
5198  return makeMdArrayResult(astate, ndims, dims, lbs, rcontext,
5199  astate->private_cxt);
5200 }
Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
Definition: arrayfuncs.c:5218
bool private_cxt
Definition: array.h:191

◆ makeArrayResultAny()

Datum makeArrayResultAny ( ArrayBuildStateAny astate,
MemoryContext  rcontext,
bool  release 
)

Definition at line 5621 of file arrayfuncs.c.

References ArrayBuildStateAny::arraystate, makeArrayResultArr(), makeMdArrayResult(), ArrayBuildState::nelems, and ArrayBuildStateAny::scalarstate.

Referenced by ExecScanSubPlan(), and ExecSetParamPlan().

5623 {
5624  Datum result;
5625 
5626  if (astate->scalarstate)
5627  {
5628  /* Must use makeMdArrayResult to support "release" parameter */
5629  int ndims;
5630  int dims[1];
5631  int lbs[1];
5632 
5633  /* If no elements were presented, we want to create an empty array */
5634  ndims = (astate->scalarstate->nelems > 0) ? 1 : 0;
5635  dims[0] = astate->scalarstate->nelems;
5636  lbs[0] = 1;
5637 
5638  result = makeMdArrayResult(astate->scalarstate, ndims, dims, lbs,
5639  rcontext, release);
5640  }
5641  else
5642  {
5643  result = makeArrayResultArr(astate->arraystate,
5644  rcontext, release);
5645  }
5646  return result;
5647 }
Datum makeArrayResultArr(ArrayBuildStateArr *astate, MemoryContext rcontext, bool release)
Definition: arrayfuncs.c:5469
Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
Definition: arrayfuncs.c:5218
ArrayBuildState * scalarstate
Definition: array.h:222
ArrayBuildStateArr * arraystate
Definition: array.h:223
uintptr_t Datum
Definition: postgres.h:411

◆ makeArrayResultArr()

Datum makeArrayResultArr ( ArrayBuildStateArr astate,
MemoryContext  rcontext,
bool  release 
)

Definition at line 5469 of file arrayfuncs.c.

References ARR_DATA_PTR, ARR_DIMS, ARR_LBOUND, ARR_NULLBITMAP, ARR_OVERHEAD_NONULLS, ARR_OVERHEAD_WITHNULLS, array_bitmap_copy(), ArrayCheckBounds(), ArrayGetNItems(), Assert, construct_empty_array(), ArrayBuildStateArr::data, ArrayType::dataoffset, ArrayBuildStateArr::dims, ArrayBuildStateArr::element_type, ArrayType::elemtype, ArrayBuildStateArr::lbs, ArrayBuildStateArr::mcontext, MemoryContextDelete(), MemoryContextSwitchTo(), ArrayBuildStateArr::nbytes, ArrayType::ndim, ArrayBuildStateArr::ndims, ArrayBuildStateArr::nitems, ArrayBuildStateArr::nullbitmap, palloc0(), PointerGetDatum, ArrayBuildStateArr::private_cxt, and SET_VARSIZE.

Referenced by array_agg_array_finalfn(), and makeArrayResultAny().

5472 {
5473  ArrayType *result;
5474  MemoryContext oldcontext;
5475 
5476  /* Build the final array result in rcontext */
5477  oldcontext = MemoryContextSwitchTo(rcontext);
5478 
5479  if (astate->ndims == 0)
5480  {
5481  /* No inputs, return empty array */
5482  result = construct_empty_array(astate->element_type);
5483  }
5484  else
5485  {
5486  int dataoffset,
5487  nbytes;
5488 
5489  /* Check for overflow of the array dimensions */
5490  (void) ArrayGetNItems(astate->ndims, astate->dims);
5491  ArrayCheckBounds(astate->ndims, astate->dims, astate->lbs);
5492 
5493  /* Compute required space */
5494  nbytes = astate->nbytes;
5495  if (astate->nullbitmap != NULL)
5496  {
5497  dataoffset = ARR_OVERHEAD_WITHNULLS(astate->ndims, astate->nitems);
5498  nbytes += dataoffset;
5499  }
5500  else
5501  {
5502  dataoffset = 0;
5503  nbytes += ARR_OVERHEAD_NONULLS(astate->ndims);
5504  }
5505 
5506  result = (ArrayType *) palloc0(nbytes);
5507  SET_VARSIZE(result, nbytes);
5508  result->ndim = astate->ndims;
5509  result->dataoffset = dataoffset;
5510  result->elemtype = astate->element_type;
5511 
5512  memcpy(ARR_DIMS(result), astate->dims, astate->ndims * sizeof(int));
5513  memcpy(ARR_LBOUND(result), astate->lbs, astate->ndims * sizeof(int));
5514  memcpy(ARR_DATA_PTR(result), astate->data, astate->nbytes);
5515 
5516  if (astate->nullbitmap != NULL)
5517  array_bitmap_copy(ARR_NULLBITMAP(result), 0,
5518  astate->nullbitmap, 0,
5519  astate->nitems);
5520  }
5521 
5522  MemoryContextSwitchTo(oldcontext);
5523 
5524  /* Clean up all the junk */
5525  if (release)
5526  {
5527  Assert(astate->private_cxt);
5528  MemoryContextDelete(astate->mcontext);
5529  }
5530 
5531  return PointerGetDatum(result);
5532 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
#define ARR_OVERHEAD_NONULLS(ndims)
Definition: array.h:303
#define PointerGetDatum(X)
Definition: postgres.h:600
void array_bitmap_copy(bits8 *destbitmap, int destoffset, const bits8 *srcbitmap, int srcoffset, int nitems)
Definition: arrayfuncs.c:4756
int32 dataoffset
Definition: array.h:89
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3440
#define ARR_OVERHEAD_WITHNULLS(ndims, nitems)
Definition: array.h:305
#define ARR_LBOUND(a)
Definition: array.h:289
bits8 * nullbitmap
Definition: array.h:202
Oid elemtype
Definition: array.h:90
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_DATA_PTR(a)
Definition: array.h:315
void ArrayCheckBounds(int ndim, const int *dims, const int *lb)
Definition: arrayutils.c:128
void * palloc0(Size size)
Definition: mcxt.c:1093
int lbs[MAXDIM]
Definition: array.h:209
#define Assert(condition)
Definition: c.h:804
int dims[MAXDIM]
Definition: array.h:208
bool private_cxt
Definition: array.h:212
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
#define ARR_NULLBITMAP(a)
Definition: array.h:293
MemoryContext mcontext
Definition: array.h:200
int ndim
Definition: array.h:88

◆ makeMdArrayResult()

Datum makeMdArrayResult ( ArrayBuildState astate,
int  ndims,
int *  dims,
int *  lbs,
MemoryContext  rcontext,
bool  release 
)

Definition at line 5218 of file arrayfuncs.c.

References Assert, construct_md_array(), ArrayBuildState::dnulls, ArrayBuildState::dvalues, ArrayBuildState::element_type, ArrayBuildState::mcontext, MemoryContextDelete(), MemoryContextSwitchTo(), PointerGetDatum, ArrayBuildState::private_cxt, ArrayBuildState::typalign, ArrayBuildState::typbyval, and ArrayBuildState::typlen.

Referenced by array_agg_finalfn(), makeArrayResult(), makeArrayResultAny(), plperl_array_to_datum(), and populate_array().

5224 {
5225  ArrayType *result;
5226  MemoryContext oldcontext;
5227 
5228  /* Build the final array result in rcontext */
5229  oldcontext = MemoryContextSwitchTo(rcontext);
5230 
5231  result = construct_md_array(astate->dvalues,
5232  astate->dnulls,
5233  ndims,
5234  dims,
5235  lbs,
5236  astate->element_type,
5237  astate->typlen,
5238  astate->typbyval,
5239  astate->typalign);
5240 
5241  MemoryContextSwitchTo(oldcontext);
5242 
5243  /* Clean up all the junk */
5244  if (release)
5245  {
5246  Assert(astate->private_cxt);
5247  MemoryContextDelete(astate->mcontext);
5248  }
5249 
5250  return PointerGetDatum(result);
5251 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
#define PointerGetDatum(X)
Definition: postgres.h:600
Datum * dvalues
Definition: array.h:183
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool typbyval
Definition: array.h:189
Oid element_type
Definition: array.h:187
bool private_cxt
Definition: array.h:191
bool * dnulls
Definition: array.h:184
char typalign
Definition: array.h:190
#define Assert(condition)
Definition: c.h:804
MemoryContext mcontext
Definition: array.h:182
int16 typlen
Definition: array.h:188
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3354

◆ mda_get_offset_values()

void mda_get_offset_values ( int  n,
int *  dist,
const int *  prod,
const int *  span 
)

Definition at line 181 of file arrayutils.c.

References i.

Referenced by array_extract_slice(), array_insert_slice(), and array_slice_size().

182 {
183  int i,
184  j;
185 
186  dist[n - 1] = 0;
187  for (j = n - 2; j >= 0; j--)
188  {
189  dist[j] = prod[j] - 1;
190  for (i = j + 1; i < n; i++)
191  dist[j] -= (span[i] - 1) * prod[i];
192  }
193 }
int i

◆ mda_get_prod()

void mda_get_prod ( int  n,
const int *  range,
int *  prod 
)

Definition at line 165 of file arrayutils.c.

References i.

Referenced by array_extract_slice(), array_insert_slice(), array_slice_size(), and ReadArrayStr().

166 {
167  int i;
168 
169  prod[n - 1] = 1;
170  for (i = n - 2; i >= 0; i--)
171  prod[i] = prod[i + 1] * range[i + 1];
172 }
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
int i

◆ mda_get_range()

void mda_get_range ( int  n,
int *  span,
const int *  st,
const int *  endp 
)

Definition at line 151 of file arrayutils.c.

References i.

Referenced by array_extract_slice(), array_get_slice(), array_insert_slice(), array_set_slice(), and array_slice_size().

152 {
153  int i;
154 
155  for (i = 0; i < n; i++)
156  span[i] = endp[i] - st[i] + 1;
157 }
int i

◆ mda_next_tuple()

int mda_next_tuple ( int  n,
int *  curr,
const int *  span 
)

Definition at line 206 of file arrayutils.c.

References i.

Referenced by array_extract_slice(), array_insert_slice(), and array_slice_size().

207 {
208  int i;
209 
210  if (n <= 0)
211  return -1;
212 
213  curr[n - 1] = (curr[n - 1] + 1) % span[n - 1];
214  for (i = n - 1; i && curr[i] == 0; i--)
215  curr[i - 1] = (curr[i - 1] + 1) % span[i - 1];
216 
217  if (i)
218  return i;
219  if (curr[0])
220  return 0;
221 
222  return -1;
223 }
int i

Variable Documentation

◆ Array_nulls

bool Array_nulls

Definition at line 42 of file arrayfuncs.c.

Referenced by ReadArrayStr().