Postgresql C/Postgres-在非PG功能中使用palloc

Postgresql C/Postgres-在非PG功能中使用palloc,postgresql,postgresql-10,Postgresql,Postgresql 10,我目前正在实现一种用户定义的数据类型——一种链表,它模拟名为intList.c的文件中的一组整数,希望与intList.source一起使用,将其安装到我的Postgres服务器上 因此,我的问题如下: 我可以在代码中编写C函数,例如(link newNode)和(link InsertEnd),其中它们不是要在源文件中声明和创建的postgres函数吗 我可以在从输入函数调用的函数中使用palloc?(在本例中为链接新节点)?或者我应该在我的输入函数中这样做 我的intList.c代码如下:p

我目前正在实现一种用户定义的数据类型——一种链表,它模拟名为intList.c的文件中的一组整数,希望与intList.source一起使用,将其安装到我的Postgres服务器上

因此,我的问题如下:

  • 我可以在代码中编写C函数,例如(link newNode)和(link InsertEnd),其中它们不是要在源文件中声明和创建的postgres函数吗

  • 我可以在从输入函数调用的函数中使用
    palloc
    ?(在本例中为链接新节点)?或者我应该在我的输入函数中这样做

  • 我的intList.c代码如下:p.S.这些函数都在c中工作,但我还没有在我的PostgreSQL server中安装它们,所以我不知道结果如何:

     // Defining struct for linked list
     typedef struct intSet *link;
    
     typedef struct intList {
        int num;
        link next;
     } intList;
    
     //  Create a new node
     link newNode(int item) {
         link n = (link) palloc(sizeof(*n));
         n->num = item;
         n->next = NULL;
         return n;
     }
    
     link insertEnd(link list, link n){
         link curr;
         // Empty list
         if(list == NULL){
             list = n;
             n->next = NULL;
         // If list not empty, iterate to end of list, then append
         } else {
             for(curr = list; curr->next != NULL; curr = curr->next) {
             }
             curr->next = n;
             n->next = NULL;
         }
         return list;
     }    
    
     PG_FUNCTION_INFO_V1(intList_in);
    
     Datum
     intList_in(PG_FUNCTION_ARGS)
     {
         char       *str = PG_GETARG_CSTRING(0);
         char       *token;
    
         // Create an empty linked list
         link newList;
         newList = NULL;
    
         // Get individual ints from a set e.g. {1, 2, 3, 4}
         token = strtok(str, ",{} ");
    
         // For each int, create a new node then
         // append to list
         while (token != NULL) {
             link a = NULL;
             a = newNode(atoi(token));
             newList = insertEnd(newList, a);
             token = strtok(NULL, ",{} ");
         }
    
         PG_RETURN_POINTER(newList);
     }
    
     Datum
     intList_out(PG_FUNCTION_ARGS)
     {
         // Start our string
         char* out = "{";
         char* num;
         // Retrieve our list from arg(0)
         link List = PG_GETARG_POINTER(0);
         link curr;
         // Traverse list till last node, add commas after each node
         for (curr = List; curr->next != NULL; curr = curr->next) {
             num = itoa(curr->num);
             strcat(num, ", "); 
             strcat(out, num);
         }
         // At last node, add closing bracket to close list
         num = itoa(curr->num);
         strcat(num, "}");
         strcat(out, num);
    
         // Psprintf to result then return it
         char *result;
         result = psprintf("%s", out);
         PG_RETURN_CSTRING(result);
    
     }
    
    这只是我整个代码的一部分,我将实现运算符和其他函数,因此任何提示和指针都将非常感谢

    我可以在代码中编写C函数,例如(link newNode)和(link InsertEnd),其中它们不是要在源文件中声明和创建的postgres函数吗

    我想你的意思是,你能在没有palloc的情况下编写它们吗。当然可以。虽然不建议这样做。PostgreSQL将
    malloc
    包装为性能原因和完整性原因(确保在txn结束时释放内存)。你必须在没有palloc的情况下解决这个问题,我不知道你会遇到什么样的挑战

    我可以在从输入函数调用的函数中使用
    palloc
    ?(在本例中为链接新节点)?或者我应该在我的输入函数中这样做


    当然,如果你在服务器上运行,那就是你应该做的。只是
    #包括

    1)
    token=strtok(str,,{})
    strtok()将损坏str(可能是只读的,或者是缓冲区或结构的一部分)2
    num=itoa(curr->num);strcat(num,“,”);strcat(out,num)肯定会出错。在1)的情况下,我可以用strcpy生成另一个字符串,但是你能推荐我做什么来代替2)?我唯一能想到的是将“out”的大小定义为BUFSIZ或更大的值。我根本不会使用strtok():还有一个0)
    strtok()
    依赖于静态数据,在同一个查询中的多个位置使用代码(并非不可能)可能会导致奇怪的结果,至少,在这种情况下,stcpy将完成这项工作,感谢您指出SEGFULT,itoa肯定不是一个标准函数,所以sprintf完成了这项工作,然后我只使用了一个静态字符串,每次调用都会重置它。