2017-06-12 48 views
1

我正在爲C語言開發postgreSQL的擴展。我創建了兩種新類型,一種是變量大小(vlen)。我不知道如何爲Geo_Polygon類型創建輸入和輸出函數。任何人都有一個例子? 這是我迄今爲止所做的。用戶自定義Type C中的PostgreSQL

typedef struct Geo_Point{ 
    double x; 
    double y; 
} Geo_Point; 

typedef struct Geo_Polygon{ 
    int32 v_len; 
    int32 n_points; 
    Geo_Point point[FLEXIBLE_ARRAY_MEMBER]; 
} Geo_Polygon; 


PG_FUNCTION_INFO_V1(geo_polygon_in); 
Datum 
geo_polygon_in(PG_FUNCTION_ARGS){ 


    char *str = PG_GETARG_CSTRING(0); 
    char *new_position = NULL; 
    char aux[1024]; 
    int i, dimension, len; 
    Geo_Polygon *result; 
    Geo_Point *point; 
    double x, y; 



point = (Geo_Point *) palloc(sizeof(Geo_Point)); 

    new_position = strchr(str, '('); 

    for (dimension = 0; *new_position != '\0'; dimension++){ 

    memset(aux, 0, sizeof(aux)); 
    for (i = 0; *new_position != ')'; i++, ++new_position) { 
     aux[i] = *new_position; 
    } 
    aux[i] = *new_position; 
    ++new_position; 
    if (*new_position == ',') { 
     ++new_position; 
    } 

    point = (Geo_Point *) repalloc(point, (dimension + 1) * sizeof(Geo_Point)); 
    if(sscanf(aux, " (%lf , %lf)", &x, &y)!= 2) 
     ereport(ERROR, 
      (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 
      errmsg("entrada errada para o tipo geo_point: \"%s\"", 
       str))); 

    point->x = x; 
    point->y = y; 

    } 

    len = sizeof(Geo_Point) * (dimension + 1)+ VARHDRSZ; 
    result = (Geo_Polygon *) palloc0(len); 
    SET_VARSIZE(result, len); 
    // copy the coordinates to the data area destino arqu e quantos bytes 
    memcpy((void *) VARDATA(result),(void *) VARDATA (point), (dimension) * sizeof(Geo_Point)); 

    result->n_points = dimension; 

    PG_RETURN_POINTER(result); 

} 


Datum 
geo_polygon_out(PG_FUNCTION_ARGS){ 
    Geo_Polygon *geo_polygon = (Geo_Polygon *) PG_GETARG_POINTER(0); 
    StringInfoData buf; 
    int   dim = geo_polygon->n_points; 

    int   i; 
    int   ndig = 2; 

    initStringInfo(&buf); 


    appendStringInfoChar(&buf, '('); 
    for (i = 0; i < dim; i++){ 

    appendStringInfo(&buf, "%.*g", geo_polygon->point[i].x, "%.*g", geo_polygon->point[i].y); 
    appendStringInfoChar(&buf, ')'); 

    } 
    PG_FREE_IF_COPY(geo_polygon, 0); 
    PG_RETURN_CSTRING(buf.data);} 

回答