{"Entry":{"collection":"sql","key":"create-language","name":"CREATE LANGUAGE","aliases":["createlanguage"],"metadata":{"aliases":["createlanguage"],"changed_in":["7.1","7.2","7.3","7.4","8.1","9.0","13"],"changes":[{"from":"6.4","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","usage"],"removed":[]},"status":"changed","synopsis":null,"to":"6.5"},{"from":"6.5","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","compatibility"],"removed":["other","bugs"]},"status":"changed","synopsis":null,"to":"7.0"},{"from":"7.0","purpose_changed":false,"renamed":{"from_file":"sql-createlanguage.htm","to_file":"sql-createlanguage.html"},"sections":{"added":[],"changed":["description","usage"],"removed":[]},"status":"changed","synopsis":{"added":["CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE 'langname'"],"removed":[]},"to":"7.1"},{"from":"7.1","purpose_changed":true,"renamed":null,"sections":{"added":["parameters","diagnostics","notes","examples","history","see_also"],"changed":["description","compatibility"],"removed":["usage"]},"status":"changed","synopsis":{"added":["CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE langname"],"removed":["CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE 'langname'","LANCOMPILER 'comment'"]},"to":"7.2"},{"from":"7.2","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["parameters","diagnostics","notes","examples","see_also"],"removed":[]},"status":"changed","synopsis":{"added":["HANDLER call_handler [ VALIDATOR valfunction ]"],"removed":[]},"to":"7.3"},{"from":"7.3","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","notes","examples","see_also"],"removed":["diagnostics","history"]},"status":"changed","synopsis":{"added":["CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name"],"removed":["CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE langname"]},"to":"7.4"},{"from":"7.4","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"8.0"},{"from":"8.0","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","notes","examples"],"removed":[]},"status":"changed","synopsis":{"added":["CREATE [ PROCEDURAL ] LANGUAGE name"],"removed":[]},"to":"8.1"},{"from":"8.1","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"8.2"},{"from":"8.2","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"8.3"},{"from":"8.3","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["notes"],"removed":[]},"status":"changed","synopsis":null,"to":"8.4"},{"from":"8.4","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","notes","examples"],"removed":[]},"status":"changed","synopsis":{"added":["CREATE [ OR REPLACE ] [ PROCEDURAL ] LANGUAGE name","CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name","HANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ]"],"removed":[]},"to":"9.0"},{"from":"9.0","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"9.1"},{"from":"9.1","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["parameters"],"removed":[]},"status":"changed","synopsis":null,"to":"9.2"},{"from":"9.2","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"9.3"},{"from":"9.3","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"9.4"},{"from":"9.4","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"9.5"},{"from":"9.5","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"9.6"},{"from":"9.6","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes","see_also"],"removed":[]},"status":"changed","synopsis":null,"to":"10"},{"from":"10","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"11"},{"from":"11","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"12"},{"from":"12","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","notes","examples"],"removed":[]},"status":"changed","synopsis":{"added":["CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name"],"removed":["CREATE [ OR REPLACE ] [ PROCEDURAL ] LANGUAGE name"]},"to":"13"},{"from":"13","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"14"},{"from":"14","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"15"},{"from":"16","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"17"},{"from":"17","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"18"}],"content_hash":"22c756fdaad151ffb68912dacc3aec0b5fba43069e274bf50a2819aeedf2158e","editorial":{},"first_version":"6.4","group":"routine","imported_at":"2026-09-30T17:43:37.233612+08:00","last_version":"20","name":"CREATE LANGUAGE","object":"LANGUAGE","position":2008,"present_in":["6.4","6.5","7.0","7.1","7.2","7.3","7.4","8.0","8.1","8.2","8.3","8.4","9.0","9.1","9.2","9.3","9.4","9.5","9.6","10","11","12","13","14","15","16","17","18","19","20"],"purpose":"define a new procedural language","purpose_zh":"","related":["alter-language","create-function","drop-language","grant","revoke"],"slug":"create-language","source_rev":"a709ab85","synopsis":"CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\nHANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ]\nCREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name","verb":"CREATE"}},"Definition":{"Collection":"sql","Key":"create-language","SourceDatabase":"center","Version":"18","SourceTable":"sqlcmd","SourceKey":"create-language","SourceRevision":"a709ab85","Facts":{"anchor":"SQL-CREATELANGUAGE","file":"sql-createlanguage.html","lang":"en","name":"CREATE LANGUAGE","purpose":"define a new procedural language","purpose_zh":"","related":["alter-language","create-function","drop-language","grant","revoke"],"sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e registers a new procedural language with a \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e database. Subsequently, functions and procedures can be defined in this new language.\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e effectively associates the language name with handler function(s) that are responsible for executing functions written in the language. Refer to \u003ca href=\"/docs/18/plhandler.html\" title=\"Chapter 57. Writing a Procedural Language Handler\"\u003eChapter 57\u003c/a\u003e for more information about language handlers.\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE OR REPLACE LANGUAGE\u003c/code\u003e will either create a new language, or replace an existing definition. If the language already exists, its parameters are updated according to the command, but the language's ownership and permissions settings do not change, and any existing functions written in the language are assumed to still be valid.\u003c/p\u003e\u003cp\u003eOne must have the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e superuser privilege to register a new language or change an existing language's parameters. However, once the language is created it is valid to assign ownership of it to a non-superuser, who may then drop it, change its permissions, rename it, or assign it to a new owner. (Do not, however, assign ownership of the underlying C functions to a non-superuser; that would create a privilege escalation path for that user.)\u003c/p\u003e\u003cp\u003eThe form of \u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e that does not supply any handler function is obsolete. For backwards compatibility with old dump files, it is interpreted as \u003ccode class=\"command\"\u003eCREATE EXTENSION\u003c/code\u003e. That will work if the language has been packaged into an extension of the same name, which is the conventional way to set up procedural languages.\u003c/p\u003e","key":"description","title":"Description"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eTRUSTED\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003ccode class=\"literal\"\u003eTRUSTED\u003c/code\u003e specifies that the language does not grant access to data that the user would not otherwise have. If this key word is omitted when registering the language, only users with the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e superuser privilege can use this language to create new functions.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003ePROCEDURAL\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThis is a noise word.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name of the new procedural language. The name must be unique among the languages in the database.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eHANDLER\u003c/code\u003e \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e is the name of a previously registered function that will be called to execute the procedural language's functions. The call handler for a procedural language must be written in a compiled language such as C with version 1 call convention and registered with \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e as a function taking no arguments and returning the \u003ccode class=\"type\"\u003elanguage_handler\u003c/code\u003e type, a placeholder type that is simply used to identify the function as a call handler.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eINLINE\u003c/code\u003e \u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e is the name of a previously registered function that will be called to execute an anonymous code block (\u003ca href=\"/docs/18/sql-do.html\" title=\"DO\"\u003e\u003ccode class=\"command\"\u003eDO\u003c/code\u003e\u003c/a\u003e command) in this language. If no \u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e function is specified, the language does not support anonymous code blocks. The handler function must take one argument of type \u003ccode class=\"type\"\u003einternal\u003c/code\u003e, which will be the \u003ccode class=\"command\"\u003eDO\u003c/code\u003e command's internal representation, and it will typically return \u003ccode class=\"type\"\u003evoid\u003c/code\u003e. The return value of the handler is ignored.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eVALIDATOR\u003c/code\u003e \u003cem class=\"replaceable\"\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e is the name of a previously registered function that will be called when a new function in the language is created, to validate the new function. If no validator function is specified, then a new function will not be checked when it is created. The validator function must take one argument of type \u003ccode class=\"type\"\u003eoid\u003c/code\u003e, which will be the OID of the to-be-created function, and will typically return \u003ccode class=\"type\"\u003evoid\u003c/code\u003e.\u003c/p\u003e\u003cp\u003eA validator function would typically inspect the function body for syntactical correctness, but it can also look at other properties of the function, for example if the language cannot handle certain argument types. To signal an error, the validator function should use the \u003ccode class=\"function\"\u003eereport()\u003c/code\u003e function. The return value of the function is ignored.\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"Parameters"},{"html":"\u003cp\u003eUse \u003ca href=\"/docs/18/sql-droplanguage.html\" title=\"DROP LANGUAGE\"\u003e\u003ccode class=\"command\"\u003eDROP LANGUAGE\u003c/code\u003e\u003c/a\u003e to drop procedural languages.\u003c/p\u003e\u003cp\u003eThe system catalog \u003ccode class=\"classname\"\u003epg_language\u003c/code\u003e (see \u003ca href=\"/docs/18/catalog-pg-language.html\" title=\"52.29. pg_language\"\u003eSection 52.29\u003c/a\u003e) records information about the currently installed languages. Also, the \u003cspan class=\"application\"\u003epsql\u003c/span\u003e command \u003ccode class=\"command\"\u003e\\dL\u003c/code\u003e lists the installed languages.\u003c/p\u003e\u003cp\u003eTo create functions in a procedural language, a user must have the \u003ccode class=\"literal\"\u003eUSAGE\u003c/code\u003e privilege for the language. By default, \u003ccode class=\"literal\"\u003eUSAGE\u003c/code\u003e is granted to \u003ccode class=\"literal\"\u003ePUBLIC\u003c/code\u003e (i.e., everyone) for trusted languages. This can be revoked if desired.\u003c/p\u003e\u003cp\u003eProcedural languages are local to individual databases. However, a language can be installed into the \u003ccode class=\"literal\"\u003etemplate1\u003c/code\u003e database, which will cause it to be available automatically in all subsequently-created databases.\u003c/p\u003e","key":"notes","title":"Notes"},{"html":"\u003cp\u003eA minimal sequence for creating a new procedural language is:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION plsample_call_handler() RETURNS language_handler\n    AS '$libdir/plsample'\n    LANGUAGE C;\nCREATE LANGUAGE plsample\n    HANDLER plsample_call_handler;\n\u003c/pre\u003e\u003cp\u003eTypically that would be written in an extension's creation script, and users would do this to install the extension:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eCREATE EXTENSION plsample;\n\u003c/pre\u003e","key":"examples","title":"Examples"},{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e is a \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e extension.\u003c/p\u003e","key":"compatibility","title":"Compatibility"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/wiki/sql/alter-language/?v=18\" title=\"ALTER LANGUAGE\"\u003e\u003cspan class=\"refentrytitle\"\u003eALTER LANGUAGE\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/create-function/?v=18\" title=\"CREATE FUNCTION\"\u003e\u003cspan class=\"refentrytitle\"\u003eCREATE FUNCTION\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/drop-language/?v=18\" title=\"DROP LANGUAGE\"\u003e\u003cspan class=\"refentrytitle\"\u003eDROP LANGUAGE\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/grant/?v=18\" title=\"GRANT\"\u003e\u003cspan class=\"refentrytitle\"\u003eGRANT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/revoke/?v=18\" title=\"REVOKE\"\u003e\u003cspan class=\"refentrytitle\"\u003eREVOKE\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"See Also"}],"sections_same_as":"","slug":"18","synopsis_html":"CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/em\u003e\n    HANDLER \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e [ INLINE \u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e ] [ VALIDATOR \u003cem class=\"replaceable\"\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e ]\nCREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/em\u003e","synopsis_text":"CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\nHANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ]\nCREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name"},"ManualEvidence":{},"MeasuredEvidence":{}},"Text":{"Collection":"sql","Key":"create-language","SourceDatabase":"pgweb","Version":"18","Locale":"zh-Hans","Title":"CREATE LANGUAGE","Summary":"定义一种新的过程语言","BodyHTML":"\u003cpre\u003eCREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\nHANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ]\nCREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\u003c/pre\u003e\u003csection\u003e\u003ch2\u003e描述\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eCREATE LANGUAGE\u003c/code\u003e在 \u003cspan\u003ePostgreSQL\u003c/span\u003e数据库中注册一种新的过程语言。随后，就可以用这种新语言定义函数和过程。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eCREATE LANGUAGE\u003c/code\u003e实际上是将该语言名称与负责执行用这种语言编写的函数的处理器函数关联起来。关于语言处理器的更多信息，参见\u003ca href=\"/docs/18/plhandler.html\" rel=\"nofollow\"\u003e第 57 章\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eCREATE OR REPLACE LANGUAGE\u003c/code\u003e会创建一种新语言，或者替换现有定义。如果该语言已经存在，其参数会按命令更新；但该语言的所有权和权限设置不会改变，并且任何现有的、用该语言编写的函数都假定仍然有效。\u003c/p\u003e\u003cp\u003e必须拥有\u003cspan\u003ePostgreSQL\u003c/span\u003e超级用户权限，才能注册新语言或更改现有语言的参数。不过，一旦语言创建完成，就可以把它的所有权赋予非超级用户；随后该用户可以删除它、更改其权限、重命名它，或者将其转让给新的所有者。（不过，不要把底层 C 函数的所有权赋予非超级用户；那样会为该用户制造一条权限提升路径。）\u003c/p\u003e\u003cp\u003e不提供任何处理器函数的\u003ccode\u003eCREATE LANGUAGE\u003c/code\u003e形式已经过时。为了向后兼容旧的转储文件，它会被解释为\u003ccode\u003eCREATE EXTENSION\u003c/code\u003e。如果该语言已被打包为一个同名扩展，这种写法就能工作，而这正是安装过程语言的惯常方式。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e参数\u003c/h2\u003e\u003cdiv\u003e\u003cdl\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eTRUSTED\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003ccode\u003eTRUSTED\u003c/code\u003e指定该语言不会让用户获得其原本无权访问的数据访问能力。如果在注册该语言时省略这个关键字，只有拥有\u003cspan\u003ePostgreSQL\u003c/span\u003e超级用户权限的用户才能使用该语言创建新函数。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003ePROCEDURAL\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e这是一个噪声词。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e新过程语言的名称。该名称不能与数据库中其他语言的名称重复。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eHANDLER\u003c/code\u003e \u003cem\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e 是一个先前注册的函数名称，它会被调用来执行该过程语言中的函数。过程语言的调用处理器必须使用某种编译型语言（例如 C）编写，并采用版本 1 调用约定。它必须在\u003cspan\u003ePostgreSQL\u003c/span\u003e 中注册为一个不带参数且返回\u003ccode\u003elanguage_handler\u003c/code\u003e类型的函数。\u003ccode\u003elanguage_handler\u003c/code\u003e是一种占位符类型，仅用于把该函数标识为调用处理器。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eINLINE\u003c/code\u003e \u003cem\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e 是一个先前注册的函数名称，它会被调用来执行该语言中的匿名代码块（\u003ca href=\"/docs/18/sql-do.html\" title=\"DO\" rel=\"nofollow\"\u003e\u003ccode\u003eDO\u003c/code\u003e\u003c/a\u003e命令）。如果没有指定\u003cem\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e 函数，则该语言不支持匿名代码块。该处理器函数必须接受一个 \u003ccode\u003einternal\u003c/code\u003e类型的参数，该参数将是 \u003ccode\u003eDO\u003c/code\u003e命令的内部表示，并且它通常返回 \u003ccode\u003evoid\u003c/code\u003e。处理器的返回值会被忽略。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eVALIDATOR\u003c/code\u003e \u003cem\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e 是一个先前注册的函数名称，在创建该语言中的新函数时会调用它来验证该新函数。如果没有指定验证器函数，那么新函数在创建时不会被检查。验证器函数必须接受一个\u003ccode\u003eoid\u003c/code\u003e类型的参数，它将是待创建函数的 OID，并且它通常返回\u003ccode\u003evoid\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e验证器函数通常会检查函数体的语法正确性，但它也可以检查函数的其他属性，例如该语言是否支持某些参数类型。要报告错误，验证器函数应使用\u003ccode\u003eereport()\u003c/code\u003e函数。函数的返回值会被忽略。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e注解\u003c/h2\u003e\u003cp\u003e使用\u003ca href=\"/docs/18/sql-droplanguage.html\" title=\"DROP LANGUAGE\" rel=\"nofollow\"\u003e\u003ccode\u003eDROP LANGUAGE\u003c/code\u003e\u003c/a\u003e删除过程语言。\u003c/p\u003e\u003cp\u003e系统目录\u003ccode\u003epg_language\u003c/code\u003e（见\u003ca href=\"/docs/18/catalog-pg-language.html\" rel=\"nofollow\"\u003e第 52.29 节\u003c/a\u003e）记录当前已安装语言的信息。此外，\u003cspan\u003epsql\u003c/span\u003e的\u003ccode\u003e\\dL\u003c/code\u003e命令也会列出已安装的语言。\u003c/p\u003e\u003cp\u003e要用某种过程语言创建函数，用户必须拥有该语言的 \u003ccode\u003eUSAGE\u003c/code\u003e权限。默认情况下，对于受信任的语言，\u003ccode\u003eUSAGE\u003c/code\u003e会授予\u003ccode\u003ePUBLIC\u003c/code\u003e（即所有人）。如果需要，也可以撤销这项授权。\u003c/p\u003e\u003cp\u003e过程语言是各个数据库本地的。不过，可以将某种语言安装到 \u003ccode\u003etemplate1\u003c/code\u003e数据库中，这样它就会在之后创建的所有数据库中自动可用。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e示例\u003c/h2\u003e\u003cp\u003e创建新过程语言的最简步骤如下：\u003c/p\u003e\u003cpre\u003eCREATE FUNCTION plsample_call_handler() RETURNS language_handler\n    AS \u0026#39;$libdir/plsample\u0026#39;\n    LANGUAGE C;\nCREATE LANGUAGE plsample\n    HANDLER plsample_call_handler;\n\u003c/pre\u003e\u003cp\u003e通常这会写在扩展的创建脚本中，而用户会通过下面的命令安装该扩展：\u003c/p\u003e\u003cpre\u003eCREATE EXTENSION plsample;\n\u003c/pre\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e兼容性\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eCREATE LANGUAGE\u003c/code\u003e是一种 \u003cspan\u003ePostgreSQL\u003c/span\u003e扩展。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e另见\u003c/h2\u003e\u003cspan\u003e\u003ca href=\"/wiki/sql/alter-language/?v=18\" title=\"ALTER LANGUAGE\" rel=\"nofollow\"\u003e\u003cspan\u003eALTER LANGUAGE\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/create-function/?v=18\" title=\"CREATE FUNCTION\" rel=\"nofollow\"\u003e\u003cspan\u003eCREATE FUNCTION\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/drop-language/?v=18\" title=\"DROP LANGUAGE\" rel=\"nofollow\"\u003e\u003cspan\u003eDROP LANGUAGE\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/grant/?v=18\" title=\"GRANT\" rel=\"nofollow\"\u003e\u003cspan\u003eGRANT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/revoke/?v=18\" title=\"REVOKE\" rel=\"nofollow\"\u003e\u003cspan\u003eREVOKE\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e\u003c/section\u003e","SourceRevision":"1b5ca64c","ContentHash":"e0d1e17c10a7d5202cdb253d261056ea33bab39b24e1436c1737f457ecc8a619","Payload":{"purpose_zh":"定义一种新的过程语言","sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e在 \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e数据库中注册一种新的过程语言。随后，就可以用这种新语言定义函数和过程。\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e实际上是将该语言名称与负责执行用这种语言编写的函数的处理器函数关联起来。关于语言处理器的更多信息，参见\u003ca href=\"/docs/18/plhandler.html\" title=\"第 57 章 编写过程语言调用处理器\"\u003e第 57 章\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE OR REPLACE LANGUAGE\u003c/code\u003e会创建一种新语言，或者替换现有定义。如果该语言已经存在，其参数会按命令更新；但该语言的所有权和权限设置不会改变，并且任何现有的、用该语言编写的函数都假定仍然有效。\u003c/p\u003e\u003cp\u003e必须拥有\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e超级用户权限，才能注册新语言或更改现有语言的参数。不过，一旦语言创建完成，就可以把它的所有权赋予非超级用户；随后该用户可以删除它、更改其权限、重命名它，或者将其转让给新的所有者。（不过，不要把底层 C 函数的所有权赋予非超级用户；那样会为该用户制造一条权限提升路径。）\u003c/p\u003e\u003cp\u003e不提供任何处理器函数的\u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e形式已经过时。为了向后兼容旧的转储文件，它会被解释为\u003ccode class=\"command\"\u003eCREATE EXTENSION\u003c/code\u003e。如果该语言已被打包为一个同名扩展，这种写法就能工作，而这正是安装过程语言的惯常方式。\u003c/p\u003e","key":"description","title":"描述"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eTRUSTED\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003ccode class=\"literal\"\u003eTRUSTED\u003c/code\u003e指定该语言不会让用户获得其原本无权访问的数据访问能力。如果在注册该语言时省略这个关键字，只有拥有\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e超级用户权限的用户才能使用该语言创建新函数。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003ePROCEDURAL\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e这是一个噪声词。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e新过程语言的名称。该名称不能与数据库中其他语言的名称重复。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eHANDLER\u003c/code\u003e \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e 是一个先前注册的函数名称，它会被调用来执行该过程语言中的函数。过程语言的调用处理器必须使用某种编译型语言（例如 C）编写，并采用版本 1 调用约定。它必须在\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e 中注册为一个不带参数且返回\u003ccode class=\"type\"\u003elanguage_handler\u003c/code\u003e类型的函数。\u003ccode class=\"type\"\u003elanguage_handler\u003c/code\u003e是一种占位符类型，仅用于把该函数标识为调用处理器。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eINLINE\u003c/code\u003e \u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e 是一个先前注册的函数名称，它会被调用来执行该语言中的匿名代码块（\u003ca href=\"/docs/18/sql-do.html\" title=\"DO\"\u003e\u003ccode class=\"command\"\u003eDO\u003c/code\u003e\u003c/a\u003e命令）。如果没有指定\u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e 函数，则该语言不支持匿名代码块。该处理器函数必须接受一个 \u003ccode class=\"type\"\u003einternal\u003c/code\u003e类型的参数，该参数将是 \u003ccode class=\"command\"\u003eDO\u003c/code\u003e命令的内部表示，并且它通常返回 \u003ccode class=\"type\"\u003evoid\u003c/code\u003e。处理器的返回值会被忽略。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eVALIDATOR\u003c/code\u003e \u003cem class=\"replaceable\"\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e 是一个先前注册的函数名称，在创建该语言中的新函数时会调用它来验证该新函数。如果没有指定验证器函数，那么新函数在创建时不会被检查。验证器函数必须接受一个\u003ccode class=\"type\"\u003eoid\u003c/code\u003e类型的参数，它将是待创建函数的 OID，并且它通常返回\u003ccode class=\"type\"\u003evoid\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e验证器函数通常会检查函数体的语法正确性，但它也可以检查函数的其他属性，例如该语言是否支持某些参数类型。要报告错误，验证器函数应使用\u003ccode class=\"function\"\u003eereport()\u003c/code\u003e函数。函数的返回值会被忽略。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"参数"},{"html":"\u003cp\u003e使用\u003ca href=\"/docs/18/sql-droplanguage.html\" title=\"DROP LANGUAGE\"\u003e\u003ccode class=\"command\"\u003eDROP LANGUAGE\u003c/code\u003e\u003c/a\u003e删除过程语言。\u003c/p\u003e\u003cp\u003e系统目录\u003ccode class=\"classname\"\u003epg_language\u003c/code\u003e（见\u003ca href=\"/docs/18/catalog-pg-language.html\" title=\"52.29. pg_language\"\u003e第 52.29 节\u003c/a\u003e）记录当前已安装语言的信息。此外，\u003cspan class=\"application\"\u003epsql\u003c/span\u003e的\u003ccode class=\"command\"\u003e\\dL\u003c/code\u003e命令也会列出已安装的语言。\u003c/p\u003e\u003cp\u003e要用某种过程语言创建函数，用户必须拥有该语言的 \u003ccode class=\"literal\"\u003eUSAGE\u003c/code\u003e权限。默认情况下，对于受信任的语言，\u003ccode class=\"literal\"\u003eUSAGE\u003c/code\u003e会授予\u003ccode class=\"literal\"\u003ePUBLIC\u003c/code\u003e（即所有人）。如果需要，也可以撤销这项授权。\u003c/p\u003e\u003cp\u003e过程语言是各个数据库本地的。不过，可以将某种语言安装到 \u003ccode class=\"literal\"\u003etemplate1\u003c/code\u003e数据库中，这样它就会在之后创建的所有数据库中自动可用。\u003c/p\u003e","key":"notes","title":"注解"},{"html":"\u003cp\u003e创建新过程语言的最简步骤如下：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION plsample_call_handler() RETURNS language_handler\n    AS '$libdir/plsample'\n    LANGUAGE C;\nCREATE LANGUAGE plsample\n    HANDLER plsample_call_handler;\n\u003c/pre\u003e\u003cp\u003e通常这会写在扩展的创建脚本中，而用户会通过下面的命令安装该扩展：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eCREATE EXTENSION plsample;\n\u003c/pre\u003e","key":"examples","title":"示例"},{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eCREATE LANGUAGE\u003c/code\u003e是一种 \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e扩展。\u003c/p\u003e","key":"compatibility","title":"兼容性"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/wiki/sql/alter-language/?v=18\" title=\"ALTER LANGUAGE\"\u003e\u003cspan class=\"refentrytitle\"\u003eALTER LANGUAGE\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/create-function/?v=18\" title=\"CREATE FUNCTION\"\u003e\u003cspan class=\"refentrytitle\"\u003eCREATE FUNCTION\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/drop-language/?v=18\" title=\"DROP LANGUAGE\"\u003e\u003cspan class=\"refentrytitle\"\u003eDROP LANGUAGE\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/grant/?v=18\" title=\"GRANT\"\u003e\u003cspan class=\"refentrytitle\"\u003eGRANT\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/revoke/?v=18\" title=\"REVOKE\"\u003e\u003cspan class=\"refentrytitle\"\u003eREVOKE\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"另见"}],"sections_same_as":"","synopsis_html":"CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/em\u003e\n    HANDLER \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecall_handler\u003c/code\u003e\u003c/em\u003e [ INLINE \u003cem class=\"replaceable\"\u003e\u003ccode\u003einline_handler\u003c/code\u003e\u003c/em\u003e ] [ VALIDATOR \u003cem class=\"replaceable\"\u003e\u003ccode\u003evalfunction\u003c/code\u003e\u003c/em\u003e ]\nCREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/em\u003e","synopsis_text":"CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\nHANDLER call_handler [ INLINE inline_handler ] [ VALIDATOR valfunction ]\nCREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name"}},"RequestedLocale":"zh-Hans","Fallback":false,"Versions":["10","11","12","13","14","15","16","17","18","19","20","6.4","6.5","7.0","7.1","7.2","7.3","7.4","8.0","8.1","8.2","8.3","8.4","9.0","9.1","9.2","9.3","9.4","9.5","9.6"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
