2

I'm trying to get a feel for processing arrays in C for PG. There are examples of reading existing arrays, but I can't find one on how to create and set a new one.

This is what I've got so far. I think my intent is clear:

PG_FUNCTION_INFO_V1(makearray);

PGMODULEEXPORT Datum makearray(PG_FUNCTION_ARGS)
{
  long a = PG_GETARG_INT32(0);
  ArrayType* result = new_intArrayType(a);

  for (long i = 0; i < a; i++)
  {
      result[i] = DatumSetInt32(i);
  }

  PG_RETURN_ARRAYTYPE_P(result);
}

How do I set the value for each element? Also, I actually want an int8[] array.

NOTE

I don't want to pass the arguments in. The array will be created entirely internally. How do I set the elements without getting them? My exact case is to have a C long long array that has the values and then copy these to the PG array.

1 Answer 1

3

You should to use function construct_array or construct_md_array

#include "catalog/pg_type.h"

PG_FUNCTION_INFO_V1(array_four);

Datum
array_four(PG_FUNCTION_ARGS)
{
    Datum       elements[4];
    ArrayType   *array;

    elements[0] = PG_GETARG_DATUM(0);
    elements[1] = PG_GETARG_DATUM(1);
    elements[2] = PG_GETARG_DATUM(2);
    elements[3] = PG_GETARG_DATUM(3);

    array = construct_array(elements, 4, INT8OID, 8, true, 'd');

    PG_RETURN_POINTER(array);
}

second variant:

Datum
array_four(PG_FUNCTION_ARGS)
{
    Datum       elements[4];
    ArrayType   *array;
    int i;

    for (i = 0; i < 4; i++)
        elements[i] = Int64GetDatum(i);

    array = construct_array(elements, 4, INT8OID, 8, true, 'd');

    PG_RETURN_POINTER(array);
}

registration:

CREATE FUNCTION array_four(int, int, int, int)
RETURNS int[]
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT;

test:

postgres=# select array_four(10,20,30,40);
┌───────────────┐
│  array_four   ��
╞═══════════════╡
│ {10,20,30,40} │
└───────────────┘
(1 row)
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. I don't want to pass the arguments in. The array will be created entirely internally. How do I set the elements without getting them? My exact case is to have a C long long array that has the values and then copy these to the PG array.
For my reference, I deduce that 'd' means 8 for int8. What's the char for int4? 'c'?
select typalign, typlen from pg_type where typname like 'int4'; -- 'i', 4. If you would to use internal value - then use function elements[0] = Int32GetDatum(int32value) or function Int64GetDatum for Int8
I know it's an old post but I'm having a similar problem. How should the parameter of array = construct_array(elements, 4, INT8OID, 8, true, 'd'); look like if I want to return an array with 4 text variables that I construct internely.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.