2017-02-07 1 views
0

최소/최대 타임 스탬프가있는 행의 열 값을 반환하는 집계 함수를 생성하려고합니다. 다음은 일부 큰 입력에 대해 세그먼트 화 오류를 발생시키는 코드입니다.PostgreSQL 커스텀 C 집계 함수가 세그먼트 화 오류를 던졌습니다.

PG_FUNCTION_INFO_V1(minmax); 

    Datum minmax(PG_FUNCTION_ARGS) { 
     if(PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3)) { 
      if(PG_ARGISNULL(0)) { 
       PG_RETURN_NULL(); 
      } 
      else { 
       PG_RETURN_HEAPTUPLEHEADER(PG_GETARG_HEAPTUPLEHEADER(0)); 
      } 
     } 

     Timestamp epoch = PG_GETARG_TIMESTAMP(1); 
     Datum col = PG_GETARG_DATUM(2); 
     Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 2); 
     bool is_min = PG_GETARG_BOOL(3); 

     Timestamp minmax_epoch = is_min ? LONG_MAX : LONG_MIN; 
     Datum minmax_col; 
     if(PG_ARGISNULL(0)) { 
      // first call 
      minmax_epoch = epoch; 
      minmax_col = col; 
     } 
     else { 
      // state 
      HeapTupleHeader hth_state = PG_GETARG_HEAPTUPLEHEADER(0); 

      bool isnull_state_minmax_timestamp; 
      Datum d_state_minmax_timestamp = GetAttributeByNum(hth_state, (AttrNumber) 1, &isnull_state_minmax_timestamp); 

      minmax_epoch = DatumGetInt64(d_state_minmax_timestamp); 
      if((is_min && epoch < minmax_epoch) || (!is_min && epoch > minmax_epoch)) { 
       minmax_epoch = epoch; 
       minmax_col = col; 
      } 
      else { 
       PG_RETURN_HEAPTUPLEHEADER(hth_state); 
      } 
     } 
     // return state 
     TupleDesc tupdesc; 
     Datum  values[2]; 
     bool  nulls[2]; 
     MemSet(values, 0, sizeof(values)); 
     MemSet(nulls, 0, sizeof(nulls)); 

     tupdesc = CreateTemplateTupleDesc(2, false); 
     TupleDescInitEntry(tupdesc, (AttrNumber) 1, "minmax_timestamp", INT8OID, -1, 0); 
     TupleDescInitEntry(tupdesc, (AttrNumber) 2, "minmax_col", element_type, -1, 0); 

     tupdesc = BlessTupleDesc(tupdesc); 
     values[0] = Int64GetDatum(minmax_epoch); 
     values[1] = minmax_col; 

     HeapTuple rettuple = heap_form_tuple(tupdesc, values, nulls); 
     PG_RETURN_DATUM(HeapTupleGetDatum(rettuple)); 
    } 

    PG_FUNCTION_INFO_V1(get_minmax); 

    Datum get_minmax(PG_FUNCTION_ARGS) { 
     if(PG_ARGISNULL(0)) { 
      PG_RETURN_NULL(); 
     } 
     else { 
      // state 
      //error here 
      HeapTupleHeader hth_state = PG_GETARG_HEAPTUPLEHEADER(0); 

      bool isnull_state_minmax_col; 
      Datum d_state_minmax_col = GetAttributeByNum(hth_state, (AttrNumber) 2, &isnull_state_minmax_col); 

      PG_RETURN_DATUM(d_state_minmax_col); 
     } 
    } 

독방 감금 오류는 함수에서 PG_GETARG_HEAPTUPLEHEADER 인수를 받고 get_minmax 것 같다. 내가 minmax 함수에서 제대로 빌드하지 않을 수도 있습니다.

+0

당신은 [적절한 C 서식] (// prohackr112.tk/pcf)로 보일 것입니다. 또는 [코드를 철저하게 난독 화하는 방법]을 배우십시오 (// prohackr112.tk/guide/coding/proper-c-obfuscation). –

+0

이 문제는 기능 등록 및 전환 유형 등록과 관련 될 수 있습니다. 이 목적을 위해 튜플은 느리다 - 자신의 내부 유형을 사용하는 것이 더 좋다 - 두 개의 타임 스탬프가있는 내부적으로 C 구조 - 타임 스탬프는 Postgres에서 고정 데이터 유형이다. –

답변

0

위의 코드에 문제가있는 것 같지 않습니다. 나는 greenplum에서 aggregate 함수를 사용하고 postgresql은 사용하지 않았다. greenplum에 집계 함수를 작성하고 PREFUNC를 구현하는 경우에는 인수가 모두 NULL인지 확인하고 그에 따라 처리해야합니다. 어떤 개선, 메모리 사용의 관점에서 위의 기능을 할 수있는 경우

전문가들은 제안 않는 등

관련 문제