backend dies on my aggregate function in 7.1.2 - Mailing list pgsql-general

From Dirk Lutzebaeck
Subject backend dies on my aggregate function in 7.1.2
Date
Msg-id 15238.50010.562845.992555@cayambe.core.aeccom.com
Whole thread Raw
Responses Re: backend dies on my aggregate function in 7.1.2  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-general
Hi,

I am trying to write an aggregate function (maxalphanum_check) for
7.1.2 but I just get abnormal termination of the backend. It uses a
function maxalphanum_gt which works quite well alone. What am I doing
wrong?

*** this is the aggregate function:

#include <postgres.h>

text * maxalphanum_check(text *internal, text *next) {
  text *new, *new_t;

  if (maxalphanum_gt(next, internal)) {
    new = next;
  } else {
    new = internal;
  }

  /* it seems that we must allocate the value we return */

  new_t = (text *) palloc(VARSIZE(new));
  memset(new_t, 0, VARSIZE(new));
  VARATT_SIZEP(new_t) = VARSIZE(new);
  memcpy((void *) VARDATA(new_t),
         (void *) VARDATA(new),
         VARSIZE(new)-VARHDRSZ);

  return(new_t);
}

*** compiled by


        gcc -O -fPIC -I../../postgresql-7.1.2/src/include -c maxalphanum.c
        gcc -shared -o maxalphanum.so maxalphanum.o


*** the aggregate is then created by

CREATE AGGREGATE maxalphanum (
   SFUNC1 = maxalphanum_check,
   BASETYPE = TEXT,
   STYPE1 = TEXT
);


*** the query which breaks the backend is then eg:

SELECT maxalphanum(x) FROM t GROUP BY x;
pqReadData() -- backend closed the channel unexpectedly.
        This probably means the backend terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

*** This is the function maxalphanum_gt which works quite well in
selects:

/*
   a state transition function for the maxalphanum aggregate
*/

#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <postgres.h>

#define MAXLEN 256

int maxalphanum_gt(text *str_a, text *str_b) {
  char *a_data = (char *) VARDATA(str_a);
  char *b_data = (char *) VARDATA(str_b);

  char a_str[MAXLEN];
  char b_str[MAXLEN];

  int a_len = VARSIZE(str_a) - VARHDRSZ;
  int b_len = VARSIZE(str_b) - VARHDRSZ;

  char a = a_data[0];
  char b = b_data[0];

  if (a_len == 0 && b_len > 0) {
    return 0;
  }

  if (a_len > 0 && b_len == 0) {
    return 1;
  }

  if (a_len >= MAXLEN || b_len >= MAXLEN) {
    return 0;
  }

  memcpy(a_str, a_data, a_len);
  a_str[a_len] = '\0';

  memcpy(b_str, b_data, b_len);
  b_str[b_len] = '\0';

  if (isdigit(a) && isdigit(b)) {
    return atoi(a_str) > atoi(b_str);
  }

  if (isdigit(a) && isalpha(b)) {
    return 1;
  }

  if (isalpha(a) && isdigit(b)) {
    return 0;
  }

  if (isalpha(a) && isalpha(b)) {
    return strcasecmp(a_str, b_str) > 0;
  }

  return a > b;
}



Dirk

pgsql-general by date:

Previous
From: "Joe Conway"
Date:
Subject: Re: store in bytea
Next
From: "Rob Arnold"
Date:
Subject: Re: problems transfering databases