SQL语法
SQL语法概要
ABORT
终止当前事务。
ABORT [WORK | TRANSACTION]
ALTER AGGREGATE
更改聚合函数的定义。
ALTER AGGREGATE <name> ( <type> [ , ... ] ) RENAME TO <new_name>
ALTER AGGREGATE <name> ( <type> [ , ... ] ) OWNER TO <new_owner>
ALTER AGGREGATE <name> ( <type> [ , ... ] ) SET SCHEMA <new_schema>
ALTER CONVERSION
更改转换的定义。
ALTER CONVERSION <name> RENAME TO <newname>
ALTER CONVERSION <name> OWNER TO <newowner>
ALTER DATABASE
更改数据库的属性。
ALTER DATABASE <name> [ WITH CONNECTION LIMIT <connlimit> ]
ALTER DATABASE <name> SET <parameter> { TO | = } { <value> | DEFAULT }
ALTER DATABASE <name> RESET <parameter>
ALTER DATABASE <name> RENAME TO <newname>
ALTER DATABASE <name> OWNER TO <new_owner>
ALTER DOMAIN
更改现有域的定义。
ALTER DOMAIN <name> { SET DEFAULT <expression> | DROP DEFAULT }
ALTER DOMAIN <name> { SET | DROP } NOT NULL
ALTER DOMAIN <name> ADD <domain_constraint>
ALTER DOMAIN <name> DROP CONSTRAINT <constraint_name> [RESTRICT | CASCADE]
ALTER DOMAIN <name> OWNER TO <new_owner>
ALTER DOMAIN <name> SET SCHEMA <new_schema>
ALTER EXTERNAL TABLE
更改外部表的定义。
ALTER EXTERNAL TABLE <name> RENAME [COLUMN] <column> TO <new_column>
ALTER EXTERNAL TABLE <name> RENAME TO <new_name>
ALTER EXTERNAL TABLE <name> SET SCHEMA <new_schema>
ALTER EXTERNAL TABLE <name> <action> [, ... ]
ALTER FUNCTION
更改函数的定义。
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
<action> [, ... ] [RESTRICT]
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
RENAME TO <new_name>
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
OWNER TO <new_owner>
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
SET SCHEMA <new_schema>
ALTER GROUP
更改角色名称或成员关系。
ALTER GROUP <groupname> ADD USER <username> [, ... ]
ALTER GROUP <groupname> DROP USER <username> [, ... ]
ALTER GROUP <groupname> RENAME TO <newname>
ALTER OPERATOR
更改运算符的定义。
ALTER OPERATOR <name> ( {<lefttype> | NONE} , {<righttype> | NONE} )
OWNER TO <newowner>
ALTER ROLE
更改数据库的角色(用户或组)。
ALTER ROLE <name> RENAME TO <newname>
ALTER ROLE <name> SET <config_parameter> {TO | =} {<value> | DEFAULT}
ALTER ROLE <name> RESET <config_parameter>
ALTER ROLE <name> RESOURCE QUEUE {<queue_name> | NONE}
ALTER ROLE <name> [ [WITH] <option> [ ... ] ]
ALTER SCHEMA
更改schema定义。
ALTER SCHEMA <name> RENAME TO <newname>
ALTER SCHEMA <name> OWNER TO <newowner>
ALTER SEQUENCE
更改序列生成器的定义。
ALTER SEQUENCE <name> [INCREMENT [ BY ] <increment>]
[MINVALUE <minvalue> | NO MINVALUE]
[MAXVALUE <maxvalue> | NO MAXVALUE]
[RESTART [ WITH ] <start>]
[CACHE <cache>] [[ NO ] CYCLE]
[OWNED BY {<table.column> | NONE}]
ALTER SEQUENCE <name> RENAME TO <new_name>
ALTER SEQUENCE <name> SET SCHEMA <new_schema>
ALTER TABLE
更改表的定义。
ALTER TABLE [ONLY] <name> RENAME [COLUMN] <column> TO <new_column>
ALTER TABLE <name> RENAME TO <new_name>
ALTER TABLE <name> SET SCHEMA <new_schema>
ALTER TABLE [ONLY] <name> SET
DISTRIBUTED BY (<column>, [ ... ] )
| DISTRIBUTED RANDOMLY
| WITH (REORGANIZE=true|false)
ALTER TABLE [ONLY] <name> <action> [, ... ]
ALTER TABLE <name>
[ ALTER PARTITION { <partition_name> | FOR (RANK(<number>))
| FOR (<value>) } partition_action [...] ]
ALTER TYPE
更改数据类型的定义。
ALTER TYPE <name>
OWNER TO <new_owner> | SET SCHEMA <new_schema>
ALTER USER
更改数据库用户(角色)的定义。
ALTER USER <name> RENAME TO <newname>
ALTER USER <name> SET <config_parameter> {TO | =} {<value> | DEFAULT}
ALTER USER <name> RESET <config_parameter>
ALTER USER <name> [ [WITH] <option> [ ... ] ]
ALTER VIEW
更改视图的定义。
ALTER VIEW <name> RENAME TO <newname>
ANALYZE
收集有关数据库的统计信息。
ANALYZE [VERBOSE] [ROOTPARTITION [ALL] ]
[<table> [ (<column> [, ...] ) ]]
BEGIN
启动事务块。
BEGIN [WORK | TRANSACTION] [<transaction_mode>]
[READ ONLY | READ WRITE]
COMMENT
定义或更改对象的注释。
COMMENT ON
{ TABLE <object_name> |
COLUMN <table_name.column_name> |
AGGREGATE <agg_name> (<agg_type> [, ...]) |
CAST (<sourcetype> AS <targettype>) |
CONSTRAINT <constraint_name> ON <table_name> |
CONVERSION <object_name> |
DATABASE <object_name> |
DOMAIN <object_name> |
FUNCTION <func_name> ([[<argmode>] [<argname>] <argtype> [, ...]]) |
INDEX <object_name> |
LARGE OBJECT <large_object_oid> |
OPERATOR <op> (<leftoperand_type>, <rightoperand_type>) |
OPERATOR CLASS <object_name> USING <index_method> |
[PROCEDURAL] LANGUAGE <object_name> |
RESOURCE QUEUE <object_name> |
ROLE <object_name> |
RULE <rule_name> ON <table_name> |
SCHEMA <object_name> |
SEQUENCE <object_name> |
TABLESPACE <object_name> |
TRIGGER <trigger_name> ON <table_name> |
TYPE <object_name> |
VIEW <object_name> }
IS '<text>'
COMMIT
提交当前事务。
COMMIT [WORK | TRANSACTION]
CREATE AGGREGATE
定义新的聚合函数。
CREATE [ORDERED] AGGREGATE <name> (<input_data_type> [ , ... ])
( SFUNC = <sfunc>,
STYPE = <state_data_type>
[, PREFUNC = <prefunc>]
[, FINALFUNC = <ffunc>]
[, INITCOND = <initial_condition>]
[, SORTOP = <sort_operator>] )
CREATE CAST
定义新的数据类型转换。
CREATE CAST (<sourcetype> AS <targettype>)
WITH FUNCTION <funcname> (<argtypes>)
[AS ASSIGNMENT | AS IMPLICIT]
CREATE CAST (<sourcetype> AS <targettype>) WITHOUT FUNCTION
[AS ASSIGNMENT | AS IMPLICIT]
CREATE CONVERSION
定义新的编码转换。
CREATE [DEFAULT] CONVERSION <name> FOR <source_encoding> TO
<dest_encoding> FROM <funcname>
CREATE DATABASE
创建新的数据库。
CREATE DATABASE name [ [WITH] [OWNER [=] <dbowner>]
[TEMPLATE [=] <template>]
[ENCODING [=] <encoding>]
[CONNECTION LIMIT [=] connlimit ] ]
CREATE DOMAIN
定义新的域。
CREATE DOMAIN <name> [AS] <data_type> [DEFAULT <expression>]
[CONSTRAINT <constraint_name>
| NOT NULL | NULL
| CHECK (<expression>) [...]]
CREATE EXTERNAL TABLE
定义新的外部表。
CREATE [ { READABLE | WRITABLE } ] EXTERNAL [TEMPORARY | TEMP] TABLE <table_name>
( column_name data_type [, ...] | LIKE other_table )
LOCATION ('s3://<uri>')
FORMAT 'TEXT'
[( [HEADER]
[DELIMITER [AS] 'delimiter' | 'OFF']
[NULL [AS] 'null string']
[ESCAPE [AS] 'escape' | 'OFF']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[FILL MISSING FIELDS] )]
| 'CSV'
[( [HEADER]
[QUOTE [AS] 'quote']
[DELIMITER [AS] 'delimiter']
[NULL [AS] 'null string']
[FORCE NOT NULL column [, ...]]
[ESCAPE [AS] 'escape']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[FILL MISSING FIELDS] )]
| 'ORC'
| 'CUSTOM' (Formatter=<formatter specifications>)
[ OPTIONS (INTEGRATION '<integration_name>') ]
[ ENCODING 'encoding' ]
[ [LOG ERRORS] SEGMENT REJECT LIMIT count
[ROWS | PERCENT] ];
CREATE FUNCTION
定义新函数。
CREATE [OR REPLACE] FUNCTION <name>
( [ [<argmode>] [<argname>] <argtype> [ { DEFAULT | = } <defexpr> ] [, ...] ] )
[ RETURNS { [ SETOF ] rettype
| TABLE ([{ argname argtype | LIKE other table }
[, ...]])
} ]
{ LANGUAGE <langname>
| IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| NO SQL | CONTAINS SQL | READS SQL DATA | MODIFIES SQL
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
| COST <execution_cost>
| SET <configuration_parameter> { TO <value> | = <value> | FROM CURRENT }
| AS '<definition>'
| AS '<obj_file>', '<link_symbol>' } ...
[ WITH ({ DESCRIBE = describe_function
} [, ...] ) ]
CREATE GROUP
定义新的数据库角色。
CREATE GROUP <name> [[WITH] <option> [ ... ]]
CREATE OPERATOR
定义新的运算符。
CREATE OPERATOR <name> (
PROCEDURE = <funcname>
[, LEFTARG = <lefttype>] [, RIGHTARG = <righttype>]
[, COMMUTATOR = <com_op>] [, NEGATOR = <neg_op>]
[, RESTRICT = <res_proc>] [, JOIN = <join_proc>]
[, HASHES] [, MERGES]
[, SORT1 = <left_sort_op>] [, SORT2 = <right_sort_op>]
[, LTCMP = <less_than_op>] [, GTCMP = <greater_than_op>] )
CREATE ROLE
定义新的数据库角色(用户或组)。
CREATE ROLE <name> [[WITH] <option> [ ... ]]
CREATE RULE
定义新的重写规则。
CREATE [OR REPLACE] RULE <name> AS ON <event>
TO <table_name> [WHERE <condition>]
DO [ALSO | INSTEAD] { NOTHING | <command> | (<command>; <command>
...) }
CREATE SCHEMA
定义新的schema。
CREATE SCHEMA <schema_name> [AUTHORIZATION <username>]
[<schema_element> [ ... ]]
CREATE SCHEMA AUTHORIZATION <rolename> [<schema_element> [ ... ]]
CREATE SEQUENCE
定义新的序列生成器。
CREATE [TEMPORARY | TEMP] SEQUENCE <name>
[INCREMENT [BY] <value>]
[MINVALUE <minvalue> | NO MINVALUE]
[MAXVALUE <maxvalue> | NO MAXVALUE]
[START [ WITH ] <start>]
[CACHE <cache>]
[[NO] CYCLE]
[OWNED BY { <table>.<column> | NONE }]
CREATE TABLE
定义新表。
CREATE [[GLOBAL | LOCAL] {TEMPORARY | TEMP}] TABLE table_name (
[ { column_name data_type [ DEFAULT default_expr ]
[column_constraint [ ... ]
[ ENCODING ( storage_directive [,...] ) ]
]
| table_constraint
| LIKE other_table [{INCLUDING | EXCLUDING}
{DEFAULTS | CONSTRAINTS}] ...}
)
[ WITH ( storage_parameter=value [, ... ] )
[ ON COMMIT {PRESERVE ROWS | DELETE ROWS | DROP} ]
[ DISTRIBUTED BY (column, [ ... ] ) | DISTRIBUTED RANDOMLY ]
[ PARTITION BY partition_type (column)
[ SUBPARTITION BY partition_type (column) ]
[ SUBPARTITION TEMPLATE ( template_spec ) ]
[...]
( partition_spec )
| [ SUBPARTITION BY partition_type (column) ]
[...]
( partition_spec
[ ( subpartition_spec
[(...)]
) ]
)
CREATE TABLE AS
从查询结果中定义新表。
CREATE [ [GLOBAL | LOCAL] {TEMPORARY | TEMP} ] TABLE table_name
[(column_name [, ...] )]
[ WITH ( storage_parameter=value [, ... ] ) ]
[ON COMMIT {PRESERVE ROWS | DELETE ROWS | DROP}]
AS query
[DISTRIBUTED BY (column, [ ... ] ) | DISTRIBUTED RANDOMLY]
CREATE TYPE
描述新的数据类型。
CREATE TYPE name AS ( <attribute_name> <data_type> [, ... ] )
CREATE TYPE <name> AS ENUM ( [ '<label>' [, ... ] ] )
CREATE TYPE <name> (
INPUT = <input_function>,
OUTPUT = <output_function>
[, RECEIVE = <receive_function>]
[, SEND = <send_function>]
[, TYPMOD_IN = <type_modifier_input_function> ]
[, TYPMOD_OUT = <type_modifier_output_function> ]
[, INTERNALLENGTH = {<internallength> | VARIABLE}]
[, PASSEDBYVALUE]
[, ALIGNMENT = <alignment>]
[, STORAGE = <storage>]
[, DEFAULT = <default>]
[, ELEMENT = <element>]
[, DELIMITER = <delimiter>] )
CREATE USER
定义新的默认带有 LOGIN 权限的数据库角色。
CREATE USER <name> [[WITH] <option> [ ... ]]
CREATE VIEW
定义新视图。
CREATE [OR REPLACE] [TEMP | TEMPORARY] VIEW <name>
[ ( <column_name> [, ...] ) ]
AS <query>
DEALLOCATE
释放准备好的语句。
DEALLOCATE [PREPARE] <name>
DELETE
从表中删除行。
DELETE FROM [ONLY] <table> [[AS] <alias>]
[USING <usinglist>]
[WHERE <condition> | WHERE CURRENT OF <cursor_name> ]
DISCARD
丢弃会话状态。
DISCARD { ALL | PLANS | TEMPORARY | TEMP }
DO
将匿名代码块作为瞬态匿名函数执行。
DO [ LANGUAGE <lang_name> ] <code>
DROP AGGREGATE
删除聚合函数。
DROP AGGREGATE [IF EXISTS] <name> ( <type> [, ...] ) [CASCADE | RESTRICT]
DROP CAST
删除数据类型转换。
DROP CAST [IF EXISTS] (<sourcetype> AS <targettype>) [CASCADE | RESTRICT]
DROP CONVERSION
删除编码转换。
DROP CONVERSION [IF EXISTS] <name> [CASCADE | RESTRICT]
DROP DATABASE
删除数据库。
DROP DATABASE [IF EXISTS] <name>
DROP DOMAIN
删除域。
DROP DOMAIN [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
DROP EXTERNAL TABLE
删除外部表定义。
DROP EXTERNAL [WEB] TABLE [IF EXISTS] <name> [CASCADE | RESTRICT]
DROP FUNCTION
删除函数。
DROP FUNCTION [IF EXISTS] name ( [ [argmode] [argname] argtype
[, ...] ] ) [CASCADE | RESTRICT]
DROP GROUP
删除数据库角色。
DROP GROUP [IF EXISTS] <name> [, ...]
DROP OPERATOR
删除运算符。
DROP OPERATOR [IF EXISTS] <name> ( {<lefttype> | NONE} ,
{<righttype> | NONE} ) [CASCADE | RESTRICT]
DROP OWNED
删除数据库角色拥有的数据库对象。
DROP OWNED BY <name> [, ...] [CASCADE | RESTRICT]
DROP ROLE
删除数据库角色。
DROP ROLE [IF EXISTS] <name> [, ...]
DROP RULE
删除重写规则。
DROP RULE [IF EXISTS] <name> ON <relation> [CASCADE | RESTRICT]
DROP SCHEMA
删除schema。
DROP SCHEMA [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
DROP SEQUENCE
删除序列。
DROP SEQUENCE [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
DROP TABLE
删除表。
DROP TABLE [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
DROP TYPE
删除数据类型。
DROP TYPE [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
DROP USER
删除数据库角色。
DROP USER [IF EXISTS] <name> [, ...]
DROP VIEW
删除视图。
DROP VIEW [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
END
提交当前事务。
END [WORK | TRANSACTION]
EXECUTE
执行一个已经准备好的SQL语句。
EXECUTE <name> [ (<parameter> [, ...] ) ]
EXPLAIN
展示语句的查询计划。
EXPLAIN [ANALYZE] [VERBOSE] <statement>
GRANT
定义一个访问权限
GRANT { {SELECT | INSERT | UPDATE | DELETE | REFERENCES |
TRIGGER | TRUNCATE } [,...] | ALL [PRIVILEGES] }
ON [TABLE] <tablename> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { {USAGE | SELECT | UPDATE} [,...] | ALL [PRIVILEGES] }
ON SEQUENCE <sequencename> [, ...]
TO { <rolename> | PUBLIC } [, ...] [WITH GRANT OPTION]
GRANT { {CREATE | CONNECT | TEMPORARY | TEMP} [,...] | ALL
[PRIVILEGES] }
ON DATABASE <dbname> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { EXECUTE | ALL [PRIVILEGES] }
ON FUNCTION <funcname> ( [ [<argmode>] [<argname>] <argtype> [, ...]
] ) [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { USAGE | ALL [PRIVILEGES] }
ON LANGUAGE <langname> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { {CREATE | USAGE} [,...] | ALL [PRIVILEGES] }
ON SCHEMA <schemaname> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { CREATE | ALL [PRIVILEGES] }
ON TABLESPACE <tablespacename> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT <parent_role> [, ...]
TO <member_role> [, ...] [WITH ADMIN OPTION]
GRANT { SELECT | INSERT | ALL [PRIVILEGES] }
ON PROTOCOL <protocolname>
TO <username>
INSERT
在表中创建新的行
INSERT INTO <table> [( <column> [, ...] )]
{DEFAULT VALUES | VALUES ( {<expression> | DEFAULT} [, ...] )
[, ...] | <query>}
PREPARE
准备一个执行的语句
PREPARE <name> [ (<datatype> [, ...] ) ] AS <statement>
REASSIGN
改变数据库角色所拥有的数据库对象的所有权。
REASSIGN OWNED BY <old_role> [, ...] TO <new_role>
RESET
恢复系统配置参数的值为默认值。
RESET <configuration_parameter>
RESET ALL
REVOKE
撤销访问权限
REVOKE [GRANT OPTION FOR] { {SELECT | INSERT | UPDATE | DELETE
| REFERENCES | TRIGGER | TRUNCATE } [,...] | ALL [PRIVILEGES] }
ON [TABLE] <tablename> [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] { {USAGE | SELECT | UPDATE} [,...]
| ALL [PRIVILEGES] }
ON SEQUENCE <sequencename> [, ...]
FROM { <rolename> | PUBLIC } [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] { {CREATE | CONNECT
| TEMPORARY | TEMP} [,...] | ALL [PRIVILEGES] }
ON DATABASE <dbname> [, ...]
FROM {rolename | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] {EXECUTE | ALL [PRIVILEGES]}
ON FUNCTION <funcname> ( [[<argmode>] [<argname>] <argtype>
[, ...]] ) [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] {USAGE | ALL [PRIVILEGES]}
ON LANGUAGE <langname> [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[ CASCADE | RESTRICT ]
REVOKE [GRANT OPTION FOR] { {CREATE | USAGE} [,...]
| ALL [PRIVILEGES] }
ON SCHEMA <schemaname> [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] { CREATE | ALL [PRIVILEGES] }
ON TABLESPACE <tablespacename> [, ...]
FROM { <rolename> | PUBLIC } [, ...]
[CASCADE | RESTRICT]
REVOKE [ADMIN OPTION FOR] <parent_role> [, ...]
FROM <member_role> [, ...]
[CASCADE | RESTRICT]
ROLLBACK
中止当前事务
ROLLBACK [WORK | TRANSACTION]
SELECT
从表或者视图中检索行。
[ WITH [ RECURSIVE1 ] <with_query> [, ...] ]
SELECT [ALL | DISTINCT [ON (<expression> [, ...])]]
* | <expression >[[AS] <output_name>] [, ...]
[FROM <from_item> [, ...]]
[WHERE <condition>]
[GROUP BY <grouping_element> [, ...]]
[HAVING <condition> [, ...]]
[WINDOW <window_name> AS (<window_specification>)]
[{UNION | INTERSECT | EXCEPT} [ALL] <select>]
[ORDER BY <expression> [ASC | DESC | USING <operator>] [NULLS {FIRST | LAST}] [, ...]]
[LIMIT {<count> | ALL}]
[OFFSET <start>]
SELECT INTO
从查询结果中定义一个新的表。
[ WITH <with_query> [, ...] ]
SELECT [ALL | DISTINCT [ON ( <expression> [, ...] )]]
* | <expression> [AS <output_name>] [, ...]
INTO [TEMPORARY | TEMP] [TABLE] <new_table>
[FROM <from_item> [, ...]]
[WHERE <condition>]
[GROUP BY <expression> [, ...]]
[HAVING <condition> [, ...]]
[{UNION | INTERSECT | EXCEPT} [ALL] <select>]
[ORDER BY <expression> [ASC | DESC | USING <operator>] [NULLS {FIRST | LAST}] [, ...]]
[LIMIT {<count> | ALL}]
[OFFSET <start>]
[...]]
SET
改变Hashdata数据库配置参数的值。
SET [SESSION | LOCAL] <configuration_parameter> {TO | =} <value> |
'<value>' | DEFAULT}
SET [SESSION | LOCAL] TIME ZONE {<timezone> | LOCAL | DEFAULT}
SET ROLE
设置当前会话当前角色的标识符。
SET [SESSION | LOCAL] ROLE <rolename>
SET [SESSION | LOCAL] ROLE NONE
RESET ROLE
SET SESSION AUTHORIZATION
设置会话角色标识符和当前会话当前角色的标识符。
SET [SESSION | LOCAL] SESSION AUTHORIZATION <rolename>
SET [SESSION | LOCAL] SESSION AUTHORIZATION DEFAULT
RESET SESSION AUTHORIZATION
SHOW
显示当前系统配置参数的值。
SHOW <configuration_parameter>
SHOW ALL
START TRANSACTION
开始一个事务块。
START TRANSACTION
TRUNCATE
清空表的所有行。
TRUNCATE [TABLE] <name> [, ...] [CASCADE | RESTRICT]
UPDATE
更新表的行。
UPDATE [ONLY] <table> [[AS] <alias>]
SET {<column> = {<expression> | DEFAULT} |
(<column> [, ...]) = ({<expression> | DEFAULT} [, ...])} [, ...]
[FROM <fromlist>]
[WHERE <condition >| WHERE CURRENT OF <cursor_name> ]
VALUES
计算一组行。
VALUES ( <expression> [, ...] ) [, ...]
[ORDER BY <sort_expression> [ASC | DESC | USING <operator>] [, ...]]
[LIMIT {<count> | ALL}] [OFFSET <start>]
ABORT
终止当前事务。
概要
ABORT [WORK | TRANSACTION]
描述
ABORT命令用于回滚当前的事务,并丢弃该事务的所有更新。这个命令在行为上与标准SQL命令ROLLBACK相同,当前ABORT命令只是出于历史原因而存在。
参数
WORK和TRANSACTION为可选关键字,它们没有任何影响。
注解
使用 COMMIT 成功终止一个事务。
不在事务内部时,发出 ABORT 命令并没有什么害处,但会引发警告消息。
兼容性
此命令是出于历史原因存在的Hashdata数据库扩展。 ROLLBACK是等效的标准SQL命令。
另见
BEGIN, COMMIT, ROLLBACK
ALTER AGGREGATE
更改聚合函数的定义。
概要
ALTER AGGREGATE <name> ( <type> [ , ... ] ) RENAME TO <new_name>
ALTER AGGREGATE <name> ( <type> [ , ... ] ) OWNER TO <new_owner>
ALTER AGGREGATE <name> ( <type> [ , ... ] ) SET SCHEMA <new_schema>
描述
用户必须拥有聚合函数才能使用ALTER AGGREGATE。要更改聚合函数的schema,还必须对新schema具有CREATE特权。要更改所有者,用户还必须是新所有者的直接或间接成员,并且该角色必须对聚合函数的schema具有 CREATE特权。
参数
- name
现有聚合函数的名称(可以是限定schema)
- type
聚合函数能运行的输入数据类型。要引用零参数聚合函数,写入*代替输入数据类型的列表。
- new_name
聚合函数的新名称。
- new_owner
聚合函数新的所有者。
- new_schema
聚合函数的新schema。
示例
要将 integer 类型的聚合函数 myavg 重命名为 my_average:
ALTER AGGREGATE myavg(integer) RENAME TO my_average;
更改 integer类型的聚合函数 myavg 的所有者为joe:
ALTER AGGREGATE myavg(integer) OWNER TO joe;
将integer 类型的聚合函数 myavg 移动到 schema myschema中:
ALTER AGGREGATE myavg(integer) SET SCHEMA myschema;
兼容性
在SQL标准中没有 ALTER AGGREGATE语句。
另见
CREATE AGGREGATE, DROP AGGREGATE
ALTER CONVERSION
更改转换的定义。
概要
ALTER CONVERSION <name> RENAME TO <newname>
ALTER CONVERSION <name> OWNER TO <newowner>
描述
用户必须拥有使用ALTER CONVERSION的转换权限。要更改所有者,用户还必须是新所有者的直接或间接成员,并且该角色必须对转换的schema具有 CREATE 权限。
参数
- name
现有转换的名称(可选schema限定)。
- newname
新的转换名称。
- newowner
转换的新所有者。
示例
要把转换 iso_8859_1_to_utf8 重命名为 latin1_to_unicode:
ALTER CONVERSION iso_8859_1_to_utf8 RENAME TO
latin1_to_unicode;
更改转换iso_8859_1_to_utf8 的所有者为 joe:
ALTER CONVERSION iso_8859_1_to_utf8 OWNER TO joe;
兼容性
在SQL标准中没有ALTER CONVERSION语句。
另见
CREATE CONVERSION, DROP CONVERSION
ALTER DATABASE
更改数据库的属性。
概要
ALTER DATABASE <name> [ WITH CONNECTION LIMIT <connlimit> ]
ALTER DATABASE <name> SET <parameter> { TO | = } { <value> | DEFAULT }
ALTER DATABASE <name> RESET <parameter>
ALTER DATABASE <name> RENAME TO <newname>
ALTER DATABASE <name> OWNER TO <new_owner>
描述
第一种命令形式更改数据库的允许连接限制。只有数据库所有者或超级用户可以更改此设置。
第二种和第三种命令形式更改了Hashdata数据库的配置参数的会话默认值。在该数据库中启动新会话时,指定的值将成为会话默认值。数据库特定的默认值会覆盖服务器配置文件(postgresql.conf)中的任何设置。只有数据库所有者或超级用户可以更改数据库的会话默认值。某些参数不能以这种方式设置,或只能由超级用户设置。
第四种命令形式更改数据库的名称。只有数据库所有者或超级用户可以重命名数据库。非超级用户也必须具有 CREATEDB 特权。
第五种命令形式更改数据库的所有者。要更改所有者,用户必须是数据库的所有者,并且也是新所有者的直接或间接成员,并且必须具有 CREATEDB 特权。(请注意,超级用户自动拥有所有这些权限。)
参数
- name
被更改的数据库的名称。
- connlimit
可能的最大并发连接数。缺省值-1表示没有限制。
- parameter value
将指定配置参数的数据库的会话默认值设置为给定值。如果值是 DEFAULT 或者 RESET,则删除数据库特定的设置,因此系统范围的默认设置将在新会话中继承。 使用RESET ALL 清除所有特定于数据库的设置。
- newname
数据库的新名称
- new_owner
数据库的新所有者
注解
也可以为特定角色(用户)而不是数据库设置配置参数会话默认值。如果存在冲突,角色特定的设置将覆盖数据库特定的设置。
示例
为mydatabase数据库设置默认schema搜索路径:
ALTER DATABASE mydatabase SET search_path TO myschema,
public, pg_catalog;
兼容性
ALTER DATABASE语句是Hashdata数据库的扩展
另见
CREATE DATABASE, DROP DATABASE, SET
ALTER DOMAIN
更改现有域的定义。
概要
ALTER DOMAIN <name> { SET DEFAULT <expression> | DROP DEFAULT }
ALTER DOMAIN <name> { SET | DROP } NOT NULL
ALTER DOMAIN <name> ADD <domain_constraint>
ALTER DOMAIN <name> DROP CONSTRAINT <constraint_name> [RESTRICT | CASCADE]
ALTER DOMAIN <name> OWNER TO <new_owner>
ALTER DOMAIN <name> SET SCHEMA <new_schema>
描述
ALTER DOMAIN 更改一个现有域的定义。 有几种子形式:
- SET/DROP DEFAULT — 此形式用于设置或删除域的默认值。请注意,默认值仅适用于后续的INSERT 命令。 它们不影响使用域的表中已经存在的行。
- SET/DROP NOT NULL — 此形式会标记域是否允许NULL 值。
- ADD domain_constraint — 此形式使用和CREATE DOMAIN相同的语法为域增加一个新的约束。如果所有使用域的列满足新的约束,则添加成功。
- DROP CONSTRAINT — 此形式删除域的约束。
- OWNER — 此形式将域的所有者更改为指定的用户。
- SET SCHEMA — 此形式更改域的schema。与域相关联的任何约束也被移动到新的schema中。
用户必须是域的所有者才能执行 ALTER DOMAIN。要更改域的schema,用户还必须对新schema具有 CREATE 特权。要更改所有者,用户还必须是新所有者的直接或间接成员,并且该角色必须对该域的schema具有 CREATE 特权。
参数
- name
要更改的现有域的名称(可选schema限定)。
- domain_constraint
域约束。
- constraint_name
要删除的现有约束的名称。
- CASCADE
自动删除依赖于约束的对象。
- RESTRICT
如果有任何依赖对象,拒绝删除约束。这是默认行为。
- new_owner
域的新所有者的用户名
- new_schema
域的新schema。
示例
添加 NOT NULL 约束:
ALTER DOMAIN zipcode SET NOT NULL;
删除NOT NULL 约束:
ALTER DOMAIN zipcode DROP NOT NULL;
向域添加检查约束:
ALTER DOMAIN zipcode ADD CONSTRAINT zipchk CHECK
(char_length(VALUE) = 5);
从域中删除检查约束:
ALTER DOMAIN zipcode DROP CONSTRAINT zipchk;
将域移动到不同的schema:
ALTER DOMAIN zipcode SET SCHEMA customers;
兼容性
ALTER DOMAIN 符合SQL标准,除了OWNER 和 SET SCHEMA 变型, 它们是Hashdata数据库扩展。
另见
CREATE DOMAIN, DROP DOMAIN
ALTER EXTERNAL TABLE
更改外部表的定义。
概要
ALTER EXTERNAL TABLE <name> RENAME [COLUMN] <column> TO <new_column>
ALTER EXTERNAL TABLE <name> RENAME TO <new_name>
ALTER EXTERNAL TABLE <name> SET SCHEMA <new_schema>
ALTER EXTERNAL TABLE <name> <action> [, ... ]
其中action是下列之一:
ADD [COLUMN] <new_column> <type>
DROP [COLUMN] <column>
ALTER [COLUMN] <column> TYPE <type> [USING <expression>]
OWNER TO <new_owner>
描述
ALTER EXTERNAL TABLE 更改一个现有外部表的定义。有几种子形式:
- ADD COLUMN — 向外部表定义添加一个新列。
- DROP COLUMN — 从外部表定义中删除一列。请注意,如果用户删除可读的外部表列,它只会更改Hashdata数据库中的表定义。外部数据文件不会更改。
- ALTER COLUMN TYPE — 更改表列的数据类型。 如果存在从旧列数据类型到新数据类型的隐式或赋值强制转换,则可选。如果没有隐式或赋值强制转换,则需要该子句。
- OWNER — 将外部表的所有者更改为指定的用户。
- RENAME — 更改外部表的名称或表中单个列的名称。对外部数据没有影响。
- SET SCHEMA — 将外部表移动到另一个schema。
用户必须是外部表的所有者才能执行ALTER EXTERNAL TABLE。要更改外部表的schema,用户还必须对新schema具有 CREATE 权限。要更改所有者,用户还必须是新所有者的直接或间接成员,该角色必须对外部表的schema具有CREATE 特权。超级用户自动拥有这些权限。
在此版本中,ALTER EXTERNAL TABLE 不能修改外部表类型,数据格式或外部数据的位置。 要修改此信息,用户必须删除并重新创建外部表定义。
参数
- name
要修改的现有外部表定义的名称(可以是schema限定)。
- column
新列或现有列的名称。
- new_column
现有列的新名称。
- new_name
外部表的新名称。
- type
新列的数据类型或现有列的新数据类型。
- new_owner
外部表的新所有者的角色名称。
- new_schema
被移动到的schema的名称。
示例
向外部表定义添加新列:
ALTER EXTERNAL TABLE ext_expenses ADD COLUMN manager text;
更改外部表的名称:
ALTER EXTERNAL TABLE ext_data RENAME TO ext_sales_data;
更改外部表的所有者:
ALTER EXTERNAL TABLE ext_data OWNER TO jojo;
更改外部表的schema:
ALTER EXTERNAL TABLE ext_leads SET SCHEMA marketing;
兼容性
ALTER EXTERNAL TABLE 是 Hashdata数据库扩展。 SQL 标准或常规 PostgreSQL中没有ALTER EXTERNAL TABLE语句。
另见
CREATE EXTERNAL TABLE, DROP EXTERNAL TABLE
ALTER FUNCTION
更改函数的定义。
概要
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
<action> [, ... ] [RESTRICT]
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
RENAME TO <new_name>
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
OWNER TO <new_owner>
ALTER FUNCTION <name> ( [ [<argmode>] [<argname>] <argtype> [, ...] ] )
SET SCHEMA <new_schema>
其中 action 是下列之一:
{CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT}
{IMMUTABLE | STABLE | VOLATILE}
{[EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER}
COST <execution_cost>
SET <configuration_parameter> { TO | = } { <value> | DEFAULT }
SET <configuration_parameter> FROM CURRENT
RESET <configuration_parameter>
RESET ALL
描述
用户必须是该函数的所有者才能执行 ALTER FUNCTION。要更改函数的schema,用户还必须对新schema具有 CREATE 特权。要更改所有者,用户还必须是新所有者的直接或间接成员,并且该角色必须对该函数的schema具有 CREATE 特权。
参数
- name
现有函数的名称(可选shema限定)。
- argmode
参数的schema: IN, OUT, INOUT, or VARIADIC。如果省略,默认值为 IN。请注意 ALTER FUNCTION 实际上并不关注OUT 参数,因为只需要通过输入参数来确定函数的身份。 因此列出 IN, INOUT, 和 VARIADIC 参数就可以了。
- argname
参数的名称。请注意,ALTER FUNCTION 实际上并不关心参数名称,因为只需要通过参数数据类型来确定函数的身份。
- argtype
函数参数的数据类型(可以是shema限定)。
- new_name
函数的新名称。
- new_owner
函数新的所有者。请注意,如果函数被标记为 SECURITY DEFINER, 它将以新所有者的身份运行。
- new_schema
该函数的新schema。
- CALLED ON NULL INPUT
RETURNS NULL ON NULL INPUT
STRICTCALLED ON NULL INPUT 在某些或者全部参数为空值时可以被调用。 RETURNS NULL ON NULL INPUT 和 STRICT 如果某个参数为空,则不会调用该函数; 而是自动假定为空结果。
- IMMUTABLE
STABLE
VOLATILE将函数的波动性改为指定的设置。
- [ EXTERNAL ] SECURITY INVOKER
[ EXTERNAL ] SECURITY DEFINER是否将该函数标记为安全定义器。 为了保持SQL的一致性,可以忽略关键词EXTERNAL。
- COST execution_cost
函数的预估执行代价。
- configuration_parameter
value当该函数被调用时,用于配置参数的值。如果 value 的值是 DEFAULT 或者 RESET, 则删除函数的本地设置,并且该函数会使用环境中存在的值执行。 使用 RESET ALL 可以清除所有函数本地的设置。 SET FROM CURRENT 将运行ALTER FUNCTION时的参数值保存为输入函数时应用的值。
- RESTRICT
为了保持SQL的一致性,可以忽略关键词RESTRICT。
示例
将 integer类型的函数sqrt 重命名为 square_root:
ALTER FUNCTION sqrt(integer) RENAME TO square_root;
更改integer 类型的 sqrt 函数的所有者为 joe:
ALTER FUNCTION sqrt(integer) OWNER TO joe;
更改integer 类型的函数 sqrt 的 schema 为math:
ALTER FUNCTION sqrt(integer) SET SCHEMA math;
调整一个函数的自动搜索路径:
ALTER FUNCTION check_password(text) RESET search_path;
兼容性
ALTER FUNCTION语句部分兼容 SQL 标准中的 ALTER FUNCTION 语句。SQL标准允许修改一个函数的更多属性,但是不提供重命名函数、标记函数为安全定义器、为函数附加配置参数值或者更改函数的拥有者、schema或者稳定性等功能。 SQL标准还需要 RESTRICT 关键字, 它在Hashdata数据库中是可选的。
另见
CREATE FUNCTION, DROP FUNCTION
ALTER GROUP
更改角色名称或成员关系。
概要
ALTER GROUP <groupname> ADD USER <username> [, ... ]
ALTER GROUP <groupname> DROP USER <username> [, ... ]
ALTER GROUP <groupname> RENAME TO <newname>
描述
ALTER GROUP 是一个被废弃的命令,不过为了向后兼容还是保留。 GROUP(和USER)已被ROLE的概念取代。
参数
- groupname
要修改的组(角色)的名称
- username
要添加或删除的用户(角色)。用户(角色)必须已经存在。
- newname
组(角色)的新名称。
示例
将用户添加到组中:
ALTER GROUP staff ADD USER karl, john;
从组中删除用户:
ALTER GROUP workers DROP USER beth;
兼容性
在SQL标准中没有 ALTER GROUP 语句。
另见
ALTER ROLE, GRANT, REVOKE
ALTER OPERATOR
更改运算符的定义。
概要
ALTER OPERATOR <name> ( {<lefttype> | NONE} , {<righttype> | NONE} )
OWNER TO <newowner>
描述
ALTER OPERATOR 用于更改运算符的定义。 唯一可用的功能是更改运算符的所有者。
用户必须是运算符的所有者才能使用 ALTER OPERATOR。要更改所有者,用户还必须是新所有者的直接或间接的成员,并且该角色必须具有该运算符schema上的 CREATE 特权。
参数
- name
现有运算符的名称(可包括schema信息)
- lefttype
运算符左操作数的数据类型; 如果没有左操作数则标记为 NONE。
- righttype
运算符右操作数的数据类型;如果没有右操作数则标记为 NONE。
- newowner
运算符新的所有者。
示例
更改text 类型的自定义运算符 a @@ b的所有者:
ALTER OPERATOR @@ (text, text) OWNER TO joe;
兼容性
在 SQL 标准中没有 ALTEROPERATOR 语句
另见
CREATE OPERATOR, DROP OPERATOR
ALTER ROLE
更改数据库的角色(用户或组)。
概要
ALTER ROLE <name> RENAME TO <newname>
ALTER ROLE <name> SET <config_parameter> {TO | =} {<value> | DEFAULT}
ALTER ROLE <name> RESET <config_parameter>
ALTER ROLE <name> RESOURCE QUEUE {<queue_name> | NONE}
ALTER ROLE <name> [ [WITH] <option> [ ... ] ]
其中option可以是:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEEXTTABLE | NOCREATEEXTTABLE
[ ( <attribute>='<value>'[, ...] ) ]
where <attributes> and <value> are:
type='readable'|'writable'
protocol='gpfdist'|'http'
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| CONNECTION LIMIT <connlimit>
| [ENCRYPTED | UNENCRYPTED] PASSWORD '<password>'
| VALID UNTIL '<timestamp>'
| [ DENY <deny_point> ]
| [ DENY BETWEEN <deny_point> AND <deny_point>]
| [ DROP DENY FOR <deny_point> ]
描述
ALTER ROLE 更改Hashdata数据库角色的属性。此命令有几种形式:
- RENAME — 更改角色的名称。数据库超级用户可以重命名任何角色。具有 CREATEROLE特权的角色可以重命名非超级用户角色。当前会话用户无法重命名(可以通过其他用户身份连接来重命名角色)。MD5加密的密码使用角色名称作为密钥,所以当密码为MD5加密时,重命名角色会清除密码。
- SET | RESET — 更改指定配置参数的角色的会话默认值。 每当角色启动新会话时,指定的值将成为会话默认值,覆盖服务器配置文件(postgresql.conf)中存在的任何设置。对于没有 LOGIN 权限的角色, 会话默认值无效。普通角色可以更改自己的会话默认值。超级用户可以更改任何人的会话默认值。 有 CREATEROLE 特权的角色可以更改非超级用户角色的默认值。
- RESOURCE QUEUE — 将角色分配给资源队列。在发出查询时,角色将受到分配资源队列的限制。参数为 NONE,代表将角色分配给默认资源队列。一个角色只能属于一个资源队列。对于没有LOGIN 特权的角色,资源队列不起作用。
- WITH 选项 — 更改在角色属性。命令中未提及的属性保留其先前的设置。 数据库超级用户可以更改所有角色的所有设置。拥有 CREATEROLE 权限的角色可以更改非超级用户和非复制角色的所有设置。普通角色只能改变自己的密码。
参数
-
name
角色的名称,其属性将被更改。
-
newname
角色的新名称。
-
config_parameter=value
将会话默认的参数值设置为给定值。如果设置为 DEFAULT或者 RESET,将删除角色特定的参数设置,因此该角色将在新会话中继承系统范围的默认设置。使用RESET ALL 清除所有特定的角色设置。
-
queue_name
要分配给此角色的资源组的名称。只有拥有LOGIN权限的角色才可以分配给资源队列。如果设置为NONE,则代表要从资源队列中移除角色并将其放入默认资源队列中。 一个角色只能属于一个资源队列。
-
SUPERUSER | NOSUPERUSER
CREATEDB | NOCREATEDB
CREATEROLE | NOCREATEROLE -
CREATEEXTTABLE | NOCREATEEXTTABLE [(attribute='value’)]
如果指定了CREATEEXTTABLE, 则允许角色创建外部表。如果没被指定,则默认类型为可读,并且默认协议是gpfdist。NOCREATEEXTTABLE(默认)不允许角色创建外部表。 注意,使用file 或 execute 协议的外部表 只能由超级用户创建。
-
INHERIT | NOINHERIT
LOGIN | NOLOGIN
CONNECTION LIMIT connlimit
PASSWORD password
ENCRYPTED | UNENCRYPT
EDVALID UNTIL ‘timestamp’这些子句改变了最初由 CREATE ROLE 设置的角色属性。
-
DENY deny_point
DENY BETWEEN deny_point AND deny_pointDENY 和DENY BETWEEN 用于设置登录时强制执行的基于时间的约束。DENY设置拒绝访问的日期或日期和时间。DENY BETWEEN设置拒绝访问的时间间隔。两者都使用具有以下格式的参数deny_point:
DAY day [ TIME 'time' ]
deny_point两部分参数使用以下格式:
对于day:
{'Sunday' | 'Monday' | 'Tuesday' |'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 0-6 }
对于time:
{ 00-23 : 00-59 | 01-12 : 00-59 { AM | PM }}
该DENY BETWEEN子句使用两个必须指示日期和时间的deny_point 参数:
DENY BETWEEN deny_point AND deny_point
注解
使用GRANT 和 REVOKE 用于添加和删除角色成员资格。
谨慎使用此命令指定未加密的密码。密码将以明文形式发送到服务器,也可能会记录在客户端命令的历史记录或服务器日志中。psql 命令行客户端包含一命令\password,可用于更改角色的密码而不暴露明文密码。
还可以将会话默认值绑定到特定数据库而不是角色。如果存在冲突,特定于角色的设置将覆盖数据库的设置。
示例
更改角色的密码:
ALTER ROLE daria WITH PASSWORD 'passwd123';
更改密码到期日期:
ALTER ROLE scott VALID UNTIL 'May 4 12:00:00 2015 +1';
使密码永久有效:
ALTER ROLE luke VALID UNTIL 'infinity';
赋予角色创建其他角色和新数据库的能力:
ALTER ROLE joelle CREATEROLE CREATEDB;
为 maintenance_work_mem参数设置非默认设置:
ALTER ROLE admin SET maintenance_work_mem = 100000;
将角色分配给资源队列:
ALTER ROLE sammy RESOURCE QUEUE poweruser;
授予角色创建可写外部表的权限:
ALTER ROLE load CREATEEXTTABLE (type='writable');
不允许角色在星期日登录:
ALTER ROLE user3 DENY DAY 'Sunday';
移除角色不能在星期日登录的约束:
ALTER ROLE user3 DROP DENY FOR DAY 'Sunday';
兼容性
ALTER ROLE 语句是一个Hashdata数据库扩展。
另见
CREATE ROLE, DROP ROLE, SET, CREATE RESOURCE QUEUE, GRANT, REVOKE
ALTER SCHEMA
更改schema定义。
概要
ALTER SCHEMA <name> RENAME TO <newname>
ALTER SCHEMA <name> OWNER TO <newowner>
描述
用户必须是该schema的所有者才能使用 ALTER SCHEMA. 要重命名schema, 用户还必须拥有该数据库的 CREATE特权。 要更改所有者,用户还必须 是新所有者角色的直接或者间接成员,并且该角色必须具有该数据库上的 CREATE 特权。 注意超级用户自动拥有所有这些特权。
参数
- name
现有schema的名称。
- newname
该schema的新名称。新名称不能以pg_开头,因为pg_开头的名称为系统schema的保留名称。
- newowner
该schema的新所有者。
兼容性
在SQL标准中没有 ALTER SCHEMA语句。
另见
CREATE SCHEMA, DROP SCHEMA
ALTER SEQUENCE
更改序列生成器的定义。
概要
ALTER SEQUENCE <name> [INCREMENT [ BY ] <increment>]
[MINVALUE <minvalue> | NO MINVALUE]
[MAXVALUE <maxvalue> | NO MAXVALUE]
[RESTART [ WITH ] <start>]
[CACHE <cache>] [[ NO ] CYCLE]
[OWNED BY {<table.column> | NONE}]
ALTER SEQUENCE <name> RENAME TO <new_name>
ALTER SEQUENCE <name> SET SCHEMA <new_schema>
描述
用户必须是该序列的所有者才能使用ALTER SEQUENCE. 要更改序列的schema,用户还必须拥有新schema的CREATE 特权。 注意超级用户自动拥有所有的特权。
参数
- name
要修改的序列的名称(可包括schema信息)。
- increment
子句 INCREMENT BY increment 是可选的。正值表示升序,负值表示降序。如果未指定,则将保留旧的增量值。
- minvalue
NO MINVALUE可选子句 MINVALUE minvalue 决定序列能生成的最小值。 如果 NO MINVALUE 被指定, 如果指定了NO MINVALUE,上升序列和下降序列的默认值分别是 1 和 -263-1。如果这些选项都没有被指定,将保持当前的 最小值。
- maxvalue
NO MAXVALUE可选子句 MAXVALUE maxvalue 决定序列能生成的最大值。 如果NO MAXVALUE 被指定, 上升序列和下降序列的默认值分别是 263-1 和 -1。如果这些选项都没有被指定,将保持当前的 最大值。
- start
可选子句RESTART WITH 更改该序列的开始值。
- cache
子句 CACHE cache允许预先分配序列号并将其存储在内存中以便更快地访问。最小值是 1(每次只生成一个值,也就是说没有缓存)。如果没有指定,将保留原先的缓冲值。
- CYCLE
可用于在升序或降序序列达到最大值或最小值时,允许序列循环。如果达到最大值或最小值,下一个被生成的数字将分别是minvalue或者maxvalue。
- NO CYCLE
如果制定了NO CYCLE,在该序列达到其最大值后,调用nextval()将会返回错误。如果 CYCLE 或NO CYCLE都没有被指定, 将维持原先的循环行为。
- OWNED BY table.column
OWNED BY NONEOWNED BY 可以将该序列与某个特定的表列相关联,如果删除该列(或者整个表),该序列也会被自动删除。 如果指定了OWNED BY,这种关联会替代之前为该序列指定的关联。被指定的表必须具有相同的所有者并且与该序列在同一个schema中。 OWNED BY NONE 可以移除现有的所有关联。
- new_name
该序列的新名称。
- new_schema
该序列的新schema。
示例
在 105重启名为 serial的序列:
ALTER SEQUENCE serial RESTART WITH 105;
兼容性
ALTER SEQUENCE符合SQL标准,除了OWNED BY、RENAME TO和SET SCHEMA子句之外,都是Hashdata数据库的扩展。
另见
CREATE SEQUENCE, DROP SEQUENCE, ALTER TABLE
ALTER TABLE
更改表的定义。
概要
ALTER TABLE [ONLY] <name> RENAME [COLUMN] <column> TO <new_column>
ALTER TABLE <name> RENAME TO <new_name>
ALTER TABLE <name> SET SCHEMA <new_schema>
ALTER TABLE [ONLY] <name> SET
DISTRIBUTED BY (<column>, [ ... ] )
| DISTRIBUTED RANDOMLY
| WITH (REORGANIZE=true|false)
ALTER TABLE [ONLY] <name> <action> [, ... ]
ALTER TABLE <name>
[ ALTER PARTITION { <partition_name> | FOR (RANK(<number>))
| FOR (<value>) } partition_action [...] ]
其中action是下列之一:
ADD [COLUMN] <column_name data_type>
[<column_constraint> [ ... ]]
DROP [COLUMN] <column> [RESTRICT | CASCADE]
ALTER [COLUMN] <column> TYPE <type> [USING <expression>]
ALTER [COLUMN] <column> SET DEFAULT <expression>
ALTER [COLUMN] <column> DROP DEFAULT
ALTER [COLUMN] <column> { SET | DROP } NOT NULL
ALTER [COLUMN] <column> SET STATISTICS <integer>
ADD <table_constraint>
DROP CONSTRAINT <constraint_name> [RESTRICT | CASCADE]
DISABLE TRIGGER [<trigger_name> | ALL | USER]
ENABLE TRIGGER [<trigger_name> | ALL | USER]
CLUSTER ON <index_name>
SET WITHOUT CLUSTER
SET WITHOUT OIDS
SET (FILLFACTOR = <value>)
RESET (FILLFACTOR)
INHERIT <parent_table>
NO INHERIT <parent_table>
OWNER TO <new_owner>
SET TABLESPACE <new_tablespace>
其中partition_action是下列之一:
ALTER DEFAULT PARTITION
DROP DEFAULT PARTITION [IF EXISTS]
DROP PARTITION [IF EXISTS] { <partition_name> |
FOR (RANK(<number>)) | FOR (<value>) } [CASCADE]
TRUNCATE DEFAULT PARTITION
TRUNCATE PARTITION { <partition_name> | FOR (RANK(<number>)) |
FOR (<value>) }
RENAME DEFAULT PARTITION TO <new_partition_name>
RENAME PARTITION { <partition_name> | FOR (RANK(<number>)) |
FOR (<value>) } TO <new_partition_name>
ADD DEFAULT PARTITION <name> [ ( <subpartition_spec> ) ]
ADD PARTITION [<partition_name>] <partition_element>
[ ( <subpartition_spec> ) ]
EXCHANGE PARTITION { <partition_name> | FOR (RANK(<number>)) |
FOR (<value>) } WITH TABLE <table_name>
[ WITH | WITHOUT VALIDATION ]
EXCHANGE DEFAULT PARTITION WITH TABLE <table_name>
[ WITH | WITHOUT VALIDATION ]
SET SUBPARTITION TEMPLATE (<subpartition_spec>)
SPLIT DEFAULT PARTITION
{ AT (<list_value>)
| START([<datatype>] <range_value>) [INCLUSIVE | EXCLUSIVE]
END([<datatype>] <range_value>) [INCLUSIVE | EXCLUSIVE] }
[ INTO ( PARTITION <new_partition_name>,
PARTITION <default_partition_name> ) ]
SPLIT PARTITION { <partition_name> | FOR (RANK(<number>)) |
FOR (<value>) } AT (<value>)
[ INTO (PARTITION <partition_name>, PARTITION <partition_name>)]
其中partition_element是:
VALUES (<list_value> [,...] )
| START ([<datatype>] '<start_value>') [INCLUSIVE | EXCLUSIVE]
[ END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE] ]
| END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE]
[ WITH ( <partition_storage_parameter>=<value> [, ... ] ) ]
[ TABLESPACE <tablespace> ]
其中subpartition_spec是:
<subpartition_element> [, ...]
subpartition_element是:
DEFAULT SUBPARTITION <subpartition_name>
| [SUBPARTITION <subpartition_name>] VALUES (<list_value> [,...] )
| [SUBPARTITION <subpartition_name>]
START ([<datatype>] '<start_value>') [INCLUSIVE | EXCLUSIVE]
[ END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE] ]
[ EVERY ( [<number | datatype>] '<interval_value>') ]
| [SUBPARTITION <subpartition_name>]
END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE]
[ EVERY ( [<number | datatype>] '<interval_value>') ]
[ WITH ( <partition_storage_parameter>=<value> [, ... ] ) ]
[ TABLESPACE <tablespace> ]
其中storage_parameter是:
APPENDONLY={TRUE|FALSE}
BLOCKSIZE={8192-2097152}
ORIENTATION={COLUMN|ROW}
COMPRESSTYPE={ZLIB|QUICKLZ|RLE_TYPE|NONE}
COMPRESSLEVEL={0-9}
FILLFACTOR={10-100}
OIDS[=TRUE|FALSE]
描述
ALTER TABLE 更改表的定义。下文描述了几种形式:
- ADD COLUMN — 向表中增加新列,使用和 CREATE TABLE相同的语义。 将列添加到append优化的表时,需要 DEFAULT 子句。
- DROP COLUMN — 从表中删除列,请注意,如果将用作Hashdata数据库分发密钥的表列删除,表的分发策略将更改为随机分配. 涉及该列的索引和表约束也将自动删除。 如果任何外部表依赖于此列(例如视图),需使用CASCADE关键字。
- ALTER COLUMN TYPE — 更改表中列的数据类型。不能修改正在用于分发密钥或分区键的列的数据类型。 涉及该列的索引和简单表约束将自动转换为使用新的列类型。可选的 USING 子句用于指定如何从旧的列值计算新列值,如果省略,则默认转换与从旧数据类型到新数据类型的赋值转换相同。如果USING没有从旧类型到新类型的隐式或赋值转换,则必须提供子句。
- SET/DROP DEFAULT — 设置或者移除默认值。 默认的值只能在后续的 INSERT 语句中生效。它们不会改变表中已存在的行。
- SET/DROP NOT NULL — 允许空值或拒绝空值。用户只能在列不包含空值时使用 SET NOT NULL。
- SET STATISTICS — 为后续的ANALYZE操作设置每列的统计信息收集目标。目标可以设置在 0 到 10000 的范围内,或者设置为 -1,以恢复使用系统默认的统计目标 ( default_statistics_target)。设置为 0 时,不收集统计信息。
- ADD table_constraint — 使用和CREATE TABLE相同的语法将新的约束添加到表(而不仅仅是分区)。
- DROP CONSTRAINT — 删除约束。
- DISABLE/ENABLE TRIGGER — 禁用或启用触发器。对于被禁用的触发器,即使被触发了也不会运行。对于延迟触发器,会在事件发生时而不是触发器函数真正被执行时检查其启用状态。 可以禁用或启用由名称指定的单个触发器,或表上的所有触发器,或用户创建的触发器。禁用或启用约束触发器需要超级用户权限。注意: Hashdata数据库不支持触发器。由于Hashdata数据库的并行性,触发器通常只具有非常有限的功能。
- CLUSTER ON/SET WITHOUT CLUSTER — 为CLUSTER 操作选择默认索引。它不会真正地对表进行重新排列。不建议通过CLUSTER来重排表,因为CLUSTER比较费时。最好是用 CREATE TABLE AS 重新创建表并由索引列排序。
注意: append优化表不支持CLUSTER ON。 - SET WITHOUT OIDS —移除oid系统列。注意,oid一旦被删除,将无法恢复。
- SET ( FILLFACTOR = value) / RESET (FILLFACTOR) — 更改表的填充因子。表的填充因子是10到100之间的百分比。默认值为100(完全填充)。当指定较小的填充因子时, INSERT操作仅将表页填充到指定的百分比;每页上的剩余空间将用于更新该页上的行。所以可以通过UPDATE将行的更新副本放在与原始页面相同的页面上,这比将其放在不同的页面上更有效。对于不更新条目的表,完全填充是最佳选择,但是在大量更新的表中,较小的填充因子更为恰当。请注意,此命令不会立即修改表内容。用户将需要重写表以获得所需的效果。
- SET DISTRIBUTED —设置表的分发策略。对于哈希分发策略,会使表数据在磁盘上重新分布。
- INHERIT parent_table / NO INHERIT parent_table — 在指定父表下,添加或删除表。查询父表会包括子表的记录。要添加子表,目标表必须已经包含与父表相同的所有列(也可能有其他列)。列必须具有匹配的数据类型, 如果父表有 NOT NULL 的约束,子表也必须有 NOT NULL 约束 。对于父表的所有CHECK约束,也必须有匹配的子表约束。
- OWNER — 将表,序列或视图的所有者更改为指定的用户。
- SET TABLESPACE — 将表的表空间更改为指定的表空间,并将与表关联的数据文件移动到新的表空间。表上的索引(如有)不会移动; 但可以通过SET TABLESPACE 命令来移动。 如果更改分区表的表空间,则所有子表分区也将被移动到新的表空间。
- RENAME — 更改表(或索引,序列或视图)的名称或表中单个列的名称。对存储的数据没有影响。请注意,Hashdata数据库分发密钥列不能重命名。
- SET SCHEMA — 将表移动到另一个schema。表列所拥有的关联索引、约束和序列也会被移动。
- ALTER PARTITION | DROP PARTITION | RENAME PARTITION | TRUNCATE PARTITION | ADD PARTITION | SPLIT PARTITION | EXCHANGE PARTITION | SET SUBPARTITION TEMPLATE — 更改分区表的结构。在大多数情况下,用户必须通过父表来更改其子表分区。
注意: 如果将分区添加到具有子分区编码的表中,则新分区将继承子分区的存储指令。
要使用 ALTER TABLE用户必须是该表的所有者。要更改表的 schema或者表空间,用户还必须拥有新schema或表空间的CREATE 特权。 要把某个表作为父表的新子表加入, 用户必须同时是该父表的所有者。要更改所有者,用户还必须 是新所有者的直接或者间接成员,并且该角色必须具有该表schema的 CREATE 特权。 超级用户自动拥有这些权限。
注意:当表有很多分区、表有压缩或表的blocksize很大时,内存使用量会显着增加。如果与表关联的关系数量很大,这种情况会迫使对表的操作占用更多内存。例如,如果表是 CO 表并且具有大量列,则每列都是一个关系。像ALTER TABLE ALTER COLUMN打开表中的所有列这样的操作会分配相关的缓冲区。如果CO表有40列100个分区,列被压缩,并且块大小为2MB(系统因子为3),系统将尝试分配24GB,即(40×100)×(2× 3) MB 或 24 GB。
参数
- ONLY
只对指定的表名进行操作。如果不使用ONLY关键字,将对表和与该表相关联的任何子表分区执行操作。
- name
要更改的表的名称(可包括schema信息)。 如果指定了ONLY,则只有该表被更改。如果未指定 ONLY,该表及其所有子表都会被修改。
注意: 限制只能添加到整个表中,而不能添加到分区。由于这个限制,该 name 参数只能包含一个表名,而不能是一个分区名。
- column
新列或现有列的名称。请注意,需谨慎处理Hashdata数据库的分发密钥列。更改或删除这些列会更改表的分发策略。
- new_column
列的新名称。
- new_name
表的新名称。
- type
新列的数据类型,或现有列的新数据类型。如果更改Hashdata分发密钥列的数据类型,则只允许将其更改为兼容类型 (例如, text 到 varchar 是允许的,但是 text 到 int 不被允许)。
- table_constraint
表的新约束。请注意,Hashdata目前不支持外键限制。还有表约束唯一的,并且必须在分发密钥中唯一。
- constraint_name
要删除的约束名称。
- CASCADE
自动删除依赖于删除列或约束的对象(例如,引用该列的视图)。
- RESTRICT
如果有任何依赖对象,拒绝删除列或约束。这是默认行为
- trigger_name
要禁用或启用的单个触发器的名称。请注意,Hashdata数据库不支持触发器。
- ALL
禁用或启用属于表的所有触发器,包括与约束相关的触发器。这需要超级用户权限
- USER
禁用或启用属于该表的所有用户创建的触发器。
- index_name
CLUSTER操作的索引名称。不建议通过CLUSTER来重排表,因为CLUSTER比较费时。最好是用 CREATE TABLE AS 重新创建表并由索引列排序。
- FILLFACTOR
设置表的fillfactor百分比
- value
FILLFACTOR参数的新值, 在10到100之间的百分比。 默认值为100。
- DISTRIBUTED BY (column) | DISTRIBUTED RANDOMLY
指定表的分发策略。对于哈希分发策略,会使表数据在磁盘上重新分布。如果用户声明相同的哈希分发策略或从哈希更改为随机分布, 则不会重新分发数据,除非用户声明了SET WITH (REORGANIZE=true),才会重新分发数据。
- REORGANIZE=true|false
当哈希分发策略维持不变或者当用户从哈希分发改为随机分布,并且用户想重新分发数据时,使用REORGANIZE=true。
- parent_table
与该表关联或取消关联的父表
- new_owner
表的新所有者的角色名称。
- new_tablespace
新的表空间的名称。
- new_schema
新的schema的名称。
- parent_table_name
更改分区表时,最上级父表的名称。
- ALTER [DEFAULT] PARTITION
更改比第一级分区更深的分区,请使用 ALTER PARTITION子句指定要更改层次结构中的哪个子分区。
- DROP [DEFAULT] PARTITION
删除指定的分区。如果分区具有子分区,子分区也将自动删除。
- TRUNCATE [DEFAULT] PARTITION
截断指定的分区。如果分区具有子分区,则子分区也将自动截断。
- RENAME [DEFAULT] PARTITION
更改分区的分区名称(而不是关系名称)。分区表是使用命名约定创建的:
_ _prt_ 。 - ADD DEFAULT PARTITION
将默认分区添加到现有分区设计。当数据与现有分区不匹配时,它将被插入到默认分区中。没有默认分区的分区设计将拒绝传入与现有分区不匹配的行。必须为默认分区命名。
- ADD PARTITION
- partition_element - 使用表(范围或列表)的现有分区类型,定义要添加的新分区的边界。
- name - 新分区名称。
- VALUES - 对于列表分区,定义分区将包含的值。
- START - 对于范围分区,定义分区的起始范围值。默认情况下,起始值为INCLUSIVE。例如,如果您声明开始日期为“ 2016-01-01”,则分区将包含所有大于或等于“ 2016-01-01”的日期。通常,START表达式的数据类型与分区键列的类型相同。如果不是这种情况,那么您必须显式转换为预期的数据类型。
- END - 对于范围分区,定义分区的结束范围值。默认情况下,结束值为 EXCLUSIVE. 如果您声明结束日期为 ' 2016-02-01’,则分区将包含所有小于但不等于 ' 2016-02-01’ 的日期。通常,END表达式的数据类型与分区键列的类型相同。如果不是这种情况,那么您必须显式转换为预期的数据类型。
- WITH - 设置分区的表存储选项。例如,用户可能希望较旧的分区是追加优化的表,较新的分区为常规堆表。
- TABLESPACE - 要在其中创建分区的表空间名称。
- subpartition_spec - 只允许在没有子分区模板的情况下创建的分区设计。声明要添加的新分区的子分区规范。如果分区表最初是使用子分区模板定义的,那么该模板将用于自动生成子分区。
- EXCHANGE [DEFAULT] PARTITION
将另一个表交换到分区层次结构中,以代替现有分区。在多级分区设计中,您只能交换最低级别的分区(包含数据的分区)。
Hashdata数据库服务器配置参数 gp_enable_exchange_default_partition 用来控制可用 EXCHANGE DEFAULT PARTITION 子句的可用性。 参数的默认值为 off。
警告: 在交换默认分区之前,用户必须确保要被交换的表(新的默认分区)中的数据对于默认分区是有效的。例如,新默认分区中的数据不能含有对该分区表其他叶子子分区中有效的数据。否则,针对被交换默认分区所在分区表的查询在被GPORCA执行时可能返回不正确的结果。- WITH TABLE table_name - 要交换到分区设计中的表的名称。用户可以交换表数据被存储在数据库中的表。例如,该表由CREATE TABLE命令创建,该表必须具有与父表相同的列数、列顺序、列名、列类型和分配策略。
通过EXCHANGE PARTITION子句,还可以将可读的外部表(使用CREATE EXTERNAL TABLE命令创建)交换到分区层次结构中,以代替现有的叶子子分区。如果您指定一个可读的外部表,您还必须指定WITHOUT VALIDATION子句以跳过针对CHECK您正在交换的分区的约束的表验证。以下情况不支持用外部表交换叶子子分区:
分区表通过SUBPARTITION子句创建,或者分区具有子分区。
分区表含有带有检查约束或者NOT NULL约束的列。 - WITH | WITHOUT VALIDATION - 验证表中的数据是否与您正在交换的分区的CHECK约束相匹配。默认是根据CHECK约束验证数据。
警告:如果指定了WITHOUT VALIDATION子句,必须确保正在交换的现有叶子子分区的表中的数据对于该分区上的CHECK约束有效。否则针对分区表的查询可能返回不正确的结果。
- WITH TABLE table_name - 要交换到分区设计中的表的名称。用户可以交换表数据被存储在数据库中的表。例如,该表由CREATE TABLE命令创建,该表必须具有与父表相同的列数、列顺序、列名、列类型和分配策略。
- SET SUBPARTITION TEMPLATE
为现有分区修改子分区模板。在设置了新的子分区模板后,所有增加的新分区都将具有新的子分区设计(现有分区不会被修改)。
- SPLIT DEFAULT PARTITION
拆分一个默认分区。在一种多级分区设计中,用户只能分裂最低层的默认分区(包含数据的分区)。拆分默认分区会创建包含指定值的新分区,并保留包含与现有分区不匹配的任何值的默认分区。- AT - 对于列表分区表,指定用作拆分条件的列表值。
- START - 对于范围分区表,指定新分区的起始值。
- END - 对于范围分区表,指定新分区的结束值。
- INTO - 允许用户为新分区指定一个。在使用INTO子句拆分默认分区时,指定的第二个分区名应该总是现有的默认分区。如果用户不知道默认分区的名称,可以使用pg_partitions视图找到它。
- SPLIT PARTITION
将现有分区分裂成两个分区。在多层分区设计中,用户只能分裂最低层的分区(包含数据的分区)。- AT - 指定用作拆分条件的值。分区将被划分成两个新分区,指定的分裂值会成为后一个分区的开始范围。
- INTO - 允许用户指定两个新分区的名字。
- partition_name
给定的分区名称。
- FOR (RANK(number))
对于范围分区,分区在范围中的排名。
- FOR (‘value’)
通过声明属于分区边界规范的值来指定一个分区。如果用FOR声明的值匹配一个分区和它的一个子分区(例如,如果该值是一个日期,并且表按月分区,然后按天分区),那么FOR将在第一个找到匹配的层次上操作(例如,每月的分区)。如果用户的目的是在子分区上操作,则必须按如下的方式声明: ALTER TABLE name ALTER PARTITION FOR ('2016-10-01') DROP PARTITION FOR ('2016-10-01');
注解
ALTER TABLE命令中指定的表名不能是表中的分区名。
在修改或者删除作为Hashdata数据库分布键相关的列时要谨慎,这可能会改变表的分布策略。
Hashdata数据库当前不支持外键约束。对于要在Hashdata数据库中强制执行的唯一约束,表必须是哈希分布的(不是DISTRIBUTED RANDOMLY),并且所有的分布键列必须和唯一约束列中前部的列相同。
增加CHECK或者NOT NULL约束要求扫描表以验证现有的行是否符合约束。
在用ADD COLUMN增加列时,表中所有的行都用该列的默认值初始化,如果没有指定DEFAULT子句则初始化为NULL(注意不允许在追加优化表中增加不指定默认值的列)。增加一个非空默认值的列或者更改现有列的类型要求重写整个表。对于大型表这可能需要大量的时间,并且会临时要求两倍的磁盘空间。
用户可以在单个ALTER TABLE命令中指定多个更改,它们将在对表的一趟扫描中完成。
DROP COLUMN形式不会物理上移除列,而是简单地将它变成对SQL操作不可见。表中的后续插入和更新操作将存储该列的空值。因此,删除列用时短,但是不会立即减少表占用的磁盘大小,因为被删除列所占据的空间没有被回收。这些空间将随着现有行被更新而逐渐被回收。
ALTER TYPE要求重写整个表的做法有时候是一种优点,因为重写过程会消除表中的死亡空间。例如,要立即回收被删除列占据的空间,最快的方法是: ALTER TABLE table ALTER COLUMN anycol TYPE sametype; 其中anycol是任何现有表列,而sametype是该列现有的数据类型。这不会对表产生任何语义可见的变化,但是该命令强制进行了重写,这可以去除无用的数据。
如果表已分区或者有子表,则不允许增加列、重命名列、更改列类型而不对其子表做同样的事情。这确保了子表总是具有和父表相匹配的列。
要查看一个分区表的结构,用户可以使用视图pg_partitions。这个视图可以识别用户想要修改的特定分区。
只有当后代表没有从任何父表继承列并且也没有对该列的独立定义时,递归的DROP COLUMN操作才会移除后代表的这个列。非递归的DROP COLUMN(ALTER TABLE ONLY … DROP COLUMN)不会移除任何后代列,而是将它们标记为独立定义而不是继承而来。
TRIGGER、CLUSTER、OWNER以及TABLESPACE不会递归到后代表,也就是说它们只在指定了ONLY的情况下执行。
如果在包含已经被交换为使用外部表的叶子子分区的分区表上没有数据被更改,则支持这些ALTER PARTITION操作。否则会返回错误。
- 添加或删除列。
- 更改列的数据类型。
这些ALTER PARTITION操作 对于已经交换为使用外部表的叶子分区的分区表,不支持以下操作:
- 设置子分区模板。
- 更改分区属性。
- 创建默认分区。
- 制定分发政策。
- 设置或删除NOT NULL 列的约束。
- 添加或删除约束。
- 拆分外部分区。
不允许更改系统目录表的任何部分。
示例
向列中添加列:
ALTER TABLE distributors ADD COLUMN address varchar(30);
重命名现有列:
ALTER TABLE distributors RENAME COLUMN address TO city;
重命名现有表:
ALTER TABLE distributors RENAME TO suppliers;
向列添加非空约束:
ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
向表中添加检查约束
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK
(char_length(zipcode) = 5);
将表移动到不同的schema:
ALTER TABLE myschema.distributors SET SCHEMA yourschema;
将新分区添加到分区表中:
ALTER TABLE sales ADD PARTITION
START (date '2017-02-01') INCLUSIVE
END (date '2017-03-01') EXCLUSIVE;
将默认分区添加到现有分区设计中:
ALTER TABLE sales ADD DEFAULT PARTITION other;
重命名分区:
ALTER TABLE sales RENAME PARTITION FOR ('2016-01-01') TO
jan08;
删除范围序列中的第一个(最旧的)分区:
ALTER TABLE sales DROP PARTITION FOR (RANK(1));
将表交换到用户的分区设计中:
ALTER TABLE sales EXCHANGE PARTITION FOR ('2016-01-01') WITH
TABLE jan08;
拆分默认分区(现有的默认分区名称为other)以添加2017年1月的新月度分区:
ALTER TABLE sales SPLIT DEFAULT PARTITION
START ('2017-01-01') INCLUSIVE
END ('2017-02-01') EXCLUSIVE
INTO (PARTITION jan09, PARTITION other);
将每月分区一分为二,第一个分区包含日期为1月1日至15日,第二个分区包含日期1月16日至31日:
ALTER TABLE sales SPLIT PARTITION FOR ('2016-01-01')
AT ('2016-01-16')
INTO (PARTITION jan081to15, PARTITION jan0816to31);
兼容性
ADD, DROP, and SET DEFAULT 符合SQL标准。 其他形式是SQL标准的Hashdata数据库扩展。 另外,在一个单一的指定多个操作的能力 ALTER TABLE命令是一个扩展。此外,在单个ALTER TABLE命令中指定多个操作的能力也是Hashdata数据库扩展。
ALTER TABLE DROP COLUMN 可用于删除表的唯一列,成为零列表。
另见
CREATE TABLE, DROP TABLE
ALTER TYPE
更改数据类型的定义。
概要
ALTER TYPE <name>
OWNER TO <new_owner> | SET SCHEMA <new_schema>
描述
用户必须是该类型的所有者才能使用 ALTER TYPE. 要更改类型的schema,用户还必须对新schema具有CREATE 特权。 要更改类型所有者,用户必须是新角色的直接或间接成员,并且该角色在类型的schema上有CREATE 特权。
参数
- name
要修改的现有类型的名称(可选限定schema)。
- new_owner
新的所有者的类型名。
- new_schema
该类型的新schema。
示例
更改自定义类型 email 的所有者为 joe:
ALTER TYPE email OWNER TO joe;
更改用户自定义的 email类型schema为 customers:
ALTER TYPE email SET SCHEMA customers;
兼容性
在SQL标准中没有 ALTER TYPE 语句.
另见
CREATE TYPE, DROP TYPE
ALTER USER
更改数据库用户(角色)的定义。
概要
ALTER USER <name> RENAME TO <newname>
ALTER USER <name> SET <config_parameter> {TO | =} {<value> | DEFAULT}
ALTER USER <name> RESET <config_parameter>
ALTER USER <name> [ [WITH] <option> [ ... ] ]
其中option可以是:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEUSER | NOCREATEUSER
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| [ENCRYPTED | UNENCRYPTED] PASSWORD '<password>'
| VALID UNTIL '<timestamp>'
描述
ALTER USER是一个已弃用的命令,但由于历史原因仍然被保留, 它是 ALTER ROLE的别名。
兼容性
ALTER USER 语句是一个Hashdata数据库扩展。
另见
ALTER ROLE
ALTER VIEW
更改视图的定义。
概要
ALTER VIEW <name> RENAME TO <newname>
描述
唯一可用的功能是重命名视图。要执行此命令用户必须是视图的所有者。
参数
- name
现有文件空间的名称(可以是限定schema)。
- newname
视图的新名称。
注解
一些 ALTER TABLE 的变体可以很好的用于视图;例如, 重命名视图时可以使用 ALTER TABLE RENAME。但是要更改视图的所有者或者schema,必须通过ALTER TABLE.
示例
把视图myview 重命名为newview:
ALTER VIEW myview RENAME TO newview;
更改表空间myfs的所有者:
ALTER FILESPACE myfs OWNER TO dba;
兼容性
ALTER VIEW是一种Hashdata数据库的SQL标准扩展。
另见
CREATE VIEW、DROP VIEW
ANALYZE
收集有关数据库的统计信息。
概要
ANALYZE [VERBOSE] [ROOTPARTITION [ALL] ]
[<table> [ (<column> [, ...] ) ]]
描述
ANALYZE 收集数据库中表内容的统计信息, 并且将结果存储在系统表 pg_statistic中。HashData数据库会通过这些统计信息来确认最有效的查询执行计划。
如果不带参数, ANALYZE收集当前数据库中每个表的统计信息。用户可以指定表名来收集单个表的统计信息。用户可以指定一组列名称,在这种情况下,仅收集这些列的统计信息。
ANALYZE不收集外部表上的统计信息。
重要:如果用户想要在启用GPORCA(默认启用)时在分区表上执行查询,那么用户必须在分区表的根分区上用ANALYZE ROOTPARTITION命令收集统计信息。
注意: 用户还可以使用Hashdata的数据库工具analyzedb更新表统计信息。analyzedb工具可以并发地为多个表更新统计信息。该工具还能检查表统计信息并且只在统计信息不是当前最新或者不存在时更新。
参数
-
ROOTPARTITION [ALL]
只在分区表的根分区上根据分区表中的数据收集统计信息。不会在叶子分区上收集统计信息,其中的数据只会被采样。
当用户指定ROOTPARTITION时,必须指定ALL或者某个分区表的名称。
如果用户在ROOTPARTITION中指定ALL,Hashdata数据库会为该数据库中所有分区表的根分区收集统计信息。如果在数据库中没有分区表,会返回一个消息说明没有分区表。对于非分区表不会收集统计信息。
如果用户在ROOTPARTITION中指定了表名并且该表不是分区表,则不会为该表收集统计信息并且会返回一个警告消息。
ROOTPARTITION子句在VACUUM ANALYZE中是无效的,VACUUM ANALYZE ROOTPARTITION返回一个错误。
运行ANALYZE ROOTPARTITION所需的时间类似于分析一个有着相同数据的非分区表所需的时间,因为ANALYZE ROOTPARTITION仅采样叶子子分区数据。
对于分区表sales_curr_yr,以下示例只在分区表的根分区上收集统计信息。ANALYZE ROOTPARTITION sales_curr_yr;
以下ANALYZE示例在数据库中所有分区表的根分区上收集统计信息。ANALYZE ROOTPARTITION ALL;
-
VERBOSE
启用进度消息的展示。被指定时,ANALYZE会发出这些信息- 正在处理的表。
- 为生成示例表而运行的查询。
- 正在为其计算统计信息的列。
- 为收集单个列的不同统计信息而生成的查询。
- 收集的统计信息。
-
table
要分析的特定表的名称(可包括schema信息)。默认为当前数据库中的所有表。
-
column
要分析的特定列的名称。默认为所有列。
注解
定期运行ANALYZE是个好主意,或者只在表内容发生大量变化时才运行。准确的统计信息会帮助Hashdata数据库选择最合适的查询计划,并且因此改进查询处理的速度。一种常用的策略是每天在系统负载低的时候运行一次VACUUM和ANALYZE。
ANALYZE要求目标表上的SHARE UPDATE EXCLUSIVE锁。这个锁会与这些锁冲突:SHARE UPDATE EXCLUSIVE、 SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、 ACCESS EXCLUSIVE。
对于分区表,指定要分析该表的哪一部分,如果分区表有大量已经分析过的分区并且只有少数叶子子表改变,根分区或者子分区(叶子子表)会很有用。
- 当用户在根分区表上运行ANALYZE时,会为所有的叶子子表(Hashdata数据库为分区表创建的子表层次中最低层的表)收集统计信息。
- 当用户在一个叶子子表上运行ANALYZE时,只会为该叶子子表收集统计信息。当用户在非叶子子表的子表上运行ANALYZE时,不会有统计信息被收集。
例如,用户可以创建一个分区表,其中包含 2006 年到 2016 年的分区以及每年每个月的子分区。如果用户在2013年的子表上运行ANALYZE,则不会有统计信息被收集。如果用户在2013年三月的叶子子表上运行ANALYZE,则只会为该叶子子表收集统计信息。
对于包含已交换为使用外部表的叶子子分区的分区表,ANALYZE不收集外部表分区的统计信息:
- 如果ANALYZE [ROOTPARTITION]被运行,外部表不会被采样并且根表统计信息不包括外部表分区。
- 如果在外部表分区上运行ANALYZE,该不分析该分区。
- 如果指定了VERBOSE子句,会显示报告消息:skipping external table.
Hashdata数据库服务器配置参数optimizer_analyze_root_partition影响何时在分区表的根分区上收集统计信息。如果该参数被启用,当用户运行ANALYZE(没有ROOTPARTITON关键词)并且指定根分区时,会在根分区上收集统计信息。
ANALYZE收集的统计信息通常包括每个列中一些最常见值构成的列表以及显示每列中近似数据分布的柱状图。如果ANALYZE对两者中的一个或者全部不感兴趣(例如,在一个唯一键列中,其中没有常见值)或者该列的数据类型不支持合适的运算符,ANALYZE可能会忽略它们。
对于大型表,ANALYZE随机抽取表内容样本,而不是检查每一行。这允许在很短的时间内分析非常大的表。不过要注意,这样的统计信息只是近似的,并且即使实际表内容没有改变,统计信息也将会在每次运行ANALYZE后略有变化。这可能会导致EXPLAIN所显示的规划器估计代价发生微小变化。在极少数情况下,这无疑将导致在两次ANALYZE运行之间查询优化器选择不同的查询计划。为了避免这种情况,可以通过调整default_statistics_target配置参数增加ANALYZE收集的统计信息量,或者逐列用ALTER TABLE … ALTER COLUMN … SET STATISTICS(见ALTER TABLE)设置每列的统计信息目标。该目标值设定了最常用值列表中的最大条目数和直方图中的最大存储单元数。默认的目标值是10,但可以改变它以平衡规划器估计精度以及ANALYZE所花的时间和在pg_statistic中所占用的空间。特别地,将统计信息目标设置为零会禁用该列的统计信息收集。对那些从不出现在查询中的WHERE、GROUP BY或者ORDER BY子句的列来说,这可能会很有用,因为规划器将不会使用这类列上的统计信息。
正在分析的列中最大的统计目标决定了为准备统计信息而采样的表行数。增加该目标会导致执行ANALYZE所需的时间空间成比例增加。
当 Hashdata 数据库执行ANALYZE操作以收集表的统计信息并检测到所有采样的表数据页都是空的(不包含有效数据)时,Hashdata数据库会显示应该执行VACUUM FULL操作的消息。如果被采样页为空,该表的统计信息会不准确。页面会在对表的大量更新后变为空,例如删除了大量行。VACUUM FULL操作会移除空页并且允许ANALYZE操作收集准确的统计信息。
如果表没有统计信息,服务器配置参数gp_enable_relsize_collection会确定传统查询优化器是使用默认统计信息文件还是使用pg_relation_size函数估算表的尺寸。默认情况下,如果统计信息不可用,传统优化器使用默认统计信息文件来估算行数。
示例
为表mytable收集统计信息:
ANALYZE mytable;
兼容性
SQL标准中没有ANALYZE语句。
另见
ALTER TABLE、 EXPLAIN、 VACUUM、 Hashdata数据库工具指南中的analyzedb工具
BEGIN
启动事务块。
概要
BEGIN [WORK | TRANSACTION] [<transaction_mode>]
[READ ONLY | READ WRITE]
其中transaction_mode是下列之一:
ISOLATION LEVEL | {SERIALIZABLE | READ COMMITTED | READ UNCOMMITTED}
描述
BEGIN启动一个事务块,即BEGIN命令之后的所有语句将在单个事务中运行,直到给出显式COMMIT或ROLLBACK。默认情况下(不带BEGIN),Hashdata 数据库以自动提交schema运行事务,即每条语句都在其自己的事务中运行,并在语句末尾隐式执行提交(如果执行成功,则执行回滚)。
语句在事务块中运行得更快,因为事务启动/提交需要大量 CPU 和磁盘活动。在进行多个相关更改时,在事务中执行多个语句对于确保一致性也很有用:在所有相关更新还没有完成之前,其他会话将更新的中间状态。
在一个事务块内的语句会执行得更快,因为事务的开始/提交也要求可观 的 CPU 和磁盘活动。在进行多个相关更改时,在一个事务内执行多个语 句也有助于保证一致性:在所有相关更新还没有完成之前,其他会话将不 能看到中间状态。
如果指定了隔离级别、读/写模式或可延迟模式,则新事务具有这些特征,就像运行了SET TRANSACTION一样。
参数
- WORK
TRANSACTION可选的关键词。它们没有任何影响。
- SERIALIZABLE
READ COMMITTED
READ UNCOMMITTEDSQL标准定义了四个事务隔离级别: READ COMMITTED, READ UNCOMMITTED, SERIALIZABLE,和REPEATABLE READ。认隔离级别为READ COMMITTED,保证语句只能看到在执行之前提交的行。在Hashdata数据库中,READ UNCOMMITTED被视为与 READ COMMITTED相同。不支持 REPEATABLE READ; 如果需要此行为请使用SERIALIZABLE 。 SERIALIZABLE 是最严格的事务隔离。该级别模拟串行事务执行,就好像事务已经连续执行,而不是同时执行。使用此级别的应用程序必须准备好重试因序列化失败而导致的事务。
- READ WRITE
READ ONLY事务是读/写还是只读。读/写是默认值。当事务为只读时,不允许以下SQL命令:INSERT, UPDATE, DELETE, 和COPY FROM(如果要写入的表不是临时表的话); 所有的CREATE, ALTER, 和DROP 命令还有 GRANT, REVOKE, TRUNCATE;和EXPLAIN ANALYZE 以及 EXECUTE (如果他们要执行的命令是在这里列出的命令中)。
注解
START TRANSACTION 具有和BEGIN相同的功能。
使用COMMIT或 ROLLBACK 来终止事务块。
在事务块中执行BEGIN 将引发警告消息。事务状态不会被影响。要在事务块中嵌套事务,可以使用保SAVEPOINT。
示例
启动事务块:
BEGIN;
使用可序列化隔离级别启动事务块:
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
兼容性
BEGIN 是Hashdata数据库语言扩展。它相当于SQL标准的命令START TRANSACTION.
BEGIN在嵌入式 SQL 中,关键字用于不同的目的。建议您在移植数据库应用程序时注意事务语义。
另见
COMMIT, ROLLBACK, START TRANSACTION, SAVEPOINT
COMMENT
定义或更改对象的注释。
概要
COMMENT ON
{ TABLE <object_name> |
COLUMN <table_name.column_name> |
AGGREGATE <agg_name> (<agg_type> [, ...]) |
CAST (<sourcetype> AS <targettype>) |
CONSTRAINT <constraint_name> ON <table_name> |
CONVERSION <object_name> |
DATABASE <object_name> |
DOMAIN <object_name> |
FUNCTION <func_name> ([[<argmode>] [<argname>] <argtype> [, ...]]) |
INDEX <object_name> |
LARGE OBJECT <large_object_oid> |
OPERATOR <op> (<leftoperand_type>, <rightoperand_type>) |
OPERATOR CLASS <object_name> USING <index_method> |
[PROCEDURAL] LANGUAGE <object_name> |
RESOURCE QUEUE <object_name> |
ROLE <object_name> |
RULE <rule_name> ON <table_name> |
SCHEMA <object_name> |
SEQUENCE <object_name> |
TABLESPACE <object_name> |
TRIGGER <trigger_name> ON <table_name> |
TYPE <object_name> |
VIEW <object_name> }
IS '<text>'
描述
COMMENT 存储关于数据库对象的注释。为了修改注释,可以对同一对象发出一个新的COMMENT 命令。 要移除注释,可在文本字符串的位置上写上 NULL。当对象被删除时,其注释也会被自动删除。
可以使用psql元命令 \dd, \d+, 和 \l+轻松检索注释。其他检索注释的用户接口可以构建在 psql使用的内建函数之上,不日即 obj_description, col_description, 和 shobj_description.
参数
- object_name
table_name.column_name
agg_name
constraint_name
func_name
op
rule_name
trigger_name要注释的对象的名称。表,聚合,域,函数,索引,运算符,运算符类,序列,类型和视图的名称,可包括schema信息。
注意: Hashdata数据库不支持触发器。
- agg_type
聚合功能运行的输入数据类型。要引用零参数聚合函数,用* 代替输入数据类型的列表。
- sourcetype
转换的源数据类型的名称。
- targettype
转换的目标数据类型的名称。
- argmode
函数或者聚合参数的schema:IN, OUT, INOUT, or VARIADIC。如果省略,默认值为 IN。请注意 ALTER FUNCTION 实际上并不关注OUT 参数,因为只需要通过输入参数来确定函数的身份。 因此列出 IN, INOUT, 和 VARIADIC 参数就可以了。
- argname
函数或者聚合参数的名称。 请注意,ALTER FUNCTION 实际上并不关心参数名称,因为只需要通过参数数据类型来确定函数的身份。
注解
目前没有用于查看评论的安全机制:任何连接到数据库的用户都可以查看该数据库中对象的所有评论。对于数据库、角色和表空间等共享对象,注释是全局存储的,因此连接到集群中任何数据库的任何用户都可以看到共享对象的所有注释。因此,请勿将安全关键信息放在评论中。
示例
为表 mytable附加注释:
COMMENT ON TABLE mytable IS 'This is my table.';
移除它:
COMMENT ON TABLE mytable IS NULL;
兼容性
SQL标准中没有COMMENT 语句。
COMMIT
提交当前事务。
概要
COMMIT [WORK | TRANSACTION]
描述
事务所做的所有更改都对其他人可见,并且在发生崩溃时保证是持久的。
参数
WORK和TRANSACTION是可选的关键词。它们没有任何影响。
注解
使用ROLLBACK 中止事务。
不在事务中时,发出COMMIT 不会产生危害,但是会发出警告消息。
示例
要提交当前事务并且让所有更改持久化:
COMMIT;
兼容性
SQL 标准指定了两种形式: COMMIT 和COMMIT WORK. 除此之外,此命令没有什么不同。
另见
BEGIN, END, START TRANSACTION, ROLLBACK
CREATE AGGREGATE
定义新的聚合函数。
概要
CREATE [ORDERED] AGGREGATE <name> (<input_data_type> [ , ... ])
( SFUNC = <sfunc>,
STYPE = <state_data_type>
[, PREFUNC = <prefunc>]
[, FINALFUNC = <ffunc>]
[, INITCOND = <initial_condition>]
[, SORTOP = <sort_operator>] )
描述
Hashdata 数据库中已经提供了一些基本和常用的聚合函数,例如count、min、max、sum等。avg如果要定义新类型或需要尚未提供的聚合函数,则可以通过CREATE AGGREGATE来提供所需的特性。
聚合函数由其名称和输入数据类型标识。如果同一schema中的两个聚合函数对不同的输入类型进行操作,则它们可以具有相同的名称。聚合函数的名称和输入数据类型也必须与同一schema中每个普通函数的名称和输入数据类型不同。此行为与普通函数名的重载相同。
聚合函数由一个,两个或三个常规函数组成(所有这些函数都必须是IMMUTABLE函数):
- 状态转移函数sfunc
- 可选的Segment级预备计算函数prefunc
- 可选的最终计算函数ffunc
这些函数被使用如下:
sfunc( internal-state, next-data-values ) ---> next-internal-state
prefunc( internal-state, internal-state ) ---> next-internal-state
ffunc( internal-state ) ---> aggregate-value
用户可以指定PREFUNC作为优化聚合执行的方法。通过指定PREFUNC,聚合可以先在Segment上并行执行然后再在Master上执行。在执行双层聚合时,在Segment上执行SFUNC 以产生部分聚合结果,而在Master上执行PREFUNC以聚合来自Segment的部分结果。如果执行单层聚合,所有的行都会被发送到Master,然后在行上应用sfunc。
单层聚合和双层聚合是等效的执行策略。任何一种聚合类型都可以在查询计划中实现。当用户实现函数prefunc和sfunc时,必须确保在Segment实例上调用sfunc,然后在主程序上调用prefunc,产生与单级聚合相同的结果,即把所有行发送到主程序,然后只对行应用sfunc。
Hashdata数据库会创建数据类型为stype的临时变量来保存聚合函数的内部状态。在每一个输入行,会计算聚合参数值,并且会调用状态转移函数,通过当前状态值和新的参数值来计算新的内部状态值。在所有的行被处理之后,会调用最终函数以计算该聚合的返回值。如果没有最终函数,则最终状态会被原样返回。
聚合函数可以提供可选的初始条件,即内部状态值的初始值。在数据库中,被指定并且存储为文本类型的值,但它必须是状态值数据类型的常数的有效外部表示。如果没有提供,那么状态值开始时是NULL。
如果状态转移函数声明为STRICT,那么就不能被NULL调用。对于这样的转移函数,聚合执行会按下面的方式执行。带有任何空输入值的行会被忽略(该函数不会被调用并且保持之前的状态值)。如果初始状态值为NULL,那么在第一个具有所有非空输入值的行那里,第一个参数值会替换状态值,并且对后续具有所有非空输入值的行调用转移函数。这对于实现max之类的聚合很有用。注意,只有当state_data_type与第一个input_data_type相同时,这种行为才可用。当这些类型不同时,用户必须提供非空初始条件或者使用非严格的转移函数。
如果状态转移函数没有声明为STRICT,那么它将在每个输入行无条件地调用,并且它必须自行处理NULL输入和NULL转移状态。这允许聚合的作者完全控制聚合对NULL值的处理。
如果最终函数声明为STRICT,那么当结束状态值为NULL时不会调用它,而是自动返回NULL结果(这是STRICT函数的通常行为)。在任何情况下,最终函数都可以选择返回NULL值。例如,avg的最终函数会在零个输入行时返回NULL。
单参数聚合函数(例如min和max)有时候可以通过查看索引而不是扫描所有输入行来优化。如果可以这样优化聚合,可通过指定排序运算符来指明。基本的要求是该聚合必须得到该运算符产生的排序顺序中的第一个元素,换句话说:
SELECT <agg>(<col>) FROM <tab>;
必须等效于:
SELECT <col> FROM <tab> ORDER BY <col> USING <sortop> LIMIT 1;
进一步的假定是聚合函数会忽略NULL输入,并且它只在没有非空输入时才给出NULL结果。通常,数据类型的<运算符是用于MIN的合适的排序运算符,而>是用于MAX的合适的排序运算符。注意除非指定的运算符是B树索引运算符类中的“小于”或者“大于”策略成员,那么这种优化将不会实际生效。
有序聚合
如果出现可选的条件ORDERED,则创建的聚合函数是有序聚合。这种情况下,不能指定预备聚合函数prefunc。
有序聚合使用下面的语法调用。
name ( arg [ , ... ] [ORDER BY sortspec [ , ...]] )
如果省略可选的ORDER BY,则会使用系统定义的排序。有序聚合函数的转移函数sfunc会在其输入参数上以指定顺序在单个Segment上被调用。在pg_aggregate表中有一个新列aggordered来指定聚合函数是否被定义为有序聚合。
参数
- name
要创建的聚合函数的名称(可包括schema信息)。
- input_data_type
聚合函数在进行操作的输入数据类型。要创建零参数的聚合函数,在输入数据类型的列表位置写上*。这类聚合的例子是count(*)。
- sfunc
为每一个输入行调用的状态转移函数的名称。对于有N个参数的聚合函数,sfunc必须接收N+1个参数,第一个参数类型为state_data_type,其余的与聚合的声明输入数据类型匹配。该函数必须返回 state_data_type 类型的值。该函数获取当前状态值和当前输入数据值,并返回下一个状态值。
- state_data_type
聚合状态值的数据类型。
- prefunc
预备聚合函数的名称。这个函数有两个参数,参数的类型都是state_data_type。它必须返回state_data_type类型的值。预备函数会拿到两个转移状态值并且返回一个新的转移状态值来表示组合的聚合。在Hashdata数据库中,如果聚合函数的结果是以分Segment的方式计算,则在各个内部状态上调用组合函数,以便将它们组合成一个结束的内部状态。
注意在Segment内部的哈希聚合模式中也会调用这个函数。因此,如果用户调用这个没有预备函数的聚合函数,则绝不会选中哈希聚合。由于哈希聚合很有效,因此只要可能,还是应该考虑定义预备函数。 - ffunc
在所有输入行被遍历后,为计算聚合结果而调用的最终函数的名称。这个函数必须接收类型为state_data_type的单个参数。该聚合的返回数据被定义为这个函数的返回类型。如果没有指定ffunc,那么结束状态值会被用作聚合结果并且该返回类型为state_data_type。
- initial_condition
状态值的初始设置。这必须是state_data_type可接受形式的字符串常量。如果没有指定,状态值会开始于NULL。
- sort_operator
用于MIN或者MAX类聚合函数的相关排序运算符。这只是运算符名称(可包括schema信息)。该运算符被假定为具有与聚合函数(必须是单参数聚合函数)相同的输入数据类型。
注解
用于定义新聚合函数的普通函数必须先被定义。注意在这个Hashdata数据库的发行中,要求用于创建聚合的sfunc、ffunc以及prefunc函数被定义为IMMUTABLE。
如果在窗口表达式中使用用户定义的聚合,必须为该聚合定义prefunc函数。 如果Hashdata数据库服务器配置参数gp_enable_multiphase_agg的值为off,只有单层聚合会被执行。
任何用于自定义函数的已编译代码(共享库文件)在用户的Hashdata数据库阵列(Master和所有Segment)中的每一台主机上都必须被放置在相同的位置。这个位置还必须在LD_LIBRARY_PATH中,这样服务器可以定位到文件。
示例
下面的例子创建计算两列总和的聚合函数。
在创建聚合函数之前,创建两个被用作该函数的SFUNC和PREFUNC的函数。
这个函数被指定为该聚合函数中的SFUNC函数。
CREATE FUNCTION mysfunc_accum(numeric, numeric, numeric)
RETURNS numeric
AS 'select $1 + $2 + $3'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
这个函数被指定为该聚合函数中的PREFUNC函数。
CREATE FUNCTION mypre_accum(numeric, numeric )
RETURNS numeric
AS 'select $1 + $2'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
CREATE AGGREGATE命令会创建将两列相加的聚合函数。
CREATE AGGREGATE agg_prefunc(numeric, numeric) (
SFUNC = mysfunc_accum,
STYPE = numeric,
PREFUNC = mypre_accum,
INITCOND = 0 );
下列命令创建一个表,增加一些行并且运行聚合函数。
create table t1 (a int, b int) DISTRIBUTED BY (a);
insert into t1 values
(10, 1),
(20, 2),
(30, 3);
select agg_prefunc(a, b) from t1;
这个EXPLAIN命令显示两阶段聚合。
explain select agg_prefunc(a, b) from t1;
QUERY PLAN
--------------------------------------------------------------------------
Aggregate (cost=1.10..1.11 rows=1 width=32)
-> Gather Motion 2:1 (slice1; segments: 2) (cost=1.04..1.08 rows=1
width=32)
-> Aggregate (cost=1.04..1.05 rows=1 width=32)
-> Seq Scan on t1 (cost=0.00..1.03 rows=2 width=8)
(4 rows)
兼容性
CREATE AGGREGATE是Hashdata数据库扩展。SQL标准不提供用户定义的聚合函数。
另见
ALTER AGGREGATE、DROP AGGREGATE、CREATE FUNCTION
CREATE CAST
定义新的数据类型转换。
概要
CREATE CAST (<sourcetype> AS <targettype>)
WITH FUNCTION <funcname> (<argtypes>)
[AS ASSIGNMENT | AS IMPLICIT]
CREATE CAST (<sourcetype> AS <targettype>) WITHOUT FUNCTION
[AS ASSIGNMENT | AS IMPLICIT]
描述
CREATE CAST 定义新的转换。一种转换指定如何在两种数据类型之间执行转换。例如,
SELECT CAST(42 AS text);
通过调用一个之前指定的函数将整数常量 42 转换成类型 text ,这种情况下是 text(int4). 如果没有定义合适的转换, 该转换会失败。
两种类型可以是二进制可兼容,这表示该转换 可以被"免费"执行而不用调用任何函数。这要求相应的 值使用同样的内部表示,例如,类型 text和varchar 二进制可兼容。
默认情况下,只有显式转换请求才会调用转换, 形式是 CAST(x AS typename) or x:: typename construct.
如果转换被标记为 AS ASSIGNMENT 那么在为一个目标数据类型的列赋值时会隐式地调用它。 例如,假设 foo.f1 是一类型为 text的列, 则:
INSERT INTO foo (f1) VALUES (42);
将被允许如果从类型 integer 到类型 text 的转换被标记为AS ASSIGNMENT, 否则不会允许。 我们通常使用 赋值转换 来描述此类转换。
如果转换被标记为 AS IMPLICIT 那么可以在任何上下文中隐式地调用它,无论是赋值还是在一个表达式内部。 我们通常用术语隐式转换 来描述这类转换。例如,因为 || 需要 text操作数,
SELECT 'The time is ' || now();
只有当从timestamp类型到text的转换被标记为implicit时,才会被允许。否则,有必要明确地写出这种转换,例如
SELECT 'The time is ' || CAST(now() AS text);
对标记转换为隐式持保守态度是明智的。过多的隐式转换路径可能导致 Hashdata数据库以令人吃惊的方式解 释命令,或者由于有多种可能解释而根本无法解析命令。 一种好的经验 是让一种转换只对于同一种一般类型分类中的类型间的信息保持转换隐式 可调用。 例如, 从 int2 到 int4 的转换可以被合理地标记为隐式,, 但是从 float8 到int4 的转换可能应该只能在赋值时使用。 跨类型分类 的转换 如 text 到 int4, 最好只被用于显式使用。
为了能够创建一个转换,用户必须拥有源或目标数据类型。要创建二进制兼容的转换,用户必须是超级用户。
参数
- sourcetype
转换的源数据类型的名称。
- targettype
转换的目标数据类型的名称。
- funcname(argtypes)
被用于执行该转换的函数。函数名称可包括schema信息。如果没有包括, 将在schema搜索路径中查找该函数。 函数的结果数据类型必须是该转换的 目标数据类型。
转换实现函数可以具有 1 到 3 个参数。 第一个参数类型必须等于源类型或者 能从源类型二进制强制得到。 第二个参数(如果存在)必须是类型 integer; 它接收与目标类型相关联的类型修饰符,如果没有类型 修饰符,它会收到-1 。第三个参数, (如果存在)必须是类型 boolean; 如果该转换是一种显式转换,它会收到true 否则会收 false 。SQL 标准在 某些情况中对显式和隐式转换要求不同的行为。这个参数被提供给必须实现这 类转换的函数。不推荐在设计自己的数据类型时用它)
通常,转换必须具有不同的源和目标数据类型。 但是,如果具有多个参数的转换实现函数,则允许声明具有相同源和目标类型的转换。 这用于表示系统目录中的特定类型的长度强制功能。 命名函数用于将类型的值强制为由其第二个参数给出的类型修饰符值。 (由于语法目前仅允许某些内置数据类型具有类型修饰符,因此此功能对用户定义的目标类型无效。)
当一个转换具有不同的源和目标类型和一个需要多个参数的函数时,它支持从一个类型转换为另一个类型,并在一个步骤中应用长度强制。 当没有这样的条目可用时, 强制使用类型修饰符的类型涉及两个转换步骤,一个用于在数据类型之间转换,另一个用于应用修饰符。 - WITHOUT FUNCTION
表示源类型可以二进制强制到目标类型,因此执行该转换不需要函数。
- AS ASSIGNMENT
指示该转换可以在赋值的情况下被隐式调用。
- AS IMPLICIT
指示该转换可以在任何上下文中被隐式调用。
注解
请注意,在此版本的Hashdata数据库中,用户定义的转换中使用的用户定义函数必须定义为IMMUTABLE。必须将用于自定义函数的任何编译代码(共享库文件)放置在Hashdata Database数组(Master和所有segment)中每个主机上的相同位置。 这个位置也必须在LD_LIBRARY_PATH 以便服务器可以找到文件。
记住如果用户想要能够双向转换类型,用户需要在两个方向上都显式声明转换。
建议用户遵循在目标数据类型之后命名操行实现函数的惯例,因为内置的操行实现函数能被命名。 许多用户习惯于使用函数式符号来转换数据类型,即 typename(x).
示例
要使用函数int4(text) 创建一种从类型 text 到类型 int4 的赋值转换(在系统中这种转换已经被预定义。):
CREATE CAST (text AS int4) WITH FUNCTION int4(text);
兼容性
CREATE CAST 命令符合 SQL标准, 不过 SQL 没有为二进制可兼容类型或者实现函数的额外参数做好准备。 AS IMPLICIT 也是一种Hashdata数据库的扩展。
另见
CREATE FUNCTION, CREATE TYPE, DROP CAST
CREATE CONVERSION
定义新的编码转换。
概要
CREATE [DEFAULT] CONVERSION <name> FOR <source_encoding> TO
<dest_encoding> FROM <funcname>
描述
CREATE CONVERSION定义了字符集编码之间的新转换。转换名称可以在 convert 函数中用于指定特定的编码转换。此外,被标记为DEFAULT 的转换将被 自动地用于客户端和服务器之间的编码转换。 为了这个目的,必须定义两个 转换(从编码 A 到 B 以及从编码 B 到 A)。
要创建转换,用户必须拥有该函数上的EXECUTE 特权 以及目标schema上的 CREATE 特权。
参数
- DEFAULT
表示这个转换是从源编码到目标编码的默认转换。在一个schema中对于每一个编码对,只应该有一个默认转换。
- name
转换的名称,可包括schema信息。如果没有包括,该转换被定义在 当前schema中。在一个schema中,转换名称必须唯一。
- source_encoding
源编码名称。
- dest_encoding
目标编码名称。
- funcname
被用来执行转换的函数。函数名可包括schema信息。如果没有,将在路径 中查找该函数。 该函数必须具有一下的特征:conv_proc( integer, -- source encoding ID integer, -- destination encoding ID cstring, -- source string (null terminated C string) internal, -- destination (fill with a null terminated C string) integer -- source string length ) RETURNS void;
注解
请注意,在本版本的Hashdata数据库中,用户定义的转换中使用的用户定义函数必须定义为IMMUTABLE. 必须将用于自定义函数的任何编译代码(共享库文件)放置在Hashdata数据库数组(Master和所有Segment)中每个主机上的相同位置。 该位置也必须位于 LD_LIBRARY_PATH中, 以便服务器可以找到文件。
示例
使用 myfunc 创建一个从编码 UTF8 到 LATIN1的转换:
CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;
兼容性
在SQL标准中没有CREATE CONVERSION 语句。
另见
ALTER CONVERSION, CREATE FUNCTION, DROP CONVERSION
CREATE DATABASE
创建新的数据库。
概要
CREATE DATABASE name [ [WITH] [OWNER [=] <dbowner>]
[TEMPLATE [=] <template>]
[ENCODING [=] <encoding>]
[CONNECTION LIMIT [=] connlimit ] ]
描述
要创建新的数据库, 用户必须是超级用户或者有 CREATEDB 特权。
默认情况下,创建者即为新数据库的所有者。超级用户可以通过 OWNER 子句创建使用其他用户拥有的数据库。 他们甚至可以创建没有特殊权限的用户拥有的数据库。 有 CREATEDB 特权的非超级用户只能创建自己拥有的数据库。
默认情况下,将通过克隆标准系统数据库创建新数据库 template1. 可以通过TEMPLATE name来指定不同的模板 . 特别是, 通过写 TEMPLATE template0, 用户可以创建一个干净的数据库,其中只包含 Greenplum 数据库预定义的标准对象。如果用户希望避免复制任何已经添加到template1的本地安装对象,这很有用。
参数
- name
要创建的数据库的名称。
- dbowner
拥有新数据库的数据库用户的名称,或DEFAULT 使用默认的所有者(执行该命令的用户)。
- template
要创建新数据库的模板的名称,或通过 DEFAULT 关键字使用默认模板 (template1).
- encoding
要在新数据库中使用的字符集编码。指定一个字符串常量(例如 'SQL_ASCII')、一个整数编码数字,或者 DEFAULT使用默认编码。
- connlimit
最大并发连接数。缺省值-1表示没有限制。
注解
CREATE DATABASE 不能在事务块内执行。
当用户通过指定其名称作为模板来复制数据库时,在复制数据库时,不会将其他会话连接到模板数据库。 到模板数据库的新连接被锁定,直到CREATE DATABASE 完成。
CONNECTION LIMIT不对超级用户强制执行。
示例
要创建一个新的数据库:
CREATE DATABASE gpdb;
创建数据库 sales, 由用户 salesapp拥有,默认表空间为 salesspace:
CREATE DATABASE sales OWNER salesapp;
创建数据库 music,支持ISO-8859-1字符集:
CREATE DATABASE music ENCODING 'LATIN1';
兼容性
SQL标准中没有CREATE DATABASE语句。 数据库等同于目录,其创建是由实现定义的。
另见
ALTER DATABASE, DROP DATABASE
CREATE DOMAIN
定义新的域。
概要
CREATE DOMAIN <name> [AS] <data_type> [DEFAULT <expression>]
[CONSTRAINT <constraint_name>
| NOT NULL | NULL
| CHECK (<expression>) [...]]
描述
CREATE DOMAIN 创建新的域。域本质上是一种带有可选约束(在允许的值集合上的限制)的数据类型。 定义一个域的用户将成为它的拥有者。 域的名称在其schema中的类型和域之间 必须保持唯一。
域主要被用于把字段上的常用约束抽象到一个单一的位置以便维护。例如, 几个表可能都包含电子邮件地址列, 而且都要求相同的 CHECK 约束来验证地址的语法。可以为此定义一个域,而不是在每个表上都单独设置一个约束。
参数
- name
要被创建的域的名称(可包括schema信息)。
- data_type
域的底层数据类型。可以包括数组指示符。
- DEFAULT expression
子句为该域数据类型的列指定一个默认值。该值是任何没有变量的表达式(但不允许子查询)。 默认值表达式 的数据类型必须匹配域的数据类型。如果没有指定默认值,那么 默认值就是空值。 默认值表达式将被用在任何没有指定列值的插入操作中。如果为一个 特定列定义了默认值,它会覆盖与域相关的默认值。 继而,域默认值会覆盖任何与底层数据类型相关的默认值。
- CONSTRAINT constraint_name
一个约束的名称(可选)。如果没有指定,系统会生成一个名称。
- NOT NULL
这个域的值通常不能为空值。
- NULL
这个域的值允许为空值,这是默认值。 这个子句只是为了与非标准 SQL 数据库相兼容而设计。在新的应用中不鼓励使用它。
- CHECK (expression)
CHECK 子句指定该域的值必须满足的完整性 约束或者测试。 每一个约束必须是一个产生布尔结果的表达式。 它应该使用关键词 VALUE 来引用要被测试的值。 目前, CHECK 表达式不能包含子查询,也不能引用 VALUE之外的变量。
示例
创建 us_zip_code 数据类型。使用正则表达式来验证该值是否为有效的美国邮政编码。
CREATE DOMAIN us_zip_code AS TEXT CHECK
( VALUE ~ '^\\d{5}$' OR VALUE ~ '^\\d{5}-\\d{4}$' );
兼容性
CREATE DOMAIN 符合 SQL 标准。
另见
ALTER DOMAIN, DROP DOMAIN
CREATE EXTERNAL TABLE
定义新的外部表。
概要
CREATE [ { READABLE | WRITABLE } ] EXTERNAL [TEMPORARY | TEMP] TABLE <table_name>
( column_name data_type [, ...] | LIKE other_table )
LOCATION ('s3://<uri>')
FORMAT 'TEXT'
[( [HEADER]
[DELIMITER [AS] 'delimiter' | 'OFF']
[NULL [AS] 'null string']
[ESCAPE [AS] 'escape' | 'OFF']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[FILL MISSING FIELDS] )]
| 'CSV'
[( [HEADER]
[QUOTE [AS] 'quote']
[DELIMITER [AS] 'delimiter']
[NULL [AS] 'null string']
[FORCE NOT NULL column [, ...]]
[ESCAPE [AS] 'escape']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[FILL MISSING FIELDS] )]
| 'ORC'
| 'CUSTOM' (Formatter=<formatter specifications>)
[ OPTIONS (INTEGRATION '<integration_name>') ]
[ ENCODING 'encoding' ]
[ [LOG ERRORS] SEGMENT REJECT LIMIT count
[ROWS | PERCENT] ];
描述
有关外部表的详细信息请参阅Hashdata数据库管理员指南中的装载和卸载数据。
CREATE EXTERNAL TABLE 在Hashdata数据库中创建一个新的可读外部表定义。可读外部表通常用于快速并行数据加载。 定义外部表后,可以使用SQL命令直接(并行)查询其数据。 例如, 用户可以选择,加入或排序外部表数据。用户还可以创建外部表的视图。 DML操作 (更新, 插入, 删除, 或 TRUNCATE) 在可读外部表上不可操作,用户不能在可读外部表上创建索引。
CREATE WRITABLE EXTERNAL TABLE 在Hashdata数据库中创建一个新的可写外部表定义。 可写外部表通常用于将数据从数据库卸载到一组文件或命名管道中。可写外部表格也可以用作Hashdata并行MapReduce计算的输出目标。 一旦写入外部表被定义,可以从数据库表中选择数据并将其插入到可写外部表中。可写的外部表仅允许INSERT操作。不允许执行SELECT,UPDATE,DELETE或TRUNCATE。
该 FORMAT 子句用于描述外部表格文件的格式。 有效的文件格式是分隔文本 (TEXT) 逗号分隔值(CSV) 格式, 与PostgreSQL可用的格式化选项类似 COPY 命令。 如果文件中的数据不使用默认列分隔符,转义字符,空字符串等,则必须指定其他格式选项,以便外部文件中的数据被Hashdata数据库正确读取。 有关使用自定义格式的信息,请参阅Hashdata数据库管理员指南中的装载和卸载数据。
参数
- READABLE | WRITABLE
指定外部表的类型,默认可读。可读外部表用于将数据加载到Hashdata数据库中。可写外部表用于卸载数据。
- table_name
新外部表的名称。
- column_name
在外部表定义中创建的列的名称。与常规表不同,外部表不具有列约束或默认值,因此不要指定。
- LIKE other_table
该LIKE 子句指定新的外部表自动复制所有列名,数据类型和Hashdata分发策略的表。 如果原始表指定了任何列约束或默认列值,那么它们将不会被复制到新的外部表定义中。data_type列的数据类型。
- Location URI
HashdData 同时支持 virtual host style 和 path host style。// virtual host style s3://<bucket>.s3.<region>.amazonaws.com.cn/<prefix> // path host style s3://s3.<region>.amazonaws.com.cn/<bucket>/<prefix>
- FORMAT
当用户用 s3 协议创建一个外部表时,只支持 TEXT,CSV和ORC格式。
注解
指定LOG ERRORS子句时,Hashdata数据库会捕获读取外部表数据时发生的错误。 用户可以查看和管理捕获的错误日志数据。
- 使用内置的SQL函数 gp_read_error_log(‘table_name’)。它需要对table_name具有 SELECT特权。 此示例显示使用COPY命令加载到表 ext_expenses 中的数据的错误日志信息:
SELECT * from gp_read_error_log('ext_expenses');
有关错误日志格式的信息,请参阅 Hashdata数据库管理员指南中的在错误日志中查看不正确的行。
如果 table_name不存在,该函数返回FALSE。 - 如果指定的表存在错误日志数据,新的错误日志数据将附加到现有的错误日志数据。 错误日志信息不会复制到镜像Segment。
- 使用内置的SQL函数 gp_truncate_error_log(‘table_name’) 删除 table_name的错误日志数据。 它需要表所有者权限,此示例删除将数据移动到表中时捕获的错误日志信息 ext_expenses:
SELECT gp_truncate_error_log('ext_expenses');
如果 table_name不存在,该函数返回 FALSE。
指定通配符以删除当前数据库中现有表的错误日志信息。指定字符串 .以删除所有数据库错误日志信息,包括由于以前的数据库问题而未被删除的错误日志信息。如果指定,则需要数据库所有者权限。 如果指定了. 则需要操作系统超级用户权限。
兼容性
CREATE EXTERNAL TABLE 是HashData数据库扩展。SQL标准没有规定外部表。
另见
CREATE TABLE AS, CREATE TABLE, COPY, SELECT INTO, INSERT
示例
-- virtual host style
CREATE READABLE EXTERNAL TABLE example (a int)
LOCATION('s3://example-bucket.s3.cn-north-1.amazonaws.com.cn/folderA/')
OPTIONS(INTEGRATION 's3_int')
FORMAT 'csv';
-- path host style
CREATE READABLE EXTERNAL TABLE example (a int)
LOCATION('s3://s3.cn-north-1.amazonaws.com.cn/example-bucket/folderA/')
OPTIONS(INTEGRATION 's3_int')
FORMAT 'csv';
CREATE FUNCTION
定义新函数。
概要
CREATE [OR REPLACE] FUNCTION <name>
( [ [<argmode>] [<argname>] <argtype> [ { DEFAULT | = } <defexpr> ] [, ...] ] )
[ RETURNS { [ SETOF ] rettype
| TABLE ([{ argname argtype | LIKE other table }
[, ...]])
} ]
{ LANGUAGE <langname>
| IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| NO SQL | CONTAINS SQL | READS SQL DATA | MODIFIES SQL
| [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER
| COST <execution_cost>
| SET <configuration_parameter> { TO <value> | = <value> | FROM CURRENT }
| AS '<definition>'
| AS '<obj_file>', '<link_symbol>' } ...
[ WITH ({ DESCRIBE = describe_function
} [, ...] ) ]
描述
CREATE FUNCTION 用于定义新的函数。CREATE OR REPLACE FUNCTION 要么创建新的函数,要么替换存在的定义。
新函数的名称不得与同一schema中具有相同输入参数类型的任何现有函数匹配。但是,不同参数类型的函数可能共享一个名称(重载)。
要更新现有函数的定义,请使用CREATE OR REPLACE FUNCTION. 无法以这种方式更改函数的名称或参数类型(这实际上会创建一个新的、不同的函数)。此外,CREATE OR REPLACE FUNCTION 不会让用户更改现有函数的返回类型。为此,用户必须删除并重新创建该函数。如果用户删除并重建函数,用户将不得不删除引用该旧函数的现有对象(如规则,视图,触发器等等)用户可以使用 CREATE OR REPLACE FUNCTION 去改变一个函数的定义,而不会破坏引用该函数的对象。
VOLATILE 和 STABLE 函数的限制使用
为了防止数据在Hashdata数据库的各个segment中变得不同步,任何分类为STABLE 或 VOLATILE的函数,如果它包含SQL或以任何方式修改数据库,都不能在segment级别执行。例如, random() 或 timeofday() 函数不允许在Hashdata数据库中的分布式数据上执行,因为他们可能会导致segent实例之间的数据不一致。
为了确保数据的一致性,VOLATILE函数STABLE可以安全地用于在 master 上评估和运行的语句中。例如,以下语句总是在 master 上运行(没有FROM子句的语句):
SELECT setval('myseq', 201);
SELECT foo();
在语句中有一个包含分布式表的FROM子句,而FROM子句中使用的函数只是返回一组行的情况下,可以允许在segment上执行。
SELECT * FROM foo();
此规则的一个例外就是返回表引用 (rangeFuncs)或使用 refCursor 数据类型的函数。请注意用户不能从Hashdata数据库中的任何类型函数返回 refcursor 。
参数
- name
创建函数的名称(可包括schema信息)
- argmode
参数的schema:要么 IN,OUT,INOUT, 或者 VARIADIC。如果省略,默认值为 IN。
- argname
参数名称。某些语言(目前只有 PL/pgSQL) 能让用户在函数体中使用这个名字。但是您可以在调用函数时使用输入参数名称来提高可读性。在任何情况下,输出参数的名称都很重要,因为它定义了结果行类型中的列名。(如果省略输出参数的名称,系统将选择默认列名。)
- argtype
函数参数的数据类型(可包括schema信息),如果有,该参数 可以是 base, composite, 或 domain 类型,或可以引用表列的类型。
根据实现的语言,也可以允许指定诸如cstring之类的伪类型。伪类型表示实际的参数类型是未完全指定的,或者在普通的SQL数据类型之外。
列的类型通过写入 tablename.columnname%TYPE来引用。使用此功能有时可以帮助函数独立于表定义的变更。 - defexpr
如果没有指定参数,则用作默认值的表达式。表达式必须对参数类型是强制的。只有IN 和 INOUT 参数可以有默认值。 参数列表中具有默认值的参数后面的每个输入参数也必须具有默认值。
- rettype
返回数据类型(可包括schema信息)。该返回值可以是base,composite,或 domain类型,或引用表列的类型。根据实现语言,也可以允许它们指定诸如 cstring 之类的伪类型。如果该函数不返回值,可以指定 void 作为其返回类型。
当有 OUT 和 INOUT 参数时, 可以省略RETURNS 子句。如果存在,它必须与输出参数所暗示的结果类型一致: 如果存在多个输出参数或与单个输出参数相同的类型,则为RECORD。
SETOF 修饰符表示该函数将返回一组条目,而不是单个条目。
列的类型通过写入 tablename.columnname%TYPE来引用。 - langname
函数实现的语言名称。可以是 SQL, C,internal,或用户自定义过程语言的名称。为了向后兼容,该名称可以用单引号括起来。
- IMMUTABLE
STABLE
VOLATILE这些属性通知查询优化器有关该函数的行为。最多可以指定一个选项。如果这些都不出现,则 VOLATILE 是默认的。由于Hashdata数据库目前对VOLATILE函数的使用是有限的,如果一个函数是 真正的 IMMUTABLE,你必须声明它才能不受限制地使用它。
IMMUTABLE表示该函数不能修改数据库,并且在给定相同的参数值时总是返回相同的结果。它不进行数据库查找或以其他方式使用不直接出现在其参数列表中的信息。如果给出此选项,则任何具有全常量参数的函数调用都可以立即替换为函数值。
STABLE表示该函数无法修改数据库,并且在单个表扫描中,对于相同的参数值,它将始终如一地返回相同的结果,但其结果可能会在 SQL 语句中发生变化。对于结果取决于数据库查找、参数值(例如当前时区)等的函数,STABLE是适当的选择。另请注意,current_timestamp 系列函数有资格作为稳定函数,因为它们的值在事务中不会改变。
VOLATILE表示即使在单个表扫描中函数值也可以更改,因此无法进行优化。从这个意义上说,相对较少的数据库函数是易变的;一些例子是random(),timeofday()。但请注意,任何具有副作用的函数都必须归类为 volatile,即使其结果是完全可预测的,以防止调用被优化掉;一个例子是setval()。 - CALLED ON NULL INPUT
RETURNS NULL ON NULL INPUT
STRICTCALLED ON NULL INPUT 为默认值,表示某些参数为NULL时,该函数仍能被正常调用。那么该函数的作者有责任在必要时检查空值,并作出适当的响应。 RETURNS NULL ON NULL INPUT 和 STRICT 表示当任何参数为空时,如果指定了该参数,则当有空参数时,该函数将不会执行。 而自动假设为null结果。
- [EXTERNAL] SECURITY INVOKER
[EXTERNAL] SECURITY DEFINERSECURITY INVOKER(默认值)表示该函数将以调用它的用户的权限运行。 SECURITY DEFINER指定该函数将以创建它的用户的权限运行。SQL 一致性允许使用关键字 EXTERNAL,但它是可选的,因为与 SQL 不同,此功能适用于所有函数,而不仅仅是外部函数。
- COST execution_cost
确定估计成本的整数,以 cpu_operator_cost 为单位。 如果函数返回一个集合,execution_cost 会标识每个返回行的成本。如果没有指定成本,C语言和内部函数默认为1个单位,然而其他语言的函数默认100个单位,当用户指定较大的 execution_cost 值时,计划程序会尝试较少的函数评估。
- configuration_parameter
value当输入函数时,SET子句将值应用于会话配置参数。当函数退出时,配置参数将恢复到其先前的值。SET FROM CURRENT在输入函数时应用会话的当前参数值。
- definition
定义函数的字符串常量;意思取决于语言。它可能是内部函数名称,目标文件的路径, 过程化语言文本中的SQL命令。
- obj_file, link_symbol
当C语言源代码中的函数名称和SQL函数的名称不同时,这种形式的 AS 子句用于动态加载C语言函数。字符串 obj_file 是包含动态可加载对象文件的名称, link_symbol 是C语言源代码中的函数名称。如果省略了连接符号,则假定与正在定义的SQL函数的名称相同。建议相对于 $libdir(位于 $GPHOME/lib)或通过动态库路径(由 dynamic_library_path 服务器配置参数所设置)来定位共享库。如果新安装的版本位于不同的位置,则可以简化升级。
- describe_function
解析调用此函数的查询时要运行的回调函数的名称。回调函数返回一个指示结果类型的元组描述符。
注解
输入参数和返回值允许使用完整的 SQL 类型语法。但是,类型规范的一些细节(例如数字类型的精度字段)是底层函数实现的责任,并且不能被 CREATE FUNCTION 命令识别或强制执行。
Hashdata数据库允许函数重载。只要具有不同的参数类型,相同的名字可以用于几个不同的函数。但是,所有函数的C名称必须不同,所以用户必须给重载C函数不同C名称(例如, 使用参数类型作为C名称的一部分)。
两个函数如果他们具有相同的名字和输入的参数类型,那他们就被认为是相同的,而不用考虑任何 OUT 参数。因此例如以下声明会产生冲突:
CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, out text) ...
具有不同参数类型列表的函数在创建的时候不会产生冲突,但是如果提供了参数的默认值,它们在使用中可能会产生冲突。例如:
CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, int default 42) ...
调用 foo(10),由于不知道该调用哪个函数,所以会产生函数调用失败。
当重复地调用 CREATE FUNCTION 时,引用同一个对象文件,该文件只被加载一次。当卸载并重新加载文件时,请使用 LOAD 命令。
用户必须对具有语言的 USAGE 权限才能使用该语言定义函数。
使用美元引用来编写定义字符串,而不是普通单引号语法,这是有帮助的。没有美元引用, 函数定义中的任何单引号或反斜杠必须通过双写来实现转义。美元引用的字符串由美元符号($),零个或者多个字符的可选标记, 另一个美元符号,构成字符串内容的任意字符序列,一个美元符号,开始这个美元引号的同一个标签以及一个美元符号组成。在美元引用的字符串中,可以使用单引号, 反斜杠和任何不需要转义的字符。字符串内容始终以字面形式写入。例如,这里有两种不同的方法来指定字符串 “Dianne’s horse”使用美元引用:
$$Dianne's horse$$
$SomeTag$Dianne's horse$SomeTag$
如果 SET 字句被附加到函数上,则在同一个变量的函数内部执行 SET LOCAL命令的作用仅限于该函数;当函数退出时,配置参数的先前值仍然被恢复。但是,普通的 SET 命令(不带 LOCAL)将覆盖 CREATE FUNCTION SET子句,与之前的 SET LOCAL 命令一样。这样命令的效果将在函数退出后持续,除非当前的事务被回滚。
如果具有 VARIADIC 参数的函数声明为 STRICT,则严格性检查将测试作为整体的可变数组是非空值。如果数组有空元素,PL/pgSQL 仍然会调用该函数。
使用分布式数据查询功能 一些情况下,Hashdata数据库不支持在查询中使用函数,如果该查询的 FROM 子句指定表中的数据分布在Hashdata数据库segment上的话。例如, 该SQL查询包含函数 func():
SELECT func(a) FROM table1;
如果遇到以下所有情况的话,则该函数不支持在查询中使用:
- table1 表的数据分布在Hashdata数据库segemnt上。
- 函数 func() 从分布式表上读或修改数据。
- 函数 func() 返回多个行,或者使用来自table1的参数。
如果任一条件不满足,则不支持该功能。具体来说,如果满足以下任一条件,则支持该功能:
- 函数 func() 不能访问来自分布表的数据,也不能访问仅存在Hashdata数据库主机上的数据。
- 表 table1 仅仅是主机上的表。
- 该函数func()只返回一行,并且只接受常量值的输入参数。如果可以将其更改为不需要输入参数,则支持该函数。
示例
一个简单的加法函数:
CREATE FUNCTION add(integer, integer) RETURNS integer
AS 'select $1 + $2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
在 PL/pgSQL 中增加使用参数名称的整数
CREATE OR REPLACE FUNCTION increment(i integer) RETURNS
integer AS $$
BEGIN
RETURN i + 1;
END;
$$ LANGUAGE plpgsql;
为 PL/pgSQL 函数增加每个查询的默认段主机内存:
CREATE OR REPLACE FUNCTION function_with_query() RETURNS
SETOF text AS $$
BEGIN
RETURN QUERY
EXPLAIN ANALYZE SELECT * FROM large_table;
END;
$$ LANGUAGE plpgsql
SET statement_mem='256MB';
使用多态返回 ENUM 数组:
CREATE TYPE rainbow AS ENUM('red','orange','yellow','green','blue','indigo','violet');
CREATE FUNCTION return_enum_as_array( anyenum, anyelement, anyelement )
RETURNS TABLE (ae anyenum, aa anyarray) AS $$
SELECT $1, array[$2, $3]
$$ LANGUAGE SQL STABLE;
SELECT * FROM return_enum_as_array('red'::rainbow, 'green'::rainbow, 'blue'::rainbow);
返回多个输出参数的记录:
CREATE FUNCTION dup(in int, out f1 int, out f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
用户可以使用明确命名的复合类型更详细地做同样的事情:
CREATE TYPE dup_result AS (f1 int, f2 text);
CREATE FUNCTION dup(int) RETURNS dup_result
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
兼容性
CREATE FUNCTION在 SQL:1999 及更高版本中定义。 该Hashdata数据库版本是相似的,但是不完全兼容。属性不可移植,不同可用语言也不可移植。
为了和其他数据库系统的兼容,可以将 argmode 写在 argname 之前或之后。但只有第一种方式符合标准。
SQL 标准没有指明参数的默认值。
另见
ALTER FUNCTION, DROP FUNCTION, LOAD
CREATE GROUP
定义新的数据库角色。
概要
CREATE GROUP <name> [[WITH] <option> [ ... ]]
该 option 可以是:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEUSER | NOCREATEUSER
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<password>'
| VALID UNTIL '<timestamp>'
| IN ROLE <rolename> [, ...]
| IN GROUP <rolename> [, ...]
| ROLE <rolename> [, ...]
| ADMIN <rolename> [, ...]
| USER <rolename> [, ...]
| SYSID <uid>
描述
从Hashdata数据库2.2版开始,CREATE GROUP 已经被 CREATE ROLE所取代, 不过为了向后兼容,它仍然被接受。
兼容性
在SQL标准中没有 CREATE GROUP 语句。
另见
CREATE ROLE
CREATE OPERATOR
定义新的运算符。
概要
CREATE OPERATOR <name> (
PROCEDURE = <funcname>
[, LEFTARG = <lefttype>] [, RIGHTARG = <righttype>]
[, COMMUTATOR = <com_op>] [, NEGATOR = <neg_op>]
[, RESTRICT = <res_proc>] [, JOIN = <join_proc>]
[, HASHES] [, MERGES]
[, SORT1 = <left_sort_op>] [, SORT2 = <right_sort_op>]
[, LTCMP = <less_than_op>] [, GTCMP = <greater_than_op>] )
描述
CREATE OPERATOR定义了一个新的运算符。定义运算符的用户成为其所有者。
运算符名称是以下列表中最多NAMEDATALEN-1(默认为 63 个)字符的序列:+ - * / < > = ~ ! @ # % ^ & | ` ?
用户选择的名称有一些限制:
- – 和 /* 不能出现在运算符的任何位置,因为他们被认为是注释的开始。
- 多字符运算符不能以 + 或 -结束, 除非该名字包含一个以下的字符: ~ ! @ # % ^ & | ` ?
例如, @- 是一个合法的运算符名字,但是 *- 却不是一个合法的运算符名字,该限制允许Hashdata数据库去解析复合SQL的命令,而不需要字符之间的空格。
运算符 != 在输出上映射为 <> ,所以这两个名字总是相等的。
至少定义 LEFTARG 和 RIGHTARG 中的一个。对于二进制运算符来说,两个都需要定义。对于右元运算符来说,只要 LEFTARG 需要定义,然而对于左元运算符来说,只要 RIGHTARG 被定义就行了。
该 funcname 程序必须使用 CREATE FUNCTION预定义,必须是 IMMUTABLE, 必须定义为能够接受正确的指定类型的参数个数(一个或者两个)
其他子句指出了可选的运算符优化子句,应在适当时提供这些子句,以加快使用运算符的查询。如果用户提供了这些子句,则须确保他们是正确的。不正确的使用优化子句可能导致服务进程的崩溃,错误输出或是其他意外结果。如果用户不确定,用户可以随时省略优化的句子。
参数
- name
将要定义的运算符的名字(可包括schema信息)。如果同一schema中的两个运算符对不同的数据类型进行操作,则它们可以具有相同的名称。
- funcname
实现该运算符的函数(必须是 IMMUTABLE 函数)。
- lefttype
该运算符左操作数的数据类型。对于左元运算符省略此选项。
- righttype
该运算符右操作数的数据类型。对于右元运算符省略此选项。
- com_op
可选的 COMMUTATOR 子句命名了一个运算符,该运算符是正在定义的运算符的交换器。如果 (x A y) 对于所有可能的输入值 x, y 等于 (y B x),我们说算子 A 是算子 B 的交换子。请注意,B 也是 A 的交换子。例如,对于特定数据类型,运算符 <和 >通常是彼此的交换子,而运算符 + 通常与自身可交换。但是运算符 -通常不能与任何东西交换。可交换运算符的左操作数类型与其交换子的右操作数类型相同,反之亦然。因此在 COMMUTATOR 子句中需要提供交换器的名称。
- neg_op
可选 NEGATOR子句命名一个运算符,该运算符是所定义运算符的否定符。如果对于所有可能的输入 x,y,两者都返回布尔结果并且 (x A y) 等于 NOT (x B y),则我们说运算符 A 是运算符 B 的否定器。请注意,B 也是 A 的否定符。例如, <并且 >=是大多数数据类型的否定符对。运算符的否定符必须与要定义的运算符具有相同的左和/或右操作数类型,因此只需要在 NEGATOR子句中给出运算符名称。
- res_proc
可选的 RESTRICT 命名了运算符的限制选择性估计函数,请注意,这只是一个函数名称,不是运算符的名称。RESTRICT 子句仅对返回 boolean的二进制运算符才有意义。限制选择性估计器背后的想法是猜测表中的哪几行满足以下格式的WHERE子句条件:column OP constant
对于当前运算符和一个特定的常量值。这有助于优化器,让它了解有多少行会被具有这种形式的WHERE子句所消除。用户通常可以为自己的运算符使用以下系统估计器函数之一:
eqsel for =
neqsel for <>
scalarltsel for < or ⇐
scalargtsel for > or >= - join_proc
可选JOIN子句为运算符命名连接选择性估计函数。请注意,这是一个函数名称,而不是运算符名称。JOIN子句只对返回的二元运算符有意义boolean。连接选择性估计器背后的想法是猜测一对表中的行的哪一部分将满足WHERE形式的条件table1.column1 OP table2.column2
: 对于当前操作员。这有助于优化器确定几个可能的连接序列中的哪一个可能需要最少的工作。
用户通常可以为许多自己的运算符使用以下系统标准连接选择性估计函数之一。
eqjoinsel for =
neqjoinsel for <>
scalarltjoinsel for < or ⇐
scalargtjoinsel for > or >=
areajoinsel for 2D area-based comparisons
positionjoinsel for 2D position-based comparisons
contjoinsel for 2D containment-based comparisons - HASHES
可选HASHES子句告诉系统允许使用散列连接方法进行基于此运算符的连接。HASHES 仅对返回boolean的二进制运算符才有意义。哈希连接运算符只能对左右值对都哈希到相同哈希码的情况才返回true。如果这两个值被放在了不同的哈希桶中,则该连接将永远不会比较他们。隐式假设连接运算符的结果必须为假。因此,对于不代表相等性的运算符,指定 HASHES是没有意义的。
要标记为 HASHES,该连接运算符必须出现在哈希索引运算符类中。如果不存在这样的运算符类,试图在运行时的哈希连接中使用运算符将导致失败。系统需要运算符类来找到运算符输入的数据类型的特定哈希函数。用户还必须提供合适的哈希函数,然后才能创建运算符号类,在准备哈希函数时要小心,因为有依赖机器的方法,该方法将可能无法做正确的事情。 - MERGES
MERGES 子句(如果存在)告诉系统可以使用基于此运算符的连接的合并方法。 MERGES 仅对于返回布尔值的二进制运算符才是有意义的,实际上,运算符必须表示某些数据类型或数据类型对的等式。
合并连接是基于按顺序排列的左右表格,然后并行扫描他们,因此,两种数据类型都能被完全排序,并且连接运算符必须只能对在排序顺序中位于相同位置的值对才能成功。实际上,这意味着连接运算符的行为必须像一个相等运算符。只要逻辑上兼容,就可以合并——连接两个不同的类型。例如,小整型对整数相等运算符是合并连接。我们只需排序运算符,这两个数据类型都将在成逻辑上相容的序列。
注解
任何实现该运算符的函数必须定义成 IMMUTABLE。
示例
下面创建一个运算符来加两个复数的例子,假设我们已经创建了 complex 类型。 首先定义执行工作的函数,然后定义运算符:
CREATE FUNCTION complex_add(complex, complex)
RETURNS complex
AS 'filename', 'complex_add'
LANGUAGE C IMMUTABLE STRICT;
CREATE OPERATOR + (
leftarg = complex,
rightarg = complex,
procedure = complex_add,
commutator = +
);
在查询中使用运算符:
SELECT (a + b) AS c FROM test_complex;
兼容性
CREATE OPERATOR 是Hashdata数据库的语言扩展。 SQL标准没有提供用户自定义运算符。
另见
CREATE FUNCTION, CREATE TYPE, ALTER OPERATOR, DROP OPERATOR
CREATE ROLE
定义新的数据库角色(用户或组)。
概要
CREATE ROLE <name> [[WITH] <option> [ ... ]]
其中option可以是:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEEXTTABLE | NOCREATEEXTTABLE
[ ( <attribute>='<value>'[, ...] ) ]
where <attributes> and <value> are:
type='readable'|'writable'
protocol='gpfdist'|'http'
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| CONNECTION LIMIT <connlimit>
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<password>'
| VALID UNTIL '<timestamp>'
| IN ROLE <rolename> [, ...]
| ROLE <rolename> [, ...]
| ADMIN <rolename> [, ...]
| RESOURCE QUEUE <queue_name>
| [ DENY <deny_point> ]
| [ DENY BETWEEN <deny_point> AND <deny_point>]
描述
角色是一个实体,可以拥有数据库对象并且有数据库权限。角色可以是用户,组,或者两者都是,这取决于它是怎么用的。用户必须有 CREATEROLE 权限或者是超级用户才能用此命令。
注意角色是在系统层级定义的,对Hashdata数据系统所有数据库都有效。
参数
- name
新角色的名字。
- SUPERUSER
NOSUPERUSER如果指定了 SUPERUSER,该定义的角色将是个超级用户,他可以覆盖数据库中的所有访问限制。超级用户状态是危险的,只应在真正需要时使用。用户自己必须是超级用户才能创建新的超级用户。默认是 NOSUPERUSER。
- CREATEDB
NOCREATEDB如果指定了 CREATEDB,被定义的角色将被允许定义新数据库。NOCREATEDB(默认)将会禁止用户创建数据库的能力。
- CREATEROLE
NOCREATEROLE如果指定了 CREATEDB,该被定义的角色将被允许创建新的角色,修改其他角色和删除其他角色。 NOCREATEROLE(默认值)将会禁止用户创建或修改(除了他们自己的)角色的能力。
- CREATEEXTTABLE
NOCREATEEXTTABLE如果指定了 CREATEEXTTABLE,被定义的角色将被允许创建外部表。该默认的 类型 是 readable ,如果没有指定,则默认的 协议 是 gpfdist。 NOCREATEEXTTABLE(默认值)禁止了角色创建外部表的能力。注意使用 file 或 execute 协议的外部表只能由超级用户创建。
- INHERIT
NOINHERIT如果指定,INHERIT (默认值)允许角色使用该直接或间接所属所有角色的数据库权利。使用 NOINHERIT,其他角色的成员资格仅通过SET ROLE 授予到其他角色。
- LOGIN
NOLOGIN如果指定,LOGIN 允许该角色登录数据库,使用 LOGIN 属性的角色可以被认为是一个用户。使用 NOLOGIN(默认值)的角色对管理数据库非常有用,可以被认为是组。
- CONNECTION LIMIT connlimit
该角色所能创建的最大并发连接数。默认值-1表示没有限制。
- PASSWORD password
为使用 LOGIN 属性的角色设置用户密码。如果用户没有打算使用密码授权,用户可以省略该属性。如果没有指定密码,该密码将被置为null,并且对该用户来说密码授权始终无效。null密码可选择性的写明为 PASSWORD NULL。
- ENCRYPTED
UNENCRYPTED这些关键字控制密码是否加密存储在系统目录中。(如果没指定,则默认行为由配置参数 password_encryption决定。)如果提供的密码字符串已经是MD5加密的格式,则无论是否指定了 ENCRYPTED 或 UNENCRYPTED 都会按原样加密存储(因为系统不能解密指定加密的密码字符串)。这允许在转储/恢复期间重新加载加密的密码。
注意老客户端可能缺乏对MD5认证机制的支持,系统需要该机制来和存储的密码一起工作。 - VALID UNTIL ‘timestamp’
该 VALID UNTIL 子句设置了日期和时间,在此时间日期之后角色的密码不再有效。如果省略了该子句,则密码将永远不会过期。
- IN ROLE rolename
将新角色添加为命令角色们的成员。请注意无法添加管理员新角色;使用单独的 GRANT 的命令可以做到。
- ROLE rolename
将命名的角色添加为该角色的成员,将该角色变成一个组。
- ADMIN rolename
该 ADMIN 子句像 ROLE,但是命令的角色通过 WITH ADMIN OPTION被添加到新角色中,给他们能授予其他用户该组成员的权利。
- RESOURCE QUEUE queue_name
新的用户级角色被分配到的资源队列名称。仅带有 LOGIN 权利的角色能被分配到资源队列。特殊的关键字 NONE 意味着该角色被分配到默认的资源队列,一个角色只能被分配到一个资源队列。
带有 SUPERUSER 属性的角色免于资源队列的限制。对于超级用户角色来说,查询总是立即运行而不顾资源队列施加的限制。 - DENY deny_point
DENY BETWEEN deny_point AND deny_point
DENY 和 DENY BETWEEN 关键字设置了基于时间的限制,该限制在登录的时候被强制。DENY设置了天或天和时间来拒绝访问。 DENY BETWEEN设置了访问拒绝后的间隔。两个都用参数 deny_point ,该参数有以下格式:DAY day [ TIME 'time' ]
该 deny_point 参数的两个部分使用以下格式:
对于day:{'Sunday' | 'Monday' | 'Tuesday' |'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 0-6 }
对于time:
{ 00-23 : 00-59 | 01-12 : 00-59 { AM | PM }}
DENY BETWEEN 子句使用两个 deny_point 参数:
DENY BETWEEN deny_point AND deny_point
注解
添加删除角色成员(管理组)最偏爱的方式就是使用 GRANT 和 REVOKE。
VALID UNTIL 子句仅对密码定义了期限时间,而不是对角色。当使用非基于密码授权方式登录时,该期限时间是不生效的。
INHERIT 属性控制可授权权限的继承(数据库对象和角色成员资格的访问权限)。它不适用与由 CREATE ROLE 和 ALTER ROLE设置的特殊角色属性。例如,成为具有 CREATEDB 权限的角色的成员,即使设置了 INHERIT,也不会授予创建数据库的功能。这些特权/属性永远不会被继承:SUPERUSER, CREATEDB, CREATEROLE, CREATEEXTTABLE, LOGIN, 和 RESOURCE QUEUE. 必须在每个用户级角色上设置这些属性。
为了向后兼容,INHERIT 属性是默认的。在先前Hashdata数据库的发行版中,用户通常访问他们所属组的所有权限。但是,NOINHERIT 提供了一个与SQL标准中指定语义更合适的匹配
小心使用 CREATEROLE 权限。对于CREATEROLE角色,并没有继承的概念。这意味着即使角色没有特定的权限,也允许创建其他角色,它可以轻松地创建具有不同于其自己权限的其他角色(除了使用超级用户创建角色)。例如,如果角色具有 CREATEROLE 权限但是不具有 CREATEDB 权限,它可以创建一个带有 CREATEDB 权限的角色。因此,将具有 CREATEROLE 权限的角色视为几乎具有超级用户角色。
永远不会对超级用户强制执行该CONNECTION LIMIT选项。
当使用此命令指定一个未加密的密码时候,必须小心。该密码将以明文形式发送到服务器,也可能会记录在客户端的命令历史记录或服务器日志中。然而,客户端程序 createuser发送加密的密码。此外, psql 还包含命令 \password,可以用来安全的更改密码。
示例
创建一个可以登录的角色,但是不给密码:
CREATE ROLE jonathan LOGIN;
创建一个属于资源队列的角色:
CREATE ROLE jonathan LOGIN RESOURCE QUEUE poweruser;
创建一个带密码的角色,改密码有效期到2016年底(CREATE USER 和 CREATE ROLE 相同除了前者暗示了 LOGIN):
CREATE USER joelle WITH PASSWORD 'jw8s0F4' VALID UNTIL '2017-01-01';
创建一个可以创建db和管理其他角色的角色:
CREATE ROLE admin WITH CREATEDB CREATEROLE;
创建一个不允许在星期天登录的角色:
CREATE ROLE user3 DENY DAY 'Sunday';
兼容性
SQL 标准定了用户和角色的概念,但是把他们视为不同的概念,并且让所有定义用户的命令由数据库实现指定。在Hashdata数据库中,用户和角色被统一为单个类型的对象。因此,角色有比标准中更多的可选属性。
CREATE ROLE 在SQL标准中,但是该标准只需要语法:
CREATE ROLE name [WITH ADMIN rolename]
允许多个初始管理员,CREATE ROLE的所有其他选项,都是Hashdata数据库扩展。
由 SQL 标准指定的行为和给与用户 NOINHERIT 属性最为接近,然而角色则赋予 INHERIT 属性。
另见
SET ROLE, ALTER ROLE, DROP ROLE, GRANT, REVOKE, CREATE RESOURCE QUEUE
CREATE RULE
定义新的重写规则。
概要
CREATE [OR REPLACE] RULE <name> AS ON <event>
TO <table_name> [WHERE <condition>]
DO [ALSO | INSTEAD] { NOTHING | <command> | (<command>; <command>
...) }
描述
CREATE RULE定义应用于指定表或视图的新规则。CREATE OR REPLACE RULE将创建一个新规则,或替换同一个表的同名现有规则。
Greenplum 数据库规则系统允许定义对数据库表中的插入、更新或删除执行的替代操作。当给定表上的给定命令运行时,规则会导致运行附加或备用命令。规则也能应用于视图。意识到规则实际上是命令转换机制,或是命令宏是很重要的。转换在执行命令开始之前发生,它不像触发器那样为每个物理行独立运行。
ON SELECT 规则必须是无条件的 INSTEAD 规则,并且必须具有由单个 SELECT 命令组成的操作。因此,ON SELECT 能有效的将表转换成视图,其视图内容是规则的SELECT 命令返回的行,而不是存储在表中的任何内容(如果有的话)。编写 CREATE VIEW 命令的风格比创建真实的表并且在其上定义ON SELECT规则要好很多。
用户可以通过定义 ON INSERT, ON UPDATE,和 ON DELETE 规则来创建可更新的视图的错觉,以便在其他表带有更新操作的视图上替换更新操作。
如果用户尝试使用条件规则进行视图更新,则会遇到一个问题:对于希望在视图中允许的每一个操作,必须要有一个无条件的 INSTEAD 规则。如果规则是有条件的或不是INSTEAD,则系统仍将拒绝执行更新操作的尝试,因为它认为在某些情况下可能会尝试对视图的虚拟表执行操作。如果要处理条件规则中的所有可用的情况,请添加无条件的 DO INSTEAD NOTHING 规则来确保系统理解它将永远不会被调用来更新虚拟表。然后使条件规则为非INSTEAD;在应用他们的场景中,他们添加到默认的 INSTEAD NOTHING 操作。(但是,该方法目前无法支持 RETURNING 查询)
参数
- name
要创建的规则的名称。这必须与同一表的任何其他规则的名称不同。同一表和同一事件类型上的多个规则按字母名称顺序应用。
- event
事件是SELECT,INSERT, UPDATE,或DELETE之一。
- table
规则所应用的表或视图的名称(可包括schema信息)。
- condition
任何SQL的条件表达式(返回布尔值)。该条件表达式可能不会引用任何表除了 NEW 和 OLD,并且可能不会包含聚合函数。 NEW 和 OLD 引用参考表中的值。NEW表在 ON INSERT 和 ON UPDATE规则中有效,以引用要插入或更新的新行。OLD 表在 ON UPDATE 和 ON DELETE规则中有效,以引用将要被更新或者删除的行。
- INSTEAD
提示该命令应当替代原命令运行。
- ALSO
提示该命令应当附加到原命令上运行。如果不指定是 ALSO也不指定 INSTEAD,则默认是ALSO。
- command
构成规则操作的命令或命令组。有效的命令是 SELECT,INSERT,UPDATE,或 DELETE。特殊表名 NEW 和 OLD 可能会被用来引用在参考表中的值。 NEW 在 ON INSERT 和 ONUPDATE 规则中有效,以引用被更新或插入的新行。OLD 在 ON UPDATE 和 ON DELETE 规则中有效,以引用将被更新和删除的行。
注解
用户必须是表的拥有者才能为其创建和改变规则。
注意避免递归规则是很重要的,递归规则在规则创建时不会被验证,但会在执行时报告错误。
示例
创建一个规则,当用户试图插入已分区的父表rank时,向子表b2001插入记录。
CREATE RULE b2001 AS ON INSERT TO rank WHERE gender='M' and
year='2001' DO INSTEAD INSERT INTO b2001 VALUES (NEW.id,
NEW.rank, NEW.year, NEW.gender, NEW.count);
兼容性
就如同整个查询重写系统一样,CREATE RULE是Hashdata数据库语言的扩展。
另见
DROP RULE, CREATE TABLE, CREATE VIEW
CREATE SCHEMA
定义新的schema。
概要
CREATE SCHEMA <schema_name> [AUTHORIZATION <username>]
[<schema_element> [ ... ]]
CREATE SCHEMA AUTHORIZATION <rolename> [<schema_element> [ ... ]]
描述
CREATE SCHEMA 将新的schema输入到当前的数据库中。schema名称必须与当前数据库中现有的名称不同。
schema本质上是一个命名空间:它包含命名对象(表、数据类型、函数和运算符),其名称可能与其他schema中存在的其他对象的名称重复。命名对象可以通过使用schema名称作为前缀来限定它们的名称,或者通过设置包含所需schema的搜索路径来访问。指定非限定对象名称的CREATE命令在当前schema中创建对象(搜索路径前面的对象,可以使用函数 current_schema确定)。
可选择地是, CREATE SCHEMA 可以包含子命令来在新schema中创建对象。这些子命令本质上和创建schema之后发出的单独命令相同, 除了如果使用 AUTHORIZATION 子句,所有创建的对象由该角色有用。
参数
- schema_name
创建schema的名称,如果省略,则用户名被用作schema名。该名字不能以 pg_开头,因为这些名字是为系统目录schema保存的。
- rolename
拥有该schema的角色的名称。如果省略,默认为执行该命令的角色。只有超级用户可以创建自己以外的角色拥有的schema。
- schema_element
定义在schema中创建对象的SQL语句。目前,只有 CREATE TABLE,CREATE VIEW,CREATE SEQUENCE,CREATE TRIGGER 和 GRANT 被认作为 CREATE SCHEMA中的子句。其他对象可能在schema创建之后以单独的命令来创建。
注意:Hashdata数据库不支持触发器
注解
要创建schema,该调用用户必须要有当前数据库的 CREATE权限或者是超级用户。
示例
创建一个schema:
CREATE SCHEMA myschema;
为角色 joe 创建schema(该schema也叫 joe):
CREATE SCHEMA AUTHORIZATION joe;
兼容性
SQL标准允许在 CREATE SCHEMA中的 DEFAULT CHARACTER SET 子句,以及比Hashdata数据库目前接受的更多的子命令类型。
SQL标准指定了在 CREATE SCHEMA 中的子命令可以出现在任何顺序。目前Hashdata数据库实现不能处理子命令中所有转发引用的问题。有时,有必要重新排序子命令,以避免转发引用。
根据SQL标准,schema的拥有者通常拥有里面的所有对象。Hashdata数据库允许对象包含不是schema对象本身拥有的对象。这当且仅当schema拥有者给其他人授权了 CREATE 权限。
另见
ALTER SCHEMA, DROP SCHEMA
CREATE SEQUENCE
定义新的序列生成器。
概要
CREATE [TEMPORARY | TEMP] SEQUENCE <name>
[INCREMENT [BY] <value>]
[MINVALUE <minvalue> | NO MINVALUE]
[MAXVALUE <maxvalue> | NO MAXVALUE]
[START [ WITH ] <start>]
[CACHE <cache>]
[[NO] CYCLE]
[OWNED BY { <table>.<column> | NONE }]
描述
CREATE SEQUENCE 创建新的序列数字生成器。 这包含了创建和初始化一个新的特殊的单行表。该生成器将被执行该命令的用户所拥有。
如果给定了schema名称,则序列在指定的schema上建立。否则在当前的schema中建立。临时序列存在于特殊的schema中,所以创建临时序列时一般不会给定schema名。序列名称不能和同schema中的其他序列,表,索引或视图同名。
创建序列之后,用户可以使用 nextval 函数来操作序列。例如,插入一行到表中要获取序列的下一个值:
INSERT INTO distributors VALUES (nextval('myserial'), 'acme');
用户也可以使用函数 setval 来操作序列,但仅适用于不对分布式数据进行操作的查询。例如,以下的查询是允许的,因为它对主机上的序列生成器进程重置了序列计数器的值:
SELECT setval('myserial', 201);
但是以下Hashdata数据库中的查询将会拒绝,因为它操作了分布式的数据:
INSERT INTO product VALUES (setval('myserial', 201), 'gizmo');
在常规数据库中(非分布式的),对序列进行操作的函数会转到本地序列表以获取所需的值。但是, 在Hashdata数据库中,要注意每个segment都是它自己特有的数据库进程。因此segment需要单个真值点来获取序列值,以至于所有的segment都能正确的递增,并且使得序列能以正确的顺序向前移动。序列服务器进程在主机上运行,是Hashdata分布式数据库中序列的真值点(point-of-truth),segment在运行时从主机获取序列值。
因为该分布式序列的设计,在对Hashdata数据库操作序列的函数上有一些限制:
- 不支持lastval 和 currval 函数。
- setval 只能用来设置主机上序列生成器的值,不能用来在子查询中更新分布式表数据的记录。
- nextval()有时会根据查询从 master 中获取一个值块供segment使用。因此,如果在segment级别证明不需要所有块,则有时可能会在序列中跳过值。请注意,常规 PostgreSQL 数据库也会这样做,因此这不是 Hashdata 数据库独有的。
尽管用户不能直接更新一个序列,但是用户可以使用以下查询:
SELECT * FROM sequence_name;
来检查参数和当前序列的状态。尤其是, 序列的 last_value 字段显示了任何会话所分配的最后值。
参数
- TEMPORARY | TEMP
如果指定了该字段,则该序列对象仅为该会话所创建,并且会在会话退出时,自动删除。当临时序列存在时,具有相同名称的现有永久序列不可见(在此会话中),除非它们被包括schema信息的名称引用。
- name
所创建的序列的名字(可包括schema信息)
- increment
指定将哪个值添加到当前序列值以创建新值。正值表示升序,负值表示降序。默认值为 1。
- minvalue
NO MINVALUE决定该序列所能生成的最小的值,如果没有提供该子句或者指定了 NO MINVALUE,则使用默认值。该升序,降序默认值分别为 1 和 -263-1。
- maxvalue
NO MAXVALUE决定该序列产生的最大值,如果没有提供该子句或者指定了 NO MAXVALUE,则将使用默认值。该升序,降序的默认值分别为263-1 and -1。
- start
允许序列能在任何地方开始,该升序的默认开始值为 minvalue,降序的默认开始值为 maxvalue。
- cache
指明了有多少预先分配并存在内存中供快速访问的序列值。最小值(也是默认值)是1(无cache)。
- CYCLE
NO CYCLE序列允许轮回当达到了 maxvalue(对升序来说)或 minvalue(对降序来说。如果达到了限制,下个生成的值将是 minvalue(对升序来说)或者 maxvalue(对降序来说)。如果指定了NO CYCLE ,任何在序列达到了极限时对 nextval 的调用都将会返回错误。如果没有指定,则默认是NO CYCLE。
- OWNED BY table.column
OWNED BY NONE会导致序列和一个特定表列相联系,因此如果删除该表列(或者删除整个表),该序列也将会自动删除,该指定的表必须和序列有相同的拥有者,并且在同一schema中。默认值为 OWNED BY NONE 指明没有这样的联系。
注解
序列基于 bigint 算法,因此范围不能超过一个八字节整数的范围(-9223372036854775808 到 9223372036854775807)。
尽管保证多个会话分配不同的序列值,但当考虑所有会话时,这些值可能会乱序生成。例如,会话A保留值1..10 并且返回 nextval=1,然后会话B可能在会话A生成nextval=2之前保留值 11..20 并且返回 nextval=11。因此,用户应该只假设 nextval 都是不同的,而不是纯粹按顺序生成。此外,last_value会反应任何会话保留的最新值。无论其是否已被 nextval返回。
示例
创建名为 myseq 的序列:
CREATE SEQUENCE myseq START 101;
使用next value向表中插入一行数据:
INSERT INTO distributors VALUES (nextval('myseq'), 'acme');
重置主机上序列计数器的值:
SELECT setval('myseq', 201);
Hashdata数据库中非法使用 setval(在分布式数据上设置序列的值):
INSERT INTO product VALUES (setval('myseq', 201), 'gizmo');
兼容性
CREATE SEQUENCE 遵循 SQL 标准,但是以下除外:
- 不支持该在SQL标准中指定的 AS data_type 表达式
- 使用 nextval() 函数替代SQL标准中指定的 NEXT VALUE FOR 表达式获得下一个值。
- 该 OWNED BY 子句是Hashdata数据库扩展。
另见
ALTER SEQUENCE, DROP SEQUENCE
CREATE TABLE
定义新表。
注意: 引用完整性约束(外键约束)被接受但不强制执行。
概要
CREATE [[GLOBAL | LOCAL] {TEMPORARY | TEMP}] TABLE <table_name> (
[ { <column_name> <data_type> [ DEFAULT <default_expr> ]
[<column_constraint> [ ... ]
[ ENCODING ( <storage_directive> [,...] ) ]
]
| <table_constraint>
| LIKE <other_table> [{INCLUDING | EXCLUDING}
{DEFAULTS | CONSTRAINTS}] ...}
)
[ WITH ( <storage_parameter>=<value> [, ... ] )
[ ON COMMIT {PRESERVE ROWS | DELETE ROWS | DROP} ]
[ DISTRIBUTED BY (<column>, [ ... ] ) | DISTRIBUTED RANDOMLY ]
[ PARTITION BY <partition_type> (<column>)
[ SUBPARTITION BY <partition_type> (<column>) ]
[ SUBPARTITION TEMPLATE ( <template_spec >) ]
[...]
( <partition_spec> )
| [ SUBPARTITION BY <partition_type> (<column>) ]
[...]
( <partition_spec>
[ ( <subpartition_spec>
[(...)]
) ]
)
其中column_constraint是:
[CONSTRAINT <constraint_name>]
NOT NULL | NULL
其中一列的 storage_directive 是:
COMPRESSTYPE={ZLIB | ZSTD| RLE_TYPE | NONE}
[COMPRESSLEVEL={0-9} ]
[BLOCKSIZE={8192-2097152} ]
其中一个表的 storage_parameter 是:
APPENDONLY={TRUE|FALSE}
ORIENTATION={COLUMN|ROW}
CHECKSUM={TRUE|FALSE}
COMPRESSTYPE={ZLIB|ZSTD|RLE_TYPE|NONE}
FILLFACTOR={10-100}
OIDS[=TRUE|FALSE]
table_constraint是:
[CONSTRAINT constraint_name]
| CHECK ( expression )
其中 key_checking_mode 是:
DEFERRABLE
| NOT DEFERRABLE
| INITIALLY DEFERRED
| INITIALLY IMMEDIATE
其中 partition_type 是:
LIST
| RANGE
其中 partition_specification 是:
<partition_element> [, ...]
partition_element是:
DEFAULT PARTITION <name>
| [PARTITION <name>] VALUES (<list_value> [,...] )
| [PARTITION <name>]
START ([<datatype>] '<start_value>') [INCLUSIVE | EXCLUSIVE]
[ END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE] ]
[ EVERY ([<datatype>] [<number | >INTERVAL] '<interval_value>') ]
| [PARTITION <name>]
END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE]
[ EVERY ([<datatype>] [<number | >INTERVAL] '<interval_value>') ]
[ WITH ( <partition_storage_parameter>=<value> [, ... ] ) ]
[ TABLESPACE <tablespace> ]
其中 subpartition_spec 或 template_spec 是:
<subpartition_element> [, ...]
subpartition_element 是:
DEFAULT SUBPARTITION <name>
| [SUBPARTITION <name>] VALUES (<list_value> [,...] )
| [SUBPARTITION <name>]
START ([<datatype>] '<start_value>') [INCLUSIVE | EXCLUSIVE]
[ END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE] ]
[ EVERY ([<datatype>] [<number | >INTERVAL] '<interval_value>') ]
| [SUBPARTITION <name>]
END ([<datatype>] '<end_value>') [INCLUSIVE | EXCLUSIVE]
[ EVERY ([<datatype>] [<number | >INTERVAL] '<interval_value>') ]
[ WITH ( <partition_storage_parameter>=<value> [, ... ] ) ]
[ TABLESPACE <tablespace> ]
其中一个分区的 storage_parameter 是:
APPENDONLY={TRUE|FALSE}
BLOCKSIZE={8192-2097152}
ORIENTATION={COLUMN|ROW}
CHECKSUM={TRUE|FALSE}
COMPRESSTYPE={ZLIB|QUICKLZ|RLE_TYPE|NONE}
COMPRESSLEVEL={1-9}
FILLFACTOR={10-100}
OIDS[=TRUE|FALSE]
描述
CREATE TABLE 在当前数据库中创建一个初始为空的表。发出该命令的人拥有该表。
如果用户指定了一个schema名字,Hashdata在特定的schema中创建该表。否则Hashdata数据库在当前的schema中创建该表。临时表存在于特殊的schema中,所以用户在创建临时表时不能指定一个schema名。在同一个schema中,表必须和其他表,外部表,序列,索引或者视图不同名。
该可选约束子句指定了条件,该新行或者更新的行必须满足该条件才能成功进行插入或更新操作。约束是一个SQL对象,该对象以不同的方式在表中帮助定义有效值集合。约束应用于表,而不是分区,用户不能添加一个约束到分区或者子分区。
有两种定义约束的方式:表约束和列约束。列约束被定义为列定义的一部分。表约束不与特定的列相关联,并且它可以包含多个列,每个列约束也能写成表约束;当表约束仅仅影响一列时,列约束仅仅是一种符号方便。
当创建一张表的时候,还有额外的子句来声明Hashdata数据库分布策略。如果没有提供 DISTRIBUTED BY 或者 DISTRIBUTED RANDOMLY 子句,则 Hashdata 使用 PRIMARY KEY(如果表有的话)或者将该表的第一列作为分布键,给表分配一种哈希分布策略。几何或用户定义的数据类型的列不符合Hashdata分布键列的资格。如果表没有一个符合条件的数据类型的列,那么这些行则是基于循环或随机分布分配的。为了确保用户的Hashdata数据库系统中的数据均匀分配,用户需要选择对每个记录唯一的分布键,否则,请选择随机分布 DISTRIBUTED RANDOMLY。
该 PARTITION BY 子句允许用户将表划分成多个子表(或部分),他们组合在一起构成父表并共享其schema。尽管子表以独立表的形式存在,但是Hashdata数据库以重要的方式限制了他们的使用。在内部,分区被实现为一种特殊形式的继承。每个子表分区的创建带有不同 CHECK 约束,该约束根据一些定义标准限制表可以包含的数据。查询优化器也使用 CHECK 约束来确定要扫描的分区,以满足给定的谓词。这些分区约束由Hashdata数据库自动管理。
参数
- GLOBAL | LOCAL
这些参数用于SQL标准兼容性,但在Hashdata数据库中不起作用。
- TEMPORARY | TEMP
如果指定,则该表被创建成临时表。临时表在会话结束时自动删除,或选择性地在当前事务结束的时候删除(参阅 ON COMMIT)。当临时表存在时当前会话中具有同名的永久表是不可见的,除非他们使用包括schema信息的名字来引用。任何在临时表中创建的索引也都是临时的。
- table_name
所创建表的名字(可包括schema信息)
- column_name
新表中所要创建的列名。
- data_type
列的数据类型,这可能包含数据说明符。对于包含文本数据的表列,通过使用 VARCHAR 或 TEXT指定数据类型。不建议指定数据类型 CHAR。在Hashdata数据库中,该数据类型 VARCHAR 或 TEXT 将添加到数据之后的补充 (最后一个非空格字符之后添加的空格字符)作为有效字符,而数据类型 CHAR 却不会。
- DEFAULT default_expr
该 DEFAULT 子句给其列定义出现的列分配一个默认值。该值时任何无变量表达式(不允许对当前表中其他列的子查询或者交叉引用)。该默认表达式的数据类型必须匹配该列的数据类型。该默认表达式将会在任何对该列没有指定值的插入操作中使用。如果对该列没有默认值,则该默认值为null。
- ENCODING ( storage_directive [, …] )
对于列,可选的 ENCODING 子句指定列数据的压缩类型和块大小。参阅 storage_options 以获取 COMPRESSTYPE, COMPRESSLEVEL,和 BLOCKSIZE 的值。
该子句仅对追加优化,面向列的表有效。 列压缩设置从表级继承到分区级再到子分区级别。最低级设置优先。 - LIKE other_table [{INCLUDING | EXCLUDING} {DEFAULTS | CONSTRAINTS}]
该 LIKE 子句指定新表将自动复制所有列名,数据类型,非空约束和分发策略的表。诸如追加优化或分区结构之类的存储属性不被复制。与 INHERITS 不同,新表创建完成之后,新表和原始表完全解耦。
复制的列定义的默认表达式仅在指定了 INCLUDING DEFAULTS 时才会被复制。默认行为是排除默认表达式,该操作导致复制的列在新表中使用null的默认值。
非空约束总是会被复制到新表中。仅当指定了INCLUDING CONSTRAINTS时,才会复制CHECK 约束。其他类型的约束将 永远不会 被复制。此外,当请求约束时,列约束和表约束之间不作区分,所有的检查约束都将会被复制。
还要注意,不像INHERITS,复制的列和约束不会与命名相似的列和约束合并。如果明确指定相同的名字,或在另一个 LIKE 子句中,则会提示错误。 - CONSTRAINT constraint_name
列或表约束的可选名称。如果违反该约束,则该约束名称会出现在错误消息中,因此诸如 该列必须为正数 的约束名称,可以用来向客户端应用传达有用的约束信息。(需要用双引号来指定包含空格的约束名称)。如果没有指定约束名称,则该系统将生成一个名称。
注意: 该指定的 constraint_name 用于约束,但是系统生成的唯一名字是用于索引名称。在先前的版本中,提供的名称用于约束名称和索引名称。 - NULL | NOT NULL
指明该列是否允许包含null。值默认值是 NULL。
- CHECK ( expression )
该 CHECK 指定了一个表达式,该表达式产生布尔结果,新的或更新行必须满足该表达式才能成功插入或更新操作。 被评估为 TRUE 或者 UNKNOWN 的表达式算是成功。 如果插入或更新的任何行产生 FALSE 结果,则会引发错误异常,并且插入或更新不会更改数据库。指定为列约束的检查约束应仅引用该列的值,而表约束中出现的表达式可能会引用多个列。CHECK 表达式不能包含子查询也不能引用当前行以外的值。
- WITH ( storage_option=value )
该 WITH 子句可以用来为表或索引设置存储选项。注意用户也能在分区说明中,通过声明 WITH 来在特定的分区或子分区上设置存储参数。最低级别的设置具有优先权。
某些表存储选项的默认值可以使用服务器配置参数 gp_default_storage_options 来指定。 有以下存储选项:- APPENDONLY — 设置为 TRUE 来创建一个表作为追加优化表。如果设置为 FALSE 或者没有指定,则该表将会被创建为常规的堆存储表。
- BLOCKSIZE — 对表中的每个块设置大小。该 BLOCKSIZE 必须在 8192 和 2097152 字节之间并且必须是8192字节的倍数。该默认值是 32768。
- ORIENTATION — 设置为 column 是面向列存储,或设置为 row(默认值)是面向行存储。该选项仅当 APPENDONLY=TRUE时才有效。堆存储表只能是面向行的。
- CHECKSUM — 该存储表仅对追加优化表(append-optimized tables)才是有效的,即(APPENDONLY=TRUE)。该值 TRUE 时默认的并且为追加优化表启用CRC校验和验证。该校验在块创建期间计算并存储在磁盘上。校验验证在块读取期间执行。如果读取期间计算的校验和存储的校验不匹配,则事务终止。如果用户设置该值为 FALSE 来禁用校验验证,则会启动检查表数据防止磁盘损坏。
- COMPRESSTYPE — 设置为 ZLIB(默认值), RLE-TYPE,或ZTSD来指明使用的压缩类型。该值 NONE 禁用压缩。zlib 提供了在低压缩速度下高压缩比。该选项仅当 APPENDONLY=TRUE时才有效。
该值 RLE_TYPE 仅在指定 ORIENTATION =column 的时候才支持。Hashdata数据库使用运行长度编码(RLE)压缩算法。
对于类型为 BIGINT, INTEGER,DATE,TIME,或 TIMESTAMP的列,如果 COMPRESSTYPE 选项设置为 RLE-TYPE压缩,同样会应用增量压缩。该增量压缩算法是基于连续的行中列值之间的增量,并且设计为当加载的数据是有序或者要压缩的列数据是有序时,能提高压缩性能。
有关使用表压缩的信息,请参阅Hashdata数据库管理员指南的“选择表的存储模式”。 - FILLFACTOR — 参阅 CREATE INDEX 获取更多关于该索引存储参数的信息。
- OIDS — 设置为 OIDS=FALSE (默认值),以便行没有分配对象表示符。Hashdata 强烈推荐用户在创建表时不启用OIDs。在大型表中(如典型的Hashdata数据库系统中的表),对表行使用OIDs会导致32位OID计数器环绕。一旦计数器环绕,OID就不能被认为是唯一的,这不仅会导致他们对用户程序无用,而且还可能在Hashdata数据库系统目录中引起问题。此外,从表中排出OID会减少表在磁盘所需存储的空间,每行4字节,这会稍微提升性能。OIDs不允许在分区表或者追加优化表面向列的表中使用。
- ON COMMIT
在事务块结束时临时表的行为可以通过使用 ON COMMIT来控制。该三个选项如下:
PRESERVE ROWS - 在事务结束时候没有对临时表特别的操作,这是默认的行为。 DELETE ROWS - 在每个事务块结束时,临时表的所有行都将被删除。本质上,在每次提交时,执行了自动删除 TRUNCATE。 DROP - 在当前事务结束时,会删除临时表。 - DISTRIBUTED BY (column, [ … ] )
DISTRIBUTED RANDOMLY使用来声明Hashdata数据库中表的分布策略。 DISTIBUTED BY 使用在分布键中声明的一行或者多行做哈希分布。对于最均匀的数据分布,该分布键应当是表的主键或者一个唯一列(或者唯一多列)。如果这是不可能的,则用户可能会选择 DISTRIBUTED RANDOMLY,该策略会循环发送数据到Segment实例。
- PARTITION BY
声明一列或多列,根据该列来将表分区。
当创建一个分区表,Hashdata数据库使用指定的表名创建根分区表(该根分区)。Hashdata数据库也会根据用户指定的分区选项创建子分区包括里面表的层次结构,子表。该Hashdata数据库 pg_partition* 系统视图包含子分区表的信息。
对于每个分区级别(每个表的层次结构),分区表做多可以有32,767 个分区。
注意: Hashdata数据库将分区表数据存储在叶子表中,子表的层次结构中的最低级表用于分区表。
partition_type
声明分区类型:LIST(值列表)或者 RANGE(数字或日期范围)。 - partition_specification
声明要创建各个分区,每个分区可以被单独定义或者为范围分区,用户可以使用 EVERY 子句(用一个 START 和可选的 END 子句)来定义用于创建各个分区的增量schema。
DEFAULT PARTITION name — 声明一个默认分区,当数据不匹配存在的分区时,则被插入到默认分区中。没有默认分区的设计将拒绝与现有分区不匹配的新的数据行的插入。
PARTITION name — 声明要用于分区的名字,使用以下命名约定创建分区: parentname_level#_prt_givenname.
VALUES — 对于列表分区,定义分区会包含的值。
START — 对于范围分区,定义分区的开始范围值。默认的是,开始值为 INCLUSIVE。 例如,如果用户声明了 ‘2016-01-01'的开始日期,则该分区会包含所有大于等于 ‘2016-01-01'的日期。通常, START 表达式的数据类型和分区键列的数据类型是一样的。如果不是这样,用户必须显式地转换为预期的数据类型。
END — 对于范围分区,定义分区的结束范围值。默认的是,结束值是 EXCLUSIVE。 例如,如果用户定义了 ‘2016-02-01'的结束日期,则该分区将会包含所有小于该 ‘2016-02-01'的日期。通常, END 表达式的数据类型和分区键列的数据类型是一样的。如果不是这样,用户必须显式地转换为预期的数据类型。
EVERY — 对于范围分区,定义如何将值从 START 增加到 END 以创建单个分区。通常,EVERY 表达式的数据类型和分区键列的数据类型相同。如果不是这样,则用户必须显式的准换为预期的数据类型。
WITH — 设置分区的存储选项,例如,用户可能希望老分区是追加优化表,而较新的分区则为常规的堆表。
注解
- 在Hashdata数据库中(一个基于Postgres的系统)数据类型 VARCHAR 或 TEXT 处理添加到文本数据后的补充(添加到最后一个非空格字符后面的空格)作为有效的字符。而数据类型 CHAR 则不会。
Hashdata数据库中,CHAR(n) 类型的值被填充尾部空格来达到指定的宽度 n。该值存储并显示空格。然而T,该添加的空格被视为语义不重要的。当值分布时,尾部的空格被忽略。当比较CHAR类型的值时,尾部的空格也被视为语义不重要的,并且将字符值转化为其他字符串类型之一时,尾部空格被删除。 - 不建议在新的应用中使用OIDs:在可能的情况下,使用 SERIAL 或其他序列生成器作为表的主键的首选。但是,如果用户的应用确实使用OID来标识表的特定行,则推荐在该OID列上创建唯一的约束,以确保表中的OID确实唯一标识行,即使在计数器轮回之后。避免假设OID在多表之间(across)是唯一的;如果用户需要数据库范围内的唯一标识符号,则可以使用表OID和行OID的组合。
- 对于追加优化表,UPDATE 和 DELETE 在序列化事务中不被允许,并且会导致事务中断。 CLUSTER,DECLARE…FORUPDATE,和 触发器在追加优化表中不支持。
- 要将数据插入到分区表中,请指定根分区表,即用 CREATE TABLE 命令创建的表。用户也可以在 INSERT 命令中指定分区表的叶子表。如果数据不符合指定的叶子表,则会返回错误。不支持在 INSERT 命令中指定不是叶子表的子表。不支持在分区表任何子表上执行 DML 命令,如 UPDATE 和 DELETE。这些命令必须在根分布表上执行,即用 CREATE TABLE 命令创建的表。 重要: 当前Hashdata数据库遗传优化器允许具有多列(复合)分区键的列表分区。GPORCA 不支持复合键,所以不建议使用复合分区键。
示例
创建一个名为 rank 的表在名为 baby 的schema中并且使用 rank,gender,和 year来分布数据:
CREATE TABLE baby.rank (id int, rank int, year smallint,
gender char(1), count int ) DISTRIBUTED BY (rank, gender,
year);
创建 gzip-压缩的追加优化表:
CREATE TABLE sales (txn_id int, qty int, date date)
WITH (appendonly=true, compresslevel=5)
DISTRIBUTED BY (txn_id);
创建3级分区表使用,使用子分区模板和每级的默认分区:
CREATE TABLE sales (id int, year int, month int, day int,
region text)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)
SUBPARTITION BY RANGE (month)
SUBPARTITION TEMPLATE (
START (1) END (13) EVERY (1),
DEFAULT SUBPARTITION other_months )
SUBPARTITION BY LIST (region)
SUBPARTITION TEMPLATE (
SUBPARTITION usa VALUES ('usa'),
SUBPARTITION europe VALUES ('europe'),
SUBPARTITION asia VALUES ('asia'),
DEFAULT SUBPARTITION other_regions)
( START (2008) END (2016) EVERY (1),
DEFAULT PARTITION outlying_years);
兼容性
CREATE TABLE 命令服从SQL标准,还有以下的例外:
- 临时表 — 在SQL标准中,在需要他们的每个会话中,临时表只定义一次并自动存在(从空的内容开始)。Hashdata数据库需要每个会话为每个要使用的临时表发出自己的CREATE TEMPORARY TABLE 命令。这允许不同的会话为不同目的使用相同的临时表名称,而标准的方法限制给定临时表名的实例具有相同的表结构
在全局和本地临时表之间的标准区别不存在于Hashdata数据库中。Hashdata数据库会在临时表的声明中接收 GLOBAL 和 LOCAL 关键字,但是他们没有影响。
如果 ON COMMIT 子句被省略,该SQL标准指定默认行为为 ON COMMIT DELETE ROWS。而然,Hashdata数据库中的默认行为为 ON COMMIT PRESERVE ROWS。该 ON COMMIT DROP 选项不存在与SQL标准中。 - 列检查约束 — 该SQL标准说 CHECK 列约束可能仅指所应用到的列;只有 CHECK 表约束可能指定到多列。Hashdata 数据不强制执行该约束,它对待列和表的约束一样。
- NULL约束 — 该 NULL 是Hashdata数据库对SQL标准的扩展,为了是和其他数据库系统的兼容(为了和 NOT NULL 约束的对称)。因为它是任何列的默认值,因此不需要它的存在。
- 继承 — 多重继承通过 INHERITS 子句是Hashdata数据库语言的扩展。SQL:1999和更高的版本使用不同的语法和语义来定义单个继承。Hashdata数据库不支持SQL:1999版的继承。
- 分区 — 表分区通过使用 PARTITION BY 子句是Hashdata数据库语言扩展。
- 零列表 —Hashdata数据库允许0列表的创建(例如,CREATE TABLE foo();)。这是从不支持0列表的 SQL 标准来的扩展。0列表本身不是非常有用,但是不允许他们对 ALTER TABLE DROP COLUMN语句会创建奇怪的特殊情况的表,所以 Hashdata 决定忽视此规范限制。
- WITH子句 — 该 WITH 子句是 Hashdata 数据库扩展;存储参数和OID都不是SQL标准中的。
- 表空间 — 该 Hashdata 表空间的概念SQL 标准的一部分。 该子句 TABLESPACE 和 USING INDEX TABLESPACE 是扩展。
- 数据分布 — 该Hashdata数据库并行和分布数据库的概念不是SQL标准的一部分。该 DISTRIBUTED 子句是扩展。
另见
ALTER TABLE, DROP TABLE, CREATE EXTERNAL TABLE, CREATE TABLE AS
CREATE TABLE AS
从查询结果中定义新表。
概要
CREATE [ [GLOBAL | LOCAL] {TEMPORARY | TEMP} ] TABLE table_name
[(column_name [, ...] )]
[ WITH ( storage_parameter=value [, ... ] ) ]
[ON COMMIT {PRESERVE ROWS | DELETE ROWS | DROP}]
AS query
[DISTRIBUTED BY (column, [ ... ] ) | DISTRIBUTED RANDOMLY]
该 storage_parameter 如下:
APPENDONLY={TRUE|FALSE}
BLOCKSIZE={8192-2097152}
ORIENTATION={COLUMN|ROW}
COMPRESSTYPE={ZLIB|QUICKLZ}
COMPRESSLEVEL={1-9 | 1}
FILLFACTOR={10-100}
OIDS[=TRUE|FALSE]
描述
CREATE TABLE AS 创建一个表并且使用由 SELECT 命令计算所得的数据进行填充。该表列和SELECT命令出来的出来的列有相同的名字和数据类型,但是用户可以复写列名通过给出明确的新列名列表。
CREATE TABLE AS 创建一个新表,并且初始计算查询一次来填充新表。该新表不会同步追踪源表查询子序列的变化。
参数
-
GLOBAL | LOCAL
这些关键字用于SQL标准的兼容性,但是在Hashdata数据库中不起作用。
-
TEMPORARY | TEMP
如果指定了,该新表被创建成为临时表。临时表在会话结束之时自动删除,或者可选地在当前事务结束时(请参阅 ON COMMIT)。当临时表存在时,在当前会话中,同名的永久表示不可见的。除非使用包括schema信息的名字来引用,临时表中创建的索引也自动是临时的。
-
table_name
所创建新表的名字(可包括schema信息)。
-
column_name
新表的列名,如果没有提供列名,则使用查询输出的列名。如果表从 EXECUTE 命令中所创建,不能指定一个列名列表。
-
WITH ( storage_parameter=value )
该 WITH 子句可以用来为表和索引设置存储选项。注意,用户可以在特定的分区或子分区中设置不同的存储参数,通过在分区中指定 WITH 子句。有以下存储选项:
APPENDONLY — 设置到 TRUE 来创建一个表作为追加优化表。如果设定为 FALSE 或者没有声明,则该表将会创建为常规的堆存储表。
BLOCKSIZE — 对表中每个块设置字节大小。该 BLOCKSIZE 必须在 8192 和 2097152 字节之间,为8192的倍数,默认值时32768。
ORIENTATION — 对面向列存储设置 列,或为面向行存储的设置行(默认值)。该选项仅在 APPENDONLY=TRUE的时候有效。堆存储表只能是面向行的。
COMPRESSTYPE — 设置 ZLIB(默认值)或者 QUICKLZ(1) 来指定使用的压缩类型。QuickLZ使用较少的CPU功率,并且比zlib具有更快的数据压缩和更低的压缩比。相反,zlib在在较低速率下提供更紧凑的压缩比。此选项仅在 APPENDONLY=TRUE时有效。
注意: (1)QuickLZ 压缩仅在Pivotal Hashdata数据库的商业版本中可用可用。
COMPRESSLEVEL — 对追加优化表的zlib压缩,设置压缩在 1(最快压缩)到 9(最高压缩比)之间。QuickLZ 压缩等级只能设置到1。如果没有声明,则默认是1。该选项仅在 APPENDONLY=TRUE时才有效。
OIDS — 设置为 OIDS=FALSE(默认值),则行没有分配的对象标识符。Hashdata 强烈推荐用户在创建表的时候不要启用OIDS 。在大型表中,如在典型的Hashdata数据库中表,对表行使用OIDs能引起32OID计数器环绕。一旦计数器环绕,OIDs就被认为是不再唯一的,这不仅使它们对用户应用程序无用,而且还可能在Hashdata数据库系统目录表中引起问题。此外,从表中排出OIDs减少了磁盘上存储区表所需的空间,每行4字节,稍微地提升了性能。不允许在面向列的表上使用OIDs。 -
ON COMMIT
事务块结束时的临时表的行为可以使用 ON COMMIT来控制。该三个选项如下:
PRESERVE ROWS — 在临时表事务结束时不采取特别行动。这是默认行为。
DELETE ROWS — 临时表中的所有行将在每个事务块结束时删除。本质上,在每次提交时候执行了 TRUNCATE。
DROP — 在当前事务块结束时将删除临时表。 -
TABLESPACE tablespace
创建的新表所在的表空间的名字。如果没有指定,则使用数据库默认的表空间。
-
AS query
该 SELECT 或 VALUES 命令,或者运行准备好的SELECT 或 VALUES 查询的 EXECUTE 命令。
-
DISTRIBUTED BY (column, [ … ] )
DISTRIBUTED RANDOMLY
用来声明Hashdata数据库表的分布策略。 DISTIBUTED BY 使用在分布键中声明一列或者多列进行哈希分布。对于大多数的均匀数据分布,该分布键应当是表的主键或是唯一列(或列的集合。如果不可能,则用户可以选择 DISTRIBUTED RANDOMLY,这会将数据随机循环发送到Segment实例。
该Hashdata数据库服务器配置参数 gp_create_table_random_default_distribution 控制默认的表分布策略,如果当用户创建表的时候没有指定 DISTRIBUTED BY 子句。如果没有指定分布策略,则Hashdata 遵循以下规则来创建表- 如果查询优化器创建表,并且该参数的值是 off,则该表的分布策略由命令所决定。
- 如果遗传查询优化器创建表,并且该参数的值为 on,则该表的分布策略是随机的。
- GPORCA 创建表,则表分布策略是随机的,该参数值没有影响。
注解
该命令功能上和 SELECT INTO相似,但是该命令更常用因为它相比使用 SELECT INTO 的语法不太可能产生混淆。此外, CREATE TABLE AS 提供了包含 SELECT INTO功能在内超集。
CREATE TABLE AS 可以用于从外部表数据源中快速加载数据。参阅 CREATE EXTERNAL TABLE。
示例
创建一个新表 films_recent 仅由表 films最近的条目组成:
CREATE TABLE films_recent AS SELECT * FROM films WHERE
date_prod >= '2007-01-01';
创建一个临时表 films_recent,仅由films表的最近的条目组成,使用预编译(prepared)语句。新表拥有OIDs并在提交时删除:
PREPARE recentfilms(date) AS SELECT * FROM films WHERE
date_prod > $1;
CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
EXECUTE recentfilms('2007-01-01');
兼容性
CREATE TABLE AS 服从SQL标准,但以下例外:
- 该标准要求将子查询用括号括起来;在Hashdata数据库中,这些括号是可选的。
- 该标准定义了 WITH [NO] DATA 子句;这目前并没有由Hashdata数据库实现。Hashdata数据库提供的行为和标准的 WITH DATA 情况是一样的。WITH NO DATA 可以通过给查询追加 LIMIT 0 来模拟。
- Hashdata数据库处理临时表不同于标准,更多细节参阅 CREATE TABLE。
- 该 WITH 子句是Hashdata数据库扩展; 存储参数和 OIDs 都不在标准中。
- 该Hashdata数据库表空间的概念不是标准的一部分。 该 TABLESPACE 子句是一个扩展。
另见
CREATE EXTERNAL TABLE, CREATE EXTERNAL TABLE, EXECUTE, SELECT, SELECT INTO, VALUES
CREATE TYPE
描述新的数据类型。
概要
CREATE TYPE name AS ( <attribute_name> <data_type> [, ... ] )
CREATE TYPE <name> AS ENUM ( [ '<label>' [, ... ] ] )
CREATE TYPE <name> (
INPUT = <input_function>,
OUTPUT = <output_function>
[, RECEIVE = <receive_function>]
[, SEND = <send_function>]
[, TYPMOD_IN = <type_modifier_input_function> ]
[, TYPMOD_OUT = <type_modifier_output_function> ]
[, INTERNALLENGTH = {<internallength> | VARIABLE}]
[, PASSEDBYVALUE]
[, ALIGNMENT = <alignment>]
[, STORAGE = <storage>]
[, DEFAULT = <default>]
[, ELEMENT = <element>]
[, DELIMITER = <delimiter>] )
描述
CREATE TYPE 在当前数据库中注册了一个新的要使用的数据类型。定义该类型的用户是他的拥有者。
如果给定了schema,则该类型就会在指定的schema中创建。否则,会在当前的schema中创建。该类型的名字必须和该schema中任何存在的类型或域的名字不同。该类型的名字也必须和同schema中存在的表的名字不同。
复合类型
CREATE TYPE 的第一个形式创建了一个复合类型。该复合类型由属性名字和数据类型的列表指定。这本质上和表的行类型一样,但是,当仅需要定义一个类型时,使用 CREATE TYPE 避免了需要去创建实际的表。独立复合类型作为参数或者函数的返回类型来说是有用的。
枚举类型
CREATE TYPE 的第二种形式创建了一个(ENUM)的枚举类型,正如在PostgreSQL文档中描述的 枚举类型。枚举类型列出一个或多个引用的标签,每个标签必须小于 NAMEDATALEN 个字节长(标准中为 64)。
基础类型
CREATE TYPE的第三种形式创建了一个新的基础类型(标量类型)。该参数可能会以任何顺序出现,不仅在语法中显示,大多数都是可选的。用户在定义类型之前,必须注册2个或更多函数(使用 CREATE FUNCTION)。支持函数 input_function 和 output_function 是必须的, 然而 receive_function,send_function,type_modifier_input_function,type_modifier_output_function,和 analyze_function 函数是可选的。一般来说,这些函数必须是以c编写或者其他低级语言。在Hashdata数据库中,任何用于实现一个数据类型的函数必须定义成 IMMUTABLE。
input_function 将类型的外部文本表示转换为为之定义的运算符和函数使用的内部表示形式。output_function 执行反向转换,该输入函数可以被声明为采用 cstring类型参数,或者声明为采用cstring, oid,integer。第一个参数是输入文本作为C字符串,第二个参数是类型自己的OID(数组类型除外,它是接收它元素类型的OID),第三个参数是目标列的 typmod(如果已知的话),如果未知的话,会传递-1。该输入函数必须返回数据类型本身的值。通常,一个输入函数应该被声明为 STRICT;如果不是,当读取 NULL 输入值时,将使用 NULL 作为第一个参数来调用函数。这种情况下,该函数必须仍然返回 NULL 值,除非他引发错误。(这种情况主要是为了支持域输入功能,可能需要拒绝 NULL 输入。)输出函数必须声明为采用新数据类型的一个参数。该输出函数必须返回 cstring。输出函数不会为 NULL 值调用。
可选的 receive_function 将类型的外部二进制表示转换为内部表示。如果未提供此函数,则该类型不能参与二进制输入。应该选择二进制表示以便宜地转换为内部形式,同时具有合理的可移植性。(例如,标准整数数据类型使用网络字节顺序作为外部二进制表示,而内部表示是机器的本机字节顺序。)接收函数应该执行足够的检查以确保该值有效。接收函数可以被声明为接受一个类型的参数internal,或者接受三个类型的参数internal, oid, integer。第一个参数是一个指向StringInfo保存接收到的字节串的缓冲区;可选参数与文本输入函数相同。接收函数必须返回数据类型本身的值。通常,应该声明一个接收函数STRICT;如果不是,它将NULL在读取 NULL 输入值时使用第一个参数调用。在这种情况下,函数必须仍然返回NULL,除非它引发错误。(本案例主要是为了支持域接收功能,可能需要拒绝NULL输入。)类似地,可选的 send_function 从内部表示转换为外部二进制表示。如果不提供此函数,则该类型不能参与二进制输出。发送函数必须声明为采用新数据类型的一个参数。发送函数必须返回类型bytea。不为NULL值调用发送函数。
如果该类型支持修饰符,则需要可选的 type_modifier_input_function 和 type_modifier_output_function。修饰符是附加到类型声明上的约束,例如 char(5) 或 numeric(30,2)。然而Hashdata数据库允许用户定义的类型将一个或多个简单常量或者标识符作为修饰符,但是该信息必须适合单个非负整数值,以便在系统目录中存储。Hashdata 数据库将声明的修饰符以cstring数组的形式传递给 type_modifier_input_function。该修饰符输入函数必须检查值的有效性,如果不正确抛出异常。如果值正确,该修饰符输入函数返回单个非负整数值,Hashdata数据库将把之作为列 typmod存储。如果该类型未使用 type_modifier_input_function 定义,则类型修饰符将被拒绝。该 type_modifier_output_function 将内部整数 typmod 值转换为正确的表单,以供用户显示。该修饰符输出函数必须返回一个 cstring 值,该值是要附加到类型名称的确切的字符串。例如, numeric’s 函数可能返回 (30,2)。 该 type_modifier_output_function 是可选的。当没有指定时,该默认显示形式是存储的括号中的 typmod 整数值。
当必须在创建新类型之前创建他们,用户应该在这一点上想知道输入和输出函数如何被声明为具有新类型的结果或参数。答案应该是首先将该类型定义为一个shell类型,他是一个占位符,除名字和所有者之外没有其他属性。这可以通过发出命令 CREATE TYPE name来完成,没有其他参数。然后可以引用shell类型定义I/O函数。最后,具有完整定义的 CREATE TYPE 将使用完整的有效的类型定义替换shell条目,之后,可以正常使用新的类型定义了。
虽然新类型的内部表示的细节只有I/O函数和用户创建的该类型的其他函数才了解,但是内部表示的几个属性必须声明到Hashdata数据库。其中最重要的额是 internallength。基本数据类型可以使固定长度的,这种情况下,internallength 是一个正整数,或者可变长度,通过将 internallength 设置为 VARIABLE来表示。(在内部,这通过将 typlen 设置成 -1来表示。) 所有可变长度 类型的内部表示必须以4字节整数开头,给出此类型值的总长度。
该可选标志 PASSEDBYVALUE 表示此数据类型的值通过值传递而不是引用传递。用户不能通过类型来传递,该类型的内部表示比 Datum 类型内部表示大小(size)大(大多数及其上为4个字节,少数机器上为8字节)。
aligment参数指定数据类型所需的存储对齐。允许的值等于1,2,4或8字节边界上的对齐。注意,可变长度类型必须具有至少4的对齐,因为它们必须包含 int4 作为其第一个组成数。
storage 参数允许为可变长度数据类型选择存储策略。(仅plain允许用于固定长度类型。)plain指定该类型的数据将始终在线存储而不是压缩。extended指定系统将首先尝试压缩长数据值,如果仍然太长,则将该值移出主表行。external允许将值移出主表,但系统不会尝试压缩它。main允许压缩,但不鼓励将值移出主表。(如果没有其他方法可以使行适合,具有这种存储策略的数据项可能仍会移出主表,但它们会优先保留在主表中extended和external项。)
可以指定默认值,以防用户希望数据类型的列默认为非空值。使用 DEFAULT 关键字来指定默认值。(这样的默认值可能会被附加到该列显式的 DEFAULT 子句覆盖。)
要指定类型为数组,请使用关键字 ELEMENT 关键字指定数组元素的类型。例如,要定义一个4字节整数的(int4)的数组,请指定 ELEMENT = int4。更多关于数组类型的更多细节如下所示。
要指定在该类型数组内部表示值之间的分隔符,可以将 delimiter 设定为特殊的字符。默认的分隔符是逗号(,)。注意,该分隔符号与数组元素类型相关联,而不是数组类型本身。
数组类型
每当创建用户定义的基本数据类型时,Hashdata数据库自动创建相关联的数组类型,其名称由前缀为下划线的基本类型名称组成。解析器了解这个命名约定,并将类型为 foo[] 的列的请求转换为类型为 _foo的请求。隐式创建的数组类型是可变长度,并使用内置的输入和输出函数 array_in 和 array_out。
如果系统自动创建正确的数组类型,用户可能会合理地问为什么有一个 ELEMENT 选项。使用 ELEMENT 有用的唯一的情况是当用户创建固定长度的类型时,恰好在内部是相同数字的数组,用户希望允许直接通过下标访问这些东西,除了用户计划为该类型整体提供的任何操作。例如,类型 name 允许以这种方式访问其组成的 char 元素。2-D 点类型可以允许其两个组成数字可以像 point[0] 和 point[1]被访问。注意,该便利,仅适用于固定长度类型,其内部格式正好是相同固定长度字段的序列。可下标表示的可变长度类型必须有由 array_in 和 array_out使用的广义内部表示。由于历史原因,固定长度数组类型的下标从零开始,而可变长度类型却不行。
参数
- name
要创建类型的名字(可包括schema信息)。
- attribute_name
复合类型属性的(列)名字。
- data_type
成为复合类型列的存在的数据类型的名字。
- label
表示与枚举类型的一个值关联的文本标签的字符串文字。
- input_function
将数据从类型的外部文本形式转换为内部表单的函数的名称。
- output_function
将数据从类型的内部表单转换为外部文本形式的函数的名称。
- receive_function
将数据类型的外部二进制形式转换为其内部形式的函数的名称。
- send_function
将数据类型的内部表单转换为其外部二进制形式的函数的名称。
- type_modifier_input_function
将类型的修饰符数组转化为内部形式的函数的名称。
- type_modifier_output_function
将类型修饰符的内部形式转化为外部文本形式的函数的名称。
- internallength
一个数字常量,用于指定新类型内部表示的字节长度。默认假设是变长的。
- alignment
数据类型的存储对齐要求。必须是 char,int2,int4, 或 double之一。默认值是 int4。
- storage
数据类型的存储策略,必须是 plain, external,extended,or main之一。 默认值是plain.
- default
数据类型的默认值,如果省略,默认值为null。
- element
正在创建的类型是数组;这指定了数组元素的类型。
- delimiter
此类型数组中值之间要使用的分隔符。
注解
用户定义的类型名称不能以下划线字符(_)开头,并且必须是62个字符长(或者一般为 NAMEDATALEN - 2,而不是允许的其他名称的 NAMEDATALEN - 1 字符)。以下划线开头的类型名称为内部创建的数组类型名称保留。
因为一旦数据类型被创建,使用数据类型就没有任何限制,所以创建基础类型就等同于为类型定义中提到的函数授予公共执行权限。(因此,该类型的创建者需要拥有这些函数。)对于类型定义中有用的各种函数,这通常不是问题。但是,在设计一种类型之前,用户可能需要三思而后行,因为该设计思路上,在将其作为转化的源或者目标类型时,可能需要一些“秘密”信息。
在Hashdata数据库 2.4 版本之前,CREATE TYPE name 语法并不存在。创建新基础类型的方法就是先创建一个输入函数。在这种方法中,Hashdata数据库会首先看到新数据类型的名称作为输入函数的返回类型。这种情况下,shell类型是隐式创建的,然后可以在其余的I/O函数的定义中引用它。这种方法仍然有效,但是已经弃用了,可能会在将来的某个版本中禁用掉。另外,为了避免由于函数定义中简单拼写错误而导致shell类型目录的异常混乱,当输入函数是用c写的时候,shell类型只能以这种方式创建。
示例
该示例创建了一个复合类型,并且在函数定义中使用了它:
CREATE TYPE compfoo AS (f1 int, f2 text);
CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$
SELECT fooid, fooname FROM foo
$$ LANGUAGE SQL;
该例子创建了枚举类型 mood 并且在表定义中使用了它。
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TABLE person (
name text,
current_mood mood
);
INSERT INTO person VALUES ('Moe', 'happy');
SELECT * FROM person WHERE current_mood = 'happy';
name | current_mood
------+--------------
Moe | happy
(1 row)
该例子创建了一个基础数据类型 box 然后在表定义中使用了它:
CREATE TYPE box;
CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS
... ;
CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS
... ;
CREATE TYPE box (
INTERNALLENGTH = 16,
INPUT = my_box_in_function,
OUTPUT = my_box_out_function
);
CREATE TABLE myboxes (
id integer,
description box
);
如果 box 的内部结构是4个 float4 元素的数组,我们可以替代使用:
CREATE TYPE box (
INTERNALLENGTH = 16,
INPUT = my_box_in_function,
OUTPUT = my_box_out_function,
ELEMENT = float4
);
这将允许通过下标访问一个box值的成员数字。否则类型的行为与以前相同。 该例子创建了一个大对象类型并在表的定义中使用了它
CREATE TYPE bigobj (
INPUT = lo_filein, OUTPUT = lo_fileout,
INTERNALLENGTH = VARIABLE
);
CREATE TABLE big_objs (
id integer,
obj bigobj
);
兼容性
CREATE TYPE 命令是Hashdata数据库扩展。 SQL标准中有 CREATE TYPE 语句,但是细节上很是不同。
另见
CREATE FUNCTION, ALTER TYPE, DROP TYPE, CREATE DOMAIN
CREATE USER
定义新的默认带有 LOGIN 权限的数据库角色。
概要
CREATE USER <name> [[WITH] <option> [ ... ]]
该 option 可以是:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEUSER | NOCREATEUSER
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<password>'
| VALID UNTIL '<timestamp>'
| IN ROLE <rolename> [, ...]
| IN GROUP <rolename> [, ...]
| ROLE <rolename> [, ...]
| ADMIN <rolename> [, ...]
| USER <rolename> [, ...]
| SYSID <uid>
| RESOURCE QUEUE <queue_name>
描述
作为Hashdata数据库 2.2发行版,CREATE USER 已经由 CREATE ROLE所替代,尽管为了向后兼容,它仍然被接受实用。
在 CREATE ROLE 和 CREATE USER 之间仅有的区别是 LOGIN 权限默认和 CREATE USER一起创建,然而 NOLOGIN 权限默认和 CREATE ROLE一起创建。
兼容性
在SQL标准中没有 CREATE USER 语句。
另见
CREATE ROLE
CREATE VIEW
定义新视图。
概要
CREATE [OR REPLACE] [TEMP | TEMPORARY] VIEW <name>
[ ( <column_name> [, ...] ) ]
AS <query>
描述
CREATE VIEW 定义视图查询。该视图没有实际物。相反,每次在查询中引用该视图时,都会运行查询。
CREATE OR REPLACE VIEW 是相似的,但是如果同名的视图已经存在,则会被替换。用户只能使用生成相同列(相同列名称和数据类型)的新查询替换视图。
如果给定了schema名称,则在指定的schema名称中创建视图。否则,在当前的schema中创建该视图。临时视图存在于特殊的schema中,所以创建临时schema时不会给定schema名。该视图的名称与同schema中其他任何视图,表,序列或索引的名称必须不同。
参数
- TEMPORARY | TEMP
如果指定,该视图创建为临时表。临时表在当前事务结束时自动删除。当临时表存在时,具有相同的名字的永久表在当前会话中不可见,除非他们使用包括schema信息的名字来引用。如果视图引用的任何表是临时的话,该视图会创建成一个临时表((不管)是否指定 TEMPORARY )。
- name
要创建的表的名字(可包括schema信息)。
- column_name
可选名字列表用于视图的列。如果没有给定,该列名将从查询中推导而来。
- query
SELECT 或 VALUES 命令,二者会提供视图的列和行。
注解
Hashdata数据库中的视图是只读的。系统不允许在视图上插入,更新,或者删除。用户可以通过在视图上创建重写规则到其他表上的适当操作来获得可更新视图的效果。
请注意,视图列的名字和数据类型可以按照用户想要的方式分配。例如:
CREATE VIEW vista AS SELECT 'Hello World';
在两种情况下是不好的形式:该列名默认为 ?column?, 而且列的数据类型默认为 unknown。如果用户想在视图的结果中使用字符串文字,请使用以下内容:
CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
视图中引用的表的访问由视图所有者的权限决定的,而不是当前用户(即使当前用户是超级用户)。这在超级用户的情况下可能会令人困惑,因为超级用户通常可以访问所有对象。在视图的这种情况下,如果用户不是视图的所有者,那么即使是超级用户也必须要明确被授予对视图引用表的访问权限才能访问。
但是,视图中调用函数的处理方式与使用视图从查询中直接调用的方式相同。因此,视图的用户必须要有具有调用视图使用的任何函数的权限。
如果用户使用 ORDER BY 子句创建了一个视图,则当用户从视图中执行SELECT 时将忽略ORDER BY子句。
示例
创建所有包含comedy电影的视图:
CREATE VIEW comedies AS SELECT * FROM films WHERE kind =
'comedy';
创建一个获取排名前10婴儿的名字:
CREATE VIEW topten AS SELECT name, rank, gender, year FROM
names, rank WHERE rank < '11' AND names.id=rank.id;
兼容性
SQL 标准指定了不在Hashdata数据库中的 CREATE VIEW 语句的一些附加功能。标准完整SQL命令的可选子句包括:
- CHECK OPTION — 该选项和可更新视图有关。 将检查视图上所有 INSERT 和 UPDATE 命令来确保数据满足视图定义条件(即新的数据将通过视图可见)。如果不满足条件,则拒绝该更新。
- LOCAL — 检查视图上的完整性
- CASCADED — 检查此视图的和任何从属视图的完整性,假定为CASCADED 如果不指定 CASCADED 或 LOCAL。
CREATE OR REPLACE VIEW是Hashdata数据库语言扩展,临时视图的概念也是如此。
另见
SELECT, DROP VIEW
DEALLOCATE
释放准备好的语句。
概要
DEALLOCATE [PREPARE] <name>
描述
DEALLOCATE 用来释放预先准备好对的SQL语句。如果用户不明确释放预备语句,它将会在会话结束时释放。
参数
- PREPARE
被忽略的可选关键字
- name
要释放的预备语句的名字
示例
释放预先准备好的叫做 insert_names的语句:
DEALLOCATE insert_names;
兼容性
SQL标准包含了 DEALLOCATE 语句,但是它只在嵌入式SQL中使用。
另见
EXECUTE, PREPARE
DELETE
从表中删除行。
概要
DELETE FROM [ONLY] <table> [[AS] <alias>]
[USING <usinglist>]
[WHERE <condition> | WHERE CURRENT OF <cursor_name> ]
描述
DELETE 从指定的表中删除满足 WHERE 子句的行,如果该 WHERE 子句是空的,则会删除整个表行,该结果是有效的,只不过是个空表。
默认情况下,DELETE 会删除指定表中的行和他所有的子表。如果用户希望仅从特定指定的表中删除,请使用 ONLY 子句。
使用数据库中其他表中包含的信息删除表中的行有两种方法:使用sub-selects,或在USING子句中指定附加表。哪种技术更合适取决于具体情况。
如果指定了 WHERE CURRENT OF 子句,则删除的行是从指定的游标中最近读取的行。 用户必须有对表的 DELETE 权限才能从中删除。
输出
成功完成后, DELETE 命令返回表单的命令标签。
DELETE <count>
删除行的数量,如果数量为0,没有满足删除条件的行(这并不认为是一个错误)。
参数
- ONLY
如果指定,仅从提名的表中删除行。如果没有指定,也会处理任何从提名的表继承的表。
- table
存在表的名字(可包括schema信息)。
- alias
目标表的别名。当提供了别名,它完全隐藏了表的实际名字。例如,给定 DELETE FROM foo AS f,该 DELETE 语句的其他部分必须将此表称为 f 而不是 foo。
- usinglist
表达式列表,允许其他表的列出现在 WHERE 条件中。这和SELECT语句中FROM子句中可以指定的表的列表相似:例如,可以指定表的别名。不要重复使用 usinglist中的目标表,除非用户希望设置自连接。
- condition
返回类型为 boolean的表达式,该表达式决定那些要删除的行。
- cursor_name
要在 WHERE CURRENT OF条件下使用的游标的名字。要删除的行是从该有游标最近读取的行。游标必须是DELETE 目标表上的简单(非连接,非聚合)查询。
WHERE CURRENT OF 不能和布尔条件一起指定。该 DELETE...WHERE CURRENT OF 游标语句只能在服务器上执行,例如交互式psql会话或脚本。语言扩展(如PL/pgSQL)不支持可更新游标。
注解
Hashdata数据库使用户在 WHERE 条件中通过指定在 USING 指定其他表来引用其他表的列。 例如,对 来自 rank 表的名为 Hannah的列,可能会这样做:
DELETE FROM rank USING names WHERE names.id = rank.id AND
name = 'Hannah';
这里发生的本质是一个在 rank 和 names表之间的连接,所有成功连接的行都被标记为删除。该语法是不标准的。但是,相比子查询风格,该连接风格通常比较容易写,也能更快执行,例如:
DELETE FROM rank WHERE id IN (SELECT id FROM names WHERE name
= 'Hannah');
当使用 DELETE 来删除表中的所有行(例如: DELETE * FROM table;),Hashdata数据库添加了隐式的 TRUNCATE 命令(当用户权限允许时)。 该添加的 TRUNCATE 命令释放了被删除行所占的空间,而没有执行表的 VACUUM 操作。这提升了后续查询的扫描性能,有助于临时表经常插入和删除的ELT工作负载。
不支持在特定分区(子表)上直接执行 UPDATE 和 DELETE 命令。相反,这些命令必须在根分区表(使用 CREATE TABLE 命令创建的表)上执行。
示例
删除除了musicals之外的所有films:
DELETE FROM films WHERE kind <> 'Musical';
清除表films:
DELETE FROM films;
使用连接删除:
DELETE FROM rank USING names WHERE names.id = rank.id AND
name = 'Hannah';
兼容性
这个命令符合SQL标准,只是USING子句是Hashdata数据库的扩展。
另见
DECLARE, TRUNCATE
DISCARD
丢弃会话状态。
概要
DISCARD { ALL | PLANS | TEMPORARY | TEMP }
描述
DISCARD 释放与数据库会话相关联的内部资源。这些资源通常在会话结束时释放。
DISCARD TEMP 删除在当前会话中创建的所有临时表。DISCARD PLANS 释放所有内部缓存的查询计划 DISCARD ALL 重置会话到原始状态,丢弃临时资源并重置会话本地配置更改。
参数
- TEMPORARY / TEMP
删除所有在当前会话中创建的临时表。
- PLANS
释放所有缓存的查询计划
- ALL
释放所有和当前会话相关联的临时资源并且重置会话到初始状态。目前,该和执行以下语句序列具有相同的效果:SET SESSION AUTHORIZATION DEFAULT; RESET ALL; DEALLOCATE ALL; CLOSE ALL; UNLISTEN *; SELECT pg_advisory_unlock_all(); DISCARD PLANS; DISCARD TEMP;
注意:DISCARD ALL不能在事务块中执行。
兼容性
DISCARD是Hashdata数据库扩展
DO
将匿名代码块作为瞬态匿名函数执行。
概要
DO [ LANGUAGE <lang_name> ] <code>
描述
DO 执行了一个匿名代码块,或换而言之为一个程序化语言的暂时的匿名函数
该代码块被认为似乎是一个没有参数的函数体,返回空值。它被解析被执行了一次。
可选参数 LANGUAGE 子句可以出现在代码块的前或者后。
匿名块是程序化语言结构,该结构提供在运行时创建和执行程序代码的能力,而不用将代码作为数据库对象持久的存储在系统目录中。匿名代码块的概念和UNIX shell脚本相似,该能允许将多个手动输入命令分组并作为一步骤执行。顾名思义,匿名块没有名字,因此不能被其他对象引用。虽然动态创建,匿名块可以轻松的作为脚本存储在操作系统文件中以便重复执行。
匿名块是标准程序语言块。他们携带语法并且遵循适用于该程序语言的规则,包括变量的声明和范围、执行、异常处理和语言使用。
匿名块的编译和执行结合在一个步骤中,而用户定义的函数需要在每次定义变更之前重新定义。
参数
- code
需要执行的程序化语言代码。这必须指定为字符串文本。正如使用 CREATE FUNCTION 命令。建议使用美元引用文字。可选关键字无效。支持这些程序语言:PL/pgSQL(plpgsql),PL/Python (plpythonu),and PL/Perl (plperl 和 plperlu)。
- lang_name
代码所用程序语言的名字。该语言默认是 plpgsql。该语言必须在Hashdata数据库中安装并且在用户数据库中注册。
注解
PL/pgSQL 语言安装在Hashdata数据库系统中并且注册在用户创建的数据库中。PL/Python 语言是默认安装的,但是没有注册。其他语言没有安装也没有注册。系统目录 pg_language 包含了在数据库中注册语言的信息。
如果语言不可信,则用户必须有对程序语言有 USAGE 权限,或者必须是超级用户。这和使用该语言创建函数的权限要求一样。
示例
该 PL/pgSQL 例子对webuser用户赋予在 public schema中所有视图的所有权限:
DO $$DECLARE r record;
BEGIN
FOR r IN SELECT table_schema, table_name FROM information_schema.tables
WHERE table_type = 'VIEW' AND table_schema = 'public'
LOOP
EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';
END LOOP;
END$$;
这个 PL/pgSQL 示例确定 Hashdata 数据库用户是否是超级用户。在示例中,匿名块从临时表中检索输入值。
DO $$
DECLARE
name TEXT := 'gpadmin' ;
superuser TEXT := '' ;
t1_row pg_authid%ROWTYPE;
BEGIN
SELECT * INTO t1_row FROM pg_authid, list
WHERE pg_authid.rolname = name ;
IF t1_row.rolsuper = 'f' THEN
superuser := 'not ';
END IF ;
RAISE NOTICE 'user % is %a superuser', t1_row.rolname, superuser ;
END $$ LANGUAGE plpgsql ;
注意: 例子 PL/pgSQL 使用 SELECT 和 INTO 子句。它和 SQL 命令的 SELECT INTO 语句不同。
兼容性
SQL标准中没有 DO 语句。
另见
CREATE LANGUAGE Hashdata PL/pgSQL 程序化语言
DROP AGGREGATE
删除聚合函数。
概要
DROP AGGREGATE [IF EXISTS] <name> ( <type> [, ...] ) [CASCADE | RESTRICT]
描述
DROP AGGREGATE 会删除一个存在的聚合函数。 要执行该命令,当前用户必须是该聚合函数的所有者。
参数
- IF EXISTS
如果该聚合函数不存在不会抛出异常。在情况下会发出通知。
- name
存在的聚合函数的名称(可包括schema信息)。
- type
聚合函数操作的输入数据类型。要引用一个0个参数的聚合函数,写 * 替代输入数据类型列表。
- CASCADE
自动删除依赖该聚合函数的对象。
- RESTRICT
如果有任何对象依赖于它,则拒绝删除聚合函数。这是默认的。
示例
删除参数为integer的聚合函数 myavg:
DROP AGGREGATE myavg(integer);
兼容性
SQL标准中没有 DROP AGGREGATE 语句。
另见
ALTER AGGREGATE, CREATE AGGREGATE
DROP CAST
删除数据类型转换。
概要
DROP CAST [IF EXISTS] (<sourcetype> AS <targettype>) [CASCADE | RESTRICT]
描述
DROP CAST 会删除之前定义的转换,为了能够删除转换,用户必须要拥有资源或目标数据类型。用户需要获得以下权限来创建转换。
参数
- IF EXISTS
如果转换不存在不会抛出错误,这种情况会发出一个通知。
- sourcetype
转换的源数据类型的名称。
- targettype
转换的目标数据类型的名称。
- CASCADE
RESTRICT这些关键词没有任何影响,因为没有对转换的依赖。
示例
删除从 text 到 int类型的转换:
DROP CAST (text AS int);
兼容性
DROP CAST命令服从SQL标准。
另见
CREATE CAST
DROP CONVERSION
删除编码转换。
概要
DROP CONVERSION [IF EXISTS] <name> [CASCADE | RESTRICT]
描述
DROP CONVERSION 删除之前定义的转换。 为了能够删除转换,用户必须是该转换的所有者。
参数
- IF EXISTS
如果该转换不存在不会抛出异常,这种情况下会发出一个通知。
- name
转换的名字,该转换名字可包括schema信息
- CASCADE
RESTRICT这些关键词没有任何效果,因为他们是不依赖该转换。
示例
删除叫 myname的转换:
DROP CONVERSION myname;
兼容性
SQL标准中没有 DROP CONVERSION 的语句。
另见
ALTER CONVERSION, CREATE CONVERSION
DROP DATABASE
删除数据库。
概要
DROP DATABASE [IF EXISTS] <name>
描述
DROP DATABASE 删除数据库。它删除了数据的目录条目并且删除了包含该数据的目录。它只能被拥有该数据库的用户执行。另外,当用户或者是其他用户正连接到该数据库时候,是不能执行删除该数据库操作的。(连接到 postgres 或其他数据库来发出此命令)
警告: DROP DATABASE不能被撤销,请小心使用。
参数
- IF EXISTS
如果数据库不存在不会抛出异常。这种情况下发出通知。
- name
要删除数据库的名字。
注解
DROP DATABASE 不能在事务块中执行。
当连接到目标数据库时,不能执行该命令。因此,使用程序 dropdb 来替代可能更方便一点。该命令是在此命令上的封装。
示例
删除叫 testdb的数据库:
DROP DATABASE testdb;
兼容性
SQL标准中没有 DROP DATABASE 语句。
另见
ALTER DATABASE, CREATE DATABASE
DROP DOMAIN
删除域。
概要
DROP DOMAIN [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
描述
DROP DOMAIN 删除之前定义的域。用户必须是该域的所有者才能删除它。
参数
- IF EXISTS
如果该域不存在不会抛出异常。这种情况下会发出通知。
- name
存在的该域的名字(可包括schema信息)。
- CASCADE
自动删除依赖于域的对象(如表列)。
- RESTRICT
如果有任何对象依赖于该域则拒绝删除该域,这是默认的。
示例
删除叫 zipcode的域:
DROP DOMAIN zipcode;
兼容性
该命令是服从SQL标准的,除了 IF EXISTS 选项,这是Hashdata数据库扩展的。
另见
ALTER DOMAIN, CREATE DOMAIN
DROP EXTERNAL TABLE
删除外部表定义。
概要
DROP EXTERNAL [WEB] TABLE [IF EXISTS] <name> [CASCADE | RESTRICT]
描述
DROP EXTERNAL TABLE 从数据库中删除存在的外部表定义。外部的数据资源和文件不会被删除。要执行这个命令用户必须是外部表的所有者。
参数
- WEB
删除外部web表的可选参数
- IF EXISTS
如果外部表存在,不会抛出异常。这种情况下会发出一个通知。
- name
存在的外部表的名字(可包括schema信息)。
- CASCADE
自动删除依赖于外部表的对象(例如视图)。
- RESTRICT
如果有对象依赖于外部表,则拒绝删除该外部表。这是默认的选项。
示例
删除叫 staging 的外部表,如果存在的话:
DROP EXTERNAL TABLE IF EXISTS staging;
兼容性
SQL标准中没有 DROP EXTERNAL TABLE 语句。
另见
CREATE EXTERNAL TABLE
DROP FUNCTION
删除函数。
概要
DROP FUNCTION [IF EXISTS] name ( [ [argmode] [argname] argtype
[, ...] ] ) [CASCADE | RESTRICT]
描述
DROP FUNCTION 删除存在函数的定义。要执行这个命令该用户必须是该函数的所有者。必须要指定参数类型,因为几个不同的函数可能存在同名,但其参数列表不同。
参数
- IF EXISTS
如果函数不存在,不会抛出错误。这种情况下会发出通知。
- name
存在函数的名称(可包括schema信息)。
- argmode
参数的模式:IN, OUT, INOUT, or VARIADIC。如果省略,默认值为 IN。请注意 ALTER FUNCTION 实际上并不关注OUT 参数,因为只需要通过输入参数来确定函数的身份。 因此列出 IN, INOUT, 和 VARIADIC 参数就可以了。
- argname
参数的名字。注意 DROP FUNCTION 实际上并不注意参数名字,因为仅需要参数数据类型就能决定函数的身份。
- argtype
函数参数的数据类型(可包括schema信息)如果有的话。
- CASCADE
自动删除依赖于该函数的对象,例如运算符号。
- RESTRICT
如果有任何对象依赖于该函数,则拒绝删除该函数,这是默认的。
示例
删除平方根函数:
DROP FUNCTION sqrt(integer);
兼容性
SQL标准中定义了DROP FUNCTION 语句,但是这和该命令不兼容。
另见
CREATE FUNCTION, ALTER FUNCTION
DROP GROUP
删除数据库角色。
概要
DROP GROUP [IF EXISTS] <name> [, ...]
描述
DROP GROUP 是一个过时的命令,尽管为了向后兼容还被支持。组(和用户)已经被更一般的角色的概念所替代。
参数
IF EXISTS如果角色不存在,也不会抛出错误。这种情况下会发出通知。name存在角色的名字。
兼容性
SQL标准中没有 DROP GROUP 语句。
另见
DROP ROLE
DROP OPERATOR
删除运算符。
概要
DROP OPERATOR [IF EXISTS] <name> ( {<lefttype> | NONE} ,
{<righttype> | NONE} ) [CASCADE | RESTRICT]
描述
DROP OPERATOR 从数据库系统中删除运算符。要执行这个命令用户必须是该运算符的所有者。
参数
- IF EXISTS
如果运算符不存在,不会抛出错误。这种情况下会发出通知。
- name
存在运算符的名字(可包括schema信息)。
- lefttype
运算符左操作数的数据类型;如果没有左操作数写 NONE。righttype运算符右操作数的数据类型;如果没有右操作数写 NONE。
- CASCADE
自动删除依赖于该运算符的对象。
- RESTRICT
如果有任何对象依赖于该运算符,则拒绝删除该运算符。这是默认的。
示例
删除integer类型的power运算符 a^b:
DROP OPERATOR ^ (integer, integer);
删除左一元 位 补码 ~b:
DROP OPERATOR ~ (none, bit);
删除右一元 bigint 的阶乘运算符 x!:
DROP OPERATOR ! (bigint, none);
兼容性
SQL标准中没有 DROP OPERATOR 语句。
另见
ALTER OPERATOR, CREATE OPERATOR
DROP OWNED
删除数据库角色拥有的数据库对象。
概要
DROP OWNED BY <name> [, ...] [CASCADE | RESTRICT]
描述
DROP OWNED 删除当前数据库中指定角色之一所拥有的所有对象。授予当前数据库中对象的给定角色的任何权限也将被撤销。
参数
- name
要删除对象的拥有者的名字和要撤销权限的拥有者的名字。
- CASCADE
自动删除依赖所影响对象的的对象。
- RESTRICT
如果有任何其他数据库对象依赖所影响的对象之一,则拒绝删除该角色所拥有的对象。这是默认的。
注解
DROP OWNED 经常被使用来准备移除一个或多个角色。因为 DROP OWNED 仅影响当前数据的对象,通常需要在每个数据库中执行此命令,该数据库要包含要删除对象所拥有的对象。
使用 CASCADE 选项可能使命令递归到其他用户所拥有的对象。
该 REASSIGN OWNED 命令是重新分配由一个或多个角色所拥有的数据库对象所有权的替代方法。
示例
删除由 sally角色所拥有的任何数据库对象:
DROP OWNED BY sally;
兼容性
该 DROP OWNED 语句是Hashdata数据库扩展。
另见
REASSIGN OWNED, DROP ROLE
DROP ROLE
删除数据库角色。
概要
DROP ROLE [IF EXISTS] <name> [, ...]
描述
DROP ROLE 移除指定的角色。要删除超级用户角色,用户必须自己是超级用户。要删除非超级用户角色,用户必须要有CREATEROLE权限。
如果一个角色仍然被集簇中的任何一个数据库引用,它就不能被移除。如果尝试移除将会抛出一个错误。在删除角色之前,用户必须删除(或者重新授予所有权)它所拥有的所有对象并且收回该已经授予给该角色的在其他对象上的特权。REASSIGN OWNED和DROP OWNED命令可以用于这个目的。
不过,没有必要移除涉及该角色的角色成员关系;DROP ROLE 会自动收回目标角色在其他角色中的成员 关系,以及其他角色在目标角色中的成员关系。其他角色不会被删除也不会被影响。
参数
- IF EXISTS
如果该角色不存在则不要抛出一个错误,而是发出一个提示。
- name
要移除的角色的名称。
示例
移除名为sally和bob的角色:
DROP ROLE sally, bob;
兼容性
SQL 标准定义了 DROP ROLE,但是它只允许一次删除一个角色并且它指定了和 Hashdata数据库不同的特权需求。
另见
REASSIGN OWNED, DROP OWNED, CREATE ROLE, ALTER ROLE, SET ROLE
DROP RULE
删除重写规则。
概要
DROP RULE [IF EXISTS] <name> ON <relation> [CASCADE | RESTRICT]
描述
DROP RULE删除表或视图相关的重写规则。
参数
- IF EXISTS
如果该规则不存在则不要抛出一个错误,而是发出一个提示。
- name
要删除的规则的名称。
- relation
该规则适用的表或视图的名称(可包括schema信息)。
- CASCADE
自动删除依赖于该规则的对象,然后删除所有依赖于那些对象的对象。
- RESTRICT
如果有任何对象依赖于该规则,则拒绝删除它。这是默认值。
示例
移除一个在表sales上名为sales_2006的重写规则:
DROP RULE sales_2006 ON sales;
兼容性
DROP RULE 不是SQL标准中的语句。
另见
CREATE RULE
DROP SCHEMA
删除schema。
概要
DROP SCHEMA [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
描述
DROP SCHEMA 从数据库中移除schema。一个schema只能由其所有者或超级用户删除。注意即使所有者不拥有该schema中的某些对象,也能删除该schema(以及所有含有的对象)。
参数
- IF EXISTS
如果该schema不存在则不要抛出一个错误,而是发出一个提示。
- name
要移除schema的名称。
- CASCADE
自动删除包含在该schema中的对象(表、函数等),然后删除所有依赖于那些对象的对象。
- RESTRICT
如果该schema含有任何对象,则拒绝删除它。这是默认值。
示例
从数据库中移除一个名为mystuff的schema及其中所包含的对象: DROP SCHEMA mystuff CASCADE;
兼容性
DROP SCHEMA 完全符合SQL标准,不过该标准只允许在每个命令中删除一个schema并且没有IF EXISTS选项。IF EXISTS 是Hashdata的一个扩展。
另见
CREATE SCHEMA, ALTER SCHEMA
DROP SEQUENCE
删除序列。
概要
DROP SEQUENCE [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
描述
DROP SEQUENCE移除序数生成器表。一个序列只能被其所有者或超级用户删除。
参数
- IF EXISTS
如果该序列不存在则不要抛出一个错误,而是发出一个提示。
- name
要移除序列的名称(可包括schema信息)。
- CASCADE
自动删除依赖于该序列的对象,然后删除所有依赖于那些对象的对象。
- RESTRICT
如果有任何对象依赖于该序列,则拒绝删除它。这是默认值。
示例
移除一个名为myserial的序列:
DROP SEQUENCE myserial;
兼容性
DROP SEQUENCE 符合SQL标准,不过该标准只允许每个命令中删除一个序列并且没有IF EXISTS 选项。IF EXISTS是一个Hashdata扩展。
另见
ALTER SEQUENCE, CREATE SEQUENCE
DROP TABLE
删除表。
概要
DROP TYPE [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
描述
DROP TABLE 从数据库移除表。只有表所有者、schema拥有者和超级用户能删除表。要清空一个表中的行但是不销毁该表,可以使用DELETE或者TRUNCATE。
DROP TABLE 总是移除目标表的任何索引、规则、触发器和约束。不过,要删除一个被视图或者另一个表的外键约束所引用的表, 必须指定CASCADE。 CASCADE 将会把依赖的视图也完全移除。
参数
- IF EXISTS
如果该表不存在则不要抛出一个错误,而是发出一个提示。
- name
要删除的表的名称(可包括schema信息)。
- CASCADE
自动删除依赖于该表的对象(例如视图),然后删除所有 依赖于那些对象的对象。
- RESTRICT
如果有任何对象依赖于该表,则拒绝删除它。这是默认值。
示例
移除一个名为mytable的表:
DROP TABLE mytable;
兼容性
DROP TABLE符合SQL标准,不过该标准只允许每个命令删除一个表并且没有IF EXISTS 选项。IF EXISTS是Hashdata的一个扩展。
另见
CREATE TABLE, ALTER TABLE, TRUNCATE
DROP TYPE
删除数据类型。
概要
DROP TYPE [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
描述
DROP TYPE 移除用户定义的数据类型。 只有一个类型的所有者才能移除它。
参数
- IF EXISTS
如果该类型不存在则不要抛出一个错误,而是发出一个提示。
- name
要移除的数据类型的名称(可包括schema信息)。
- CASCADE
自动删除依赖于该类型的对象(例如表列、函数、运算符),然后删除所有 依赖于那些对象的对象。
- RESTRICT
如果有任何对象依赖于该类型,则拒绝删除它。这是默认值。
示例
移除名为box的数据库类型:
DROP TYPE box;
兼容性
这个命令类似于 SQL 标准中的对应命令,但IF EXISTS 选项是Hashdata数据库的一个扩展。 但是要注意Hashdata数据库中的CREATE TYPE命令和数据类型扩展机制都与SQL标准不同。
另见
ALTER TYPE, CREATE TYPE
DROP USER
删除数据库角色。
概要
DROP USER [IF EXISTS] <name> [, ...]
描述
DROP USER是一个被弃用的命令,不过为了向后兼容仍然可以使用。组(用户)已经被更加通用的概念角色替代。 更多详细信息见DROP ROLE 。
参数
- IF EXISTS
如果该角色不存在则不要抛出一个错误,而是发出一个提示。
- name
一个存在的角色的名称。
兼容性
在SQL标准中没有 DROP USER 命令。 SQL标准把用户的定义留给具体实现自行解释。
另见
DROP ROLE
DROP VIEW
删除视图。
概要
DROP VIEW [IF EXISTS] <name> [, ...] [CASCADE | RESTRICT]
描述
DROP VIEW移除一个现有的视图。只有一个视图的所有者才能移除它。
参数
- IF EXISTS
如果该视图不存在则不要抛出一个错误,而是发出一个提示。
- name
要移除的视图的名称(可包括schema信息)。
- CASCADE
自动删除依赖于该视图的对象(例如其他视图),然后删除所有 依赖于那些对象的对象。
- RESTRICT
如果有任何对象依赖于该视图,则拒绝删除它。这是默认值。
示例
移除一个名为topten的视图:
DROP VIEW topten;
兼容性
DROP VIEW 这个命令符合 SQL 标准,不过该标准只允许在每个命令中删除一个视图 并且没有 IF EXISTS 选项。IF EXISTS 是Hashdata数据库的一个扩展。
另见
CREATE VIEW
END
提交当前事务。
概要
END [WORK | TRANSACTION]
描述
END 提交当前事务。所有该事务做的更改变得对他人可见并且被保证发生崩溃时仍然是持久的。这个命令是一种Hashdata数据库的扩展,它等效于 COMMIT。
参数
WORK
TRANSACTION
可选关键词,它们没有任何影响。
示例
提交当前事务:
END;
兼容性
END是一种Hashdata数据库的扩展,它提供和COMMIT等效的功能,后者是SQL标准中指定的。
另见
BEGIN、ROLLBACK、COMMIT
EXECUTE
执行一个已经准备好的 SQL 语句。
概要
EXECUTE <name> [ (<parameter> [, ...] ) ]
描述
EXECUTE 被用来执行一个之前准备好的语句。 由于预备语句只在会话期间存在,该预备语句必须在当前会话中由一个更早 执行的PREPARE 语句所创建。
如果创建预备语句的PREPARE语句指定了一些参数,必须向EXECUTE语句传递一组兼容的参数,否则会发生错误。 注意(与函数不同)预备语句无法基于其参数的类型或者数量重载。 在一个数据库会话中,预备语句的名称必须唯一。
更多创建和使用预备语句的信息请见PREPARE。
参数
- name
要执行的预备语句的名称。
- parameter
给预备语句的参数的实际值。这必须是一个能得到与该参数数据类型( 在预备语句创建时决定)兼容的值的表达式。
示例
为一个INSERT语句创建一个预备语句,然后执行它:
PREPARE fooplan (int, text, bool, numeric) AS INSERT INTO
foo VALUES($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
兼容性
SQL标准包括了EXECUTE 语句,但是只被用于嵌入式 SQL。这个版本的EXECUTE 语句也用了一种有点不同的语法。
另见
DEALLOCATE, PREPARE
EXPLAIN
展示语句的查询计划。
概要
EXPLAIN [ANALYZE] [VERBOSE] <statement>
描述
EXPLAIN 显示Hashdata计划器为提供的语句所生成的查询计划。查询计划是一颗节点计划树。在计划中的每个节点代表了一个操作,例如表扫描、连接、聚合或者是一个排序操作。
因为每个节点直接向它上面的节点提供行结果,所以计划应该从下往上进行阅读。最底层的节点通常是一些表扫描操作(顺序扫描、索引扫描或者是位图扫描)。如果查询要求连接、聚合或者排序(或者其他在原始行上的操作),那么需要再扫描节点增加这些操作的节点。计划最顶层的节点通常是Hashdata的motion节点(重分布、显式重分布、广播或者聚合motion)。这些运算符代表了在查询处理期间在分片示例之间移动行数据。 的输出EXPLAIN对于计划树中的每个节点都有一行,显示基本节点类型以及计划者为执行该计划节点所做的以下成本估算:
- cost — 通过用取磁盘页面的次数来度量。即,1.0代表一个连续磁盘页面的读取。首先是启动代价(获取第一行的代价),第二个代价是总的代价(获取所有行的代价)。注意总的代价假设所有的行都将要被取回,但并不是总是这种情况(比如使用LIMIT语句)。
- rows — 该计划节点总的输出行数。这通常是小于实际由计划节点处理或者扫描的行数,主要是由于任何一个WHERE条件语句的评估选择性。理想情况下,最高层的节点估计近似等于实际由该查询返回、更新或者删除的行数。
- width — 该计划节点所有行输出的总的字节数。
值得注意的是更上一层的节点的代价包括了所有它孩子节点的代价。计划中最顶层节点是估计执行整个计划的代价。该数字是计划器寻求最小化的地方。同时也需要意识到代价仅仅反应了查询优化器关心的部分。特别是,代价没有考虑将结果行传输到客户端所花费的时间。
EXPLAIN ANALYZE 导致该语句被实际执行,而不仅仅是被计划。EXPLAIN ANALYZE 计划显示实际的结果以及计划器的评估。这个对于看是否计划器评估接近实际的情况非常有用。除了显示在EXPLAIN计划中的信息,EXPLAIN ANALYZE还要外加显示下面的信息:
- 总的花费在执行该查询的时间间隔(以毫秒为单位)。
- 在一个计划节点操作中涉及到的workers(Segment)的数量。只有返回行的Segment被计入。
- 一个操作中输出最多行的Segment返回的最大行数。如果多个Segment输出了相同数量的行数,取time to end最长的那个Segment。
- 在一个操作中输出最多行的Segment的ID。
- 对于相关的操作,该操作使用的work_mem。如果work_mem不足以在内存中执行操作,计划将显示有多少数据溢出到磁盘上以及对于使用工作内存最少的执行Segment要求了多少趟对数据的处理。例如:
Work_mem used: 64K bytes avg, 64K bytes max (seg0). Work_mem wanted: 90K bytes avg, 90K bytes max (seg0) to abate workfile I/O affecting 2 workers. [seg0] pass 0: 488 groups made from 488 rows; 263 rows written to workfile [seg0] pass 1: 263 groups made from 263 rows
- 产生最多行的Segment检索到第一行所花的时间(以毫秒计),以及在该Segment上获取所有行所花费的时间。如果
重要提示: 记住当使用EXPLAIN ANALYZE语句会被实际执行。尽管EXPLAIN ANALYZE 将丢弃SELECT 所返回的任何输出,照例该语句的其他副作用还是会发生。如果用户希望在一个DML语句上执行EXPLAIN ANALYZE而不希望它们影响用户的数据,可以使用下面的方法:
BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK;
参数
- name
将要执行的预备语句的名称。
- parameter
预备语句的一个参数的实际值。这必须是一个表达式,产生一个与该参数的数据类型兼容的值,这是在创建预备语句时确定的。
注解
为了允许查询计划器在优化查询时能做出合理的知情决策,ANALYZE语句需要被执行用来记录关于在表内数据的分布统计信息。如果用户还没有完成这个操作(或者如果表内数据从上一次执行ANALYZE语句后的统计分布发生了很大的变化),那么评估代价不会很符合实际的查询属性,同时因此会导致选择一个较差的计划被选中。
一个SQL语句在一个EXPLAIN ANALYZE命令被执行时执行会从Hashdata资源队列中排出。
示例
为了展示如何阅读一个EXPLAIN查询计划,考虑下面的一个简单查询的例子:
EXPLAIN SELECT * FROM names WHERE name = 'Joelle';
QUERY PLAN
------------------------------------------------------------
Gather Motion 2:1 (slice1) (cost=0.00..20.88 rows=1 width=13)
-> Seq Scan on 'names' (cost=0.00..20.88 rows=1 width=13)
Filter: name::text ~~ 'Joelle'::text
如果我们从下往上阅读该计划,查询优化器开始于顺序扫描表names。注意WHERE子句作为一个过滤条件被应用。这意味着一个扫描操作要检验扫描中的每一行是否满足该条件,同时返回那些满足条件的行。
扫描操作的结果将向上传递到一个gather motion操作。在Hashdata数据库中,gather motion是Segment向上传递行到Master的时机。在该例子中,我们有2个Segment实例发送到1个Master实例(2:1)。该操作工作在并行查询执行计划的slice1上。在Hashdata数据库中,一个查询计划被分成切片,这样每个查询计划的多个部分能够被Segment并行地执行。
该计划的估计启动代价是00.00(没有代价)以及总代价为20.88次取磁盘页。计划器认为该查询将会返回一行。
兼容性
在SQL标准中没有定义EXPLAIN语句。
另见
ANALYZE
GRANT
定义访问权限。
概要
GRANT { {SELECT | INSERT | UPDATE | DELETE | REFERENCES |
TRIGGER | TRUNCATE } [,...] | ALL [PRIVILEGES] }
ON [TABLE] <tablename> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { {USAGE | SELECT | UPDATE} [,...] | ALL [PRIVILEGES] }
ON SEQUENCE <sequencename> [, ...]
TO { <rolename> | PUBLIC } [, ...] [WITH GRANT OPTION]
GRANT { {CREATE | CONNECT | TEMPORARY | TEMP} [,...] | ALL
[PRIVILEGES] }
ON DATABASE <dbname> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { EXECUTE | ALL [PRIVILEGES] }
ON FUNCTION <funcname> ( [ [<argmode>] [<argname>] <argtype> [, ...]
] ) [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { USAGE | ALL [PRIVILEGES] }
ON LANGUAGE <langname> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { {CREATE | USAGE} [,...] | ALL [PRIVILEGES] }
ON SCHEMA <schemaname> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT { CREATE | ALL [PRIVILEGES] }
ON TABLESPACE <tablespacename> [, ...]
TO {<rolename> | PUBLIC} [, ...] [WITH GRANT OPTION]
GRANT <parent_role> [, ...]
TO <member_role> [, ...] [WITH ADMIN OPTION]
GRANT { SELECT | INSERT | ALL [PRIVILEGES] }
ON PROTOCOL <protocolname>
TO <username>
描述
GRANT 命令有两种基本形式:一种授予在一个数据库对象(表、列、视图、外部表、序列、数据库、外部数据包装器、外部服务器、函数、过程语言、schema或表空间)上的特权,另一个授予一个角色中的成员关系。
在数据库对象上GRANT
这种GRANT 命令的形式将一个数据库对象上的指定特权交给一个或多个角色。如果有一些已经被授予,这些特权会被加入到它们之中。
关键词PUBLIC指示特权要被授予给所有角色,包括那些可能稍后会被创建的角色。
PUBLIC 可以被认为是一个被隐式定义的总是包含所有角色的组。 任何特定角色都将具有直接授予给它的特权、授予给它作为成员所在的任何角色的特权以及被授予给PUBLIC的特权。
如果指定了WITH GRANT OPTION ,特权的接收者可以接着把它授予给其他人。 如果没有授权选项,接收者就不能这样做。授权选项不能被授予给 PUBLIC。
没有必要把权限授予给一个对象的所有者(通常就是创建该对象的用户), 因为所有者默认具有所有的特权。 删除一个对象或者以任何方式修改其定义的权力是不被当作一个可授予特权的,它被固化在所有者中,并且不能被授予和撤回。所有者也隐式地拥有该对象的所有授权选项。
会把某些类型的对象上的默认特权授予给PUBLIC。默认不包括对表、schema以及表空间的公共访问;CONNECT特权以及数据库中对TEMP表的创建特权;函数的EXECUTE特权;语言的USAGE特权。对象的所有者当然可能revoke这些特权。
角色上的GRANT
GRANT 命令的这种形式把一个角色中的成员关系授予一个或者多个其他角色。一个角色中的成员关系是有意义的,因为它会把授予给一个角色的特权带给该角色的每一个成员。
如果指定了 WITH ADMIN OPTION ,成员接着可以把该角色中的成员关系授予给其他用户,也可以撤回该角色中的成员关系。 数据库超级用户能够授予或撤回任何角色中任何人的成员关系。 具有CREATEROLE 特权的角色能够授予或者撤回任何非超级用户角色中的成员关系。
和特权的情况不同,一个角色中的成员关系不能被授予PUBLIC。
协议上的GRANT
当创建用户协议后,CREATE TRUSTED PROTOCOL指定哪些用户可以访问受信任的协议。如果协议是不可信的,用户不能给任何其他用户通过该协议来读或者写数据。当一个TRUSTED协议被创建后,可以用GRANT命令指定哪些用户可以访问它。
- 为了让用户能够创建带有可信协议的外部可读表,使用 GRANT SELECT ON PROTOCOL protocolname TO username
- 为了让用户能够创建带有可信协议的外部可写表,使用 GRANT INSERT ON PROTOCOL protocolname TO username
- 为了让用户能够创建带有可信协议的外部可读且可写表,使用 GRANT ALL ON PROTOCOL protocolname TO username
参数
- SELECT
允许从指定表、视图或序列的任何列或者列出的特定列进行 SELECT。还允许使用 COPY TO。 对于序列,这个特权也允许使用ccurrval 函数。
- INSERT
允许INSERT 一个新行到指定表中。 还允许 COPY FROM。
- UPDATE
允许对指定表的特定列进行UPDATE。 SELECT ... FOR UPDATE and SELECT ... FOR SHARE 也需要该特权(同时也要SELECT 特权)。 对于序列,这个特权允许使用nextval 和setval 函数。
- DELETE
允许从指定的表中DELETE 一行。
- REFERENCES
这个关键词是可以接受的,尽管现在外键约束在Hashdata数据库中还不支持。要创建一个外键约束,必须在引用列和被引用列上都有这个特权。
- TRIGGER
允许在指定的表上创建触发器。
注解: Hashdata数据库不支持触发器。 - TRUNCATE
允许在指定表上使用TRUNCATE 。
- CREATE
对于数据库,允许在其中创建新scehma。对于scehma,允许在其中创建新的对象。要重命名一个已有对象,用户必须拥有该对象并且具有所在schema的这个特权。对于表空间,允许在其中创建表、索引,并且允许创建使用该表空间作为默认表空间的数据库(注意撤回这个特权将不会更改现有对象的放置位置)。
- CONNECT
允许用户连接到指定数据库。在连接开始时会检查这个特权(除了检查由pg_hba.conf施加的任何限制之外)。
- TEMPORARY
TEMP允许在使用指定数据库时创建临时表。
EXECUTE允许使用指定的函数以及使用在该函数之上实现的任何运算符。这是适用于函数的唯一一种特权类型(这种语法也可用于聚合函数)。 - USAGE
对于过程语言,允许使用指定的语言创建函数。这是适用于过程语言的唯一一种特权类型。对于schema,允许访问包含在指定schema中的对象(假定这些对象的拥有特权要求也满足)。本质上这允许被授权者在schema中"查阅"对象。对于序列,这种特权允许使用currval 和nextval函数。
- ALL PRIVILEGES
一次授予所有的可用特权。在Hashdata数据库中,PRIVILEGES 关键词是可选的,但是在严格的 SQL 中是要求它的。
- PUBLIC
一个特别的组级别的角色,它指示了那些授予给所有角色的特权,包括后来可能会被创建的。
- WITH GRANT OPTION
特权接受者可以把该特权授予给其他的用户。
- WITH ADMIN OPTION
成员接着可以把该角色中的成员关系授予给其他用户。
注解
数据库超级用户可以访问所有对象而不管对象特权的设置。对于该规则的一个例外是视图。访问视图中引用的表取决于视图的拥有者而不是当前用户(即使当前用户是超级用户)。
如果超级用户选择发出GRANT或者REVOKE 命令,该命令将被执行,好像它是由被影响对象的所有者发出的一样。特别地,通过这样一个命令授予的特权将好像是由对象所有者授予的一样。对于角色成员关系,该成员关系好像是由该角色本身授予的一样。
GRANT以及REVOKE 也可以由一个不是受影响对象所有者的角色完成,不过该角色是拥有该对象的角色的一个成员,或者是在该对象上持有特权的WITH GRANT OPTION的角色的一个成员。在这种情况下,特权将被记录为由实际拥有该对象的角色授予或者是由持有特权的WITH GRANT OPTION的角色授予。
授予表上的权限不会自动地扩展权限给该表使用的任何序列,包括绑定在SERIAL 列上的序列。序列上的权限必须被独立设置。
Hashdata数据库不支持授予或者回收一个表上单独列上的特权。一个可选的方案是在需要赋予的特权的列上创建视图,然后授予视图特权。
使用psql的 \z 命令能够获取一个对象上现在存在的特权信息。
示例
授予所有角色在表mytable上的插入特权:
GRANT INSERT ON mytable TO PUBLIC;
授予所有可以的特权给角色sally在视图 topten上。注意只有在超级用户或者视图topten拥有者执行时才会真正的将所有特权都授予,如果执行的是其他用户,那么只会授予那么授予角色现在拥有的可进行授予的特权。
GRANT ALL PRIVILEGES ON topten TO sally;
将角色admins授予用户joe:
GRANT admins TO joe;
兼容性
在SQL标准中, PRIVILEGES 关键词是必需的,但是在Hashdata数据库中是可选的。SQL标准不支持在每个命令中设置超过一个对象上的特权。
Hashdata数据库允许用户的所有者撤回它们它们拥有的普通特权:表所有者可以通过撤回其自身拥有的 INSERT、UPDATE、DELETE和 TRUNCATE特权让该表对它们自己只读。 根据 SQL 标准 这是不可能发生的。 原因在于Hashdata数据库认为所有者的特权是由所有者授予给它们自己的,因此它们也能够撤回它们。 在 SQL 标准中,所有者的特权是有一个假设的实体system所授予。
SQL标准允许在表的单独列上设置特权。
SQL 标准提供了其他对象类型上的USAGE 特权:字符集、排序规则、翻译、域。
数据库、表空间、schema和语言上的特权都是Hashdata数据库扩展。
另见
REVOKE
INSERT
在表中创建新的行。
概要
INSERT INTO <table> [( <column> [, ...] )]
{DEFAULT VALUES | VALUES ( {<expression> | DEFAULT} [, ...] )
[, ...] | <query>}
描述
INSERT 将新行插入到表中。我们可以 插入一个或者更多由值表达式指定的行,或者插入来自一个查询的零行或者更多行。
目标列的名称可以以任意顺序列出。如果没有给出列名列表,默认的方式是按照表在定义时列的顺序。VALUES子句或者query提供的值会被从左至右关联到这些显式或者隐式给出的目标列。
每一个没有出现在显式或者隐式列列表中的列都将被默认填充,如果为该列 声明过默认值则用默认值填充,否则用空值填充。
如果任意列的表达式不是正确的数据类型,将会尝试自动类型转换。
为了向表中插入数据,用户必须拥有在其上的INSERT 特权。
输出
成功完成时,INSERT 命令会返回以下形式的命令标签:
INSERT oid count
count 是被插入的行数。 如果count正好为 1 并且 目标表具有 OID,那么oid 就是分配给被插入行的 OID。否则oid为零。
参数
- table
一个已有表的名称(可包括schema信息)。
- column
在表中的列的名称。如有必要,列名可以用一个子域名或者数组下标限定(指向 一个组合列的某些列中插入会让其他域为空)。
- DEFAULT VALUES
所有列都将被其默认值填充。
- expression
要赋予给相应列的表达式或者值。
- DEFAULT
相应的列将被其默认值填充。
- query
提供要被插入行的查询(SELECT语句)。 其语法描述参考SELECT语句。
注解
要插入数据到一个分区表中,需要制定根分区表,该表通过CREATE TABLE命令创建。也需要在INSERT命令中指定分区表的一个叶子还在表。如果对于指定的叶子还在表数据是无效将抛出错误。在INSERT命令指定一个非叶子表为子表还不支持。其他DML命令,例如UPDATE和DELETE,在任何一个分区表的子表上的执行还不支持。这些命令一定是执行在根分区表上面,即那些通过CREATE TABLE创建的表。
对于追加优化表,Hashdata数据库支持最大并行度为127的并行INSERT事务插入到一个追加优化表中。
对于可写S3外部表,INSERT操作更新在配置S3桶中的一个或者更多的文件,正如描述在s3://协议中的。通过Ctrl-c能够取消INSERT同时停止更新到S3。
示例
插入行到表films中:
INSERT INTO films VALUES ('UA502', 'Bananas', 105,
'1971-07-13', 'Comedy', '82 minutes');
在这个示例中,列length 被忽略,因此它将被默认值填充:
INSERT INTO films (code, title, did, date_prod, kind) VALUES
('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
这个示例中对列date_prod使用了DEFAULT子句而不是指定一个具体的值:
INSERT INTO films VALUES ('UA502', 'Bananas', 105, DEFAULT,
'Comedy', '82 minutes');
插入一条全部都是由默认值组成的行:
INSERT INTO films DEFAULT VALUES;
通过VALUES语法同时插入多行数据:
INSERT INTO films (code, title, did, date_prod, kind) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
在这个示例中,从具有相同表结构的表tmp_films插入若干的行到表films:
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod <
'2004-05-07';
兼容性
INSERT符合SQL标准。列名列表被省略,但不是所有的列都从VALUES子句或查询中被填入,这种情况是SQL标准不允许。
另见
COPY, SELECT, CREATE EXTERNAL TABLE, s3://协议
PREPARE
准备执行语句。
概要
PREPARE <name> [ (<datatype> [, ...] ) ] AS <statement>
描述
PREPARE创建预备语句,有可能有未绑定参数。预备语句是一种服务器端对象,它可以被用来优化性能。一个预备语句可能后续给参数绑定值后被执行。Hashdata数据库可能选择对同一预备语句的不同执行进行重新规划。
预备语句可以接受参数:在执行时会被替换到语句中的值。在创建预备语句时,可以用位置引用参数,如$1、$2等。也可以选择性地指定参数数据类型的一个列表。当一个参数的数据类型没有被指定或者被声明为unknown时,其类型会从该参数被使用的环境中推知(如果可能)。在执行该语句时,在EXECUTE语句中为这些参数指定实际值。
预备语句只在当前数据库会话期间存在。当会话结束时,预备语句会消失,因此在重新使用之前必须重新建立它。这也意味着一个预备语句不能被多个数据库客户端同时使用。不过,每一个客户端可以创建它们自己的预备语句来使用。预备语句可以用DEALLOCATE命令手工清除。
当一个会话要执行大量类似语句时,预备语句可能会有最大性能优势。如果该语句很复杂(难于规划或重写),例如,如果查询涉及很多表的连接或者要求应用多个规则,性能差异将会特别明显。如果语句相对比较容易规划和重写,但是执行起来开销相对较大,那么预备语句的性能优势就不那么显著了。
参数
- name
给这个特定预备语句的任意名称。它在一个会话中必须唯一并且后续将被用来执行或者清除一个之前准备好的语句。
- datatype
预备语句一个参数的数据类型。如果一个特定参数的数据类型没有被指定或者被指定为unknown,将从该参数被使用的环境中推得。要在预备语句本身中引用参数,可以使用$1、 $2等。
- statement
任何SELECT, INSERT, UPDATE, DELETE或者VALUES语句。
注解
在某些场景中,为预备语句产生的查询计划将比不上该语句被正常提交执行时的查询计划。这是因为当语句被规划并且规划器尝试确定最优查询计划时,该语句中指定的任何参数的实际值都还不可用。Hashdata数据库收集表中数据分布的统计信息,同时可以用语句中的常量值来猜测执行该语句的可能结果。由于在使用参数规划预备语句时,这种数据还不可用,被选中的计划可能是次优的。为了检测Hashdata数据库中为预备语句选择的查询计划,可以使用EXPLAIN。
可以通过查询pg_prepared_statements系统视图来看到会话中所有可用的预备语句。
示例
为INSERT语句创建预备语句,然后执行它:
PREPARE fooplan (int, text, bool, numeric) AS INSERT INTO
foo VALUES($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
为SELECT语句创建预备语句,然后执行它。注意第二个参数的数据类型没有被指定,因此会从使用$2的环境中推知:
PREPARE usrrptplan (int) AS SELECT * FROM users u, logs l
WHERE u.usrid=$1 AND u.usrid=l.usrid AND l.date = $2;
EXECUTE usrrptplan(1, current_date);
兼容性
SQL标准包括PREPARE语句,但是它只用于嵌入式 SQL。这个版本的PREPARE语句也使用了一种有些不同的语法。
另见
EXECUTE, DEALLOCATE
REASSIGN OWNED
改变数据库角色所拥有的数据库对象的所有权。
概要
REASSIGN OWNED BY <old_role> [, ...] TO <new_role>
描述
REASSIGN OWNED指示系统把old_role们拥有的任何数据库对象的拥有关系更改为new_role。注意它并不改变数据库本身的拥有关系。
参数
- old_role
一个角色的名称。这个角色在当前数据库中所拥有的 所有对象以及所有共享对象(数据库、表空间)的 所有权都将被重新赋予给new_role。
- new_role
将作为受影响对象的新拥有者的角色名称。
注解
REASSIGN OWNED 经常被用来为移除一个或者多个角色做准备。因为REASSIGN OWNED 只影响当前数据库中的对象,通常需要在包含有 被删除的角色所拥有的对象的每一个数据库中都执行这个命令。
DROP OWNED 命令可以简单地删掉一个或者多个角色所拥有的所有数据库对象。
The REASSIGN OWNED命令不会影响授予给old_role们 的在它们不拥有的对象上的任何特权。DROP OWNED可以回收那些特权。
示例
重新将sally和bob拥有的对象改为admin拥有的:
REASSIGN OWNED BY sally, bob TO admin;
兼容性
REASSIGN OWNED语句是Hashdata数据库的扩展。
另见
DROP OWNED, DROP ROLE
RESET
恢复系统配置参数的值为默认值。
概要
RESET <configuration_parameter>
RESET ALL
描述
RESET是SET configuration_parameter TO DEFAULT的另外一种写法。
默认值被定义为如果在当前会话中没有发出过 SET, 参数必须具有的值。这个值的实际来源可能是一个编译在内部的默认值、 配置文件(postgresql.conf)、命令行选项、或者针对每个数据库或者每个用户的默认设置。
参数
- configuration_parameter
一个可设置的运行时参数名称。 见服务器参数配置获取细节信息。
- ALL
把所有可设置的运行时参数重置为默认值。
示例
将statement_mem设置为其默认值:
RESET statement_mem;
兼容性
RESET是Hashdata数据库的扩展。
另见
SET
REVOKE
撤销访问权限。
概要
REVOKE [GRANT OPTION FOR] { {SELECT | INSERT | UPDATE | DELETE
| REFERENCES | TRIGGER | TRUNCATE } [,...] | ALL [PRIVILEGES] }
ON [TABLE] <tablename> [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] { {USAGE | SELECT | UPDATE} [,...]
| ALL [PRIVILEGES] }
ON SEQUENCE <sequencename> [, ...]
FROM { <rolename> | PUBLIC } [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] { {CREATE | CONNECT
| TEMPORARY | TEMP} [,...] | ALL [PRIVILEGES] }
ON DATABASE <dbname> [, ...]
FROM {rolename | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] {EXECUTE | ALL [PRIVILEGES]}
ON FUNCTION <funcname> ( [[<argmode>] [<argname>] <argtype>
[, ...]] ) [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] {USAGE | ALL [PRIVILEGES]}
ON LANGUAGE <langname> [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[ CASCADE | RESTRICT ]
REVOKE [GRANT OPTION FOR] { {CREATE | USAGE} [,...]
| ALL [PRIVILEGES] }
ON SCHEMA <schemaname> [, ...]
FROM {<rolename> | PUBLIC} [, ...]
[CASCADE | RESTRICT]
REVOKE [GRANT OPTION FOR] { CREATE | ALL [PRIVILEGES] }
ON TABLESPACE <tablespacename> [, ...]
FROM { <rolename> | PUBLIC } [, ...]
[CASCADE | RESTRICT]
REVOKE [ADMIN OPTION FOR] <parent_role> [, ...]
FROM <member_role> [, ...]
[CASCADE | RESTRICT]
描述
REVOKE命令收回之前从一个或者更多角色 授予的特权。关键词PUBLIC隐式定义的全部角色的组。 特权类型的含义见GRANT。
注意任何特定角色拥有的特权包括直接授予给它的特权、从它作为其成员的角色中得到的特权以及授予给PUBLIC的特权。因此,例如从PUBLIC收回SELECT特权并一定意味着所有角色都失去在该对象上的SELECT特权:那些直接被授 予的或者通过另一个角色被授予的角色仍然会拥有它。
如果指定了 GRANT OPTION FOR ,只会回收该特权 的授予选项,特权本身不被回收。否则,特权及其授予选项都会被回收。
如果用户持有一个带有授予选项的特权并且把它授予给了其他用户, 那么被那些其他用户持有的该特权被称为依赖特权。如果第一个用户持有 的该特权或者授予选项正在被收回且存在依赖特权,指定CASCADE 可以连带回收那些依赖特权,不指定则会导致回收动作失败。 这种递归回收只影响通过可追溯到该REVOKE的主体的用户链授予的特权。因此, 如果该特权经由其他用户授予给受影响用户,受影响用户可能实际上还保留有该特权。
在回收一个角色中的成员关系时,GRANT OPTION 被改称为ADMIN OPTION但行为是类似的。
参数
见 GRANT 部分
示例
从public收回表films的插入特权:
REVOKE INSERT ON films FROM PUBLIC;
从角色sally收回视图topten上的所有特权,注意实际意味着回收所有当前角色(如果不是超级用户)授予的特权:
REVOKE ALL PRIVILEGES ON topten FROM sally;
从joe收回角色admins中的成员关系:
REVOKE admins FROM joe;
兼容性
GRANT命令的兼容性注解同样适用于REVOKE。
关键词RESTRICT或者CASCADE根据标准是必需的,但是Hashdata数据库假定RESTRICT为默认值。
另见
GRANT
ROLLBACK
中止当前事务。
概要
ROLLBACK [WORK | TRANSACTION]
描述
ROLLBACK回滚当前事务并且导致该事务所作的所有更新都被丢弃。
参数
WORK
TRANSACTION
可选关键词。它们没有任何影响。
注解
使用COMMIT 可成功的结束事务。
在一个事务块之外发出ROLLBACK会发出一个警告并且不会有任何效果。
示例
丢弃当前事务所做的所有修改:
ROLLBACK;
兼容性
SQL标准中只指定了两种形式ROLLBACK 和ROLLBACK WORK。其他方面,该命令完全符合SQL标准。
另见
BEGIN, COMMIT, SAVEPOINT, ROLLBACK TO SAVEPOINT
SELECT
从表或者视图中检索行。
概要
[ WITH [ RECURSIVE1 ] <with_query> [, ...] ]
SELECT [ALL | DISTINCT [ON (<expression> [, ...])]]
* | <expression >[[AS] <output_name>] [, ...]
[FROM <from_item> [, ...]]
[WHERE <condition>]
[GROUP BY <grouping_element> [, ...]]
[HAVING <condition> [, ...]]
[WINDOW <window_name> AS (<window_specification>)]
[{UNION | INTERSECT | EXCEPT} [ALL] <select>]
[ORDER BY <expression> [ASC | DESC | USING <operator>] [NULLS {FIRST | LAST}] [, ...]]
[LIMIT {<count> | ALL}]
[OFFSET <start>]
其中with_query 是:
<with_query_name> [( <column_name> [, ...] )] AS ( <select> )
其中grouping_element可以是下列之一:
()
<expression>
ROLLUP (<expression> [,...])
CUBE (<expression> [,...])
GROUPING SETS ((<grouping_element> [, ...]))
其中window_specification可以是:
[<window_name>]
[PARTITION BY <expression >[, ...]]
[ORDER BY <expression> [ASC | DESC | USING <operator>] [NULLS {FIRST | LAST}] [, ...]
[{RANGE | ROWS}
{ UNBOUNDED PRECEDING
| <expression> PRECEDING
| CURRENT ROW
| BETWEEN <window_frame_bound> AND <window_frame_bound> }]]
其中window_frame_bound可以是下列之一:
UNBOUNDED PRECEDING
<expression> PRECEDING
CURRENT ROW
<expression> FOLLOWING
UNBOUNDED FOLLOWING
其中from_item可以是下列之一:
[ONLY] <table_name> [[AS] <alias> [( <column_alias> [, ...] )]]
(select) [AS] <alias> [( <column_alias> [, ...] )]
with\_query\_name [ [AS] <alias> [( <column_alias> [, ...] )]]
<function_name> ( [<argument> [, ...]] ) [AS] <alias>
[( <column_alias> [, ...]
| <column_definition> [, ...] )]
<function_name> ( [<argument> [, ...]] ) AS
( <column_definition> [, ...] )
<from_item> [NATURAL] <join_type> <from_item>
[ON <join_condition> | USING ( <join_column> [, ...] )]
描述
SELECT从零或更多表中检索行。 SELECT的通常处理如下:
- WITH子句中的所有查询都会被计算。这些查询实际充当了在FROM列表中可以引用的临时表。
- FROM列表中的所有元素都会被计算(FROM中的每一个元素都是一个真实表或者虚拟表)。 如果在FROM列表中指定了多于一个元素,它们会被交叉连接在一起。
- 如果指定了WHERE子句,所有不满足该条件的行都会被从输出中消除。
- 如果GROUP BY指定了子句,或者存在聚合函数调用,则输出将组合成与一个或多个值匹配的行组,并计算聚合函数的结果。如果该HAVING子句存在,它将消除不满足给定条件的组。
- 如果指定了窗口表达式(可选的WINDOW子句),输出会根据位置(行)或者基于值(范围)的窗口帧来组织。
- DISTINCT从结果中消除重复的行。DISTINCT ON消除在所有指定表达式上匹配的行。ALL(默认)将返回所有候选行, 包括重复的行。
- 对于每一个被选中的行,会使用SELECT输出表达式计算实际的输出行。
- 通过使用运算符UNION、 INTERSECT和EXCEPT,多于 一个SELECT语句的输出可以被整合形成 一个结果集。UNION运算符返回位于一个或者两 个结果集中的全部行。INTERSECT运算符返回同时 位于两个结果集中的所有行。EXCEPT运算符返回 位于第一个结果集但不在第二个结果集中的行。在所有三种情况下, 重复行都会被消除(除非指定ALL)。
- 如果指定了ORDER BY子句,被返回的行会以指定的顺序排序。如果没有给定ORDER BY,系统会以能最快产生行的顺序返回它们。
- 如果指定了LIMIT或者OFFSET子句,SELECT语句只返回结果行的一个子集。 用户必须拥有在要读取值的表上的 SELECT特权。FOR UPDATE、 FOR SHARE还要求UPDATE特权。
参数
WITH 子句
WITH子句允许用户指定一个或者多个在主查询中可以其名称引用的子查询。在主查询期间子查询实际扮演了临时表或者视图的角色。每一个子查询都可以是一个SELECT或者VALUES语句。
对于每一个WITH子句,都必须指定一个名称(可以不包括schema信息)。可选地,可以指定一个列名列表。如果省略该列表,会从该子查询中推导列名。主查询和WITH查询全部(理论上)都在同一时间被执行。
SELECT列表
SELECT列表(位于关键词SELECT和FROM之间)指定构成SELECT语句输出行的表达式。这些表达式 可以(并且通常确实会)引用FROM子句中计算得到的列。
另一个名字可以被指定用于一个输出列的名称,使用[AS] output_name。该名称最基本是出于显示目的标记列。一个输出列的名称可以被用来在ORDER BY以及ORDER BY子句中引用该列的值,但是不能用于 WHERE和HAVING子句(在其中必须写出表达式)。在大多数场景下,AS关键词是可选的(例如当为一个列名、常量、函数调用、简单一元操作表达式声明一个别名)。 为了避免声明的别名与关键词冲突,输出名一定要使用双引号包含起来。推荐总是写上AS或者用双引号引用输出名称。
一个SELECT列表中的表达式可以为常量值、一个列引用、一个运算符调用、一个函数调用、一个窗口表达式、一个标量子查询(scalar subquery)等等。一些构造可以分类为一个表达式但是不符合通用的语法规则。这些通常有一个运算符或者函数的语义。
可以在输出列表中写来取代表达式,它是被选中行的所有列的一种简写方式。还可以写table_name.,它 是只来自那个表的所有列的简写形式。
FROM 子句
FROM子句为SELECT指定一个或者更多源表。如果指定了多个源表,结果将是所有源表的 笛卡尔积(交叉连接)。但是通常会增加限定条件,来把返回的行限制为该笛卡尔积的一个小子集。FROM子句可以包含下列元素:
-
table_name
一个现有表或视图的名称(可包括schema信息)。如果在表名前指定了 ONLY,则只会扫描该表。如果没有指定ONLY,该表及其所有后代表(如果有)都会被扫描。
-
alias
一个包含别名的FROM项的替代名称。别名被用于让书写简洁或者消除自连接中的混淆(其中同一个表会被扫描多次)。当提供一个别名时,表或者函数的实际名称会被隐藏。例 如,给定FROM foo AS f,SELECT的剩余部分就必须以f而不是foo来引用这个FROM项。如果写了一个别名,还可以写一个列别名列表来为该表的一个或者多个列提供替代名称。
-
select
子SELECT语句可以出现在 FROM子句中。这就好像把它的输出创建为一个存在于该SELECT命令期间的临时表。注意 子SELECT必须用圆括号包围,并且必须为它提供一个别名。也可以在这里使用一个VALUES命令。
-
with_query_name
在FROM子句中,可以通过写一个WITH查询的名称来引用WITH查询,就好像 该查询的名称是一个表名。WITH查询的名称不能包含一个schema限定词。可以像表一样, 以同样的方式提供一个别名。
-
function_name
函数调用可以出现在FROM子句中(对于返回结果集合的函数特别有用,但是可以使用任何函数)。这就好像把该函数的输出创建为一个存在于该SELECT命令期间的临时表。可以用和表一样的方式提供一个别名。如果写了一个别名,还可以写一个列别名列表来为该函数的组合返回类型的一个或者多个属性提供替代名。如果函数被定义为返回record数据类型,那么必须出现一个 别名或者关键词AS,后面跟上形为 ( column_name data_type [, ... ] )的列定义列表。列定义列表必须匹配该函数返回的列的实际数量和类型。
-
join_type
- [INNER] JOIN
- LEFT [OUTER] JOIN
- RIGHT [OUTER] JOIN
- FULL [OUTER] JOIN
- CROSS JOIN
对于INNER和OUTER连接类型,必须指定一个连接条件,即NATURALON join_condition或者 USING ( join_column [, ...]) 之一(只能有一种)。其含义见下文。对于CROSS JOIN,上述子句不能出现。
一个JOIN子句结合了两个FROM项。如果需要的话,使用括号来确定嵌套的顺序。在没有括号的情况下,JOIN是从左到右嵌套的。在任何情况下,JOIN都比分隔FROM项的逗号结合得更紧密。
CROSS JOIN和INNER JOIN会产生简单的笛卡尔积,也就是与在FROM的顶层列出两个表得到的结果相同,但是要用连接条件(如果有)约束该结果。CROSS JOIN与INNER JOIN ON(TRUE)等效,也就是说条件不会移除任何行。这些连接类型只是一种记号上的方便,因为没有什么是用户用纯粹的FROM和WHERE能做而它们不能做的。
LEFT OUTER JOIN返回被限制过的笛卡尔积中的所有行(即所有通过了其连接条件的组合行),外加左手表中 没有相应的通过了连接条件的右手行的每一行的拷贝。通过在右手列中插入空值,这种左手行会被扩展为连接表的完整行。注意在决 定哪些行匹配时,只考虑JOIN子句自身的条件。之后才应用外条件。
相反,RIGHT OUTER JOIN返回所有连接行,外加每 一个没有匹配上的右手行(在左端用空值扩展)。这只是为了记号 上的方便,因为用户可以通过交换左右表把它转换成一个LEFT OUTER JOIN。 FULL OUTER JOIN返回所有连接行,外加每 一个没有匹配上的左手行(在右端用空值扩展),再外加每一个没有 匹配上的右手行(在左端用空值扩展)。
-
ON join_condition
是一个会得到boolean类型值的表达式(类似于一个WHERE子句),它说明一次连接中哪些行被认为相匹配。
-
USING (join_column [, …])
形如USING ( a, b, ... )的子句是ON left_table.a = right_table.a AND left_table.b = right_table.b ... 的简写。还有,USING表示每一对相等列中只有一个会被包括在连接输出中。
-
NATURAL
是列出在两个表中所有具有 相同名称的列的USING的简写。
WHERE子句
可选的WHERE子句的形式:
WHERE <condition>
其中condition是任一计算得到boolean类型结果的表达式。任何不满足 这个条件的行都会从输出中被消除。如果用一行的实际值替换其中的 变量引用后,该表达式返回真,则该行符合条件。
GROUP BY 子句
可选的GROUP BY子句的形式:
GROUP BY <grouping_element >[, ...]
grouping_element可以为下列之一:
()
<expression>
ROLLUP (<expression> [,...])
CUBE (<expression> [,...])
GROUPING SETS ((<grouping_element> [, ...]))
GROUP BY将会把所有被选择的行中共享相同分组表达式值的那些行压缩成一个行。一个被用在 expression可以是输入列名、输出列 (SELECT列表项)的名称或序号或者由输入列 值构成的任意表达式。在出现歧义时,GROUP BY名称 将被解释为输入列名而不是输出列名。
聚合函数(如果使用)会在组成每一个分组的所有行上进行计算,从而为每一个分组产生一个单独的值(如果有聚合函数但是没有GROUP BY子句,则查询会被当成是由所有选中行构成的一个单一分组)。当存在GROUP BY子句或者任何聚合函数时,SELECT列表表达式不能引用非分组列(除非它 出现在聚合函数中或者它函数依赖于分组列),因为这样做会导致返回非分组列的值时会有多种可能的值。
Hashdata数据库有下面增加的OLAG分组扩展(通常被称为supergroups):
-
ROLLUP
一个ROLLUP分组是GROUP BY分组的扩展。 该分组创建一个从最细的级别到一个粗粒度级别上卷聚合操作,后面紧跟着一系列的分组列(或者表达式)。 ROLLUP接受一个有序的分组列,计算在GROUP BY中指定的标准聚合值,然后从右到左进一步创建高层次的部分和。最后创建了累积和。一个ROLLUP 分组能够看做一系列的分组集。例如:GROUP BY ROLLUP (a,b,c)
等价于:
GROUP BY GROUPING SETS( (a,b,c), (a,b), (a), () )
注意,一个有n个元素的 ROLLUP翻译为 n+1 分组集。同时, 在ROLLUP中指定分组表达式的顺序很重要。
-
CUBE CUBE分组是 GROUP BY子句的一个扩展。它能够为给定的分组列(或者表达式)所有可能的组合创建部分和。在多维分析上,CUBE为指定维度的、可计算的数据立方体计算出所有的部分和。例如:
GROUP BY CUBE (a,b,c)
等价于:
GROUP BY GROUPING SETS( (a,b,c), (a,b), (a,c), (b,c), (a), (b), (c), () )
注意,一个有 n 个元素的CUBE翻译为2n个分组集。 在任何需要交叉表报表的场景下,考虑使用CUBE。CUBE典型的适用于查询中从多个维度中使用列而不是一个列代表不同层次上使用列。例如,例如,通常要求的交叉制表可能需要月份、州和产品的所有组合的小计。
-
GROUPING SETS
GROUP BY子句中,可以在想要使用GROUPING SETS表达式的地方选择性指定分组集合。这允许精确的规范在多个维度而不用计算整个ROLLUP或CUBE。例如:GROUP BY GROUPING SETS( (a,c), (a,b) )
如果使用分组扩展子句ROLLUP、 CUBE或者GROUPING SETS,有两个挑战将会出现。 首先,如何决定哪些结果行需要是部分和,以及给定的部分和的准确聚合层次。或者用户如何区别包含NULL或者由ROLLUP 、CUBE产生"NULL"值的结果行。第二,当在GROUP BY子句中指定了重复分组,如何决定哪些结果行是冗余的呢?有两个额外的分组函数可以使用在SELECT列表中帮助:
- grouping(column [, …]) — 该grouping函数可应用于一个或多个分组属性,以区分超聚合行和常规分组行。这有助于将表示超聚合行中所有值的集合的“NULL”与NULL常规行中的值区分开来。此函数中的每个参数都会产生一个位 ,1或0,其中1表示结果行是超聚合的,并且0表示结果行来自常规分组。该grouping函数通过将这些位视为二进制数然后将其转换为以 10 为底的整数来返回一个整数。
- group_id() — 对于包含重复分组集的分组扩展查询,该group_id函数用于识别输出中的重复行。所有唯一分组集输出行的 group_id 值为 0。对于检测到的每个重复分组集,该group_id函数分配一个大于 0 的 group_id 编号。特定重复分组集中的所有输出行都由相同的 group_id 编号标识。
WINDOW 子句
WINDOW子句是用来定义一个能够被用在一个窗口函数(例如,rank或者avg)的OVER()表达式中的窗口。 例如:
SELECT vendor, rank() OVER (mywindow) FROM sale
GROUP BY vendor
WINDOW mywindow AS (ORDER BY sum(prc*qty));
一个 WINDOW子句有一般的形式:
WINDOW <window_name> AS (<window_specification>)
其中 window_specification可以为:
[<window_name>]
[PARTITION BY <expression >[, ...]]
[ORDER BY <expression> [ASC | DESC | USING <operator>] [NULLS {FIRST | LAST}] [, ...]
[{RANGE | ROWS}
{ UNBOUNDED PRECEDING
| <expression> PRECEDING
| CURRENT ROW
| BETWEEN <window_frame_bound> AND <window_frame_bound> }]]
其中 window_frame_bound可以为下列之一:
UNBOUNDED PRECEDING
<expression> PRECEDING
CURRENT ROW
<expression> FOLLOWING
UNBOUNDED FOLLOWING
- window_name
给窗口说明一个名字。
- PARTITION BY
基于指定表表达式的唯一值将结果集组织为逻辑组。当同窗口函数使用,函数将被单独地应用到每个分片。例如,如果用户在一个列名后紧跟一个PARTITION BY,结果集将会通过列的不同值进行分割。如果忽略,整个结果集被看做一个分片。
- ORDER BY
子句定义了如何对结果集的每个分区中的记录进行排序。如果省略,行将以最有效的顺序返回,并且可能会有变化。注意:缺乏一致性排序的数据类型的列,例如time,不适合在窗口规范的ORDER BY子句中使用。时间,无论是否有时区,都缺乏连贯的排序,因为加法和减法没有预期的效果。例如,下面的一般不为真:x::time < x::time + '2 hour'::interval
- ROWS | RANGE
通过使用ROWS或者RANGE子句来表示窗口的界(bounds)。窗口的界可能为一个分区的一个,多个行或者所有行。可以根据一系列的值距离当前行的值偏移量来表达(RANGE)或者依据距离当前行的偏移行数来表达(ROWS)。当使用 RANGE子句,一定要使用一个 ORDER BY子句。这是因为执行产生窗口的计算需要值是排好序的。另外,ORDER BY子句不能包含多于一个的表达式,同时表达式的必须为一个日期或者一个数值值。当使用 ROWS 或者 RANGE子句,如果用户只指定了一个开始行,那么当前行会作为窗口的最后一行。
PRECEDING — PRECEDING 子句定义以当前行为参考点窗口的第一行的位置。开始行依据距离当前行的前驱行数来表达。例如,在 ROWS 框架中,5 PRECEDING设置窗口开始于当前的第五个前驱行。在RANGE框架中,设置窗口开始于按照给定顺序的当前行的第五个前驱行。如果按照时间升序指定顺序,那么第一行为当前行五天前的行。UNBOUNDED PRECEDING设置窗口中的第一行为分区中的第一行。
BETWEEN — BETWEEN子句使用当前行作为参考点,定义了窗口的第一行和最后一行。第一行和最后一行依据当前行的前驱和后继的行的数目表达。例如,BETWEEN 3 PRECEDING AND 5 FOLLOWING设置窗口开始于当前行前驱的第三个行,结束于当前行后面的第五行。使用BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING设置窗口的第一行和最后一行为该分区中的一行和最后一行。这等效于在没有ROW 或者RANGE子句指定是的默认行为。
FOLLOWING — FOLLOWING 子句定义了使用当前行作为参考点的窗口的最后一行。最后一行的表示依据跟在当前行后面的行的行号。例如,在ROWS 框架中, 5 FOLLOWING 设置窗口的结束为止在当前行后的第五个行。在RANGE框架中,它设置窗口的结束为按在给定顺序跟在当前行后面的5行。如果指定属性为按照日期的升序,那么最一行为当前行之后5天的行。使用UNBOUNDED FOLLOWING设置窗口中的最后一行为分区中的最后一行。
如果没有指定一个ROW或者RANGE子句,窗口的界会从分区的第一行开始(UNBOUNDED PRECEDING) 同时以当前行为结束(CURRENT ROW),如果使用了ORDER BY 。如果ORDER BY 没有指定,那么窗口开始于分区(UNBOUNDED PRECEDING)的第一行同时结束语分区(UNBOUNDED FOLLOWING)的最后一行。
HAVING子句
可选 HAVING子句的形式:
HAVING <condition>
其中condition与WHERE子句中指定的条件相同。HAVING消除不满足该条件的分组行。 HAVING与WHERE不同:WHERE会在应用GROUP BY之前过滤个体行,而HAVING过滤由GROUP BY创建的分组行。condition中引用的每一个列必须无歧义地引用一个分组列(除非该引用出现在一个聚合函数)。
即使没有GROUP BY子句,HAVING的存在也会把一个查询转变成一个分组查询。这和查询中包含聚合函数但没有GROUP BY子句时的情况相同。所有被选择的行都被认为是一个 单一分组,并且SELECT列表和 HAVING子句只能引用聚合函数中的表列。如果该HAVING条件为真,这样一个查询将会发出一个单一行; 否则不返回行。
UNION子句
UNION子句具有下面的形式:
<select_statement> UNION [ALL] <select_statement>
select_statement 是任何没有ORDER BY、LIMIT、 FOR UPDATE、 FOR SHARE和FOR KEY SHARE子句的SELECT语句(如果子表达式被包围在圆括号内, ORDER BY和LIMIT可以被附着到其上。如果没有圆括号,这些子句将被应用到UNION的结果而不是右手边的表达式上)。
UNION运算符计算所涉及的 SELECT 语句所返回的行的并集。如果一行 至少出现在两个结果集中的一个内,它就会在并集中。作为UNION两个操作数的SELECT语句必须产生相同数量的列并且 对应位置上的列必须具有兼容的数据类型。
UNION的结果不会包含重复行,除非指定了ALL选项。ALL会阻止消除重复(因此, UNION ALL通常显著地快于UNION, 尽量使用ALL)。
除非用圆括号指定计算顺序, 同一个SELECT语句中的多个 UNION运算符会从左至右计算。
当前,FOR UPDATE 和FOR SHARE不能用于UNION结果或者 UNION的任何输入。
INTERSECT 子句
INTERSECT子句具有下面的形式:
<select_statement> INTERSECT [ALL] <select_statement>
select_statement 是任何没有ORDER BY、LIMIT、FOR UPDATE以及FOR SHARE子句的SELECT语句。
INTERSECT运算符计算所涉及的SELECT语句返回的行的交集。如果 一行同时出现在两个结果集中,它就在交集中。
INTERSECT的结果不会包含重复行,除非指定了ALL选项。如果有ALL,一个在左表中有m次重复并且在右表中有n次重复的行将会在结果中出现min(m, n)次。
除非用圆括号指定计算顺序, 同一个SELECT语句中的多个INTERSECT运算符会从左至右计算。 INTERSECT的优先级比UNION更高。也就是说,A UNION B INTERSECT C被被读成 A UNION (B INTERSECT C)。
当前, FOR UPDATE 和FOR SHARE不能用于INTERSECT结果或者INTERSECT的任何输入。
EXCEPT子句
EXCEPT 子句具有如下形式:
select_statement EXCEPT [ALL] select_statement
select_statement是任何没有ORDER BY、LIMIT、FOR UPDATE以及FOR SHARE子句的SELECT语句。
EXCEPT运算符计算位于左SELECT语句的结果中但不在右 SELECT语句结果中的行集合。 EXCEPT的结果不会包含重复行,除非指定了ALL选项。如果有ALL,一个在左表中有m次重复并且在右表中有n次重复的行将会在结果集中出现max(m-n,0)次。
除非用圆括号指定计算顺序, 同一个SELECT语句中的多个 EXCEPT运算符会从左至右计算。EXCEPT的优先级与UNION相同。
当前,FOR UPDATE 和 FOR SHARE不能用于 EXCEPT结果或者 EXCEPT的任何输入。
ORDER BY子句
ORDER BY子句可选的形式如下:
ORDER BY <expression> [ASC | DESC | USING <operator>] [NULLS { FIRST | LAST}] [, ...]
每一个expression可以是输出列(SELECT列表项)的名称或者序号,它也可以是由输入列值构成的任意表达式。
ORDER BY子句导致结果行被按照指定的表达式排序。 如果两行按照最左边的表达式是相等的,则会根据下一个表达式比较它们,依次类推。如果按照所有指定的表达式它们都是相等的,则它们被返回的顺序取决于实现。
序号指的是输出列的顺序(从左至右)位置。这种特性可以为不具有唯一名称的列定义一个顺序。这不是绝对必要的,因为总是可以使用AS子句为输出列赋予一个名称。
也可以在ORDER BY子句中使用任意表达式,包括没有出现在SELECT输出列表中的列。因此,下面的语句是合法的:
SELECT name FROM distributors ORDER BY code;
这种特性的一个限制是一个应用在UNION、INTERSECT或者EXCEPT子句结果上的ORDER BY只能指定输出列名称或序号,但不能指定表达式。
如果一个ORDER BY表达式是一个既匹配输出列名称又匹配 输入列名称的简单名称,ORDER BY将把它解读成输出列名称。这与在同样情况下GROUP BY会做出的选择相反。这种不一致是为了与SQL标准兼容。
可以为ORDER BY子句中的任何表达式之后增加关键词 ASC(上升)DESC(下降)。如果没有指定, ASC被假定为默认值。或者,可以在USING子句中指定一个特定的排序运算符名称。ASC通常等价于USING <而DESC通常等价于USING >(但是一种用户定义数据类型的创建者可以 准确地定义默认排序顺序是什么,并且它可能会对应于其他名称的运算符)。
如果指定NULLS LAST,空值会排在非空值之后;如果指定NULLS FIRST,空值会排在非空值之前。如果都没有指定, 在指定或者隐含ASC时的默认行为是NULLS LAST, 而指定或者隐含DESC时的默认行为是NULLS FIRST(因此,默认行为是空值大于非空值)。 当指定USING时,默认的空值顺序取决于该运算符是否为小于或者大于运算符。
注意顺序选项只应用到它们所跟随的表达式上。例如ORDER BY x, y DESC和ORDER BY x DESC, y DESC是不同的。
字符串数据被根据区域相关的排序规则顺序排序,该顺序在Hashdata数据库系统被初始化时建立。
DISTINCT子句
如果指定了 DISTINCT 子句,所有重复的行会被从结果 集中移除(为每一组重复的行保留一行)。ALL则 指定相反的行为:所有行都会被保留,这也是默认情况。
DISTINCT ON ( expression [, …] )只保留在给定表达式上计算相等的行集合中的第一行。DISTINCT ON表达式使用和ORDER BY相同的规则(见上文)解释。注意,除非用ORDER BY来确保所期望的行出现在第一位,每一个集 合的"第一行"是不可预测的。例如
SELECT DISTINCT ON (location) location, time, report FROM
weather_reports ORDER BY location, time DESC;
为每个地点检索最近的天气报告。但是如果我们不使用ORDER BY来强制对每个地点的时间值进行降序排序, 我们为每个地点得到的报告的时间可能是无法预测的。
DISTINCT ON表达式必须匹配最左边的ORDER BY表达式。ORDER BY子句通常将包含额外的表达式,这些额外的表达式用于决定在每一个DISTINCT ON分组内行的优先级。
当Hashdata数据库处理包含有DISTINCT子句的查询时,查询将会转换为GROUP BY查询。在很多场景中,变换能够提供显著的性能提升。然而,当distinct值的数量与总的行数相近时,该转换可能会导致多个层次的分组计划的产生。在这种情况下,由于引入的低聚合度开销,预期性能会降低。
LIMIT 子句
LIMIT子句两个独立的子句构成:
LIMIT {<count> | ALL}
OFFSET <start>
count指定要返回 的最大行数,而start指定在返回行之前要跳过的行数。在两者都被指定时,在开始计算要返回的 count行之前会跳过 start行。
在使用LIMIT时,用一个ORDER BY子句把 结果行约束到一个唯一顺序是个好办法。否则用户讲得到该查询结果行的 一个不可预测的子集 — 用户可能要求从第 10 到第 20 行,但是在 什么顺序下的第 10 到第 20 呢?除非指定ORDER BY,用户 是不知道顺序的。
查询规划器在生成一个查询计划时会考虑LIMIT,因此 根据用户使用的LIMIT和OFFSET,用户很可能 得到不同的计划(得到不同的行序)。所以,使用不同的LIMIT/OFFSET值来选择一个查询结果的 不同子集将会给出不一致的结果,除非用户 用ORDER BY强制一种可预测的结果顺序。这不是一个 缺陷,它是 SQL 不承诺以任何特定顺序(除非使用 ORDER BY来约束顺序)给出一个查询结果这一事实造 成的必然后果。
示例
把表films与表distributors连接:
SELECT f.title, f.did, d.name, f.date_prod, f.kind FROM
distributors d, films f WHERE f.did = d.did
要对所有电影的length列求和并且用 kind对结果分组:
SELECT kind, sum(length) AS total FROM films GROUP BY kind;
要对所有电影的length列求和、对结果按照 kind分组并且显示总长小于 5 小时的分组:
SELECT kind, sum(length) AS total FROM films GROUP BY kind
HAVING sum(length) < interval '5 hours';
根据kind 和 distributor计算所有电影销售的部分和以及总和。
SELECT kind, distributor, sum(prc*qty) FROM sales
GROUP BY ROLLUP(kind, distributor)
ORDER BY 1,2,3;
基于总的销售对电影的发行商进行排名:
SELECT distributor, sum(prc*qty),
rank() OVER (ORDER BY sum(prc*qty) DESC)
FROM sale
GROUP BY distributor ORDER BY 2 DESC;
下面的两个例子都是根据第二列(name)的内容排序结果:
SELECT * FROM distributors ORDER BY name;
SELECT * FROM distributors ORDER BY 2;
接下来的例子展示了如何得到表distributors和 actors的并集,把结果限制为那些在每个表中以 字母 W 开始的行。只想要可区分的行,因此省略了关键词 ALL:
SELECT distributors.name FROM distributors WHERE
distributors.name LIKE 'W%' UNION SELECT actors.name FROM
actors WHERE actors.name LIKE 'W%';
这个例子展示了如何在FROM子句中使用函数, 分别使用和不使用列定义列表:
CREATE FUNCTION distributors(int) RETURNS SETOF distributors
AS $$ SELECT * FROM distributors WHERE did = $1; $$ LANGUAGE
SQL;
SELECT * FROM distributors(111);
CREATE FUNCTION distributors_2(int) RETURNS SETOF record AS
$$ SELECT * FROM distributors WHERE did = $1; $$ LANGUAGE
SQL;
SELECT * FROM distributors_2(111) AS (dist_id int, dist_name
text);
这个例子展示了如何使用简单的WITH子句:
WITH test AS (
SELECT random() as x FROM generate_series(1, 3)
)
SELECT * FROM test
UNION ALL
SELECT * FROM test;
这个例子使用WITH 子句来展示每个产品只在最好销售区域的销售总额。
WITH regional_sales AS
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
), top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales) FROM
regional_sales)
)
SELECT region, product, SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;
该示例能够不用WITH子句进行重写,但是将需要两层的子-SELECT语句。
兼容性
SELECT语句是兼容 SQL 标准的。 但是也有一些扩展和缺失的特性。
省略FROM子句
Hashdata数据库允许我们省略 FROM子句。一种简单的使用是计算简单表达式 的结果,例如:
SELECT 2+2;
某些其他SQL数据库需要引入一个假的 单行表放在该SELECT要选择的表上。
注意,如果没有指定一个FROM子句,该查询就不能引用任何数据库表。对于依赖这种行为的应用的兼容性,add_missing_from配置参数能够可以启动。
AS关键词
在 SQL 标准中,可选关键词AS只是一个噪声,能够直接被省略没有任何的语义影响。
Hashdata数据库解析器在重命名输出列时需要该关键词,因为没有它在类型扩展特性上回出现解析歧义。 只要新列名是一个合法的列名(就是说与任何保留关键词不同), 就可以省略输出列名之前的可选关键词AS。 PostgreSQL要稍微严格些:只要新列名匹配 任何关键词(保留或者非保留)就需要AS。推荐的习惯是使用 AS或者带双引号的输出列名来防止与未来增加的关键词可能的冲突。然而,在FROM中AS是可选的。
可用于GROUP BY和ORDER BY的名字空间
在 SQL-92 标准中,一个ORDER BY子句只能使用输出列名或者序号,而一个GROUP BY子句只能使用基于输入列名的表达式。Hashdata数据库扩展了这两种子句以允许它们使用其他的选择(但如果有歧义时还是使用标准的解释)。Hashdata数据库也允许两种子句指定任意表达式。注意出现在一个表达式中的名称将总是被当做输入列名而 不是输出列名。
SQL:1999 及其后的标准使用了一种略微不同的定义,它并不完全向后兼容 SQL-92。不过,在大部分的情况下, Hashdata数据库会以与 SQL:1999 相同的 方式解释ORDER BY或GROUP BY表达式。
非标准子句
DISTINCT ON、LIMIT以及OFFSET 子句并没有在SQL标准中有定义。
STABLE以及VOLATILE函数的限制使用
为了防止数据在在Hashdata数据库的多个segment间不同步,任何一个定义为STABLE或者 VOLATILE的函数不能在Segment级别执行(如果它包含了SQL或者修改了数据库)。见CREATE FUNCTION获取更多信息。
另见
EXPLAIN
SELECT INTO
从查询结果中定义一个新的表。
概要
[ WITH <with_query> [, ...] ]
SELECT [ALL | DISTINCT [ON ( <expression> [, ...] )]]
* | <expression> [AS <output_name>] [, ...]
INTO [TEMPORARY | TEMP] [TABLE] <new_table>
[FROM <from_item> [, ...]]
[WHERE <condition>]
[GROUP BY <expression> [, ...]]
[HAVING <condition> [, ...]]
[{UNION | INTERSECT | EXCEPT} [ALL] <select>]
[ORDER BY <expression> [ASC | DESC | USING <operator>] [NULLS {FIRST | LAST}] [, ...]]
[LIMIT {<count> | ALL}]
[OFFSET <start>]
[...]]
描述
SELECT INTO创建一个新表并且用一个查询计算得到的数据填充它。这些数据不会像普通的SELECT那样被返回给客户端。新表的列具有和SELECT的输出列相关的名称和数据类型。
参数
SELECT INTO 主要的参数同 SELECT是一样的。 TEMPORARY TEMP 如果被指定,该表被创建为一个临时表。 new_table 要创建的表的名字(可包括schema信息)。
示例
创建一个新的表 films_recent,只包含表 films 的最近条目: SELECT * INTO films_recent FROM films WHERE date_prod >= ‘2016-01-01’;
兼容性
SQL 标准用于SELECT INTO将选择值表示为主机程序的标量变量,而不是创建新表。 SELECT INTO表示表创建的 Hashdata 数据库使用是历史性的。最好在新应用程序中为此目的使用CREATE TABLE AS 。
另见
SELECT, CREATE TABLE AS
SET
改变Hashdata数据库配置参数的值。
概要
SET [SESSION | LOCAL] <configuration_parameter> {TO | =} <value> |
'<value>' | DEFAULT}
SET [SESSION | LOCAL] TIME ZONE {<timezone> | LOCAL | DEFAULT}
描述
SET命令更改运行时配置参数。任何被分类到session的参数可以用SET即时更改。SET只影响当前会话所使用的值。
如果在一个事务内发出SET(或者等效的SET SESSION)而该事务后来 中止,在该事务被回滚时SET命令的效果会 消失。一旦所在的事务被提交,这些效果将会持续到会话结束(除非被另 一个SET所覆盖)。
SET LOCAL的效果只持续到当前事务结束, 不管事务是否被提交。一种特殊情况是在一个事务内SET后面跟着SET LOCAL:SET LOCAL值将会在该事务结束前一直可见, 但是之后(如果该事务被提交)SET值将会生效。
如果在一个函数内使用SET LOCAL并且该函数 还有对同一变量的SET选项(见CREATE FUNCTION),在函数退出时SET LOCAL命令的效果会消失。也就是说,该函数被调用时的值会被恢复。这允许用SET LOCAL在函数内动态地或者重复地更改一个参数,同时仍然能便利地使用SET选项来保存以及恢复调用 者的值。不过,一个常规的SET命令会覆盖它所在的任何函数的SET选项,除非回滚,它的效果将一直保持。
如果在一个事务中,使用 DECLARE创建了一个游标,那么久不能在该事务中使用SET命令,直到使用CLOSE命令关闭游标。
见 服务配置参数 获取关于参数的信息。
参数
- SESSION
指定该命令对当前会话有效(这是默认值)。
- LOCAL
指定该命令只对当前事务有效。在COMMIT或者ROLLBACK之后,会话级别的设置会再次生效。注意SET LOCAL出现在事务块外部执行,不会有效果。
- configuration_parameter
一个可设置运行时参数的名称。只有被分类为session类别的参数能够通过SET命令就行修改。 见 服务配置参数获取细节信息。
- value
参数的新值。根据特定的参数,值可以被指定为字符串常量、标识符、 数字或者以上构成的逗号分隔列表。写DEFAULT可以指定把该参数重置成它的默认值。如果指定内存大小伙子时间单位,则值包含在单引号中。
- TIME ZONE
SET TIME ZONE value是 SET timezone TO value的一个别 名。语法SET TIME ZONE允许用于时区指定的特 殊语法。这里是合法值的例子:
'PST8PDT'
'Europe/Rome'
-7 (UTC 以西 7 小时的时区)
INTERVAL '-08:00' HOUR TO MINUTE (UTC 以西 8 小时的时区)。 - LOCAL
DEFAULT把时区设置为用户的本地时区(也就是说服务器的timezone默认值)。
示例
设置schema搜索路径:
SET search_path TO my_schema, public;
增加每个查询的segment主机内存到200MB:
SET statement_mem TO '200MB';
把日期风格设置为传统 POSTGRES的 “日在月之前"的输入习惯:
SET datestyle TO postgres, dmy;
设置时区为加州伯克利:
SET TIME ZONE 'PST8PDT';
设置时区为意大利:
兼容性
SET TIME ZONE扩展了SQL标准定义的语法。标准只允许数字的时区偏移量而 Hashdata数据库允许更灵活的时区说明。所有其他SET特性都是Hashdata数据库的扩展。
另见
RESET, SHOW
SET ROLE
设置当前会话当前角色的标识符。
概要
SET [SESSION | LOCAL] ROLE <rolename>
SET [SESSION | LOCAL] ROLE NONE
RESET ROLE
描述
这个命令把当前SQL会话的当前用户标识符设置为rolename。角色名可以写成一个标识符或者一个字符串。在SET ROLE后,对SQL命令的权限检查时就 好像该角色就是原先登录的角色一样。
当前会话用户必须是指定的角色rolename的一个成员。如果会话用户是一个超级用户,则可以选择任何角色。
NONE和RESET形式把当前用户标识符重置为当前会话用户标识符。这些形式可以由任何用户执行。
参数
- SESSION
指明命令作用于当前会话。这是默认值。
- LOCAL
指明命令只作用于当前事务中。在COMMIT或者ROLLBACK之后,会话级设置继续恢复影响。注意SET LOCAL好像没有任何的影响,如果该命令执行在事务外时。
- rolename
在会话中用来进行权限检查的有角色名。
- NONE
RESET重置当前角色(用户)标识符成为当前会话角色(用户)标识符(即用来登录的角色)。
注解
使用这个命令可以增加特权或者限制特权。如果会话用户角色具有 INHERITS属性,则它会自动具有它能SET ROLE到的所有角色的全部特权。在这种情况下。SET ROLE 实际会删除所有直接分配给会话用户的特 权以及分配给会话用户作为其成员的其他角色的特权,只留下所提及 角色可用的特权。换句话说,如果会话用户没有NOINHERITS属性, SET ROLE 会删除直接分配给会话用户的特权而得到所提及角色可用的特权。
特别地,当一个超级用户选择SET ROLE 到一个非超级用户角色时,它们会丢失其超级用户特权。
SET ROLE的效果堪比SET SESSION AUTHORIZATION,但是涉及的特权检查完全不同。 还有,SET SESSION AUTHORIZATION决定后来的SET ROLE 命令可以使用哪些角色,不过用SET ROLE更改角色并不会改变后续SET ROLE能够使用的角色集。
示例
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+--------------
peter | peter
SET ROLE 'paul';
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+--------------
peter | paul
兼容性
Hashdata数据库允许标识符语法(rolename),而SQL标准要求 角色名被写成字符串。 SQL 不允许在事务中使用这个命令;但 Hashdata数据库并不做此限制。和RESET语法一样,SESSION和LOCAL 修饰符是Hashdata数据库的扩展。
另见
SET SESSION AUTHORIZATION
SET SESSION AUTHORIZATION
设置会话角色标识符和当前会话当前角色的标识符。
概要
SET [SESSION | LOCAL] SESSION AUTHORIZATION <rolename>
SET [SESSION | LOCAL] SESSION AUTHORIZATION DEFAULT
RESET SESSION AUTHORIZATION
描述
这个命令把当前 SQL 会话的会话用户标识符和当前用户标识符设置为rolename。用户名可以被写成一个标识符或者一个字符串。例如,可以使用这个 命令临时成为一个无特权用户并且稍后切换回来成为一个超级用户。
会话用户标识符初始时被设置为客户端提供的(可能已认证的)用户名。 当前用户标识符通常等于会话用户标识符,但是可能在setuid函数和类似的机制的环境中发生临时更改。也可以使用SET ROLE更改它。当前用户标识符与权限检查相关。
会话用户标识符只能在初始会话用户 已认证用户具有超级用户特权时被更改。否则,只有该命令指定已认证用户名时才会被接受。
DEFAULT和RESET形式把会话用户标识符和 当前用户标识符重置为初始的已认证用户名。这些形式可以由任何用户执行。
参数
- SESSION
指明命令作用于当前会话。这是默认值。
- LOCAL
指明命令只作用于当前事务中。在COMMIT或者ROLLBACK之后,会话级设置继续恢复影响。注意SET LOCAL好像没有任何的影响,如果该命令执行在事务外时。
- rolename
假定的角色名。
- NONE
RESET重置当前角色(用户)标识符成为当前会话角色(用户)标识符(即用来登录的角色)。
示例
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+--------------
peter | peter
SET SESSION AUTHORIZATION 'paul';
SELECT SESSION_USER, CURRENT_USER;
session_user | current_user
--------------+--------------
paul | paul
兼容性
SQL 标准允许一些其他表达式出现在文本 rolename的位置上,但是实际上这些 选项并不重要。 Hashdata数据库允许标识符语法(rolename),而 SQL 标准不允许。 SQL 不允许在事务中使用这个命令,而 Hashdata数据库并不做此限制。 和RESET语法一样,SESSION和LOCAL 修饰符是Hashdata数据库的扩展。
另见
SET ROLE
SHOW
显示当前系统配置参数的值。
概要
SHOW <configuration_parameter>
SHOW ALL
描述
SHOW将显示当前Hashdata数据库系统配置参数的当前设置。 这些变量可以使用SET语句、编辑Hashdata数据库Master上的 postgresql.conf配置参数。注意 :一些能够使用SHOW查看的参数是只读的,它们的值只能被查看,不能被修改。见Hashdata数据库参考指南了解细节信息。
参数
- configuration_parameter
系统配置参数的名称。
- ALL
所有配置参数的当前值。
示例
显示参数search_path的当前设置: SHOW search_path; 显示所有配置参数的当前的值: SHOW ALL;
兼容性
SHOW是Hashdata数据库的扩展。
另见
SET, RESET
START TRANSACTION
开始事务块。
概要
START TRANSACTION
示例
开始一个事务块:
START TRANSACTION;
另见
BEGIN
TRUNCATE
清空表的所有行。
概要
TRUNCATE [TABLE] <name> [, ...] [CASCADE | RESTRICT]
描述
TRUNCATE 可以从一组表中快速地移除所有行。 它具有和在每个表上执行无条件DELETE相同的效果,不过它会更快,因为它没有实际扫描表。在大表上它最有用。
要截断一个表,用户必须具有其上的TRUNCATE特权。
参数
- name
要截断的表的名字(可包括schema信息)。
- CASCADE
因为关键字应用到外键引用上Hashdata数据库还没有支持,所有没有效果。
- RESTRICT
因为关键字应用到外键引用上Hashdata数据库还没有支持,所有没有效果。
注解
TRUNCATE将不会引发表上可能存在的任何用户定义的ON DELETE触发器。
TRUNCATE 不会截断任何从命名的表继承而来的表。只有命名的表被截断,它的子表不会截断。
TRUNCATE 不会截断任何一个分区表的子表。如果用户指定了一个分区表的子表,TRUNCATE不会从子表以及它的孩子表上移除行。
示例
清空表films:
TRUNCATE films;
兼容性
在SQL标准中没有TRUNCATE命令。
另见
DELETE, DROP TABLE
UPDATE
更新表的行。
概要
UPDATE [ONLY] <table> [[AS] <alias>]
SET {<column> = {<expression> | DEFAULT} |
(<column> [, ...]) = ({<expression> | DEFAULT} [, ...])} [, ...]
[FROM <fromlist>]
[WHERE <condition >| WHERE CURRENT OF <cursor_name> ]
描述
UPDATE更改满足条件的所有行中指定列 的值。只有要被修改的列需要在 SET 子句中提及, 没有被显式修改的列保持它们之前的值。
默认地,UPDATE 命令将会更新指定表的所有列以及它的所有子表。如果只想要更新提到的指定表,必须使用ONLY子句。
有两种方法使用包含在数据库其他表中的信息来修改一个表:使用子选择 或者在FROM 子句中指定额外的表。这种技术只适合特定的环境。
如果WHERE CURRENT OF子句被指定,被更新的行则为最近从指定游标获取的行。
用户必须拥有在要更新表上的UPDATE 特权。如果任何一列的值需要被expressions或者 condition读取, 用户还必须拥有该列上的SELECT特权。
输出
成功完成时,一个UPDATE命令返回命令标签如下形式:
UPDATE count
count是被更新的行数。 如果count 为0,没有行被该查询更新(这不是一个错误)。
参数
- ONLY
如果指定,则只会更新所提及表中的匹配行。如果没有指定,任何从所提及表继承得到的表中的匹配的行也会被更新。table要更新的表的名称(可包括schema信息)。
- alias
目标表的一个替代名称。在提供了一个别名时,它会完全隐藏表的真实 名称。例如,给定UPDATE foo AS f,UPDATE语句的剩余部分必须用 f而不是foo引用该表。
- column
所指定的表的一列的名称。 如果需要,该列名可以用一个子域名称或者数组下标限定。不要在目标列的说明中包括表的名称。
- expression
要被赋值给该列的一个表达式。该表达式可以使用该表中这一列或者其他列的旧值。
- DEFAULT
将该列设置为它的默认值(如果没有为它指定默认值表达式,默认值将会为NULL)。
- fromlist
表的表达式的列表,允许来自其他表的列出现在WHERE条件和更新表达式中。 这类似于可以在SELECT语句的FROM子句中指定的表列表。注意目标表不能出现在fromlist中,除非用户想做自连接(这种情况下它必须以alias(别名)出现在fromlist中)。
- condition
一个返回boolean类型值的表达式。让这个 表达式返回true的行将会被更新。
- cursor_name
要在WHERE CURRENT OF条件中使用的游标名。要被更新的是从这个游标中最近取出的行。该游标必须是一个在UPDATE目标表上的简单(非连接,非聚合)的查询。有关创建游标更多信息请见DECLARE。
- WHERE CURRENT OF
不能和一个布尔条件一起指定。UPDATE...WHERE CURRENT OF语句只能在服务器端执行,例如在一个交互式的psql会话中或者一个脚本中。 语言扩展,例如PL/pgSQL不支持可更新游标。有关创建游标更多信息请见DECLARE。
- output_expression
在每一行被更新后,要被UPDATE命令计算并且返回的表达式。该表达式可以使用FROM列出的表中的任何列名。写*可以返回所有列。
- output_name
用于一个被返回列的名称。
注解
SET在Hashdata数据库表的分布主键列上是不允许的。
当存在FROM 子句时,实际发生的是:目标表被连接到 from_list中的表,并且该连接的每一个输出行表示对目标表的一个更新操作。在使用FROM时,用户应该确保该连接对每一个要修改的行产生至多一个输出行。换句话说,一个目标行不应该连接到来自其他表的多于一行上。如果发生这种情况,则只有一个连接行将被用于更新目标行,但是将使用哪 一行是很难预测的。
由于这种不确定性,只在一个子选择中引用其他表更安全,不过这种语句通常很难写并且也比使用连接慢。
直接在一个分区表的特定分区(子表)执行UPDATE 和 DELETE还不支持。相反,可以在根分区表(由CREATE TABLE命令创建的表)上执行这些命令。
示例
把表films的列kind中的单词Drama改成Dramatic:
UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';
在天气表的一行中调整温度条目并将降水重置为其默认值:
UPDATE weather SET temp_lo = temp_lo+1, temp_hi =
temp_lo+15, prcp = DEFAULT
WHERE city = 'San Francisco' AND date = '2016-07-03';
使用另一种列列表语法来做同样的更新:
UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1,
temp_lo+15, DEFAULT)
WHERE city = 'San Francisco' AND date = '2016-07-03';
为管理Acme Corporation账户的销售人员增加销售量,使用 FROM 子句语法(假定所有连接的表在Hashdata数据库中是通过id列进行分布的):
UPDATE employees SET sales_count = sales_count + 1 FROM
accounts
WHERE accounts.name = 'Acme Corporation'
AND employees.id = accounts.id;
执行相同的操作,在 WHERE子句中使用子选择:
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT id FROM accounts WHERE name = 'Acme Corporation');
尝试插入一个新库存项及其库存量。如果该项已经存在,则转而更新 已有项的库存量。要这样做并且不让整个事务失败,可以使用保存点:
BEGIN;
-- 其他操作
SAVEPOINT sp1;
INSERT INTO wines VALUES('Chateau Lafite 2003', '24');
-- 假定上述语句由于未被唯一键失败,
-- 那么现在我们发出这些命令:
ROLLBACK TO sp1;
UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau
Lafite 2003';
-- 继续其他操作,并且最终
COMMIT;
兼容性
这个命令符合SQL标准,不过 FROM子句是Hashdata数据库的扩展。
根据标准,列语法应该允许列为从一个单一的行值表达式赋值,如子选择:
UPDATE accounts SET (contact_last_name, contact_first_name) =
(SELECT last_name, first_name FROM salesmen
WHERE salesmen.id = accounts.sales_id);
这还没有实现 — 源必须是独立的表达式列表。
有些其他数据库系统提供了一个FROM选项,在其中在其中目标表 可以在FROM中被再次列出。
但 Hashdata数据库不是这样解释FROM的。在移植使用这种扩展的应用时要小心。
另见
DECLARE, DELETE, SELECT, INSERT
VALUES
计算一组行。
概要
VALUES ( <expression> [, ...] ) [, ...]
[ORDER BY <sort_expression> [ASC | DESC | USING <operator>] [, ...]]
[LIMIT {<count> | ALL}] [OFFSET <start>]
描述
VALUES计算由值表达式指定的一个行值或者一组行值。 更常见的是把它用来生成一个大型命令内的"常量表”,但是它也可以被独自使用。
当多于一行被指定时,所有行都必须具有相同数量的元素。 结果表的列数据类型 由出现在该列的表达式的显式或者推导类型组合决定,决定的规则与UNION相同。
在大型的命令中,在语法上允许VALUES出现在SELECT出现的任何地方。因为语法把它当做一个SELECT,可以为一个VALUES命令使用ORDERBY、LIMIT和OFFSET 子句。
参数
- expression
要在结果表(行集合)中指定位置计算并且插入的一个常量或者表达式。在一个出现于INSERT顶层的VALUES列表中, expression可以被DEFAULT替代以表示应该插入目标列的默认值。 当VALUES出现在其他环境中时,不能使用DEFAULT。
- sort_expression
一个指示如何排序结果行的表达式或者整型常量。这个表达式 可以用column1、column2等来引用该VALUES结果的列。更多细节,见SELECT的参数中的“ORDER BY子句”。
- operator
一个排序运算符。更多细节,请见SELECT的参数中的“ORDER BY子句”。
- LIMIT count
OFFSET start要返回的最大行数。更多细节,请见SELECT的参数中的“LIMIT子句”。
注解
应该避免具有大量行的VALUES列表,否则可能会 碰到内存不足失败或者很差的性能。出现在INSERT中的VALUES是一种特殊情况(因为想要的列类型 可以从INSERT的目标表得知,并且不需要通过扫描该VALUES列表来推导),因此它可以处理比其他环境中更大的列表。
示例
一个纯粹的VALUES命令:
VALUES (1, 'one'), (2, 'two'), (3, 'three');
这将返回一个具有两列、三行的表。它实际等效于:
SELECT 1 AS column1, 'one' AS column2
UNION ALL
SELECT 2, 'two'
UNION ALL
SELECT 3, 'three';
更常用地,VALUES可以被用在一个大型SQL命令中。 在INSERT中最常用:
INSERT INTO films (code, title, did, date_prod, kind)
VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
在INSERT环境中,一个VALUES 列表的项可以是DEFAULT指示应该使用该列的默认值而不是指定一个值:
INSERT INTO films VALUES
('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82
minutes'),
('T_601', 'Yojimbo', 106, DEFAULT, 'Drama', DEFAULT);
VALUES也可以被用在可以写子-SELECT 的地方,例如在一个FROM子句中:
SELECT f.* FROM films f, (VALUES('MGM', 'Horror'), ('UA',
'Sci-Fi')) AS t (studio, kind) WHERE f.studio = t.studio AND
f.kind = t.kind;
UPDATE employees SET salary = salary * v.increase FROM
(VALUES(1, 200000, 1.2), (2, 400000, 1.4)) AS v (depno,
target, increase) WHERE employees.depno = v.depno AND
employees.sales >= v.target;
注意当VALUES被用在一个FROM子句中时, 需要提供一个AS句,与SELECT相同。 不需要为所有的列用AS子句指定名称,但是那样做是一种好习惯。在Hashdata数据库中,VALUES的默认列名是column1、column2等,但在其他数据库系统中可能会不同。
当在INSERT中使用VALUES时,值都会被自动地强制为相应目标列的数据类型。当在其他环境中使用时,有必要指定正确的数据类型。如果项都是带引号的字符串常量,强制第一个就足以为所有项假设数据类型:
SELECT * FROM machines WHERE ip_address IN
(VALUES('192.168.0.1'::inet), ('192.168.0.10'),
('192.0.2.43'));
tips: 对于简单的IN测试,最好使用IN的list-of-scalars形式 而不是写一个上面那样的VALUES查询。标量列表方法的书写更少并且常常更加高效。
兼容性
VALUES符合 SQL 标准,但LIMIT 和OFFSET是Hashdata数据库的扩展。
另见
INSERT, SELECT