/* * Module initialize function: fetch function pointers for cross-module calls. */ void _PG_init(void) { /* Asserts verify that typedefs above match original declarations */ AssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t); PLyObject_AsString_p = (PLyObject_AsString_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyObject_AsString", true, NULL); #if PY_MAJOR_VERSION >= 3 AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t); PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize", true, NULL); #endif AssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t); hstoreUpgrade_p = (hstoreUpgrade_t) load_external_function("$libdir/hstore", "hstoreUpgrade", true, NULL); AssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t); hstoreUniquePairs_p = (hstoreUniquePairs_t) load_external_function("$libdir/hstore", "hstoreUniquePairs", true, NULL); AssertVariableIsOfType(&hstorePairs, hstorePairs_t); hstorePairs_p = (hstorePairs_t) load_external_function("$libdir/hstore", "hstorePairs", true, NULL); AssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t); hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t) load_external_function("$libdir/hstore", "hstoreCheckKeyLen", true, NULL); AssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t); hstoreCheckValLen_p = (hstoreCheckValLen_t) load_external_function("$libdir/hstore", "hstoreCheckValLen", true, NULL); }
/* * Module initialize function: fetch function pointers for cross-module calls. */ void _PG_init(void) { /* Asserts verify that typedefs above match original declarations */ AssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t); PLyObject_AsString_p = (PLyObject_AsString_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyObject_AsString", true, NULL); #if PY_MAJOR_VERSION >= 3 AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t); PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize", true, NULL); #endif AssertVariableIsOfType(&PLy_elog_impl, PLy_elog_impl_t); PLy_elog_impl_p = (PLy_elog_impl_t) load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLy_elog_impl", true, NULL); }
/* * Validator for C language functions * * Make sure that the library file exists, is loadable, and contains * the specified link symbol. Also check for a valid function * information record. */ Datum fmgr_c_validator(PG_FUNCTION_ARGS) { Oid funcoid = PG_GETARG_OID(0); void *libraryhandle; HeapTuple tuple; Form_pg_proc proc; bool isnull; Datum tmp; char *prosrc; char *probin; /* * It'd be most consistent to skip the check if !check_function_bodies, * but the purpose of that switch is to be helpful for pg_dump loading, * and for pg_dump loading it's much better if we *do* check. */ tuple = SearchSysCache(PROCOID, ObjectIdGetDatum(funcoid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for function %u", funcoid); proc = (Form_pg_proc) GETSTRUCT(tuple); tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosrc, &isnull); if (isnull) elog(ERROR, "null prosrc"); prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp)); tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_probin, &isnull); if (isnull) elog(ERROR, "null probin"); probin = DatumGetCString(DirectFunctionCall1(textout, tmp)); (void) load_external_function(probin, prosrc, true, &libraryhandle); (void) fetch_finfo_record(libraryhandle, prosrc); ReleaseSysCache(tuple); PG_RETURN_VOID(); }
static int InitFsysInterfaceFromFlatfile(FsysName name, FsysInterface fsys) { int retval = 0; char *filename; FILE *fsys_file; List *list = NIL; ListCell *cell; char *libFile; char *funcName; filename = filesystem_getflatfilename(); fsys_file = AllocateFile(filename, "r"); if (fsys_file == NULL) ereport(FATAL, (errcode_for_file_access(), errmsg("could not open file \"%s\": %m", filename))); if (!get_pg_filesystem_from_flatfile(filename, fsys_file, name, &list)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("cannot find filesystem \"%s\" in flatfile \"%s\"", name, filename))); if (list_length(list) != FSYS_FUNC_TOTALNUM+1) elog(ERROR, "not enough items in flatfile for filesystem \"%s\", need %d, found %d", name, FSYS_FUNC_TOTALNUM+1, list_length(list)); cell = list_head(list); /* get fsys libfile */ libFile = lfirst(cell); cell = lnext(cell); /* Init all funcs used by filesystem */ for(int i = 0; i < FSYS_FUNC_TOTALNUM; i++) { FmgrInfo *finfo = &(fsys->fsysFuncs[i]); void *libraryhandle; funcName = lfirst(cell); cell = lnext(cell); finfo->fn_addr = load_external_function(libFile, funcName, true, &libraryhandle); finfo->fn_oid = (Oid) (i+1); finfo->fn_nargs = 0; finfo->fn_strict = 0; finfo->fn_strict = 0; finfo->fn_retset = 0; finfo->fn_stats = 1; finfo->fn_extra = NULL; finfo->fn_mcxt = CurrentMemoryContext; finfo->fn_expr = NULL; } FreeFile(fsys_file); pfree(filename); if (list != NIL) { foreach (cell, list) pfree(lfirst(cell)); list_free(list); list = NIL; } return retval; }
static int InitFsysInterface(FsysName name, FsysInterface fsys) { int retval = 0; Relation rel; TupleDesc dsc; HeapScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; Datum funcDatum; Datum libFileDatum; char *libFile; char *funcName; bool isNull; /* * Search pg_filesystem. We use a heapscan here even though there is an * index on oid, on the theory that pg_filesystem will usually have just a * few entries and so an indexed lookup is a waste of effort. */ rel = heap_open(FileSystemRelationId, AccessShareLock); dsc = RelationGetDescr(rel); ScanKeyInit(&entry[0], Anum_pg_filesystem_fsysname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(name)); scandesc = heap_beginscan(rel, SnapshotNow, 1, entry); tuple = heap_getnext(scandesc, ForwardScanDirection); /* We assume that there can be at most one matching tuple */ if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("filesystem \"%s\" does not exist", name))); /* get libfile */ libFileDatum = heap_getattr(tuple, Anum_pg_filesystem_fsyslibfile, dsc, &isNull); if(isNull) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("filesystem \"%s\" has no libfile specified", name))); } libFile = TextDatumGetCString(libFileDatum); /* Init all funcs used by filesystem */ for(int i = 0; i < FSYS_FUNC_TOTALNUM; i++) { FmgrInfo *finfo = &(fsys->fsysFuncs[i]); void *libraryhandle; funcDatum = heap_getattr(tuple, fsys_func_type_to_attnum(i), dsc, &isNull); if(isNull) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("filesystem \"%s\" has no %s function defined", name, fsys_func_type_to_name(i)))); } funcName = NameStr(*(DatumGetName(funcDatum))); finfo->fn_addr = load_external_function(libFile, funcName, true, &libraryhandle); finfo->fn_oid = (Oid) 1; finfo->fn_nargs = 0; finfo->fn_strict = 0; finfo->fn_strict = 0; finfo->fn_retset = 0; finfo->fn_stats = 1; finfo->fn_extra = NULL; finfo->fn_mcxt = CurrentMemoryContext; finfo->fn_expr = NULL; } heap_endscan(scandesc); heap_close(rel, AccessShareLock); return retval; }
/* ---------- * conv_proc( * INTEGER, -- source encoding id * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) * INTEGER -- source string length * ) returns VOID; * ---------- */ Datum sjis_eudc_to_utf8(PG_FUNCTION_ARGS) { unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); unsigned char *p; unsigned char *fallback_character = NULL; int len = PG_GETARG_INT32(4); int sjis_len; int clen; CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_UTF8); if (sjis_to_utf8 == NULL) sjis_to_utf8 = load_external_function( "utf8_and_sjis", "sjis_to_utf8", true, NULL); *dest = '\0'; p = src; sjis_len = 0; for (; len > 0; len -= clen) { const unsigned char *c = p + sjis_len; if (c[0] == '\0') report_invalid_encoding(PG_SJIS, (const char *) p + sjis_len, len); if (c[0] >= 0xf0 && c[0] <= 0xf9 && len >= 2 && ISSJISTAIL(c[1])) { int ucs; int m; int n; clen = 2; /* SJIS to UTF8 */ if (sjis_len > 0) { DirectFunctionCall5(sjis_to_utf8, PG_SJIS, PG_UTF8, CStringGetDatum(p), CStringGetDatum(dest), sjis_len); dest = dest + strlen((char *) dest); p += sjis_len; sjis_len = 0; } p += clen; elog(eudc_log_level, "eudc character found: %02x%02x in SJIS to UTF8 conversion", c[0], c[1]); /* SJIS EUDC to UTF8 */ if (eudc_fallback_character && eudc_fallback_character[0]) { /* map to fallback character */ int i; if (fallback_character == NULL) { fallback_character = pg_do_encoding_conversion( (unsigned char *) eudc_fallback_character, strlen(eudc_fallback_character), GetDatabaseEncoding(), PG_UTF8); } for (i = 0; fallback_character[i]; i++) *dest++ = fallback_character[i]; } else { /* linear mapping */ n = c[0] - 0xf0; m = c[1] - 0x40; if (m >= 0x40) m--; ucs = 0xe000 + n * 188 + m; *dest++ = (ucs >> 12) | 0xe0; *dest++ = (ucs & 0x0fc0) >> 6 | 0x80; *dest++ = (ucs & 0x003f) | 0x80; } *dest = '\0'; } else {