사용자 정의 함수는 C (또는 언어로 작성할 수 있습니다. C ++와 같은 C와 호환 될 수 있습니다). 그러한 기능은입니다 동적으로로드 가능한 객체 (공유라고도합니다 라이브러리) 및 주문형 서버에 의해로드됩니다. 역학 로딩 기능은 구별되는 것입니다"c 언어"함수"내부"함수 --- 실제 코딩 컨벤션은 본질적으로 두 가지 모두 동일합니다. (따라서 표준 내부 기능 라이브러리는 풍부한 코딩 소스입니다. 사용자 정의 C 함수에 대한 예제.)
현재 두 개의 다른 통화 규칙이 c 기능. 최신"버전 1"전화 컨벤션은 A를 작성하여 표시됩니다.pg_function_info_v1 ()매크로 기능을 요청합니다. 아래 그림과 같이. 그러한 매크로의 부족은 구식을 나타냅니다 ( "버전 0") 함수. 지정된 언어 이름기능 만들기isCin 두 경우 모두. 구식 기능은 이제 이상으로 인해 더 이상 사용되지 않습니다 이식성 문제와 기능 부족 호환성 이유를 위해 여전히 지원됩니다.
처음으로 사용자 정의 기능이 처음입니다 로드 가능한 객체 파일은 백엔드 세션에서 호출됩니다. 동적 로더는 해당 객체 파일을 메모리에로드하여 기능을 호출 할 수 있습니다. 그만큼생성 기능사용자 정의 C 함수의 경우 | 함수에 대한 두 가지 정보를 지정합니다. 로드 가능한 객체 파일 및 C 이름 (링크 기호) 해당 객체 파일 내에서 호출 할 특정 기능. c 이름은 명시 적으로 지정되지 않으면 SQL 기능 이름과 동일합니다.
다음 알고리즘은 공유 객체를 찾는 데 사용됩니다. 에 주어진 이름을 기준으로 파일생성 기능명령 :
이름이 절대 경로 인 경우 주어진 파일은 짐을 실은.
이름이 문자열로 시작하면$ libdir, 그 부분은로 대체됩니다.PostgreSQL패키지 라이브러리 빌드 타임에 결정된 디렉토리 이름
이름에 디렉토리 부분이없는 경우 파일
구성에 의해 지정된 경로에서 검색됩니다.
변하기 쉬운dynamic_library_path
.
그렇지 않으면 (파일은 경로에서 발견되지 않았습니다. 비 변제 디렉토리 부분), 동적 로더가 포함되어 있습니다 주어진대로 이름을 가져 가려고 할 것입니다. 실패하다. (현재 작업에 의존하는 것은 신뢰할 수 없습니다 예배 규칙서.)
이 시퀀스가 작동하지 않으면 플랫폼 별 공유 라이브러리 파일 이름 확장 (종종.so)는 주어진 이름과 이것에 추가됩니다 시퀀스가 다시 시도됩니다. 그것이 실패하면 부하가 있습니다 실패하다.
참고 :사용자 ID범퍼카 토토서버가 가능 해야하는대로 실행됩니다 로드하려는 파일로의 경로를 가로 지르려면. 만들기 파일 또는 더 높은 수준의 디렉토리는 읽을 수없고/또는 에 의해 실행되지 않음"Postgres"사용자는 일반적인 실수입니다.
어쨌든에 나와있는 파일 이름은함수 생성명령은 문자 그대로 기록됩니다 시스템이 카탈로그가되므로 파일을 다시로드 해야하는 경우 동일한 절차가 적용됩니다.
참고 : PostgreSQLC 함수를 자동으로 컴파일하지 않습니다. 대상 파일은 a에 참조되기 전에 컴파일해야합니다.기능 만들기명령. 보다섹션 12.5.7추가 정보.
참고 :처음으로 사용 된 후 a 동적으로로드 된 객체 파일은 메모리에 유지됩니다. 향후 같은 세션에서 함수에 대한 호출 파일은 심볼 테이블의 작은 오버 헤드 만 발생합니다. 조회. 객체 파일을 다시로드 해야하는 경우 예를 들어 다시 컴파일 한 후를 사용하십시오.로드신선한 세션을 지휘하거나 시작하십시오.
공유 라이브러리를 상대적으로 찾는 것이 좋습니다 에게$ libdir또는 동적을 통한 도서관 경로. 이것은 새로운 경우 버전 업그레이드를 단순화합니다 설치는 다른 위치에 있습니다. 실제 디렉토리 저것$ libdirstand는 찾을 수 있습니다 명령과 함께PG_CONFIG --pkglibdir.
참고 :전PostgreSQL릴리스 7.2, 정확히 만 객체 파일에 대한 절대 경로는에 지정할 수 있습니다.함수 만들기. 이 접근법은입니다 기능 정의를 만들기 때문에 이제는 더 이상 사용되지 않습니다 불필요하게 포송 할 수 없습니다. 만 지정하는 것이 가장 좋습니다 경로 나 확장 상태가없는 공유 라이브러리 이름을 검색 메커니즘 대신 정보를 제공합니다.
표 12-1C 함수의 매개 변수에 필요한 C 유형을 제공합니다. 그것은에로드 될 것입니다범퍼카 토토. 그만큼"" 정의열은 헤더 파일을 제공합니다 유형 정의를 얻으려면 포함해야합니다. (실제 정의는 나열된 파일. 사용자가 정의 된 것을 고수하는 것이 좋습니다 인터페이스.) 항상 포함해야합니다postgres.h먼저 모든 소스 파일에서 어쨌든 필요한 많은 것들을 선언합니다.
표 12-1. 내장에 대한 동등한 C 유형PostgreSQL타입
SQL 유형 | C 유형 | 정의 |
---|---|---|
Abstime | AbsoluteTime | utils/nabstime.h |
부울 | bool | postgres.h(아마도 컴파일러 내장) |
Box | Box* | utils/geo_decls.h |
BYTEA | BYTEA* | postgres.h |
"char" | char | (컴파일러 내장) |
캐릭터 | BPCHAR* | postgres.h |
CID | CommandId | postgres.h |
날짜 | dateadt | utils/date.h |
smallint(int2) | int2또는int16 | postgres.h |
int2vector | int2vector* | postgres.h |
정수(int4) | int4또는int32 | postgres.h |
Real(float4) | float4* | postgres.h |
이중 정밀도(float8) | float8* | postgres.h |
간격 | 간격* | utils/timestamp.h |
LSEG | LSEG* | utils/geo_decls.h |
이름 | 이름 | postgres.h |
OID | OID | postgres.h |
oidvector | oidvector* | postgres.h |
PATH | Path* | utils/geo_decls.h |
포인트 | 포인트* | utils/geo_decls.h |
Regproc | Regproc | postgres.h |
Reltime | RelativeTime | utils/nabstime.h |
텍스트 | 텍스트* | postgres.h |
TID | ItemPointer | Storage/itemptr.h |
Time | Timeadt | utils/date.h |
시간대가있는 시간 | Timetzadt | utils/date.h |
타임 스탬프 | 타임 스탬프* | utils/timestamp.h |
TinterVal | TimeInterval | utils/nabstime.h |
Varchar | Varchar* | postgres.h |
xid | TransactionId | postgres.h |
내부,PostgreSQL기본 유형을 a로 간주합니다."Blob of 메모리". 사용자 정의 된 기능을 정의하는 기능 턴 유형은의 방식을 정의합니다.PostgreSQL작동 할 수 있습니다. 즉,PostgreSQL24453_24642
통과 별 가치, 고정 길이
참조로 통과, 고정 길이
참조별로 전달, 가변 길이
바이 값 유형은 길이가 1, 2 또는 4 바이트 일 수 있습니다 (또한 8 바이트, ifsizeof (Datum)는 8입니다 기계). 당신은 당신의 유형을 정의하는 데주의해야합니다. 모든 아키텍처에서 크기 (바이트)가됩니다. 을 위한 예,Long유형은 위험합니다 일부 기계에서는 4 바이트이고 다른 기계의 8 바이트이기 때문에 반면int타입은 대부분의 유닉스에서 4 바이트입니다 기계. 의 합리적인 구현int4유닉스 머신의 타입 :
/ * 4-byte 정수, 가치에 따라 통과 */ typedef int int4;
PostgreSQL자동으로 정수 유형이 실제로 그들이 광고하는 크기.
반면에, 모든 크기의 고정 길이 유형은 다음과 같습니다. 회의 별 통과. 예를 들어 샘플이 있습니다 A 구현PostgreSQL유형 :
/ * 16 바이트 구조, 참조로 통과 */ typedef struct 더블 X, y; 가리키다;
전달할 때 그러한 유형에 대한 포인터 만 사용할 수 있습니다. 그리고PostgreSQL함수. 그러한 유형의 값을 반환하려면 권리를 할당하십시오. 를 가진 메모리의 양palloc (), 채우기 할당 된 메모리에서 포인터를 반환하십시오. (또는 동일한 유형의 입력 값을 반환 할 수 있습니다. 포인터를 반환하여.절대a의 내용을 수정하십시오 그러나 추천 입력 값을 통과합니다.)
마지막으로 모든 가변 길이 유형도 지나쳐야합니다 참조. 모든 가변 길이 유형은 길이로 시작해야합니다 정확히 4 바이트의 필드 및 그 안에 저장 될 모든 데이터 유형은 그 다음에 메모리에 위치해야합니다. 길이 필드. 길이 필드는 총 길이입니다 구조 (즉, 길이 필드의 크기를 포함합니다. 그 자체). 텍스트 유형을 다음과 같이 정의 할 수 있습니다.
typedef struct int4 길이; 숯 데이터 [1]; 텍스트;
분명히 여기에 선언 된 데이터 필드는 충분히 길지 않습니다. 가능한 모든 줄을 잡고 있습니다. 선언하는 것은 불가능하기 때문에 의 가변 크기 구조C, 우리는에 대한 지식에 의존합니다.C컴파일러는 범위 점검되지 않습니다 배열 구역. 우리는 필요한 금액을 할당합니다 공간에 배열이 선언 된 것처럼 배열에 액세스하십시오. 올바른 길이. (이것이 당신에게 친숙한 트릭이 아니라면 입문으로 시간을 보내고 싶다C탐구하기 전에 교과서 프로그래밍 더 깊이PostgreSQL서버 프로그래밍.) 가변 길이 유형을 조작 할 때, 우리는해야합니다 올바른 양의 메모리를 할당하고 길이 필드가 올바르게. 예를 들어, 우리가 40을 저장하려는 경우 텍스트 구조의 바이트는 다음과 같은 코드 조각을 사용할 수 있습니다. 이것:
#include "postgres.h" ... 숯 버퍼 [40]; / * 소스 데이터 */ ... 텍스트 *대상 = (텍스트 *) palloc (varhdrsz + 40); 대상- 길이 = varhdrsz + 40; memcpy (대상- 데이터, 버퍼, 40); ...
varhdrsz|sizeof (int4)이지만 좋은 스타일로 간주됩니다 매크로 사용varhdrsz가변 길이 유형에 대한 오버 헤드 크기.
이제 우리는 가능한 모든 구조를 살펴 보았습니다. 기본 유형, 실제 기능의 몇 가지 예를 보여줄 수 있습니다.
우리는를 발표합니다."구식"컨벤션을 먼저 호출합니다 더 이상 사용되지 않으면 처음에 처리하는 것이 더 쉽습니다. 에서 버전 -0 메소드, C 함수의 인수 및 결과 정상적인 C 스타일로 방금 선언되지만 사용에주의를 기울입니다. 위와 같이 각 SQL 데이터 유형의 C 표현.
여기 몇 가지 예가 있습니다.
#include "postgres.h" #include <string.h / * 가치 별 */ int add_one (int arg) 반환 Arg + 1; / * 참조로 고정 길이 */ float8 * add_one_float8 (float8 *arg) float8 *result = (float8 *) palloc (sizeof (float8)); *결과 = *arg + 1.0; 반환 결과; 가리키다 * MakePoint (point *pointx, point *pointy) 지점 *new_point = (point *) palloc (sizeof (point)); new_point- x = pointx- x; new_point- y = pointy- y; New_Point를 반환합니다. / * 참조적으로 가변 길이 */ 텍스트 * 카피 텍스트 (텍스트 *t) /* * varsize는 바이트의 구조물의 총 크기입니다. */ 텍스트 *new_t = (텍스트 *) palloc (varsize (t)); varatt_sizep (new_t) = varsize (t); /* * Vardata는 구조물의 데이터 영역에 대한 포인터입니다. */ memcpy ((void *) vardata (new_t), / *대상 * / (void *) vardata (t), / *소스 * / varsize (t) -varhdrsz); / * 얼마나 많은 바이트 */ 뉴 _t를 반환합니다. 텍스트 * concat_text (text *arg1, text *arg2) int32 new_text_size = varsize (arg1) + varsize (arg2) - varhdrsz; 텍스트 *new_text = (텍스트 *) palloc (new_text_size); varatt_sizep (new_text) = new_text_size; memcpy (vardata (new_text), vardata (arg1), varsize (arg1) -varhdrsz); memcpy (vardata (new_text) + (varsize (arg1) -varhdrsz), vardata (arg2), varsize (arg2) -varhdrsz); new_text를 반환합니다.
위의 코드가 파일에서 준비되었다고 가정funcs.c공유로 컴파일했습니다 객체, 우리는 함수를 정의 할 수 있습니다PostgreSQL다음과 같은 명령과 함께 :
함수 생성 add_one (int4)은 int4를 반환합니다 처럼 'pgroot/튜토리얼/funcs 언어 c (isstrict)와 함께; - SQL 기능 이름의 과부하 참고 add_one () 함수 add_one (float8)을 생성합니다 처럼 'pgroot/튜토리얼/funcs ', 'add_one_float8' 언어 C (isstrict); 함수 makepoint (점, 점)를 반환합니다 처럼 'pgroot/튜토리얼/funcs 언어 c (isstrict)와 함께; 함수 CopyText (텍스트)를 작성합니다 텍스트를 반환합니다 처럼 'pgroot/튜토리얼/funcs 언어 c (isstrict)와 함께; CONCIT CONCAT_TEXT (텍스트, 텍스트) 텍스트를 반환합니다 처럼 'pgroot/튜토리얼/funcs 언어 c (isstrict);
여기pgroot에 대한 전체 경로PostgreSQL소스 트리. (더 나은 스타일은 그냥 사용하는 것입니다'funcs'inas조항, 추가 후pgroot/튜토리얼검색 경로로. 어쨌든 우리는 생략 할 수 있습니다 공유 라이브러리의 시스템 별 확장, 일반적으로.so또는.SL.)
함수를 다음과 같이 지정했음을 알 수 있습니다."엄격한", 시스템은해야한다는 것을 의미합니다 입력 값이 NULL 인 경우 자동으로 NULL 결과를 가정합니다. 이렇게함으로써, 우리는 기능 코드. 이것 없이는 널을 확인해야합니다 예를 들어, 각각에 대한 널 포인터를 확인하여 명시 적으로 통과 참조 주장. (패스 별 값 주장의 경우, 우리 확인 방법조차 없습니다!)
이 호출 대회는 사용하기가 간단하지만 매우 휴대 성; 일부 아키텍처에는 문제가 있습니다 INT보다 작은 데이터 유형을 이런 식으로 전달합니다. 또한 아무도 없습니다 널 결과를 반환하거나 널에 대처하는 간단한 방법 기능을 엄격하게 만드는 것 외에 다른 방식으로 논쟁. 그만큼 다음에 발표 된 버전 -1 컨벤션은 이것을 극복합니다 이의 제기.
버전 1 호출 컨벤션은 매크로에 의존합니다 통과 된 주장의 복잡성을 억제하고 결과. 버전 -1 기능의 C 선언은 다음과 같습니다 언제나
Datum funcname (pg_function_args)
또한 매크로 호출
pg_function_info_v1 (funcname);
동일한 소스 파일에 나타나야합니다 (일반적으로 함수 자체 바로 앞에 쓰여진). 이 매크로 콜은입니다 필요하지 않음내부-언어 기능, 이후PostgreSQL현재 모든 내부 기능이 버전 -1이라고 가정합니다. 그러나필수동적으로로드 된 경우 기능.
버전 -1 함수에서는 각 실제 인수가 가져옵니다
a 사용pg_getarg_xxx()
매크로에 해당합니다
인수의 데이터 유형 및 결과는 a를 사용하여 반환됩니다.pg_return_xxx()
반품을위한 매크로
유형.
여기서 우리는 Version-1에 코딩 된 위와 동일한 함수를 보여줍니다. 스타일:
#include "postgres.h" #include <string.h #include "fmgr.h" / * 가치 별 */ pg_function_info_v1 (add_one); 자료 add_one (pg_function_args) int32 arg = pg_getarg_int32 (0); pg_return_int32 (arg + 1); / * 참조로 고정 길이 */ pg_function_info_v1 (add_one_float8); 자료 add_one_float8 (pg_function_args) / * float8에 대한 매크로는 패스 바로 회의 특성을 숨 깁니다 */ float8 arg = pg_getarg_float8 (0); pg_return_float8 (arg + 1.0); pg_function_info_v1 (makepoint); 자료 makepoint (pg_function_args) / * 여기서, 포인트의 추천 특성은 숨겨져 있지 않습니다 */ point *pointx = pg_getarg_point_p (0); point *pointy = pg_getarg_point_p (1); 지점 *new_point = (point *) palloc (sizeof (point)); new_point- x = pointx- x; new_point- y = pointy- y; pg_return_point_p (new_point); / * 참조적으로 가변 길이 */ pg_function_info_v1 (CopyText); 자료 CopyText (pg_function_args) 텍스트 *t = pg_getarg_text_p (0); /* * varsize는 바이트의 구조물의 총 크기입니다. */ 텍스트 *new_t = (텍스트 *) palloc (varsize (t)); varatt_sizep (new_t) = varsize (t); /* * Vardata는 구조물의 데이터 영역에 대한 포인터입니다. */ memcpy ((void *) vardata (new_t), / *대상 * / (void *) vardata (t), / *소스 * / varsize (t) -varhdrsz); / * 얼마나 많은 바이트 */ pg_return_text_p (new_t); pg_function_info_v1 (concat_text); 자료 concat_text (pg_function_args) 텍스트 *arg1 = pg_getarg_text_p (0); 텍스트 *arg2 = pg_getarg_text_p (1); int32 new_text_size = varsize (arg1) + varsize (arg2) - varhdrsz; 텍스트 *new_text = (텍스트 *) palloc (new_text_size); varatt_sizep (new_text) = new_text_size; memcpy (vardata (new_text), vardata (arg1), varsize (arg1) -varhdrsz); memcpy (vardata (new_text) + (varsize (arg1) -varhdrsz), vardata (arg2), varsize (arg2) -varhdrsz); pg_return_text_p (new_text);
the함수 만들기명령은 버전 -0 등가와 동일합니다.
언뜻보기에 버전 1 코딩 규칙이 나타날 수 있습니다
무의미한 모호함이되기 위해. 그러나 그들은 제안합니다
매크로가 불필요하게 숨길 수 있기 때문에 개선 횟수
세부 사항. 예를 들어 코딩에서add_one_float8
, 우리는 더 이상 알 필요가 없습니다
저것float8는 추천 유형입니다.
또 다른 예는getarg가변 길이 유형에 대한 매크로는 다루어야 할 필요성을 숨 깁니다.
페치"토스트"(압축 또는
외부) 값. 구식CopyText
andconcat_text
위에 표시된 기능은 다음과 같습니다
토스트 된 값이있을 때 실제로 잘못되었습니다.
전화하지 마십시오pg_detoast_datum ()
on
그들의 입력. (구식 스타일의 핸들러는 동적으로로드되었습니다
기능은 현재이 세부 사항을 처리하지만 그렇게합니다.
버전 -1의 경우보다 덜 효율적입니다
기능.)
버전 -1 기능의 큰 개선이 더 좋습니다
널 입력 및 결과 처리. 매크로PG_ARGISNULL (n)
함수를 테스트 할 수 있습니다
각 입력이 무효인지 여부 (물론, 이것을하는 것은
선언되지 않은 기능에 필요"엄격한"). 와 마찬가지로pg_getarg_xxx()
매크로, 입력 인수
0에서 시작합니다. 하나는 자제해야합니다
실행pg_getarg_xxx()
하나가 확인할 때까지
논쟁은 무효가 아닙니다. 널 결과를 반환하려면 executepg_return_null ()
; 이것은 작동합니다
엄격한 기능과 기적 기능.
버전 -1 기능 호출 규칙을 통해 가능합니다 반품"set"결과 및 구현 트리거 기능 및 절차 적 통화 처리기. 버전 1 코드는 버전 -0보다 휴대가 가능합니다. 기능 통화 프로토콜에서 ANSI C 제한을 중단하지 않습니다. 자세한 내용은 참조src/backend/utils/fmgr/readme소스에서 분포.
복합 유형은 C와 같은 고정 레이아웃이 없습니다. 구조. 복합 유형의 인스턴스는 null을 포함 할 수 있습니다 전지. 또한 AN의 일부인 복합 유형 상속 계층 구조는 다른 필드와 다른 필드를 가질 수 있습니다 동일한 상속 계층의 구성원. 그러므로,PostgreSQL제공 a 복합 유형의 필드에 액세스하기위한 절차 인터페이스 C. as에서PostgreSQL행 세트를 처리하면 각 행이 귀하에게 전달됩니다. 유형의 불투명 구조로 기능튜플. 우리가 함수를 작성하고 싶다고 가정 해 봅시다 쿼리 답변
이름, C_overpaid (EMP, 1500)를 초과 지불로 선택하십시오 emp에서 여기서 name = 'bill'또는 name = 'sam';
위의 쿼리에서 정의 할 수 있습니다c_overpaid
as :
#include "postgres.h" #include "executor/executor.h"/ * for getAttributeByName () */ 부 c_overpaid (tupletableslot *t, / *현재 행의 행 * / int32 한도) bool isnull; INT32 급여; Salary = DatumgetInt32 (getAttributeByName (t, "Salary", & isnull)); if (isnull) 반환 (거짓); 반품 급여 한도; / * 버전 -1 코딩에서 위는 다음과 같습니다. */ pg_function_info_v1 (c_overpaid); 자료 c_overpaid (pg_function_args) tupleTablesLot *t = (tupleTablesLot *) pg_getarg_pointer (0); int32 한계 = pg_getarg_int32 (1); bool isnull; INT32 급여; Salary = DatumgetInt32 (getAttributeByName (t, "Salary", & isnull)); if (isnull) pg_return_bool (false); / * 또는 널 급여에 대해 pg_return_null ()를 선호 할 수 있습니다 */ pg_return_bool (급여 한도);
getAttributeByName
PostgreSQL시스템 기능
현재 행에서 속성을 반환합니다. 세 가지가 있습니다
인수 : 유형의 주장tupletableslot*이름, 이름으로 전달되었습니다
원하는 속성 및 반환 매개 변수의
속성이 null인지 여부.getAttributeByName
a 반환Datum적절한 데이터로 변환 할 수있는 값
적절한 사용으로 입력Datumgetxxx()
매크로.
다음 명령은PostgreSQLc_overpaid
기능 :
함수 만들기 c_overpaid (emp, int4) Bool을 반환합니다 처럼 'pgroot/튜토리얼/funcs ' 언어 C;
새 행을 구성하거나 수정하는 방법이 있습니다. C 함수 내에서 기존 행, 이것도 멀리 있습니다. 이 매뉴얼에서 논의하기위한 복잡한. 백엔드 소스를 참조하십시오 예제 코드.
우리는 이제 더 어려운 글쓰기 과제로 돌아갑니다. 언어 기능 프로그래밍. 경고 :이 섹션 의이 부분 매뉴얼은 당신을 프로그래머로 만들지 않을 것입니다. 당신은 좋은 것이 있어야합니다 에 대한 이해C(포인터 사용 및 Malloc 메모리 관리자 포함) 쓰기 전에C사용하기위한 기능PostgreSQL. 가능할 수 있습니다 이외의 언어로 작성된로드 기능CinPostgreSQL, 이것은 종종 어렵다 (언제 전혀 가능합니다)과 같은 다른 언어이기 때문에Fortran및Pascal종종 같은 것을 따르지 않습니다전화 컨벤션asC. 즉, 다른 언어는 통과하지 않습니다 같은 방식으로 함수 사이의 인수 및 반환 값. 이러한 이유로 우리는 귀하의 프로그래밍 언어가 함수는로 작성됩니다.C.
건축을위한 기본 규칙C함수는 다음과 같습니다.
usePG_CONFIG
-includedir-serverPostgreSQL서버 헤더 파일입니다
시스템에 설치 (또는 사용자가
실행 중). 이 옵션은PostgreSQL7.2. 을 위한PostgreSQL7.1 사용해야합니다
옵션-includedir
. (PG_CONFIG0이 아닌 상태로 종료됩니다
알 수없는 옵션이 발생합니다.) 7.1 이전에 릴리스
당신은 추측해야 할 것이지만, 그 이후로
현재 전화 규칙이 소개되었을 가능성은 거의 없습니다
그 릴리스를 지원하고 싶다.
메모리를 할당 할 때를 사용하십시오.PostgreSQL루틴Palloc
andpfree
해당 대신C도서관 루틴Malloc
및무료
. 에 의해 할당 된 메모리Palloc
가 해방됩니다
각 트랜잭션이 끝날 때 자동으로 방지합니다
메모리 누출.
항상 구조물의 바이트를 항상 0memset
또는bzero
. 여러 루틴 (해시 등
액세스 방법, 해시 조인 및 정렬 알고리즘) 계산
당신의 구조에 포함 된 원시 비트의 기능. 심지어
구조의 모든 필드를 초기화하면
정렬 패딩의 여러 바이트가 되십시오 (구멍에
쓰레기 값을 포함 할 수있는 구조)
대부분의 내부PostgreSQL유형은postgres.h46169_46220pg_function_args등)fmgr.h이므로 AT를 포함시켜야합니다 최소한이 두 파일. 휴대 할 수있는 이유로 가장 좋습니다 포함하다postgres.h 첫 번째시스템 또는 사용자 헤더 파일. 포함postgres.h포함elog.h및Palloc.h당신을 위해.
객체 파일 내에 정의 된 기호 이름은 안됩니다 서로 충돌하거나에 정의 된 기호와 충돌PostgreSQL서버 실행 파일. 당신은 당신의 함수의 이름을 바꿔야합니다 이 효과에 오류 메시지가 표시되는 경우 변수
객체 코드를 컴파일하고 연결하여 동적으로로드PostgreSQL항상 특별해야합니다 깃발. 보다섹션 12.5.7특정 운영 체제.
사용하기 전에PostgreSQL확장 기능이 작성되었습니다 C, 그들은 특별한 생산 방법으로 편집하고 연결되어야합니다. 서버에서 동적으로로드 할 수있는 파일. 장차 ~ 가 되는 정확한, A공유 도서관생성.
자세한 내용은 문서를 읽어야합니다 운영 체제, 특히 C의 수동 페이지 컴파일러,CC및 링크 편집기,ld. 또한PostgreSQL소스 코드에는 여러 가지가 포함되어 있습니다 의 작업 예제Contrib디렉토리. 이 예에 의존하면 의 가용성에 따라 모듈PostgreSQL소스 코드.
공유 생성 라이브러리는 일반적으로 실행 파일 연결과 유사합니다 소스 파일은 객체 파일로 컴파일 된 다음 객체 파일은 함께 연결됩니다. 객체 파일은 있어야합니다 생성위치 독립 코드(PIC), 개념적으로 임의의 위치에 배치 할 수 있음을 의미합니다. 실행 파일에 의해로드 될 때 메모리. (객체 파일 실행 파일을위한 의도는 일반적으로 그런 식으로 컴파일되지 않습니다.) 공유 라이브러리를 연결하라는 명령에는 특수 플래그가 포함됩니다. 실행 파일 연결과 구별됩니다. --- 적어도 이것은입니다 이론. 일부 시스템에서는 연습이 훨씬 추악합니다.
다음 예에서는 소스 코드가 파일에서foo.c그리고 우리는 a 공유 도서관foo.so. 그만큼 중간 객체 파일은입니다.foo.o49604_49720
생성 할 컴파일러 플래그PICis-fpic
. 링커 플래그는 공유를 생성합니다
도서관은-shared
.
gcc -fpic -c foo.c ld -shared -o foo.so foo.o
버전 4.0에서 적용 가능BSD/OS.
생성 할 컴파일러 플래그PICis-fpic
. 공유 라이브러리를 만들려면
컴파일러 플래그는-shared
.
gcc -fpic -c foo.c gcc -shared -o foo.so foo.o
버전 3.0에서 적용 가능freebsd.
생성 할 시스템 컴파일러의 컴파일러 플래그PICis+z
. 사용시GCCit-fpic
. 공유 링커 플래그
도서관은-B
. 그래서
CC +Z -C foo.c
또는
gcc -fpic -c foo.c
그리고
ld -b -o foo.sl foo.o
HP-UX확대.SL공유 대부분의 다른 시스템과 달리 라이브러리.
PIC기본값입니다.
특수 컴파일러 옵션이 필요하지 않습니다. 링커
공유 라이브러리를 생산하는 옵션-shared
.
CC -C foo.c ld -shared -o foo.so foo.o
생성 할 컴파일러 플래그PICis-fpic
. 일부 플랫폼에서
상황-fpic
사용해야합니다
만약에-fpic
작동하지 않습니다. 나타내다
자세한 내용은 GCC 매뉴얼에. 컴파일러 플래그
공유 라이브러리를 만들려면-shared
. 완전한 예는 다음과 같습니다
이것:
cc -fpic -c foo.c cc -shared -o foo.so foo.o
생성 할 컴파일러 플래그PICis-fpic
. 을 위한ELF시스템, 컴파일러가있는 시스템
깃발-shared
링크에 사용됩니다
공유 라이브러리. 이전 비 ELF 시스템에서ld -Bsharable사용됩니다.
gcc -fpic -c foo.c gcc -shared -o foo.so foo.o
생성 할 컴파일러 플래그PICis-fpic
. LD
-Bsharable공유 라이브러리를 연결하는 데 사용됩니다.
gcc -fpic -c foo.c ld -bsharable -o foo.so foo.o
생성 할 컴파일러 플래그PICis-kpic
SUN 컴파일러와-fpic
withGCC. 공유 라이브러리를 연결하기 위해
컴파일러 옵션은-g
컴파일러 또는 대안 적으로-shared
withGCC.
cc -kpic -c foo.c cc -g -o foo.so foo.o
또는
gcc -fpic -c foo.c gcc -g -o foo.so foo.o
PIC기본값입니다. 따라서 컴파일 명령은 일반적인 명령입니다.LD특수 옵션이있는 경우 사용됩니다 링크 :
CC -C FOO.C ld -shared -expect_unresolved '*'-o foo.so foo.o
동일한 절차가 GCC 대신 GCC와 함께 사용됩니다. 시스템 컴파일러; 특별한 옵션이 필요하지 않습니다.
생성 할 컴파일러 플래그PICis-K
PIC
SCO 컴파일러와-fpic
withGCC. 공유 라이브러리를 연결하기 위해
컴파일러 옵션은-g
SCO 컴파일러 및-shared
withGCC.
CC -K PIC -C FOO.C cc -g -o foo.so foo.o
또는
gcc -fpic -c foo.c gcc -shared -o foo.so foo.o
팁 :확장자를 포장하려는 경우 사용을 고려해야 할 광범위한 분포 모듈gnu libtool공유 도서관 건물. 플랫폼을 캡슐화합니다 일반적이고 강력한 인터페이스의 차이점. 심각한 포장에는 라이브러리에 대한 고려가 필요합니다 버전화, 기호 해상도 메소드 및 기타 문제.
결과 공유 라이브러리 파일을로드 할 수 있습니다PostgreSQL. 지정할 때 파일 이름함수 생성명령, 공유 라이브러리 파일의 이름을 알려야합니다. 중간 객체 파일이 아닙니다. 시스템의 경우에 유의하십시오 표준 공유 라이브러리 확장 (일반적으로.so또는.SL) 할 수 있습니다 에서 생략기능 생성명령은 일반적으로 최선을 위해 생략해야합니다 이식성.
다시 참조섹션 12.5.157151_57222