PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL आंतरिक C फ़ंक्शन की प्रतिलिपि बनाएँ और इसे उपयोगकर्ता परिभाषित फ़ंक्शन के रूप में लोड करें

psql क्लाइंट पूछ रहा है कि क्या आप फिर से कनेक्ट करना चाहते हैं क्योंकि टिप्पणियों के अनुसार बैकएंड segfaulting है।

इस तरह की दुर्घटना से कोर डंप एकत्र करना और डीबगर (उदाहरण के लिए जीडीबी) के साथ इसकी जांच करना संभव होगा ताकि यह पता लगाया जा सके कि यह कहां दुर्घटनाग्रस्त हो रहा है। हालांकि, मेरा सबसे अच्छा अनुमान यह है कि यह क्रैश हो रहा है क्योंकि आपने पोस्टग्रेस्क्ल के मुख्य घटक के रूप में लिखी गई एक बड़ी फ़ाइल ली है, इसे अलग से संकलित किया है, और इसे एक एक्सटेंशन मॉड्यूल के रूप में लोड करने का प्रयास किया है।

फ़ाइल numeric.c में बड़ी संख्या में फ़ंक्शन, स्थिर चर और डेटा संरचनाएं हैं, जिनमें से आप केवल एक को डुप्लिकेट करने का प्रयास कर रहे हैं। ये सभी कार्य, चर, आदि पहले से चल रहे पोस्टग्रेस्क्ल सिस्टम में मौजूद हैं। जब आप numeric.c के अपने संस्करण को संकलित करते हैं और इसे लोड करते हैं, तो आप जो नया फ़ंक्शन जोड़ रहे हैं, वह मुख्य पोस्टग्रेस्क्ल प्रोग्राम में उपयोग करने के बजाय आपकी लाइब्रेरी में फ़ंक्शंस और वेरिएबल्स को संदर्भित करेगा। यह शायद डेटा संरचनाओं को संदर्भित कर रहा है जो ठीक से प्रारंभ नहीं किए गए हैं, जिससे यह क्रैश हो रहा है।

मेरा सुझाव है कि आप एक खाली फ़ाइल से शुरू करें और केवल numeric.c से int2_avg_accum फ़ंक्शन में कॉपी करें (जैसा आपने किया है उसका नाम बदला)। यदि वह फ़ंक्शन पोस्टग्रेस्क्ल में अन्य कार्यों को कॉल कर रहा है, या चर का संदर्भ दे रहा है, तो यह मुख्य पोस्टग्रेस्क्ल बाइनरी में फ़ंक्शन और चर का उपयोग करेगा, जो कि आप चाहते हैं। आप सभी बाहरी कार्यों की घोषणाओं को प्राप्त करने के लिए #मूल संख्या को शामिल कर सकते हैं।

फ़ंक्शन को आंतरिक फ़ंक्शन के रूप में कैसे परिभाषित किया जाता है और गतिशील रूप से लोड किए गए मॉड्यूल के रूप में लोड होने पर इसे कैसे परिभाषित किया जाना चाहिए, इसके बीच कुछ अन्य अंतर हैं:

  • आपको मैक्रो जोड़कर यह निर्दिष्ट करना होगा कि आप V1 कॉलिंग कन्वेंशन का उपयोग कर रहे हैं:

    PG_FUNCTION_INFO_V1(int2_avg_accum2);

    यदि यह गायब है तो यह segfaults का कारण बनेगा क्योंकि postgresql संस्करण 0 कॉलिंग सम्मेलनों को ग्रहण करेगा, जो फ़ंक्शन परिभाषा से मेल नहीं खाता है!

  • जैसा कि आपने बताया है कि आपको PG_MODOULE_MAGIC को शामिल करना होगा।

मेरे लिए काम करने वाली पूरी फाइल है:

#include "postgres.h"
#include "fmgr.h"
#include "utils/array.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

typedef struct Int8TransTypeData
{
    int64       count;
    int64       sum;
} Int8TransTypeData;

PG_FUNCTION_INFO_V1(int2_avg_accum2);

Datum
int2_avg_accum2(PG_FUNCTION_ARGS)
{
    ArrayType  *transarray;
    int16       newval = PG_GETARG_INT16(1);
    Int8TransTypeData *transdata;

    /*
     * If we're invoked as an aggregate, we can cheat and modify our first
     * parameter in-place to reduce palloc overhead. Otherwise we need to make
     * a copy of it before scribbling on it.
     */
    if (AggCheckCallContext(fcinfo, NULL))
        transarray = PG_GETARG_ARRAYTYPE_P(0);
    else
        transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);

    if (ARR_HASNULL(transarray) ||
        ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
        elog(ERROR, "expected 2-element int8 array");

    transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    transdata->count++;
    transdata->sum += newval;

    PG_RETURN_ARRAYTYPE_P(transarray);
}

इसके साथ संकलित:

gcc -I/usr/pgsql-9.2/include/server -fPIC -c my_avg_accum.c
gcc -shared -o my_avg_accum.so my_avg_accum.o

मैं Centos 6 पर Postgresql 9.2 का उपयोग कर रहा था। आपको अपने सेटअप के अनुसार अपने पथ समायोजित करने की आवश्यकता हो सकती है।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. फंक्शन रैप sql के साथ postgresql इतना धीमा?

  2. अजगर में postgresql कथन के लिए पैरामीटर पास करने के लिए एक शब्दकोश का उपयोग करना

  3. गोरोइन्स ने कनेक्शन पूल को अवरुद्ध कर दिया

  4. स्प्रिंग/हेरोकू/एसएसएल डेटासोर्स को पोस्टग्रेज कैसे सेट करें

  5. PostgreSQL 8.3 के बाद से TPC-H का प्रदर्शन