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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.