C로 작성된 기능은 동적으로로드 가능하게 컴파일 할 수 있습니다. 객체, 사용자 정의 SQL 기능을 구현하는 데 사용됩니다. 그만큼 사용자 정의 된 기능이 처음으로 백엔드 내부에서 호출되는 경우 동적 로더는 함수의 객체 코드를 메모리에로드하고 그리고 함수를 실행 중 링크Postgres실행 가능. SQL 구문함수 생성SQL 함수를 연결합니다 C 소스는 두 가지 방법 중 하나로 기능합니다. SQL 기능이있는 경우 C 소스 함수와 동일한 이름의 첫 번째 형태 진술이 사용됩니다. AS 절의 문자열 인수는 전체입니다. 동적으로로드 가능한 파일의 PathName 편집 된 개체. C 함수의 이름이 다른 경우 SQL 함수의 원하는 이름 인 다음 두 번째 양식이 사용됩니다. 이 형식에서 As 절은 두 개의 문자열 인수를 가져옵니다. 첫 번째는 동적으로로드 가능한 객체 파일의 전체 경로 이름과 두 번째는 동적 로더가 검색 해야하는 링크 기호입니다. 을 위한. 이 링크 기호는 C 소스의 함수 이름입니다. 암호.
참고 :처음으로 사용 된 후 a 동적으로로드 된 사용자 토토 사이트은 메모리에 유지됩니다 토토 사이트에 대한 향후 호출은 작은 오버 헤드 만 발생합니다. 기호 테이블 조회.
개체 파일을 지정하는 문자열 (문자열의 문자열 조항)은이어야합니다.전체 경로의 인용 표시로 괄호로 된 함수의 객체 코드 파일. 만약에 링크 기호는 AS 절에 사용되며 링크 기호도 단일 인용 표시로 괄호를 받아야하며 정확히 C 소스 코드의 함수 이름과 동일합니다. 유닉스에서 시스템nm모든 것을 인쇄합니다 동적으로로드 가능한 객체의 기호를 연결합니다. (Postgres함수를 컴파일하지 않습니다 자동으로; 생성에 사용되기 전에 컴파일해야합니다. 토토 사이트 명령. 추가 정보는 아래를 참조하십시오.)
다음 표는 매개 변수에 필요한 C 유형을 제공합니다. C는 Postgres에로드 될 C 기능입니다. "정의 된" 열은 실제 헤더 파일을 제공합니다 (.../src/backend/디렉토리) 동등한 c 유형이 정의됩니다. 그러나 포함하는 경우utils/buildins.h,이 파일은 자동으로됩니다 포함.
표 38-1. 내장에 대한 동등한 C 유형Postgrestype
내장 유형 | C 유형 | 정의 |
---|---|---|
Abstime | AbsoluteTime | utils/nabstime.h |
bool | bool | 포함/c.h |
Box | (Box *) | utils/geo-decls.h |
BYTEA | (Bytea *) | 포함/postgres.h |
char | char | N/A |
CID | CID | 포함/postgres.h |
DateTime | (dateTime *) | 포함/c.h 또는 포함/postgres.h |
int2 | int2 | 포함/postgres.h |
int2vector | (int2vector *) | 포함/postgres.h |
int4 | int4 | 포함/postgres.h |
float4 | float32 또는 (float4 *) | 포함/c.h 또는 포함/postgres.h |
float8 | float64 또는 (float8 *) | 포함/c.h 또는 포함/postgres.h |
lseg | (lseg *) | include/geo-decls.h |
이름 | (이름) | 포함/postgres.h |
OID | OID | 포함/postgres.h |
oidvector | (oidvector *) | 포함/postgres.h |
PATH | (Path *) | utils/geo-decls.h |
포인트 | (Point *) | utils/geo-decls.h |
Regproc | Regproc 또는 Regproc | 포함/postgres.h |
Reltime | RelativeTime | utils/nabstime.h |
텍스트 | (텍스트 *) | 포함/postgres.h |
tid | ItemPointer | Storage/itemptr.h |
Timespan | (TimesPan *) | 포함/c.h 또는 포함/postgres.h |
TinterVal | TimeInterval | utils/nabstime.h |
uint2 | UINT16 | 포함/c.h |
UINT4 | UINT32 | 포함/c.h |
xid | (xid *) | 포함/postgres.h |
내부,Postgres"메모리 덩어리"로서 기본 유형. 사용자 정의 기능은 다음과 같습니다 당신은 턴에서 유형을 정의합니다.Postgres작동 할 수 있습니다. 즉,Postgres보관 전용 디스크에서 데이터를 검색하고 사용자 정의 기능을 사용하십시오. 데이터를 입력, 프로세스 및 출력합니다. 기본 유형은 하나를 가질 수 있습니다 세 가지 내부 형식 :
통과 별 가치, 고정 길이
참조로 통과, 고정 길이
참조 별 통과, 가변 길이
바이 값 유형은 길이가 1, 2 또는 4 바이트 일 수 있습니다 ( 컴퓨터는 다른 크기의 부가 가치 유형을 지원합니다.)Postgres그 자체는 정수 유형 만 전달합니다 값. 당신은 당신의 유형을 그들이 당신의 유형을 정의하도록주의해야합니다. 모든 아키텍처에서 크기 (바이트)가됩니다. 예를 들어, 그만큼Long타입은 4이기 때문에 위험합니다 일부 기계의 바이트, 다른 기계의 8 바이트, 반면int유형은 대부분의 Unix 시스템에서 4 바이트입니다 (그러나 대부분의 개인용 컴퓨터는 아닙니다). 의 합리적인 구현int4유닉스 머신의 타입 :
/ * 4-byte 정수, 가치에 따라 통과 */ typedef int int4;
반면에, 모든 크기의 고정 길이 유형이 전달 될 수 있습니다. 회의 별. 예를 들어 다음은 A의 샘플 구현이 있습니다.Postgres유형 :
/ * 16 바이트 구조, 참조로 통과 */ typedef struct 더블 X, y; 가리키다;
그러한 유형에 대한 포인터 만 사용할 때만 사용할 수 있습니다. 에서Postgres기능. 마지막으로 모든 가변 길이 유형도 지나쳐야합니다 참조. 모든 가변 길이 유형은 길이 필드로 시작해야합니다 정확히 4 바이트의 경우, 해당 유형 내에 저장 될 모든 데이터는 그 길이 필드 바로 다음에 메모리에 위치하십시오. 길이 필드는 구조의 총 길이입니다 (즉, IT 길이 필드 자체의 크기를 포함합니다). 우리는 정의 할 수 있습니다 다음과 같이 텍스트 유형 :
typedef struct int4 길이; 숯 데이터 [1]; 텍스트;
분명히 데이터 필드는 모든 것을 유지하기에 충분하지 않습니다. 가능한 줄; 그러한 구조를 선언하는 것은 불가능합니다C. 가변 길이를 조작 할 때 유형, 우리는 올바른 양의 메모리를 할당하기 위해주의해야합니다. 길이 필드를 초기화하십시오. 예를 들어, 저장하고 싶다면 텍스트 구조의 40 바이트는 다음과 같은 코드 조각을 사용할 수 있습니다. 이것:
#include "postgres.h" ... 숯 버퍼 [40]; / * 소스 데이터 */ ... 텍스트 *대상 = (텍스트 *) palloc (varhdrsz + 40); 대상- 길이 = varhdrsz + 40; Memmove (대상- 데이터, 버퍼, 40); ...
이제 우리는베이스를위한 가능한 모든 구조를 살펴 보았습니다. 유형, 우리는 실제 토토 사이트의 몇 가지 예를 보여줄 수 있습니다. 가정하다funcs.c모양 :
#include <string.h #include "postgres.h" / * 가치 별 */ int add_one (int arg) 반환 (arg + 1); / * 참조로 고정 길이 */ 가리키다 * 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)); memset (new_t, 0, varsize (t)); varsize (new_t) = varsize (t); /* * Vardata는 구조물의 데이터 영역에 대한 포인터입니다. */ memcpy ((void *) vardata (new_t), / *대상 * / (void *) vardata (t), / *소스 * / varsize (t) -varhdrsz); / * 얼마나 많은 바이트 */ 반환 (new_t); 텍스트 * concat_text (text *arg1, text *arg2) int32 new_text_size = varsize (arg1) + varsize (arg2) - varhdrsz; 텍스트 *new_text = (텍스트 *) palloc (new_text_size); memset ((void *) new_text, 0, new_text_size); varsize (new_text) = new_text_size; strncpy (vardata (new_text), vardata (arg1), varsize (arg1) -varhdrsz); strncat (vardata (new_text), vardata (arg2), varsize (arg2) -varhdrsz); return (new_text);
onOSF/1우리는 다음을 입력 할 것입니다 :
함수 생성 add_one (int4)은 int4를 반환합니다 처럼 'pgroot/tutorial/funcs.so 'language'c '; 함수 makepoint (점, 점)를 반환합니다 처럼 'pgroot/tutorial/funcs.so 'Language'C '; CONCIT CONCAT_TEXT (텍스트, 텍스트) 텍스트를 반환합니다 처럼 'pgroot/tutorial/funcs.so 'Language'C '; 함수 CopyText (텍스트)를 작성합니다 텍스트를 반환합니다 처럼 'pgroot/tutorial/funcs.so 'language'c ';
다른 시스템에서는 파일 이름을 .sl에서 끝내야 할 수도 있습니다. (공유 도서관임을 나타 내기 위해).
복합 유형에는 C 구조와 같은 고정 레이아웃이 없습니다. 복합 유형의 인스턴스에는 널 필드가 포함될 수 있습니다. 게다가, 상속 계층의 일부인 복합 유형은 같은 상속의 다른 구성원과는 다른 필드 계층. 그러므로,Postgres복합 필드에 액세스하기위한 절차 인터페이스를 제공합니다 C.에서 유형Postgres인스턴스 세트를 처리하면 각 인스턴스가 전달됩니다. 유형의 불투명 구조로서의 토토 사이트튜플. 대답 할 토토 사이트을 작성하고 싶다고 가정 해 봅시다 쿼리
* 이름, c_overpaid (EMP, 1500)를 초과 지불로 선택하십시오 emp에서 여기서 name = 'bill'또는 name = 'sam';위의 쿼리에서 c_overpaid를 다음과 같이 정의 할 수 있습니다.
#include "postgres.h" #include "executor/executor.h"/ * for getAttributeByName () */ 부 c_overpaid (tupletableslot *t, / *현재 emp * / int4 한계) bool isnull = false; int4 급여; 급여 = (int4) getAttributeByName (t, "Salary", & isnull); if (isnull) 반환 (거짓); 반품 (급여 한도);
getAttributeByNamePostgres반환되는 시스템 기능 현재 인스턴스의 속성. 그것은 세 가지 주장이 있습니다 : 튜플 유형의 인수는 함수, 이름으로 전달됩니다. 원하는 속성 및 여부를 설명하는 리턴 매개 변수 속성은 null입니다.getAttributeByName데이터를 올바르게 정렬하여 반환 값을 원하는 유형. 예를 들어, 속성 이름이있는 경우 유형 이름의getAttributeByName전화는 다음과 같습니다.
char *str; ... str = (char *) getAttributeByName (t, "name", & isnull)
다음 쿼리는Postgresc_overpaid에 대해 알고 있습니다 토토 사이트:
* 함수 만들기 c_overpaid (emp, int4)는 bool을 반환합니다 처럼 'pgroot/tutorial/obj/funcs.so 'language'c ';
새로운 인스턴스를 구성하거나 수정하는 방법이 있지만 C 함수 내에서 기존 인스턴스도 있습니다. 이 매뉴얼에서 논의하기 위해 복잡합니다.
이제 우리는 프로그래밍 작성의 더 어려운 작업으로 돌아갑니다. 언어 토토 사이트. 경고 :이 매뉴얼 섹션은 그렇지 않습니다 당신을 프로그래머로 만드십시오. 당신은 잘 이해해야합니다C(포인터 사용 포함 및 malloc 메모리 관리자) 쓰기를 시도하기 전에C사용하기위한 토토 사이트Postgres. 로드하는 것이 가능할 수 있습니다 이외의 언어로 작성된 토토 사이트CinPostgres, 이것은 종종 (전혀 가능할 때) 종종 어렵습니다. 와 같은 언어FortranandPascal종종 같은 것을 따르지 않습니다전화 컨벤션asC. 즉, 다른 언어는 논쟁을 통과하지 않습니다 같은 방식으로 함수 사이의 값을 반환합니다. 이것을 위해 이유, 우리는 귀하의 프로그래밍 언어 토토 사이트이 작성C.
c 기본 유형 인수가있는 함수는 간단한 방식. C는 내장 Postgres와 동등합니다 C 파일에서 유형에 액세스 할 수 있습니다.pgroot/src/backend/utils/builtins.hIS 헤더 파일로 포함됩니다. 이것은를 통해 달성 할 수 있습니다.
#include <utils/buildins.hC 소스 파일의 상단에 있습니다.
건물의 기본 규칙C함수는 다음과 같습니다.
대부분의 헤더 (포함) 파일 용Postgres이미 설치해야합니다pgroot/include(그림 2 참조). 너 항상 포함해야합니다
-i $ pgroot/include22989_23222
-i $ pgroot/src/백엔드 -i $ pgroot/src/백엔드/포함 -i $ pgroot/src/backend/port/<portname -i $ pgroot/src/backend/obj(여기서 <portname은 포트의 이름입니다. 또는 sparc).
메모리를 할당 할 때를 사용하십시오.Postgres대신 Palloc과 Pfree의 루틴 해당C라이브러리 일상적인 malloc 및 무료. Palloc이 할당 한 메모리 각 거래가 끝날 때 자동으로 해제되고 메모리 누출 방지.
항상 Memset 또는 BZERO. 여러 루틴 (예 : 해시 액세스 방법, 해시 가입 및 정렬 알고리즘) 원시 비트의 토토 사이트 계산 귀하의 구조에 포함되어 있습니다. 모든 필드를 초기화하더라도 귀하의 구조에는 여러 바이트의 정렬이있을 수 있습니다. 쓰레기를 포함 할 수있는 패딩 (구조의 구멍) 값.
대부분의 내부Postgres유형은postgres.h이므로 항상 좋은 생각입니다 해당 파일도 포함하십시오. Postgres.h도 포함합니다 elog.h와 palloc.h 포함.
객체 코드를 컴파일하고로드하여 동적으로로드Postgres항상 특별한 플래그가 필요합니다. 보다링크 동적으로로드 된 함수에 대한 자세한 설명 특정 운영 체제를 위해 수행하는 방법.