이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 볼 수 있습니다PostgreSQL : 문서 : 17 : 36.10. C- 언어 사설 토토 사이트버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

38.10. C- 언어 메이저 토토 사이트

사용자 정의 함수는 C (또는 C ++와 같은 C와 호환 될 수있는 언어)로 작성할 수 있습니다. 이러한 메이저 토토 사이트은 동적으로로드 가능한 객체 (공유 라이브러리라고도 함)로 컴파일되며 주문시 서버에서로드됩니다.C 언어메이저 토토 사이트내부함수 - 실제 코딩 규칙은 본질적으로 두 가지 모두 동일합니다. (따라서 표준 내부 메이저 토토 사이트 라이브러리는 사용자 정의 C 함수에 대한 코딩 예제의 풍부한 소스입니다.)

현재 하나의 호출 컨벤션 만 C 함수에 사용됩니다 (버전 1). 해당 전화 컨벤션에 대한 지원은 A를 작성하여 표시됩니다.pg_function_info_v1 ()매크로 아래 그림과 같이 함수를 호출합니다.

38.10.1. 동적 로딩

특정로드 가능한 객체 파일의 사용자 정의 함수가 세션에서 호출되면 동적 로더는 해당 객체 파일을 메모리로로드하여 메이저 토토 사이트을 호출 할 수 있습니다. 그만큼함수 만들기사용자 정의 C 함수의 경우 함수에 대한 두 가지 정보를 지정해야합니다.로드 가능한 객체 파일의 이름과 해당 객체 파일 내에서 호출 할 특정 함수의 C 이름 (링크 기호). C 이름이 명시 적으로 지정되지 않은 경우 SQL 메이저 토토 사이트 이름과 동일하다고 가정합니다.

다음 알고리즘은에 주어진 이름에 따라 공유 객체 파일을 찾는 데 사용됩니다.함수 만들기명령 :

  1. 이름이 절대 경로 인 경우 주어진 파일이로드됩니다.

  2. 이름이 문자열로 시작하면$ libdir, 그 부분은로 대체됩니다.PostgreSQL빌드 시간에 결정되는 패키지 라이브러리 디렉토리 이름.

  3. 이름에 디렉토리 부분이 포함되어 있지 않으면 구성 변수로 지정된 경로에서 파일이 검색됩니다dynamic_library_path.

  4. 그렇지 않으면 (파일이 경로에서 발견되지 않았거나, absolute 디렉토리가 아닌 부품이 포함되어 있지 않음) 동적 로더는 주어진 이름을 가져 오려고 시도 할 가능성이 높습니다. (현재 작업 디렉토리에 의존하는 것은 신뢰할 수 없습니다.)

이 시퀀스가 ​​작동하지 않으면 플랫폼 별 공유 라이브러리 파일 이름 확장 (종종.so)가 주어진 이름에 추가 되고이 시퀀스가 ​​다시 시도됩니다. 그것이 실패하면 부하가 실패합니다.

공유 라이브러리를 찾는 것이 좋습니다$ libdir또는 동적 라이브러리 경로를 통한. 새 설치가 다른 위치에 있으면 버전 업그레이드를 단순화합니다.$ libdirstand는 명령으로 찾을 수 있습니다pg_config --pkglibdir.

사용자 IDPostgreSQL서버는로드하려는 파일로 경로를 가로 질러 이동할 수 있어야합니다. 파일 또는 더 높은 수준의 디렉토리를 읽을 수 없거나/또는 실행할 수 없음Postgres사용자는 일반적인 실수입니다.

어쨌든에 나와있는 파일 이름은함수 만들기명령이 시스템 카탈로그에 문자 그대로 기록되어 있으므로 파일을 다시로드 해야하는 경우 동일한 절차가 적용됩니다.

Note

PostgreSQLC 함수를 자동으로 컴파일하지 않습니다. 객체 파일은 a에 참조되기 전에 컴파일해야합니다.함수 만들기명령. 보다섹션 38.10.5추가 정보는

동적으로로드 된 객체 파일이 호환되지 않는 서버에로드되지 않도록하기 위해PostgreSQL파일에 A가 포함되어 있는지 확인합니다매직 블록적절한 내용이 있습니다. 이를 통해 서버는 다른 주요 버전의 코드와 같은 명백한 비 호환성을 감지 할 수 있습니다.PostgreSQL. 매직 블록을 포함하려면 헤더를 포함한 후 모듈 소스 파일 중 하나 (그리고 하나만)로 작성하십시오.fmgr.h:

PG_MODULE_MAGIC;

처음으로 사용 된 후 동적으로로드 된 객체 파일이 메모리에 유지됩니다. 동일한 세션에서 해당 파일의 함수에 대한 향후 통화는 심볼 테이블 조회의 작은 오버 헤드 만 발생합니다.

선택적으로 동적으로로드 된 파일에는 초기화 및 최종화 메이저 토토 사이트이 포함될 수 있습니다. 파일에 이름 함수가 포함 된 경우_pg_init, 해당 함수는 파일을로드 후 즉시 호출됩니다. 함수는 매개 변수를 수신하지 않으며 void를 반환해야합니다._pg_fini, 해당 함수는 파일을 내리기 직전에 호출됩니다. 마찬가지로, 함수는 매개 변수를 수신하지 않으며 void를 반환해야합니다._pg_fini프로세스 종료 중에는 파일을 내릴 때만 호출됩니다. (현재, 언로드는 장애가없고 결코 발생하지 않을 것이지만, 이것은 미래에 변할 수 있습니다.)

38.10.2. C-Language 함수의 기본 유형

c-language functions를 작성하는 방법을 알아하려면 방법을 알아야합니다PostgreSQL내부적으로 기본 데이터 유형과 함수와의 전달 방법을 나타냅니다. 내부,PostgreSQL기본 유형을 a로 간주합니다.메모리의 블로브. 유형을 정의하는 사용자 정의 함수는 턴으로 정의합니다.PostgreSQL작동 할 수 있습니다. 즉,PostgreSQL디스크에서 데이터를 저장하고 검색하고 사용자 정의 메이저 토토 사이트을 사용하여 데이터를 입력, 프로세스 및 출력합니다.

기본 유형은 세 가지 내부 형식 중 하나를 가질 수 있습니다.

  • 통과 별 가치, 고정 길이

  • 참조로 통과, 고정 길이

  • 참조별로 전달, 가변 길이

바이 값 유형은 길이가 1, 2 또는 4 바이트 일 수 있습니다 (또한 8 바이트, ifsizeof (Datum)는 컴퓨터에서 8입니다). 모든 아키텍처에서 동일한 크기 (바이트)가되도록 유형을 정의해야합니다.Long유형은 일부 기계에서 4 바이트이고 다른 기계의 8 바이트이기 때문에 위험합니다.int유형은 대부분의 Unix 시스템에서 4 바이트입니다. 의 합리적인 구현int4Unix 기계의 타입 :

/ * 4-byte 정수, 가치에 따라 통과 */

(실제 PostgreSQL C 코드는이 유형을 호출int32, C의 컨벤션이기 때문에intxx평균xx 비트. 따라서 C 유형도 참고int8크기는 1 바이트입니다. SQL 유형int8int64in C 참조표 38.1.)

반면에, 모든 크기의 고정 길이 유형은 회의를 전달할 수 있습니다. 예를 들어 다음은 A의 샘플 구현이 있습니다.PostgreSQL유형 :

/ * 16 바이트 구조, 참조로 통과 */

그러한 유형에 대한 포인터 만 사용 할 수 있습니다.PostgreSQL메이저 토토 사이트. 그러한 유형의 값을 반환하려면에 적절한 양의 메모리를 할당하십시오.Palloc, 할당 된 메모리를 채우고 포인터를 반환하십시오. (또한 동일한 데이터 유형의 입력 인수 중 하나와 동일한 값을 반환하려면 추가를 건너 뛸 수 있습니다Palloc그리고 입력 값으로 포인터를 반환하십시오.)

마지막으로 모든 가변 길이 유형도 참조로 전달해야합니다. 모든 가변 길이 유형은 정확히 4 바이트의 불투명 길이 필드로 시작해야하며, 이에 따라 설정됩니다.set_varsize; 이 필드를 직접 설정하지 마십시오!

또 다른 중요한 요점은 데이터 유형 값 내에 초기화되지 않은 비트를 남기지 않는 것입니다. 예를 들어, 스트러크에 존재할 수있는 정렬 패딩 바이트를 제로화하십시오.

경고

절대Pass-by-Reference 입력 값의 내용을 수정합니다. 그렇게한다면, 당신이 주어진 포인터가 디스크 버퍼를 직접 가리킬 수 있기 때문에, 당신은 온 디스크 데이터를 손상시킬 가능성이 높습니다.섹션 38.11.

예를 들어, 유형을 정의 할 수 있습니다텍스트다음과 같이 :

typedef struct

the[flexible_array_member]표기법은 데이터 부분의 실제 길이 가이 선언에 의해 지정되지 않았 음을 의미합니다.

가변 길이 유형을 조작 할 때 올바른 양의 메모리를 할당하고 길이 필드를 올바르게 설정하도록주의해야합니다. 예를 들어, 40 바이트를 A에 저장하고 싶다면텍스트구조, 우리는 다음과 같은 코드 조각을 사용할 수 있습니다 :

#include "postgres.h"

varhdrsz|sizeof (int32), 그러나 매크로를 사용하는 것은 좋은 스타일로 간주됩니다varhdrsz가변 길이 유형에 대한 오버 헤드 크기를 참조합니다. 또한 길이 필드필수를 사용하여 설정하십시오set_varsize간단한 과제가 아닌 매크로.

표 38.1내장 된 SQL 데이터 유형에 해당하는 C 유형을 보여줍니다.PostgreSQL. 그만큼정의열은 유형 정의를 얻기 위해 포함되어야하는 헤더 파일을 제공합니다. (실제 정의는 나열된 파일에 포함 된 다른 파일에있을 수 있습니다. 사용자는 정의 된 인터페이스를 고수하는 것이 좋습니다.) 항상 포함해야합니다.postgres.h먼저 서버 코드의 모든 소스 파일에서, 어쨌든 필요한 여러 가지를 선언하고 다른 헤더를 먼저 포함시킬 수 있기 때문에.

표 38.1. 내장 SQL 유형의 동등한 C 유형

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
float4 (Real) float4 postgres.h
float8 (이중 정밀) float8 postgres.h
int2 (smallint) int16 postgres.h
int4 (정수) int32 postgres.h
int8 (bigint) int64 postgres.h
간격 간격* DataType/Timestamp.h
LSEG lseg* utils/geo_decls.h
이름 이름 postgres.h
숫자 숫자 utils/numeric.h
OID OID postgres.h
oidvector oidvector* postgres.h
PATH Path* utils/geo_decls.h
포인트 포인트* utils/geo_decls.h
Regproc Regrocedure postgres.h
Reltime Relativetime utils/nabstime.h
텍스트 텍스트* postgres.h
tid ItemPointer Storage/itemptr.h
Time Timeadt utils/date.h
시간대가있는 시간 Timetzadt utils/date.h
타임 스탬프 타임 스탬프 DataType/Timestamp.h
시간대가있는 타임 스탬프 Timestamptz DataType/Timestamp.h
TinterVal TimeInterval utils/nabstime.h
Varchar Varchar* postgres.h
xid TransactionId postgres.h

이제 우리는 기본 유형에 대한 가능한 모든 구조를 살펴 보았으므로 실제 메이저 토토 사이트의 몇 가지 예를 보여줄 수 있습니다..

38.10.3. 버전 1 전화 규칙

버전 -1 컨벤션은 거대에 의존하여 인수와 결과를 통과하는 복잡성의 대부분을 억제합니다. 버전 -1 메이저 토토 사이트의 C 선언은 항상 :

Datum funcname (pg_function_args)

또한 매크로 호출 :

pg_function_info_v1 (funcname);

동일한 소스 파일에 나타나야합니다. (일반적으로 메이저 토토 사이트 자체 직전에 작성되었습니다.)이 매크로 호출은 필요하지 않습니다내부-이후 언어 함수PostgreSQL모든 내부 메이저 토토 사이트이 버전 -1 컨벤션을 사용한다고 가정합니다. 그러나 동적으로로드 된 함수에 필요합니다.

버전 -1 메이저 토토 사이트에서 각 실제 인수는 A를 사용하여 가져옵니다pg_getarg_xxx()인수의 데이터 유형에 해당하는 매크로. (비 스트릭 함수에서는 인수 null-sness에 대한 이전 점검이 필요합니다PG_ARGISNULL (); 아래를 참조하십시오.) 결과는 a를 사용하여 반환됩니다.pg_return_xxx()반환 유형의 매크로.pg_getarg_xxx()카운트가 0에서 시작되는 메이저 토토 사이트 인수의 수를 인수로 간주합니다.pg_return_xxx()반환 할 실제 값을 인수로 간주합니다.

버전 -1 통화 규칙을 사용하는 몇 가지 예는 다음과 같습니다.

#include "postgres.h"

위의 코드가 파일에서 준비되었다고 가정funcs.c공유 객체로 컴파일하면 함수를 정의 할 수 있습니다.PostgreSQL다음과 같은 명령과 함께 :

함수 생성 add_one (정수) 정수를 반환합니다디렉토리/funcs ','add_one '디렉토리/funcs ','add_one_float8 '디렉토리/funcs ','makepoint '디렉토리/funcs ','CoppyText '디렉토리/funcs ','concat_text '

여기,디렉토리공유 라이브러리 파일의 디렉토리를 나타냅니다 (예 :PostgreSQL이 섹션에 사용 된 예제에 대한 코드가 포함 된 튜토리얼 디렉토리). (더 나은 스타일은 그냥 사용하는 것입니다'funcs'inas조항, 추가 후디렉토리검색 경로로. 어쨌든 공유 라이브러리의 시스템 별 확장을 생략 할 수 있습니다. 일반적으로.so.)

함수를로 지정했음을 알 수 있습니다.엄격한, 즉 입력 값이 널 인 경우 시스템이 자동으로 널 결과를 가정해야합니다. 이렇게하면 함수 코드에서 널 입력을 확인하지 않아도됩니다.PG_ARGISNULL ().

매크로PG_ARGISNULL (n)함수가 각 입력이 null인지 테스트 할 수 있습니다. (물론이 작업을 수행하는 것은 선언되지 않은 메이저 토토 사이트에서만 필요합니다엄격한.)와 마찬가지로pg_getarg_xxx()매크로, 입력 인수는 0에서 시작됩니다. 실행을 자제해야합니다pg_getarg_xxx()인수가 무효가 아님을 확인할 때까지. 널 결과를 반환하려면 executepg_return_null (); 이것은 엄격한 메이저 토토 사이트과 nompollict 메이저 토토 사이트 모두에서 작동합니다.

언뜻보기에, 버전 -1 코딩 규칙은 평범한 사용에 비해 무의미한 모호한 것으로 보일 수 있습니다C전화 컨벤션. 그러나 그들은 우리가 처리 할 수있게합니다NULLABLE 인수/반환 값 및토스트(압축 또는 외부인) 값.

버전 -1 인터페이스에서 제공하는 기타 옵션은의 두 가지 변형입니다.pg_getarg_xxx()매크로. 이 중 첫 번째,pg_getarg_xxx_copy (), 글을 쓰는 데 안전한 지정된 인수의 사본을 반환하도록 보장합니다. (일반 매크로는 때때로 테이블에 물리적으로 저장된 값에 대한 포인터를 반환합니다.pg_getarg_xxx_copy ()매크로는 쓰기 가능한 결과를 보장합니다.) 두 번째 변형은로 구성됩니다.pg_getarg_xxx_slice ()세 가지 인수를하는 매크로. 첫 번째는 함수 인수의 수입니다 (위와 같이).외부. (a 열의 저장 유형은를 사용하여 지정할 수 있습니다Alter TableTableNameAlter ColumnColname스토리지 설정StorageType. StorageType중 하나입니다일반, 외부, 확장또는Main.)

마지막으로, 버전 -1 메이저 토토 사이트 호출 규칙은 설정 결과를 반환 할 수있게합니다 (섹션 38.10.8) 및 트리거 함수 구현 (토토 꽁 머니 : 문서 : 11 : 39 장. 트리거) 및 절차 적 통화 처리기 (PostgreSQL : 문서 : 11 : 56 장. 절차 적 언어 젠 토토 작성). 자세한 내용은 참조src/backend/utils/fmgr/readme소스 분포에서.

38.10.4. 쓰기 코드

보다 진보 된 주제로 돌아 가기 전에에 대한 코딩 규칙에 대해 논의해야합니다.PostgreSQLc-language functions. c 이외의 언어로 작성된 함수를로드 할 수는 있지만PostgreSQL, C ++, Fortran 또는 Pascal과 같은 다른 언어는 종종 C와 동일한 통화 규칙을 따르지 않기 때문에 일반적으로 (전혀 가능할 때), 이것은 일반적으로 가능합니다. 이러한 이유로, 우리는 귀하의 C- 언어 메이저 토토 사이트이 실제로 C로 작성되었다고 가정합니다.

C 메이저 토토 사이트 작성 및 구축을위한 기본 규칙은 다음과 같습니다.

  • usePG_CONFIG-includedir-serverPostgreSQL서버 헤더 파일이 시스템에 설치되어 있습니다 (또는 사용자가 실행중인 시스템).

  • 코드를 컴파일하고 연결하여 동적으로로드 할 수 있도록PostgreSQL항상 특별한 플래그가 필요합니다. 보다섹션 38.10.5특정 운영 체제를 위해 수행하는 방법에 대한 자세한 설명.

  • a 정의하는 것을 잊지 마십시오.매직 블록공유 라이브러리의 경우섹션 38.10.1.

  • 메모리를 할당 할 때를 사용하십시오.PostgreSQL메이저 토토 사이트Pallocandpfree해당 C 라이브러리 메이저 토토 사이트 대신Mallocand무료. 에 의해 할당 된 메모리Palloc각 트랜잭션이 끝날 때 자동으로 해제되어 메모리 누출을 방지합니다.

  • 항상 구조물의 바이트를 항상 제로 제로memset(또는 그와 함께 할당Palloc0처음에는). 구조물의 각 필드에 할당하더라도 쓰레기 값을 포함하는 정렬 패딩 (구조의 구멍)이있을 수 있습니다.

  • 대부분의 내부PostgreSQL유형은postgres.h, 메이저 토토 사이트 관리자가 인터페이스하는 동안 (pg_function_args등)fmgr.h,이 두 파일을 포함해야합니다. 휴대 할 수있는 이유로 포함하는 것이 가장 좋습니다postgres.h 첫 번째, 다른 시스템 또는 사용자 헤더 파일 앞에. 포함postgres.h포함elog.handpalloc.h당신을 위해.

  • Symbol names defined within object files must not conflict with each other or with symbols defined in thePostgreSQL서버 실행 가능. 이 효과에 오류 메시지를 받으면 함수 또는 변수의 이름을 바꿔야합니다.

38.10.5. 동적으로로드 된 함수 컴파일 및 연결

사용하기 전에PostgreSQL확장 메이저 토토 사이트 C로 작성된 확장 메이저 토토 사이트은 서버에서 동적으로로드 할 수있는 파일을 생성하기 위해 특별한 방법으로 컴파일하고 연결되어야합니다. 정확히 말하면, a공유 도서관만들어야합니다.

이 섹션에 포함 된 정보를 넘어서는 운영 체제의 문서, 특히 C 컴파일러의 수동 페이지를 읽어야합니다.CC및 링크 편집기,ld. 또한PostgreSQL소스 코드에는에 몇 가지 작업 예제가 포함되어 있습니다.Contrib디렉토리. 이 예제에 의존하는 경우 모듈의 가용성에 따라 모듈을 만들게됩니다.PostgreSQL소스 코드.

공유 라이브러리 생성은 일반적으로 실행 파일 연결과 유사합니다. 먼저 소스 파일이 객체 파일로 컴파일 된 다음 객체 파일이 함께 연결됩니다. 객체 파일을로 만들어야합니다.위치 독립 코드 (PIC),이는 개념적으로 실행 파일에 의해로드 될 때 메모리의 임의의 위치에 배치 될 수 있음을 의미합니다. (실행 파일을위한 객체 파일은 일반적으로 그런 식으로 컴파일되지 않습니다.) 공유 라이브러리를 연결하라는 명령에는 특수 플래그가 포함되어있어 실행 파일을 연결하는 것과 구별되는 특수 플래그가 포함되어 있습니다 (적어도 일부 시스템에서는 실습이 훨씬 추악합니다)..

다음 예에서는 소스 코드가 파일에 있다고 가정합니다foo.c그리고 우리는 공유 라이브러리를 만들 것입니다.so. 중간 객체 파일이 호출됩니다.foo.o달리 명시되지 않는 한. 공유 라이브러리에는 하나 이상의 객체 파일이 포함될 수 있지만 여기에는 하나만 사용합니다.

freebsd

생성 할 컴파일러 플래그PICis-fpic. 공유 라이브러리를 만들려면 컴파일러 플래그는입니다.-shared.

gcc -fpic -c foo.c

버전 3.0의 기준으로 적용 가능합니다.freebsd.

hp-ux

생성 할 시스템 컴파일러의 컴파일러 플래그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대부분의 다른 시스템과 달리 공유 라이브러리의 경우.

Linux

생성 할 컴파일러 플래그PICis-fpic. 공유 라이브러리를 만들기위한 컴파일러 플래그는입니다.-shared. 완전한 예는 다음과 같습니다.

cc -fpic -c foo.c
MacOS

여기 예입니다. 개발자 도구가 설치되었다고 가정합니다.

CC -C FOO.C
NetBsd

생성 할 컴파일러 플래그PICis-fpic. 을 위한ELF시스템, 플래그가있는 컴파일러-shared공유 라이브러리를 연결하는 데 사용됩니다. 이전 비 ELF 시스템에서ld -Bsharable사용됩니다.

gcc -fpic -c foo.c
OpenBSD

생성 할 컴파일러 플래그PICis-fpic. ld -Bsharable공유 라이브러리를 연결하는 데 사용됩니다.

gcc -fpic -c foo.c
Solaris

생성 할 컴파일러 플래그PICis-kpicSUN 컴파일러와-fpicwithGCC. 공유 라이브러리를 연결하려면 컴파일러 옵션은입니다.-g컴파일러 또는 대안으로-sharedwithGCC.

cc -kpic -c foo.c

또는

gcc -fpic -c foo.c

이것이 너무 복잡하다면 사용을 고려해야합니다gnu libtool, 균일 한 인터페이스 뒤에 플랫폼 차이를 숨 깁니다.

결과 공유 라이브러리 파일을로드 할 수 있습니다PostgreSQL. 파일 이름을 지정할 때함수 만들기명령, 중간 객체 파일이 아닌 공유 라이브러리 파일의 이름을 지정해야합니다. 시스템의 표준 공유-라이브러리 확장 (일반적으로.so또는.SL)에서 생략 할 수 있습니다함수 만들기명령, 일반적으로 최상의 휴대 성을 위해 생략해야합니다.

다시 참조섹션 38.10.1서버가 공유 라이브러리 파일을 찾을 예정인 위치에 대한 정보.

38.10.6. 복합 유형 인수

복합 유형에는 C 구조와 같은 고정 레이아웃이 없습니다. 복합 유형의 인스턴스에는 널 필드가 포함될 수 있습니다.PostgreSQLC에서 복합 유형의 필드에 액세스하기위한 메이저 토토 사이트 인터페이스를 제공합니다

쿼리에 응답하기 위해 함수를 작성하려고한다고 가정 해 봅시다 :

이름, C_overpaid (EMP, 1500)를 초과 지불로 선택하십시오

버전 -1 컨벤션을 사용하여 정의 할 수 있습니다c_overpaidas :

#include "postgres.h"

getAttributeByNamePostgreSQL지정된 행에서 속성을 반환하는 시스템 함수. 그것은 세 가지 주장이 있습니다 : 유형의 주장HeappupleHeader함수, 원하는 속성의 이름 및 속성이 null인지 알려주는 반환 매개 변수로 전달되었습니다.getAttributeByName반환 aDatum적절한 데이터 유형을 사용하여 적절한 데이터 유형으로 변환 할 수있는 값Datumgetxxx()매크로. 널 플래그가 설정된 경우 리턴 값은 의미가 없습니다.

또한GetAttributeBynum, 이름 대신 열 숫자로 대상 속성을 선택합니다.

다음 명령은 함수를 선언합니다c_overpaidsql :

함수 만들기 c_overpaid (emp, integer)는 부울을 반환합니다디렉토리/funcs ','c_overpaid '

우리가 사용한 통지엄격한입력 인수가 무효인지 확인할 필요가 없었습니다.

38.10.7. 반환 행 (복합 유형)

c-language 함수에서 행 또는 복합 유형 값을 반환하려면 매크로와 함수를 제공하는 특수 API를 사용하여 복합 데이터 유형을 구축하는 대부분의 복잡성을 숨길 수 있습니다. 이 API를 사용하려면 소스 파일에는 다음을 포함해야합니다.

#include "funcapi.h"

복합 데이터 값을 구축 할 수있는 두 가지 방법이 있습니다 (따라서 A튜플) : Datum 값 배열 또는 튜플 열 데이터 유형의 입력 변환 메이저 토토 사이트으로 전달 될 수있는 C 문자열 배열에서 빌드 할 수 있습니다. 두 경우 모두 먼저 a를 얻거나 구성해야합니다.tupledesc튜플 구조에 대한 설명자. Datums와 함께 일할 때를 통과합니다.tupledesctoBlessTupledesc그리고 전화heap_form_tuple각 행마다. C 줄로 작업 할 때를 통과합니다.tupledesctotupledescgetattinmetadata그리고 전화BuildTupleFromCstrings각 행에 대해. 함수의 경우 튜플 세트를 반환하는 경우 메이저 토토 사이트의 첫 번째 호출 중에 설정 단계를 모두 수행 할 수 있습니다.

필요한 것을 설정하기 위해 여러 도우미 메이저 토토 사이트을 사용할 수 있습니다tupledesc. 복합 값을 반환하는 대부분의 메이저 토토 사이트 에서이 작업을 수행하는 권장 방법은 다음과 같습니다.

saptuncclass get_call_result_type (functioncallinfo fcinfo,

같은 통과fcinfo구조는 호출 함수 자체로 전달되었습니다. (물론 이것은 버전 -1 통화 컨벤션을 사용해야합니다.)resultTypeid|NULL또는 메이저 토토 사이트의 결과 유형을 수신하기위한 로컬 변수의 주소로서resultTupledesc지역의 주소 여야합니다tupledesc변수. 결과가인지 확인하십시오.stupbunc_composite; 그렇다면,resultTupledesc필요한 것으로 채워졌습니다tupledesc. (그렇지 않은 경우의 선을 따라 오류를보고 할 수 있습니다.유형 레코드를 허용 할 수없는 맥락에서 호출 된 메이저 토토 사이트 반환 레코드.)

get_call_result_type실제 유형의 다형성 메이저 토토 사이트 결과를 해결할 수 있습니다. 따라서 복합재를 반환하는 메이저 토토 사이트뿐만 아니라 스칼라 다형성 결과를 반환하는 메이저 토토 사이트에 유용합니다.resultTypeid출력은 주로 다형성 스칼라를 반환하는 메이저 토토 사이트에 유용합니다.

Note

get_call_result_type형제가 있습니다get_expr_result_type, 표현식 트리로 표시되는 함수 호출에 대한 예상 출력 유형을 해결하는 데 사용할 수 있습니다. 메이저 토토 사이트 자체 외부에서 결과 유형을 결정하려고 할 때 사용할 수 있습니다.get_func_result_type, 메이저 토토 사이트의 OID 만 사용할 수있을 때 사용할 수 있습니다. 그러나 이러한 메이저 토토 사이트은 반환으로 선언 된 메이저 토토 사이트을 다룰 수 없습니다레코드get_func_result_type다형성 유형을 해결할 수 없으므로 우선적으로 사용해야합니다get_call_result_type.

획득하기위한 구식, 현재 배제 된 메이저 토토 사이트tupledescs는 :

tupledesc relationnamegetTupledesc (const char *relname)

atupledesc지명 관계의 행 유형의 경우 :

tupledesc typegetTupledesc (Oid typeoid, list *colaliases)

atupledesc유형 OID를 기준으로합니다. 이것은 A를 얻는 데 사용될 수 있습니다.tupledesc베이스 또는 복합 유형의 경우. 반환하는 함수에 대해서는 작동하지 않습니다레코드, 그러나 다형성 유형을 해결할 수 없습니다.

일단 당신이 atupledesc, 전화 :

tupledesc blesstupledesc (tupledesc tupdesc)

Datums와 함께 일할 계획 인 경우 :

Attinmetadata *tupledescgetattinmetadata (tupledesc tupdesc)

C 스트링으로 작업하려는 경우. 메이저 토토 사이트 반환 세트를 작성하는 경우에서 이러한 메이저 토토 사이트의 결과를 저장할 수 있습니다.FUNCCALLCONTEXT구조 - 사용tuple_desc또는Attinmeta필드

Datums에서 작업 할 때 :

heappuple heap_form_tuple (tupledesc tupdesc, datum *값, bool *isnull)

aHeappupleDatum Form의 사용자 데이터가 주어졌습니다.

C 문자열로 작업 할 때 :

Heaptuple BuildTuplefffflffflfflings (AttinMetadata *AttinMeta, char ** value)

aHeappupleC 문자열 양식의 사용자 데이터가 주어졌습니다.는 반환 행의 각 속성마다 하나의 C 문자열 배열입니다. 각 C 문자열은 속성 데이터 유형의 입력 함수에 의해 예상되는 형식이어야합니다.배열을 설정해야합니다NULL. 이 메이저 토토 사이트은 반환하는 각 행마다 다시 호출해야합니다.

메이저 토토 사이트에서 돌아 오기 위해 튜플을 만들면 A로 변환해야합니다Datum. 사용:

HeappuplegetDatum (Heppuple Tuple)

변환Heappuple유효한 데이텀으로. 이것Datum단일 행 만 반환하려는 경우 직접 반환 할 수 있습니다.

다음 섹션에 예제가 나타납니다.

38.10.8. 반환 세트

c-language 함수에는 세트를 반환하기위한 두 가지 옵션 (다중 행)이 있습니다. 하나의 방법으로Valuepercall모드, 모드에서 설정 함수는 반복적으로 호출되고 (매번 같은 인수를 전달) 각 호출에 새 행을 반환합니다. 정해진 함수 (SRF) 그러므로 전화를 걸어 충분한 상태를 저장 해야하는 일을 기억하고 각 통화에서 올바른 다음 항목을 반환해야합니다. 다른 방법에서는실체화모드, SRF가 전체 결과를 포함하는 Tuplestore 객체를 채우고 반환합니다. 그런 다음 전체 결과에 대해 하나의 호출 만 발생하며 전화 간 상태가 필요하지 않습니다.

ValuePercall 모드를 사용할 때 쿼리가 완료되지 않은 것으로 보장되지 않는다는 것을 기억하는 것이 중요합니다. 즉,과 같은 옵션으로 인해Limit, 집행자는 모든 행을 가져 오기 전에 정해진 함수에 대한 호출을 중단 할 수 있습니다. 이것은 마지막 통화에서 정리 활동을 수행하는 것이 안전하지 않다는 것을 의미합니다.

이 섹션의 나머지 부분은 Valuepercall 모드를 사용하여 SRF에 일반적으로 사용되는 (사용되지 않아도)의 도우미 매크로 세트를 문서화합니다. 실체화 모드에 대한 추가 세부 사항은에서 찾을 수 있습니다.src/backend/utils/fmgr/readme. 또한,Contrib모듈의PostgreSQL소스 분포는 Valuepercall과 INSATERIZE 모드를 모두 사용하는 SRF의 많은 예를 포함합니다.

여기에 설명 된 ValuePercall 지원 매크로를 사용하려면 포함funcapi.h. 이 매크로는 구조와 함께 작동합니다FUNCCALLCONTEXT통화에 걸쳐 저장 해야하는 상태가 포함되어 있습니다. 호출 SRF 내에서fcinfo-> flinfo-> fn_extra포인터를 보유하는 데 사용됩니다FUNCCALLCONTEXT통화 전체. 매크로는 처음 사용하면 해당 필드를 자동으로 채우고 후속 용도에서 동일한 포인터를 찾을 것으로 예상됩니다.

typedef struct funccallcontext

매크로는 AN에서 사용합니다SRF이 인프라 사용 사용은 다음과 같습니다.

srf_is_firstcall ()

이것을 사용하여 첫 번째 또는 후속 시간 동안 메이저 토토 사이트이 요구되는지 확인하십시오. 첫 번째 전화 (만)에서 전화 :

SRF_FIRSTCALL_INIT ()

초기화하려면FUNCCALLCONTEXT. 첫 번째를 포함하여 모든 메이저 토토 사이트 호출에서 :

srf_percall_setup ()

사용을 위해 설정하려면FUNCCALLCONTEXT.

메이저 토토 사이트이 현재 통화에서 반환 할 데이터가있는 경우 :

srf_return_next (funcctx, result)

발신자에게 반환하려면. (결과유형이어야합니다Datum, 위에서 설명한대로 준비한 단일 값 또는 튜플.) 마지막으로, 메이저 토토 사이트이 완료되면 데이터를 반환하면 다음을 사용합니다.

srf_return_done (funcctx)

청소하고 끝내려면SRF.

SRF호출은 호출 사이에 지워질 일시적인 컨텍스트입니다. 이것은 당신이 전화 할 필요가 없다는 것을 의미합니다pfree사용하여 할당 한 모든 것에서Palloc; 어쨌든 사라질 것입니다.multi_call_memory_ctx|SRF가 끝났습니다. 대부분의 경우 이것은로 전환해야 함을 의미합니다.multi_call_memory_ctx첫 번째 집합을 수행하는 동안. 사용funcctx-> user_fctx그러한 교차 데이터 구조에 대한 포인터를 보유합니다. (당신이 할당하는 데이터multi_call_memory_ctx쿼리가 종료되면 자동으로 사라질 것이므로 수동으로 해당 데이터를 자유롭게 해제 할 필요가 없습니다.)

경고

함수에 대한 실제 인수는 통화간에 변경되지 않은 상태로 유지되지만 인수 값 (일반적으로 투명하게 수행됩니다).pg_getarg_xxx매크로) 일시적 컨텍스트에서는 각주기마다 고발 된 사본이 해제됩니다. 따라서, 당신이 당신의 그러한 값에 대해 언급하면user_fctx, 당신은 그것들을에 복사해야합니다multi_call_memory_ctx고발 후, 또는 해당 맥락에서만 값을 해제하는지 확인하십시오.

완전한 의사 코드 예제는 다음과 같습니다.

Datum필요에 따른 추가 선언if (srf_is_firstcall ())사용자 코드
        복합재를 반환하는 경우
            tupledesc 빌드 및 아마도 AttinMetadata
        Endif 리턴 컴포지트
        사용자 코드MemoryContexTswitchto (OldContext);사용자 코드funcctx = srf_percall_setup ();사용자 코드/ * 이것은 우리가 끝났는지 테스트 할 수있는 한 가지 방법 일뿐입니다. */사용자 코드
        결과 기준 획득srf_return_next (funcctx, result);

간단한 완전한 예SRF복합 유형을 반환하는 것은 다음과 같습니다.

pg_function_info_v1 (retcomposite);

SQL 에서이 메이저 토토 사이트을 선언하는 한 가지 방법은 다음과 같습니다.

유형 생성 __retcomposite as (F1 Integer, F2 Integer, F3 Integer);filename','retcomposite '

다른 방법은 매개 변수를 사용하는 것입니다 :

함수 retcomposite 생성 또는 교체 (정수, 정수,filename','retcomposite '

이 방법에서 함수의 출력 유형은 공식적으로 익명입니다레코드타입.

38.10.9. 다형성 논증 및 반환 유형

c-language 함수는 다형성 유형을 수락하고 반환하도록 선언 할 수 있습니다Anylement, AnyArray, AnynonArray, AnyEnumAnyRange. 보다섹션 38.2.5다형성 메이저 토토 사이트에 대한 자세한 설명. 함수 인수 또는 반환 유형이 다형성 유형으로 정의되면 메이저 토토 사이트 저자는 어떤 데이터 유형을 호출하거나 반환 해야하는지 미리 알 수 없습니다.fmgr.h버전 -1 C 메이저 토토 사이트이 인수의 실제 데이터 유형과 반환 될 것으로 예상되는 유형을 발견하도록합니다. 루틴은라고합니다.get_fn_expr_rettype (fmgrinfo *flinfo)andget_fn_expr_argtype (fmgrinfo *flinfo, int argnum). 결과 또는 인수 유형 OID를 반환합니다.Invalidoid정보를 사용할 수없는 경우. 구조flinfo일반적으로에 액세스됩니다.fcinfo-> flinfo. 매개 변수Argnum는 제로 기반입니다.get_call_result_type대안으로 사용할 수 있습니다get_fn_expr_rettype. 또한get_fn_expr_variadic, 이는 변수 인수가 배열에 병합되었는지 확인하는 데 사용할 수 있습니다. 이것은 주로 유용합니다Variadic "Any"함수, 이러한 병합은 일반적인 배열 유형을 취하는 변수 함수에 대해 항상 발생했기 때문에

예를 들어, 모든 유형의 단일 요소를 수락하기 위해 함수를 작성하고 해당 유형의 1 차원 배열을 반환한다고 가정합니다.

pg_function_info_v1 (make_array);

다음 명령은 함수를 선언합니다make_arraysql :

함수 생성 make_array (Anylement)는 anyArray를 반환합니다디렉토리/funcs ','make_array '

c- 언어 함수에만 사용할 수있는 다형성의 변형이 있습니다."Any". (이 유형 이름은 SQL 예약 단어이기 때문에이 유형 이름이 두 배로 인용되어야합니다.) 이것은와 같습니다.Anylement다른 제한을 제외하고"Any"인수는 동일한 유형이거나 메이저 토토 사이트의 결과 유형을 결정하는 데 도움이되지 않습니다. c-language 함수는 또한 최종 매개 변수를 선언 할 수 있습니다Variadic "Any". 이것은 모든 유형의 하나 이상의 실제 인수와 일치합니다 (반드시 같은 유형은 아닙니다).not정상적인 변수 함수와 마찬가지로 배열로 수집해야합니다. 그들은 단지 함수로 별도로 전달됩니다.pg_nargs ()매크로 및 위에서 설명한 방법을 사용 하여이 메이저 토토 사이트을 사용할 때 실제 인수의 수와 해당 유형을 결정해야합니다. 또한 이러한 메이저 토토 사이트을 가진 사용자는를 사용하고 싶을 수도 있습니다.variadic함수 호출의 키워드 메이저 토토 사이트이 배열 요소를 별도의 인수로 취급 할 것으로 기대합니다. 함수 자체는 원하는 경우 해당 동작을 구현해야합니다.get_fn_expr_variadic실제 인수가 표시되었음을 감지하기 위해variadic.

38.10.10. 메이저 토토 사이트 변환

함수와 관련된 속성을 기반으로 계획 중에 일부 함수 호출을 단순화 할 수 있습니다. 예를 들어,int4mul (n, 1)단순화 할 수 있습니다n. 이러한 메이저 토토 사이트 별 최적화를 정의하려면 A를 작성하십시오.변환 메이저 토토 사이트에 OID를 배치하십시오.protransform기본 함수 필드PG_PROC입력. 변환 메이저 토토 사이트에는 SQL 서명이 있어야합니다돌기 (내부) 내부 반환. 논쟁, 실제로funcexpr *, 기본 함수에 대한 호출을 나타내는 더미 노드입니다. 표현 트리에 대한 변환 함수의 연구가 단순화 된 발현 트리가 표현 된 모든 가능한 콘크리트 호출을 대체 할 수 있음을 증명하는 경우, 표현식을 단순화하고 반환합니다.NULL포인터 (notSQL NULL).

우리는 그것을 보장하지 않습니다PostgreSQL변환 함수가 단순화 될 수있는 경우 기본 함수를 절대 호출하지 않습니다. 단순화 된 표현식과 기본 메이저 토토 사이트에 대한 실제 호출 사이의 엄격한 동등성을 보장합니다.

현재이 시설은 보안 문제로 인해 SQL 수준의 사용자에게 노출되지 않으므로 내장 메이저 토토 사이트을 최적화하는 데만 사용하는 것이 실용적입니다..

38.10.11. 공유 메모리 및 LWLOCKS

애드 인은 서버 시작에 LWLOCKS 및 공유 메모리 할당을 예약 할 수 있습니다. Add-in의 공유 라이브러리는를 지정하여 사전로드해야합니다.shared_preload_libraries. 공유 메모리는 다음과 같이 호출하여 예약됩니다.

void requestAdDinshMemsPace (int size)

에서_pg_init메이저 토토 사이트.

lwlocks는 다음과 같이 예약됩니다.

void requestNamedlwlocktranche (const char *tranche_name, int num_lwlocks)

From_pg_init. 이것은 배열을 보장합니다.num_lwlockslwlocks는 이름으로 사용할 수 있습니다tranche_name. 사용getNamedlwlocktranche이 배열에 대한 포인터를 얻으려면

가능한 경주 조건을 피하기 위해 각 백엔드는 lwlock을 사용해야합니다addinshmeminitlock여기에 표시된대로 공유 메모리 할당을 연결하고 초기화 할 때 :

정적 myStruct *ptr = null;

38.10.12. 확장 성을 위해 C ++ 사용

비록PostgreSQL백엔드는 C로 작성되었으며,이 지침이 다음과 같은 경우 C ++로 확장을 쓸 수 있습니다.

  • 백엔드에서 액세스하는 모든 메이저 토토 사이트은 백엔드에 C 인터페이스를 제시해야합니다. 이 C 함수는 C ++ 메이저 토토 사이트을 호출 할 수 있습니다.extern C백엔드 액세스 함수에는 연결이 필요합니다. 이것은 백엔드와 C ++ 코드 사이의 포인터로 전달되는 모든 메이저 토토 사이트에도 필요합니다.

  • 적절한 거래 방법을 사용한 무료 메모리. 예를 들어, 대부분의 백엔드 메모리는를 사용하여 할당됩니다.palloc (), 사용pfree ()그것을 자유롭게하려면. C ++ 사용삭제그러한 경우 실패합니다.

  • 예외는 C 코드로 전파되는 것을 방지합니다 (모두 최상위 수준의 포획 블록 사용extern C함수). 메모리 외과 같은 이벤트는 여전히 예외를 제외 할 수 있기 때문에 C ++ 코드가 예외를 명시 적으로 던지지 않더라도 필요합니다.-fno-exceptions예외를 완전히 제거하기 위해; 이 경우 C ++ 코드에서 실패를 확인해야합니다 (예 :new ().

  • C ++ 코드에서 백엔드 메이저 토토 사이트을 호출하는 경우 C ++ 통화 스택에 일반 이전 데이터 구조 만 포함되어 있는지 확인하십시오 (POD). 백엔드 오류가 먼 것을 생성하기 때문에 필요합니다longjmp ()POD 객체가없는 C ++ 호출 스택을 제대로 풀지 않습니다.

요약하면 C ++ 코드를 벽 뒤에 배치하는 것이 가장 좋습니다extern C백엔드를 인터페이스하고 예외, 메모리 및 호출 스택 누출을 피하는 메이저 토토 사이트.