AgensGraph Developer Manual
Copyright Notice
Copyright © 2016-2022, Bitnine Inc. All Rights Reserved.
Restricted Rights Legend
PostgreSQL is Copyright © 1996-2022 by the PostgreSQL Global Development Group.
Postgres95 is Copyright © 1994-5 by the Regents of the University of California.
AgensGraph is Copyright © 2016-2022 by Bitnine Inc.
Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN ”AS-IS” BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
Trademarks
AgensGraph® is a registered trademark of Bitnine Global Inc. Other
products, titles or services may be registered trademarks of their
respective companies.
Open Source Software Notice
Some modules or files of this product are subject to the terms of
the following licenses. : OpenSSL, RSA Data Security, Inc., Apache
Foundation, Jean-loup Gailly and Mark Adler, Paul Hsieh’s hash.
Information of technical documentation
Title : AgensGraph Developer Manual
Published date : 11 10, 2022
S/W version : AgensGraph v2.13.0
Technical documentation version : v1.0
Introduction
AgensGraph Highlights
AgensGraph, a database built on a graph data model that ensures ACID transactions, is implemented by utilizing main features of PostgreSQL, an open source database.
Key features include:
- Multi-model database
- Supports Graph, Relational, and Document models
- Intuitive and flexible data modeling using Graph and JSON documents
- High-level query features
- Supports ANSI SQL and Cypher query
- Supports ACID transactions
- Possible to create a hybrid query statement that combines SQL and Cypher syntax when creating a query
- Able to create hierarchical graph labels
- High performance query statement processing
- Supports graph indexing for fast graph traversal
- Possible to generate vertex and edge index
- Supports a full-text search for JSON document processing
- Constraints
- Supports Unique, Mandatory, Check constraints
- High Availability
- Possible active-standby configuration
- Visualization tools
- Visualizes the result data of graph queries
- Advanced security features
- Implements an authentication system using Kerberos and LDAP
- Encrypts via SSL/TLS protocols
- Connectivity
- Provides JDBC and Hadoop drivers
Graph Database Concepts
This section introduces the graph data model.
AgensGraph Database
The graph database stores and manages objects of a real model in
graph form.
A relation (edge) exists between objects (vertices), and a group of
similar vertices can be expressed as a group (label).
As vertices and edges have data (properties), they can be called
Property Graph Models as well.
Let’s take a closer look at the components of this graph data
model.
The following example shows components of a graph:
Vertices
Vertices are the most basic elements in the graph data model. They represent entities in the real world and have properties.
A graph has vertices and edges as the base units. In AgensGraph, both vertices and edges may contain Properties. While entities are usually represented by vertices, they may be indicated using edges in some cases. Unlike edges and properties, vertices may have zero or multiple label values.
The simplest form of a graph consists of a single vertex. A vertex
can have zero or more properties.
The next step is to construct a graph with multiple vertices. Add two
or more vertices to the graph of the previous step and add one or more
properties to the existing vertex.
Edges
Edges connect vertices. When two vertices are connected via en edge
and each vertex plays as start vertex or end vertex depending on the
direction of the edge. Like vertices, edges have properties.
The edges between vertices play an important role in the graph database,
especially when you search for linked data.
With edges, you may make vertices into a variety of data structures,
such as lists, trees, maps, and composite entities. By adding edges to
the example we are building, we can represent more meaningful
data.
In the example, ACTED_IN and DIRECTEDare used as edge types. The ACTED_IN property, Roles, stores the value of the array type.
The ACTED_IN edge has Tom Hanks vertex as start vertex and Forrest Gump vertex as end vertex. In other words, we can say that the Tom Hanks vertex has an outgoing edge and the Forrest Gump vertex has an incoming edge.
If there is an edge in a single direction, you do not have to duplicate the edge and add it in the opposite direction; this is related to the graph traversal or performance.
Edges are always directional, but they may ignore directionality if
it is not needed in your application. The diagram below shows a vertex
having an edge pointing to itself.
All edges are recommended to have an edge type to perform the graph
traversal in a more efficient manner.
Properties
Both vertices and edges may have properties. Properties are attribute values, and each attribute name should be defined only as a string type.
The available data types for property values are:
- Numeric type
- String type
- Boolean type
- List type (a collection of various data types)
NULL values cannot be used as property values. If NULL is entered, the property itself is assumed to be absent. NULL values, however, can be used in List.
Type | Description | Value range |
---|---|---|
boolean | true/false | |
byte | 8-bit integer | -128 to 127, inclusive |
short | 16-bit integer | -32768 to 32767, inclusive |
int | 32-bit integer | -2147483648 to 2147483647, inclusive |
long | 64-bit integer | -9223372036854775808 to 9223372036854775807, inclusive |
float | variable-precision, inexact | 15 decimal digits precision |
char | 16-bit unsigned integers representing Unicode characters |
u0000 to uffff (0 to 65535) |
String | sequence of Unicod characters | infinite |
Labels
You may define the roles or types of vertices or edges using labels. Vertices or edges with similar characteristics can be grouped and the name of such a group can be defined, which is called a “label.” That is, all vertices or edges with similar labels belong to the same group.
Database query statements can be performed only on the group (not the entire graph) using labels, which is helpful for more efficient querying.
Using labels for vertices is optional, and each vertex may have zero or only one label.
Labels can also be used to define constraints on properties or to add indexes.
You may also assign a label similar to a vertex to an edge. Unlike vertices, there is no edge without a label; all edges should have at least one label.
Let us add Person and Movie labels to the existing
example graph.
Label names
Label names can be expressed using letters and numbers, all converted to lowercase letters.
Labels stores a unique id of int type, which means that the database may
contain up to 2^16-1(65535) labels.
Traversal
Traversal is to traverse paths while exploring a graph to answer the requested query. Traversal is a process of searching for the relevant vertices from the start vertex to find the answer to the requested query. In other words, it refers to following the vertices that are traversing the graph and the derived edges according to a specific rule.
In the examples illustrated so far, we try to find a movie featured
by Tom Hanks. Starting with the Tom Hanks vertex, you
can traverse all the processes that end at the vertex of Forrest Gump
along the ACTED_IN edge associated with it.
By using the traversal of cypher query statements and additional techniques in the graph database, you may derive better result data. For more information, see Cypher Query Language.
Paths
Paths are the result data of a query statement or traversal, which shows one or more vertices and the edges connected to them.
The path (traversal result data) from the previous example is as
follows:
The length of the above path is 1. The shortest path length is 0,
which is the case when a single vertex does not have edges.
If the vertex has an edge pointing to itself, the length of the path
is 1.
Get Started
Install AgensGraph
Pre-Installation on Linux
Get the pre-compiled binary
AgensGraph works on Linux/Windows and can be installed in two ways. One is to download its binary package, and the other is to download its source code and compile the package. The binary package can be downloaded from Bitnines’s website, and the source code can be downloaded from Github. If you want to know your system environment, enter the following command in the command window.
uname -sm
Extract the package
Unzip the downloaded file in the desired location. (e.g.: /usr/local/AgensGraph/)
tar xvf /path/to/your/use
Post-Installation Setup and Configuration
Setting environment variables (Optional)
Add the following three lines to your shell startup file (e.g. .bash_profile).
export LD_LIBRARY_PATH=/usr/local/AgensGraph/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/AgensGraph/bin:$PATH
export AGDATA=/path/to/make/db_cluster
Creating a database cluster
Create a database cluster using the following command: If you do not
specify the -D
option, use the AGDATA
specified in .bash_profile
.
initdb [-D /path/to/make/db_cluster]
Starting the server
You can start AgensGraph with the following command.
ag_ctl start [-D /path/created/by/initdb]
Creating a database
createdb [dbname]
If you do not specify the database name and user name, the default value will apply. The default is the name of the current user.
Running a terminal
agens [dbname]
When you run a terminal like above, you can see the following screen:
username=#
If it is a superuser, “= #” will be displayed at the prompt; “=>” will be displayed for other users.
username=# CREATE
username-# (
username(# (
username(# )
username(# )
username-#
In case you are in the middle of entering a query, -
is
displayed. If you are typing content to be included in parentheses,
(
is displayed. Even multi-parentheses can be expressed as
needed. You may customize the input prompt, and the detailed options can
be found in the following link.
Setting server parameters
AgensGraph enables you to configure the server to improve
performance. Setting the server parameters in consideration of the size
of data and resources of the server (memory, CPU, disk size, and speed)
is critical for the improvement of performance. The following server
variables have a significant effect on AgensGraph’s graph query
performance. You may change server parameters by changing
$AGDATA/postgresql.conf
. If you modify
$AGDATA/postgresql.conf, you need to restart the server.
shared_buffers
: Memory size for data object caching. This variable must conform to the product environment. It is optimal when this variable is as large as the size of the data. shared_buffers should be set carefully considering the amount of memory allocated for concurrent sessions and each query. The recommended value is half the physical memory.work_mem
: Increases in size depending on the physical memory and the attributes of the query being executed.random_page_cost: A parameter for query optimization. This parameter should be lowered to 1 or 0.005 for graph queries (when the graph data is completely cached in memory)
Get started with Cypher
This section introduces Cypher and the following:
- Basic understanding of graphs and patterns
- Simple troubleshooting
- Cypher syntax writing
About Cypher
AgensGraph supports Cypher, a query language, for retrieving and processing graph data. Cypher is a declarative language similar to SQL.
Pattern
AgensGraph’s graph consists of vertices and edges. Vertices and edges can have many properties. The actual data consists of simple graphs in patterns. AgensGraph searches and processes the patterns of graphs through cypher.
Creating Graphs
AgensGraph may store multiple graphs in a single database. Cypher cannot figure out multiple graphs. AgensGraph supports variables for generating and managing graphs using DDL and Cypher. The following syntax generates a graph called the network and sets the current graph.
CREATE GRAPH network;
SET graph_path = network;
In this example, the graph_path
variable is set to
network. However, if graph_path
is not set before creating
a graph, it will be set automatically after a graph is generated.
Creating Users
CREATE ROLE user1 LOGIN IN ROLE graph_owner;
DROP ROLE user1;
You can create new users to manage ownership and other privileges on database objects. If a new user wants to generate a label in the graph, the new user must be in the same group as the user who created the graph. See this link for more options regarding creating users.
Creating Labels
You should generate a label before generating graph data in
principle. However, for your convenience, a label will be automatically
created if it is specified when Cypher’s CREATE is executed. In
AgensGraph, you should have one label for a vertex and an edge. The
following example creates a vertex label named person
and
an edge label knows
.
CREATE VLABEL person;
CREATE ELABEL knows;
CREATE (n:movie {title:'Matrix'});
Creating Vertices and Edges
This section uses CREATE
of Cypher to create the
person
vertex and knows
edge. The CREATE
clause creates a pattern consisting of
vertices and edges. (variable:label {property: value, ...})
is a vertex type, and
-[variable:label {property: value, ...}]-
is an edge type.
The direction of the edge can be represented by <
or
>
. Variables may or may not exist in the forms of
vertices and edges.
Note : AgensGraph does not support
--
edge patterns.--
means a comment at the end of a sentence.
In the following example, patterns such as “Tom knows Summer,” “Pat knows Nikki” and “Olive knows Todd” are created.
CREATE (:person {name: 'Tom'})-[:knows]->(:person {name: 'Summer'});
CREATE (:person {name: 'Pat'})-[:knows]->(:person {name: 'Nikki'});
CREATE (:person {name: 'Olive'})-[:knows]->(:person {name: 'Todd'});
AgensGraph uses the jsonb type for vertex/edge attributes. Attributes are expressed using JSON objects.
Cypher Query Language
Introduction
Cypher is
A graph query language for querying graph data. The main features are as follows:
Declarative
Cypher is a declarative language that describes what it is, rather than how it should be done. In contrast to imperative languages that specific algorithms to be executed, such as C and Java, Cypher specifies goals. This type of processing relieves the user of the detailed implementation of the query. This type of processing relieves the burden of detailed implementation in user queries.
Pattern Matching
Cypher is a language that illustrates the graph data that you are looking for. The graph pattern to be searched is expressed by using parentheses and dashes as ASCII Art, and the graph data matching the pattern is found. You can create queries in an intuitive manner because it allows you to draw the form you want to search.Expressive
Cypher borrowed various processing methods for expressive queries. Most keywords such as WHERE and ORDER BY are borrowed from SQL, pattern matching from SPARQL, and the collection concept from languages such as Haskell and Python. This makes it possible for you to express queries in an easy and simple manner.
Elements of Cypher
The basic elements of Cypher include vertex, edge, vlabel, elabel, property, and variable.
Vertex
The most basic element that constructs a graph, representing an entity. Even if vertices are mostly used to represent entities, their uses can vary depending on the purposes.Edge
Represents the relationship between vertices and cannot exist as an edge alone.Vlabel
A specific name given by the user to be a criterion for classifying vertices.Elabel
The name of the edge. Represents the relationship between vertices.Property
An attribute that can be assigned individually to a vertex or edge.Variable
An identifier that is assigned arbitrarily to a vertex or an edge.
Handling Graph
Before describing Cypher in detail, let’s look at how to use it. We will show you how to create a graph, query the graph, and modify the graph.
Creating Graph
AgensGraph is capable of storing multiple graphs within a single database. Thus, you should first create/select graphs to use to enable graph query using Cypher.
Create Graph
CREATE GRAPH graphName; SET graph_path = graphName;
CREATE GRAPH
is a command to create a graph. The command is used along with the name of the graph to be generated (Spaces are allowed in graphName from v1.3).
graph_path
is a variable to handle the current graph. Set the name of the graph you want to handle usingSET
.Drop Graph
DROP GRAPH graphname CASCADE;
DROP GRAPH
is a command to delete a graph from a graph database. To be noticed, a graph automatically contains vertex and edge labels when it is created, so to delete a graph you first must delete labels that are bound to that graph. To delete a graph and its’ labels altogether, useDROP GRAPH
graphname CASCADE.Create Labels
CREATE VLABEL vlabelName; CREATE ELABEL elabelName; CREATE VLABEL childVlabelName inherits (parentVlabelName); CREATE ELABEL childElabelName inherits (parentElabelName1, parentElabelName2);
CREATE VLABEL
creates vlabel, andCREATE ELABEL
creates elabel. Each command is used along with the name of vlabel or elabel to generate.
inherits()
is a command that inherits another label. When you create a label, you can inherit other labels by specifying the names of the parent labels along with the corresponding keyword after the child label name. There can be multiple parent labels for inheritance.Drop Labels
DROP VLABEL vlabelName; DROP ELABEL elabelName; DROP ELABEL elabelName CASCADE;
DROP VLABEL
deletes vlabel andDROP ELABEL
deletes elabel. Each command should be used with the names of vlabel and elabel you wish to erase. A vlabel that is inherited by other vlabels cannot be deleted directly, so you must use CASCADE command to delete all dependant data.Create vertices and edges
CREATE (:person {name: 'Jack'}); CREATE (:person {name: 'Emily'})-[:knows]->(:person {name: 'Tom'});
The
CREATE
clause is used to create vertices and edges. When using this command, make sure to write vertices or edges to generate correctly using the pattern. (The pattern that represents various clauses and vertices/edges along with the CREATE clause will be described in detail later on).
Querying Graph
Querying a graph is the process of getting the information you need from the graph(s) by describing some specific graph pattern and finding it in that graph.
:person {name: 'Jack'})-[:likes]->(v:person)
MATCH (RETURN v.name;
name-------
Emily1 row) (
The MATCH
clause finds graph data that matches the
pattern in the clause. In the RETURN
clause, specify only
the elements that you want to return from the graph you find.
Manipulating Graph
In order to modify the existing graph data, the pattern of the MATCH clause should be displayed; after finding the matched graph, modifications can be made.
:person {name: 'Jack'})
MATCH (vSET v.age = '24';
You can use the SET
clause to set property values of
vertices and edges.
Data Type
This section describes the graph data types such as graphid, graphpath, vertex, and edge. Each data type is specified below.
Name | Size | Description |
---|---|---|
graphid | 8 | unique ID of vertex/edge |
graphpath | tuple | Array of consecutive vertices and edges |
vertex | tuple | A tuple that combines id and properties |
edge | tuple | A tuple that combines start vertex id, end vertex id, edge id and properties |
graphid
A unique ID is assigned to the newly-created label of vertex/edge. Graphid is generated based on the labid of ag_label and the sequence values of vertex and edge.
graphpath
An array type of continuous vertices and edges.
Column | Type | Description |
---|---|---|
vertices | vertex[] | |
edges | edge[] |
vertex
vA vertex has a vertex id and properties
Column | Type | Description |
---|---|---|
id | graphid | vertex id |
properties | jsonb | vertex property |
edge
An edge connects vertices and has edge id, start vertex id, end vertex id, and properties.
Columnid |
Typegraphid |
Descriptionedge id |
|
start | graphid | start vertex id | ||
end | graphid | end vertex id | ||
properties | jsonb | edge property |
Syntax
Pattern
A pattern is an expression that represents a graph. As a pattern is represented by a combination of one or more vertices or edges, how you create vertices and edges as a pattern is critical.
Vertex
Vertex is expressed using parentheses and can be specified with vlabel, property, and variable to further refine the vertex to be searched.
( )
Vertex is represented by ( )
. A pattern
that does not have vlabel or property in parentheses, as in the example
above, means all vertices.
:person) (
To represent vlabel in a vertex, use
(:vlabelName)
. The name of vlabel is
indicated with a colon in parentheses indicating the vertex. The above
example represents a vertex with vlabel named “person.”
(v)
(var)
(var_1):person) (v
If you want to assign a variable to the vertex, use
(variableName)
. A variable can be named a
combination of alphanumeric (a~z, 0~9) and underbars (note that it
should not start with a number). When you want to display the variable
and vlabel at the same time in vertex, use
(variableName: vlabelName)
.
'Jack'})
({name: :person {name: 'Jack'})
(v:person {name: 'Jack', age: 24}) (v
You can further refine the properties by listing them in the vertex.
If you want to represent a property, use
({propertyName:propertyValue})
. If the
value is a string, the value must be wrapped with ‘ ’.
If you want to represent multiple properties,
,
should be used.
Edge
An edge is expressed with two dashes and can be marked along with elabel, property, and variable.
-[]-
-[]->
<-[]-
An edge is expressed using -[]-
. You
can express direction with < >
. In
the above example, -[ ]- expressed as dashes only means
“all edges” since no constraint is indicated. -[ ]-> <-[
]- with additional angle brackets means “all edges with one
directionality.”
-[:knows]->
If you want to express other elements in the edge, specify them in
[ ]
. If you want to represent elabel on
the edge, use -[:elabelName]->
. The
above example means an edge with elabel named “knows.”
-[e]->
-[e:likes]->
If you want to assign a variable to an edge, use
-[variableName]->
. When you want to
display variable and elabel simultaneously on the edge, use
-[variableName:elabelName]->
.
-[{why: 'She is lovely'}]->
-[:likes {why: 'She is lovely'}]->
-[e:likes {why: 'She is lovely'}]->
If you want to represent a property on the edge use
-[{propertyName:propertyValue}]->
. If
the value is a string, use ‘ ’ . If you want to
represent multiple properties, ,
should be
used.
Vertices and Edges
Patterns can be used to express vertices, edges, or a combination of them.
-[]->()
():person {name: 'Jack'})-[k:knows]->(emily:person {name: 'Emily'})
(jack= (:person)-[:knows]->(:person) p
The basic frame of a pattern consisting of a combination of vertices
and edges is ( )-[]->( )
. It is good to
give meaning to the pattern by specifying properties and labels on
vertices and edges. Variables can be assigned to individual vertices and
edges, or the entire pattern. If you want to assign a variable to the
entire pattern, use =
. In the above
example, p is a variable and is applied to the entire
pattern by using =
.
Path
The number of vertices and edges in a pattern may continue to increase. The unit for a series of path in a pattern is called a path.
-[]->( )-[]->(c)
(a)-[*2]->(c)
(a)
-[]->( )-[]->( )-[]->(d)
(a)-[*3]->(d)
(a)
-[]->( )-[]->( )-[]->( )-[]->(e)
(a)-[*4]->(e) (a)
In the case of a long path, it can be written in abbreviated form for better readability and ease of writing. If n vertices go through an edge n-1 times, you can put an asterisk (*) and n-1 in brackets (see example above).
Flexible Length
Depending on the situation, you may need to dynamically change the number of edges that must be gone through in a query.
-[*2..]->(b)
(a)-[*..7]->(b)
(a)-[*3..5]->(b)
(a)-[*]->(b) (a)
If you want to give a dynamic change to the length of the path,
..
can be used. The example above shows a
path with two or more edges, a path with seven or fewer paths, a path
with three or more and five or fewer paths, and an infinite path (in
sequence from top to bottom).
Clauses
Read Clauses
MATCH
The MATCH clause is a clause that describes the graph pattern you want to find in the database. This is the most basic way to import data. For more information on the Pattern specification, see the Pattern section above.
Mathing
'Jack'}) MATCH (j {name: RETURN j; 'Jack'})-[l:knows]->(e) MATCH (j {name: RETURN l; 'Jack'}) MATCH (j {name: RETURN j.age; =(j {name: 'Jack'})-[l:knows]->(e) MATCH pRETURN p;
The graph pattern to be searched is described in the MATCH clause and then returned using the RETURN clause.
Various Notation
:person {name: 'Jack'})-[:knows]->(v:person) MATCH (j:person {name: 'Emily'})-[:knows]->(v) MATCH (eRETURN v.name; :person {name: 'Jack'})-[:knows]->(v:person), MATCH (j:person {name: 'Emily'})-[:knows]->(v) (eRETURN v.name; :person {name: 'Jack'})-[:knows]->(v:person)<-[:knows]-(e:person {name: 'Emily'}) MATCH (jRETURN v.name;
The above three queries output the names of common acquaintances of Jack and Emily. They all output the same result, but the number of MATCH clauses and the pattern notations in the MATCH clause is different. The first query used the MATCH clause twice, while the second query expressed two patterns using a comma in one MATCH clause; the third query used one pattern in one MATCH clause. Likewise, you can use the MATCH clause in a variety of ways to derive the same result.
When you generate, query, delete, add, or modify graph data, you will need to find a graph that matches a certain pattern first in most cases. Thus, the MATCH clause is a very basic and important clause.
[Reference]
When a large volume of data across multiple pages are printed in Agens, you may see help on scrolling by using the
?
keyword.by integer argument k. Defaults in brackets. Most commands optionally preceded *) indicates argument becomes new default. Star (------------------------------------------------------------------------------- <space> Display next k lines of text [current screen size] next k lines of text [current screen size]* z Display <return> Display next k lines of text [1]* or ctrl-D Scroll k lines [current scroll size, initially 11]* d or Q or <interrupt> Exit from more q Skip forward k lines of text [1] s Skip forward k screenfuls of text [1] f or ctrl-B Skip backwards k screenfuls of text [1] b ' Go to place where previous search started = Display current line number /<regular expression> Search for 'k'th occurrence of regular expression [1] n Search for 'k'th occurrence of last r.e [1] !<cmd> or :!<cmd> Execute <cmd> in a subshell v Start up /usr/bin/vi at current line ctrl-L Redraw screen :n Go to kth next file [1] :p Go to kth previous file [1] :f Display current file name and line number . Repeat previous command ---------------------------------------------------------------------------
Shortest Path
Single Shortest Path
Finding a single shortest path between two vertices usingshortestpath
function.= shortestpath( (j:person {name: 'Jack'})-[l:knows*..15]-(a:person {name: 'Alice'}) ) MATCH p RETURN p;
Find single shortest path between two vertices,
Alice
andJack
, between which 15 edges exist. Feed a graph path consists of the start vertex, the end vertex, and the edges between them (single link path) into the function as its argument. Edge type, max hops and directions are all used in finding the shortest path.All Shortest Paths
Find all the shortest paths between two vertices.= allshortestpaths( (j:person {name: 'Jack'})-[l:knows*]-(a:person {name: 'Alice'}) ) MATCH p RETURN p;
Find all the shortest paths between two vertices.
Alice
andJack
.
OPTIONAL MATCH
The OPTIONAL MATCH clause, like the MATCH clause, is a clause describing the graph pattern to be searched. The OPTIONAL MATCH clause differs from the MATCH clause in that it returns NULL if there are no results to return.
Optional Matching
:person {name:'Emily'}) OPTIONAL MATCH (eRETURN e.hobby;
The use of the OPTIONAL MATCH clause is the same as the MATCH clause. Put the pattern you want to find in the OPTIONAL MATCH clause and return the result through the RETURN clause. The returned result may contain NULL.
MATCH ONLY
The Only keyword allows you to use the MATCH query to return results that exclude child labels.
Match only
:person ONLY) RETURN n; MATCH (n-[r:knows ONLY]->() RETURN r; MATCH ()
Projecting Clauses
RETURN
The RETURN clause is a clause that specifies the result of a cypher query. It returns data that matches the graph pattern you are looking for and can return vertices, edges, properties, and so on.
Vertex Return
'Jack'}) MATCH (j {name: RETURN j;
If you want to return a vertex, specify the vertex you want to find in the MATCH clause and assign a variable to it. You can then return a vertex by specifying the corresponding variable in the RETURN clause.
Edge Return
'Jack'})-[k:knows]->(e) MATCH (j {name: RETURN k;
If you want to return an edge, specify the edge you want to find in the MATCH clause and assign a variable to it. You can then return an edge by specifying the corresponding variable in the RETURN clause.
Property Return
'Jack'}) MATCH (j {name: RETURN j.age;
If you want to return a property of a vertex or edge, specify the vertex or edge you want to find in the MATCH clause and assign a variable to it. In the RETURN clause, you can return the property by specifying
.
with the variable and property.All Return
'Jack'})-[k:knows]->(e) MATCH (j {name: RETURN *;
If you want to return all the elements in the MATCH clause, specify
*
in the RETURN clause. The elements returned are the elements to which variables are assigned. Elements with no variable assigned will not be returned.Path Return
=(j {name: 'Jack'})-[k:knows]->(e) MATCH pRETURN p;
If you want to return a path that matches the pattern shown in the MATCH clause, you should apply a variable to the entire pattern. If the pattern is preceded by a variable and
=
, the variable can be applied to the entire pattern. You can then return the path by specifying the variable in the RETURN clause.Alias Return
'Jack'}) MATCH (j {name: RETURN j.age AS HisAge; 'Jack'}) MATCH (j {name: RETURN j.age AS "HisAge";
You can output an alias to the column of the returned result. The returned element is followed by alias with the
AS
keyword. If you list the alias without double quotation marks, the output will be in lower case; with double quotation marks, the output will be printed as it is.Function Return
'Jack'})-[k:knows]->(e) MATCH (j {name: RETURN id(k), properties(k); =(j {name: 'Jack'})-[k:knows]->(e) MATCH pRETURN length(p), nodes(p), edges(p); MATCH (a)RETURN count(a);
It provides a function to obtain only id and properties for vertices and edges, and a function to get the length and each element separately of the path. You may also use the aggregation function supported by PostgreSQL.
Constant Return
RETURN 3 + 4, 'Hello ' + 'AgensGraph'; RETURN 3 + 4 AS lucky, 'Hello ' + 'AgensGraph' AS greeting
Constant values and their operators can be expressed. All of the expressions useable in the SQL SELECT statement can be used with the RETURN clause, except for table and column expressions. For more information, see PostgreSQL Expression.
Unique Return
'Jack' })-[k:knows]->(e) MATCH (j { name: RETURN DISTINCT e;
Removes the duplicate records of the returned result and outputs only the unique result. You can add DISTINCT before the returned element.
WITH
The WITH clause is a clause that connects multiple cypher queries. It passes the result of the preceding WITH clause query to the following WITH clause query. That is, the WITH clause can be regarded as a RETURN clause that passes the value of the preceding query to the input of the following query.
WITH
:person {name:'Jack'})-[:knows]->(common:person)<-[:knows]-(other:person) MATCH (jRETURN other, count(common); WHERE count(common) > 1 RETURN other; :person {name:'Jack'})-[:knows]->(common:person)<-[:knows]-(other:person) MATCH (jWITH other, count(common) AS cnt WHERE to_jsonb(cnt) > 1 RETURN other;
The WITH clause is described as an example of the above three queries. The first query returns the number of acquaintances that Jack and ‘someone’ know in common with the ‘someone’. If we think the second query is in line with the first query, we can figure out that it is a query that returns ‘someone’ when the number of common acquaintances is greater than one (1). The second query cannot be executed alone; it is only meaningful when combined with the first query. The WITH clause plays the role of connecting the two queries.
The third query is a query that includes a WITH clause that links the first and second queries. It holds the returned results of the first query in variable and alias forms, and then passes the results to the second query. In the case where you want to connect multiple queries, as in this case, and the output of the preceding query is used as the input of the trailing query, you can concatenate them with the WITH clause. The WITH clause must be held in variable or alias form.
Partitioning
:person {name:'Jack'})-[:knows]->(common:person)<-[:knows]-(other:person) MATCH (jRETURN other, count(common) ORDER BY other.name LIMIT 10; WHERE count(common) > 1 RETURN other; :person {name:'Jack'})-[:knows]->(common:person)<-[:knows]-(other:person) MATCH (jWITH other, count(common) AS cnt ORDER BY other.name LIMIT 10 WHERE to_jsonb(cnt) > 1 RETURN other;
It is important to partition the entire query when using the WITH clause. Think of the WITH clause as a RETURN clause, and consider ORDER BY, LIMIT as a partition after RETURN. Therefore, if there is an ORDER BY, LIMIT clause in the preceding query, the clause must be written after the WITH clause, and then the following query is created.
Reading sub-Clauses
WHERE
The WHERE clause is a clause that adds constraints to the MATCH or OPTIONAL MATCH clause or filters the results of the WITH clause. The WHERE clause cannot be used alone; it is dependent on the MATCH, OPTIONAL MATCH, START, and WITH clauses when used.
Basic Usage
Boolean operations
MATCH (v)WHERE v.name = 'Jack' AND v.age < '30' OR NOT (v.name= 'Emily' OR v.name ='Tom') RETURN v.name, v.age;
You can use the boolean operators
AND
,OR
.Filter on vertex label
MATCH (v)WHERE label(v) = 'person' RETURN v.name;
To filter nodes by label, write a label predicate after the WHERE keyword using
WHERE label(n) = 'foo'
.Filter on vertex property
MATCH (v)WHERE v.age < '30' RETURN v.name, v.age;
To filter on a vertex property.
Filter on edge property
-[l:likes]->(p) MATCH (v)WHERE l.why = 'She is lovely' RETURN p;
To filter on aedge property.
String matching
STARTS WITH and ENDS WITH can be used to search for a character having a certain prefix and suffix in a string. You can use CONTAINS when retrieving a matching string regardless of its position. It is case-sensitive and returns null if a non-string value is queried.
Prefix string search using
STARTS WITH
MATCH (v)WHERE v.name STARTS WITH 'Em' RETURN v.name, v.age;
STARTS WITH is used to perform a case-sensitive matching at the beginning of a string.
Suffix string search using
ENDS WITH
MATCH (v)WHERE v.name ENDS WITH 'ly' RETURN v.name, v.age;
ENDS WITH is used to perform a case-sensitive matching at the end of a string.
Substring search using
CONTAINS
MATCH (n)WHERE n.name CONTAINS 'il' RETURN n.name, n.age;
CONTAINS is used for case-sensitive matching regardless of the position in the string.
ORDER BY
The ORDER BY clause is a clause that sorts result values. It is used with the RETURN clause or WITH clause and determines whether to sort in ascending or descending order by column.
Order by Property
:person) MATCH (aRETURN a.name AS NAME ORDER BY NAME; :person) MATCH (aRETURN a.name AS NAME, a.age AS AGE ORDER BY NAME, AGE; :person) MATCH (aRETURN a ORDER BY a.name;
The ORDER BY clause basically sorts by properties of vertices and edges. You may specify the aliases of the properties that will be the basis of sorting in the ORDER BY clause. That is, in the RETURN clause, an alias is given to a property to be sorted, and then the alias is specified in the ORDER BY clause. If multiple sorting criteria are specified in the ORDER BY clause, sorting is done first based on the first criterion and then the second sorting is performed only for duplicated values after the first sorting.
However, if a property is not specified in the RETURN clause, you can directly specify the property other than the corresponding alias in the ORDER BY clause.Descending Order
:person) MATCH (aRETURN a.name AS NAME ORDER BY NAME DESC; :person) MATCH (aRETURN a.name AS NAME, a.age AS AGE ORDER BY NAME DESC, AGE;
The ORDER BY clause basically sorts in ascending order. If you want to sort in descending order, you can write the
DESC
keyword. If multiple criteria are specified in the ORDER BY clause,DESC
must be followed by the elements to be sorted in descending order.
SKIP
The SKIP clause is a clause that changes the search start location.
Skip
MATCH (a)RETURN a.name SKIP 3;
When searching for a pattern in the MATCH clause, skip the number of patterns specified in the SKIP clause and start the search.
LIMIT
The LIMIT clause is a clause that limits the number of results in a result set.
Limit Result Set
MATCH (a)RETURN a.name LIMIT 10;
If you want to limit the number of results you want to output, you can specify the number in the LIMIT clause. If the number of results in the result set is smaller than or equal to the number specified in the LIMIT clause, all results will be output; if bigger, only the number of results specified in the LIMIT clause will be output.
Writing Clauses
CREATE
The CREATE clause is a clause that creates graph elements such as vertices and edges.
Create Vertex
CREATE ( ); CREATE (:person); CREATE (:person {name: 'Edward'}); CREATE (:person {name: 'Alice', age: 20}); CREATE (a {name:'Alice'}), (b {name:a.name});
When you want to create a vertex, you need to write a vertex-related pattern in the CREATE clause. When creating a vertex, you can create it by referring to the vertex specified earlier as in the last example.
Create Edge
:person {name: 'Edward'}), (A:person {name: 'Alice'}) MATCH (ECREATE (E)-[:likes]->(A); :person {name: 'Edward'}), (A:person {name: 'Alice'}) MATCH (ECREATE (E)-[:likes {why: 'She is lovely'}]->(A); :person {name: 'Edward'}) MATCH (ECREATE (E)-[:IS_PROUD_OF]->(E);
An edge is a link between two vertices. Therefore, we need to create an edge after finding two vertices through the MATCH clause. Note that two vertices do not necessarily mean different vertices. Like the third query above, self-edge is also possible.
Create Path
CREATE (E:person {name: 'Edward'})-[:likes]->(A:person {name: 'Alice'}); :person {name: 'Edward'}) MATCH (ECREATE (E)-[:likes]->(A:person {name: 'Alice'}); :person {name: 'Edward'}), (A:person {name: 'Alice'}) MATCH (ECREATE (E)-[:likes]->(A);
You may create each element separately, but you may also create a pattern you want at a time by listing the path in the CREATE clause. Be careful when creating a path at once. If it is not used with the MATCH clause like the first query, it creates new data even if there is the same data as the corresponding pattern (i.e. duplicate data). If you use it with a MATCH clause like the second query, it finds the Edward vertex and then creates the likes edge on the vertex and Alice vertex. If you want to create only the likes edges in existing Edward and Alice vertices, you can use it as the third query.
DELETE
The DELETE clause is a clause that removes vertices or edges.
Delete vertex
:person {name: 'Michael'}) MATCH (mDELETE m;
Find the vertices you want to remove through the MATCH clause and remove them by marking corresponding variables in the DELETE clause. However, if the vertices you want to remove are connected to other vertices and edges, remove the edges first before removing the vertices.
Delete edge
:person {name: 'Michael'})-[l:likes]->(b:person {name: 'Bella'}) MATCH (mDELETE l;
Find the edges you want to remove with the MATCH clause and remove them by marking corresponding variables in the DELETE clause.
DETACH DELETE
Delete a vertex with all its relationships
:person {name: 'Michael'}) MATCH (mDELETE m; DETACH
If the DETACH keyword is used together, the edges associated with the vertices are also removed. If the vertices you want to remove are linked to other vertices and edges, you may skip the edge-removing process.
SET
The SET clause is a clause that adds, sets, or removes properties, or adds vlabels.
Add Property
:person {name: 'Edward'}) MATCH (ESET E.habit = 'play the guitar';
Find the vertices or edges to which you want to add properties through the MATCH clause, and specify the names and values of the properties to add to the SET clause. When describing a property, mark it with single or double quotation marks.
Modify Property
:person {name: 'Edward'}) MATCH (ESET E.name = 'Edward Williams';
Find the vertices or edges whose properties you want to change through the MATCH clause, and specify the names of the properties to be changed in the SET clause. When describing a property, mark it with single or double quotation marks.
Remove Property
:person {name: 'Edward'}) MATCH (ESET E.hobby = NULL;
Find the vertices or edges from which you want to remove the properties through the MATCH clause, and mark the names of the properties to be removed and NULL in the SET clause.
Copy properties between nodes and relationships
at {name:'Edward'}), (pn {name: 'Peter'}) MATCH (SET at = pn RETURN at.name, at.age, pn.name, pn.age;
SET can be used to copy all properties from one vertex/edge to another vertex/edge. All properties of “pn” are copied to the properties of “at”, and all existing properties of “at” are removed.
Replace all properties using a map and
=
'Edward' }) MATCH (p { name: SET p = { name: 'Edward William', position: 'Enterpreneur' } RETURN p.name, p.age, p.position;
Use the
=
operator to replace the existing properties of the vertex/edge with the properties provided by the map.Remove all properties using an empty map and
=
'Edward' }) MATCH (p { name: SET p = { } RETURN p.name, p.age, p.position;
Use the
=
operator to remove all existing properties of the vertex/edge.Mutate specific properties using a map and
+=
'Edward' }) MATCH (p { name: SET p += { age: 38, hungry: TRUE, position: 'Enterpreneur' } RETURN p.name, p.age, p.hungry, p.position;;
Use the
+=
operator to change existing properties of the vertex/edge or add new ones. The properties of the vertex and edge are not removed if the map is empty as shown below.'Edward' }) MATCH (p { name: SET p += { } RETURN p.name, p.age, p.hungry, p.position;
Set multiple properties using one SET clause
'Peter' }) MATCH (n { name: SET n.position = 'Developer', n.surname = 'Taylor';
Sets multiple properties at once by separating them with commas (
,
).
REMOVE
The REMOVE clause is a clause that removes properties.
Remove property
:person {name: 'Edward'}) MATCH (ESET E.habit = NULL; :person {name: 'Edward'}) MATCH (E REMOVE E.habit;
How to remove a property using the SET clause has already been described in SET. You can also remove a property using the REMOVE clause.
Locate the element from which you want to remove the property through the MATCH clause, and name the property to be removed in the REMOVE clause.
Reading/Writing Clauses
MERGE
The MERGE clause is a clause that i) adds a corresponding pattern (like the CREATE clause) if the specified pattern does not exist in the graph, and ii) verifies the existence of the pattern (like the Match clause) if it already exists in the graph. The MERGE clause recognizes the entire pattern specified in the clause.
Merge
MERGE (:person {name: 'Edward'}); :person {name: 'Edward'}) RETURN p; MATCH (p CREATE (:person {name: 'Edward'});
If you specify a pattern in the MERGE clause and execute it, you can see whether the pattern exists or not in the graph. If it is already in the graph, it functions like the MATCH clause; if it is not in the graph, it newly creates the pattern like the CREATE clause.
Merge Path
MERGE (E:person {name: 'Edward'})-[L:likes]->(A:person {name: 'Alice'}) RETURN E, L, A; MERGE (E:person {name: 'Edward'}) MERGE (A:person {name: 'Alice'}) MERGE (E)-[L:likes]->(A) RETURN E, L, A;
The MERGE clause recognizes the entire pattern. Even if the specified pattern partially exists in the graph, it does not create only the rest of it that does not exist. We will explain this with the above query as an example. The first query does not create an edge if the Edward and Alice vertices already exist in the graph and are not linked to the likes edge. New Edward and Alice vertices are created and an edge is created between the two vertices.
If you are not sure whether some elements of the pattern already exist in the graph, you had better divide each element as in the second query and use the MERGE clause.ON CREATE SET and ON MATCH SET
MERGE (E:person {name: 'Edward'}) ON CREATE SET E.lastMERGEOP = 'CREATE' ON MATCH SET E.lastMERGEOP = 'MATCH' RETURN E.lastMERGEOP;
ON CREATE SET and ON MATCH SET clauses can be used to set properties depending on how the MERGE clause behaves. If the MERGE clause behaves like a CREATE clause, the ON CREATE SET clause will be performed; if the MERGE clause behaves like a MATCH clause, the ON MATCH SET clause will be performed.
Set operations
UNION and UNION ALL
The UNION clause combines the results of several queries into one.
UNION and UNION ALL
:person) MATCH (aWHERE 20 < a.age RETURN a.name AS name UNION :person) MATCH (bWHERE b.age < 50 RETURN b.name AS name; :person) MATCH (aWHERE 20 < a.age RETURN a.name AS name UNION ALL :person) MATCH (bWHERE b.age < 50 RETURN b.name AS name;
If you put the
UNION
keyword between the two queries, you can combine the two results together. In the case of duplicate values,UNION
outputs it only once. When you use both theUNION
andALL
keywords, the duplicate values (when the two results are combined) will be output as they are.
LOAD Clauses
LOAD FROM
You can load data by table using the LOAD FROM clause.
create vertex
FROM person AS v LOAD CREATE (:person {id: v.id, name: v.name});
create edge
FROM friend AS e LOAD :person),(b:person) MATCH (aWHERE id(a) = to_jsonb(e.start_id) AND id(b) = to_jsonb(e.end_id) CREATE (a)-[:friend {date: '2018'}]->(b);
Schema Clauses
CREATE and DROP CONSTRAINT
Provides the ability to control data by setting constraints on properties.
CREATE and DROP CONSTRAINT
CREATE CONSTRAINT [constraint_name] ON label_name ASSERT field_expr IS UNIQUE CREATE CONSTRAINT [constraint_name] ON label_name ASSERT check_expr DROP CONSTRAINT constraint_name ON label_name CREATE CONSTRAINT ON person ASSERT id IS UNIQUE; CREATE CONSTRAINT ON person ASSERT name IS NOT NULL; CREATE CONSTRAINT ON person ASSERT age > 0 AND age < 128;
If the constraint name is omitted, it is generated automatically.
UNIQUE restricts the value of a field to be unique in that label.
check_expr returns a true or false value of the properties that are newly entered or modified. If the result is false, the corresponding input/change will fail.
You may use\dGv
,\dGe
commands to check the constraints when querying information on the vertices and edges.CREATE VLABEL people; CREATE CONSTRAINT ON people ASSERT age > 0 AND age < 99; MERGE (s:people {name: 'David', age: 45}); :people) return s; MATCH (s s------------------------------------------ 24.1]{"age": 45, "name": "David"} people[1 row) ( MERGE (s:people {name: 'Daniel', age: 100}); new row for relation "people" violates check constraint "people_properties_check" ERROR: row contains (24.2, {"age": 100, "name": "Daniel"}). DETAIL: Failing MERGE (s:people {name: 'Emma', age: -1}); new row for relation "people" violates check constraint "people_properties_check" ERROR: row contains (24.3, {"age": -1, "name": "Emma"}). DETAIL: Failing :people) return s; MATCH (s s------------------------------------------ 24.1]{"age": 45, "name": "David"} people[1 row) (
functions
Aggregation functions
Create the data to be used in the example.
CREATE (:person {name: 'Elsa', age: 20});
CREATE (:person {name: 'Jason', age: 30});
CREATE (:person {name: 'James', age: 40});
CREATE (:person {name: 'Daniel', age: 50});
avg()
Returns the average of numeric values.:person) MATCH (vRETURN avg(v.age);
collect()
Returns a list containing the values returned by the expression; aggregates data by merging multiple records or values into a single list.:Person) MATCH (vRETURN collect(v.age);
count()
Prints the number of result rows; able to print the number or properties of vertices and edges and can be given an alias.:person) MATCH (vRETURN count(v); :person)-[k:knows]->(p) MATCH (vRETURN count(*); :person) MATCH (vRETURN count(v.name) AS CNT;
min()/max()
Takes the numeric attribute as input, returns the minimum/maximum values to the corresponding column.:person) MATCH (vRETURN max(v.age); :person) MATCH (vRETURN min(v.age);
stDev()
Returns the standard deviation. The stDev function returns the standard deviation of the sample population and must cast the property.:person) MATCH (vRETURN stDev(v.age);
stDevP()
Returns the standard deviation. The stDevP function returns the standard deviation of the sample population and must cast the property.:person) MATCH (vRETURN stDevP(v.age);
sum()
Returns the sum of the numeric values. As it is the sum of the numeric values. The property must be cast.:person) MATCH (vRETURN sum(v.age);
Predicates functions
all()
Returns true if all elements in the list satisfy the condition.RETURN ALL(x in [] WHERE x = 0);
any()
Returns true if at least one element in the list satisfies the condition.RETURN ANY(x in [0] WHERE x = 0);
none()
Returns true if no elements in the list satisfy the condition.RETURN NONE(x in [] WHERE x = 0);
single()
Returns true if a single function satisfies only a condition in the list.RETURN SINGLE(x in [] WHERE x = 0);
Scalar functions
coalesce()
Returns the first non-null value in the list.CREATE (:person {name: 'Jack', job: 'Teacher'}); MATCH (a)WHERE a.name = 'Jack' RETURN coalesce(a.age, a.job);
endNode()
Returns the last node in the relationship.CREATE vlabel Developer; CREATE vlabel language; CREATE elabel be_good_at; CREATE (:Developer {name: 'Jason'})-[:be_good_at]->(:language {name: 'C'}); CREATE (:Developer {name: 'David'})-[:be_good_at]->(:language {name: 'JAVA'}); :Developer)-[r]-() MATCH (xRETURN endNode(r);
head()
Returns the first element in the list.CREATE (:person {name: 'Richard', array: [ 1, 2, 3 ]}); MATCH(a)where a.name = 'Richard' RETURN a.array, head(a.array);
When an edge is targeted, the element of the first edge in the sequence is returned.
CREATE (E:person {name: 'Edward'})-[L:likes{why:'genius'}]-> :person {name: 'Alice'})-[O:loves{how:'3000'}]-> (A:person {name: 'Andrew'})-[P:knows{when:'16 years ago'}]->(Q:person{name: 'Chalee'}); (M :person{name:'Edward'})-[e*3]->(n) MATCH(pRETURN head(e);
id()
Returns the relationship or id of the node; returns the node id for all nodes specified in the argument.MATCH (a)RETURN id(a);
last()
Returns the last element in the list.MATCH (a)WHERE a.name = 'Richard' RETURN a.array, last(a.array);
When an edge is targeted, the element of the last edge is returned.
CREATE (E:person {name: 'Edward'})-[L:likes{why:'genius'}]-> :person {name: 'Alice'})-[O:loves{how:'3000'}]-> (A:person {name: 'Andrew'})-[P:knows{when:'16 years ago'}]->(Q:person{name: 'Chalee'}); (M :person{name:'Edward'})-[e*3]->(n) MATCH(pRETURN last(e);
length()
Returns the length of a string or path. If you specify the property of a string or a string type as an argument, the number of characters in the string is returned.RETURN length('string'); :person) MATCH (aWHERE length(a.name) > 4 RETURN a.name;
properties()
Converts the arguments to a list of key/value mappings. If the argument is already a key/value mapped list, it is returned unchanged.CREATE (p:Person { name: 'Stefan', city: 'Berlin' }) RETURN properties(p);
startNode()
Returns the starting node of the relationship.:Developer)-[r]-() MATCH (xRETURN startNode(r);
toBoolean()
Converts a string to a boolean.RETURN toBoolean('TRUE'), toBoolean('FALSE');
type()
Returns the elabel of the edge passed as an argument. If the elabel of the edge also inherits another elabel, it returns a parent elabel as well. You should be careful when passing arguments to the type function; when you find an edge that matches the pattern using MATCH clause, assign a variable, and then pass the variable as an argument, the edge itself cannot be passed as an argument to the type function, but must always be passed as a variable.CREATE elabel loves; CREATE (:person {name: 'Adam'})-[:loves]->(:person {name: 'Eve'}); 'Adam'})-[r]->({name: 'Eve'}) MATCH ({name: RETURN type(r);
List functions
keys()
Returns a list containing strings for all attribute names of nodes, relationships, and maps.MATCH (a)WHERE a.name = 'Jack' RETURN keys(a);
labels()
Returns vlabel of the vertex passed as an argument. You should be careful when passing arguments to the label function; when you find a vertex that matches the pattern using MATCH clause, assign a variable, and pass that variable as an argument, the vertex itself cannot be passed as an argument to the label function, but must always be passed as a variable.MATCH (a)WHERE a.name='Jack' RETURN labels(a);
nodes()
Returns a vertex that exists in the path passed as an argument. You should be careful when passing arguments to the nodes function; when you find a path that matches the pattern using MATCH clause, assign a variable, and pass that variable as an argument, the path itself cannot be passed as an argument to the nodes function, but must always be passed as variable. When used with the length function, the number of vertices in the path can be found.= (a)-[r]->(b) MATCH p WHERE a.name = 'Adam' and b.name = 'Eve' RETURN nodes(p); = (a)-[r]->(b) MATCH p WHERE a.name = 'Adam' and b.name = 'Eve' RETURN length(nodes(p));
relationships()
Returns the edges present in the path passed as an argument. You should be careful when passing arguments to the relationships function; when you find a path that matches the pattern using MATCH clause, assign a variable, and pass that variable as an argument, the path itself cannot be passed as an argument to the relationships function, but must always be passed as variable. When used with the count function, the number of edges in the path can be found.= (a)-[r]->(b) MATCH p WHERE a.name = 'Adam' and b.name = 'Eve' RETURN relationships(p); = (a)-[r]->(b) MATCH p WHERE a.name = 'Adam' and b.name = 'Eve' RETURN count(relationships(p));
tail()
Returns a list result that contains all elements except the first element in the list.MATCH (a)WHERE a.name = 'Richard' RETURN a.array, tail(a.array);
When an edge is targeted, elements other than of the first edge are returned.
CREATE (E:person {name: 'Edward'})-[L:likes{why:'genius'}]-> :person {name: 'Alice'})-[O:loves{how:'3000'}]-> (A:person {name: 'Andrew'})-[P:knows{when:'16 years ago'}]->(Q:person{name: 'Chalee'}); (M :person{name:'Edward'})-[e*3]->(n) MATCH(pRETURN tail(e);
Mathematics functions
Number
abs()
Returns a numeric value passed as an argument. It may be passed as a decimal number or as a subtraction. The MATCH clause can be used to find a specific element and pass a subtraction of the properties, which are numeric values, among the properties of the elements.RETURN abs(-3.14); RETURN abs(20-45); 'Jack'}), (b {name:'Emily'}) MATCH (a {name:RETURN abs(a.age-b.age);
ceil(), floor(), round()
The ceil function rounds the numeric value passed as an argument to the first decimal place. The floor function returns the numeric value passed as an argument to the first decimal place. The round function rounds the numeric value passed as the argument to the first decimal place.RETURN ceil(3.1); RETURN ceil(1); RETURN ceil(-12.19); RETURN floor(3.1); RETURN floor(1); RETURN floor(-12.19); RETURN round(3.1); RETURN round(3.6); RETURN round(-12.19); RETURN round(-12.79);
rand()
Returns an arbitrary floating-point number between 0 and 1.RETURN rand();
sign()
Returns the sign of the numeric value passed as an argument; returns ‘1’ if the argument passed is positive, ‘-1’ if negative, and ‘0’ if zero.RETURN sign(25); RETURN sign(-19.93); RETURN sign(0);
Logarithmic
log()
Returns the natural logarithm of a number.RETURN log(27);
The natural logarithm of 27 is returned.
log10()
Returns the common logarithm (base 10) of a number.RETURN log10(27);
The common logarithm of 27 is returned.
exp()
The exp function returns a power value to base (e) exponentiated by the numeric value passed as an argument. That is, exp(1) returns e^1≒2.71828182845905, exp(2) returns e^2≒7.38905609893065, and exp(-1), e^-1≒0.367879441171442.RETURN exp(1); RETURN exp(2); RETURN exp(-1);
sqrt()
Returns the square root of the numeric value passed as an argument. The sqrt function cannot pass a negative number as an argument.RETURN sqrt(25);
Trigonometric
sin()/cos()/tan()
The sin, cos, and tan functions return the sine, cosine, and tangent values of the numeric values passed as arguments, respectively. sin(), cos(), and tan() print the values in radians; sind(), cosd(), and tand() are used to print the values in degrees.RETURN sin(0.5); RETURN sin(-1.5); RETURN cos(0); RETURN cos(-1); RETURN tan(0); RETURN tan(15.2);
cot()/asin()/acos()/atan()/atan2()
The cot function returns a cotangent value (inverse of tangent) of the numeric value passed as an argument, the asin function returns an arcsine value (inverse of sine) of the numeric value passed as the argument, and the acos function returns an arccosine value of the numeric value (inverse of cosine). The atan, atan2 functions return the arctangent value (inverse of tangent) of the numeric value passed as an argument. The argument range of the acos function is a numeric value between -1 and 1. atan2 has two arguments in order to make the atan function more granular. Conceptually, atan2(a, b) is equivalent to atan (a/b). However, it is not clear whether atan(-5) is atan(-15/3) or atan (15/(-3)). The trigonometric function requires a definite distinction because the argument is a radian value. Therefore, using atan2 rather than atan makes it more accurate.RETURN cot(1.5); RETURN asin(1); RETURN acos(0.5); RETURN atan(-1); RETURN atan2(-1.5, 1.3);
pi()/degrees()/radians()
The pi function returns pi as a number. The degrees function takes the arguments passed as radians and returns them to degrees. The radians function converts the arguments passed to degrees into radians.RETURN pi(); RETURN degrees(12.3); RETURN degrees(pi()); RETURN radians(180);
String functions
replace()
If the second argument is contained in the first argument, replace the second argument with the third argument.RETURN replace('ABCDEFG', 'C', 'Z'); RETURN replace('ABCDEFG', 'CD', 'Z'); RETURN replace('ABCDEFG', 'C', 'ZX'); RETURN replace('ABCDEFG', 'CD', 'ZXY');
substring()
Prints the first argument from the nth digit (n is the number indicated by the second argument). The third argument indicates how many characters to be printed. If there is no third argument and it is greater than the number of characters in the first argument, it prints to the end.RETURN substring('ABCDEFG', 2); RETURN substring('ABCDEFG', 2, 3); RETURN substring('ABCDEFG', 4, 10);
left()/right()
The left function prints the first argument from the left, and the right function prints characters up to the length of n (n is the number indicated by in the second argument) from the right. If the value of the second argument is larger than the number of characters remaining, the number of characters remaining will be printed out.RETURN left('AAABBB', 3); RETURN right('AAABBB', 3);
lTrim()/rTrim()
The lTrim function removes all left whitespace from the passed argument, and the rTrim function removes all right whitespace before printing.RETURN lTrim(' ABCD '); RETURN rTrim(' ABCD ');
toLower()/toUpper()
The toLower function converts all passed arguments to lower case and the toUpper function converts them to upper case.RETURN toLower('AbCdeFG'); RETURN toUpper('AbCdeFG');
reverse()
Prints the arguments in reverse order.RETURN reverse('ABCDEFG');
toString()
Converts an integer, floating, or boolean value to a string.RETURN toString(11.5), toString('already a string'), toString(TRUE);
trim()
Returns the original string with the leading and trailing spaces removed.RETURN trim(' hello ');
SQL Language
Introduction
AgensGraph supports SQL for relational data queries. It supports DDL (create, alter, drop, etc.) for creating, modifying, and deleting objects such as table, column, constraints, and schema and DML (insert, update, delete, etc.) for inserting, modifying and deleting data.
SQL Syntax is identical to PostgreSQL’s SQL Syntax. See PostgreSQL-The SQL Language for more information.
Data Type
AgensGraph provides diverse data types. You can add new types as well using CREATE TYPE command. Refer to the User-defined Type clause for more information on CREATE TYPE.
The following table lists the generic data types provided by default, and some of the types that are used internally or not used may not be included. (“Alias” is an internally-used name.)
Name | Alias | Description |
---|---|---|
bigint | int8 | Signed 8-byte integer |
bigserial | Auto-incrementing 8-byte integer | |
bit [ (n) ] | 16-bit integer | Fixed length bit string |
bit varying [ (n) ] | varbit | Variable-length bit string |
boolean | bool | Logical Boolean (true / false) |
box | Square box on a plane | |
bytea | Binary data (“byte array”) | |
character [ (n) ] | char [ (n) ] | Fixed-length character string |
character varying [ (n) ] | varchar [ (n) ] | Variable-length character string |
cidr | IPv4 or IPv6 network address | |
circle | Circle on a plane | |
date | Calendar date (year, month, day) | |
double precision | float8 | Double-precision floating-point number (8 bytes) |
inet | IPv4 or IPv6 host address | |
integer | int, int4 | Signed 4-byte integer |
interval [ fields ] [ (p) ] | Time range | |
json | Text JSON data | |
jsonb | Binary JSON data, disjointed | |
line | Infinite straight line on a plane | |
lseg | Segment on a plane | |
macaddr | Media Access Control (MAC) address | |
money | Traffic volume | |
numeric [ (p, s) ] | decimal [ (p, s) ] | The exact number of selectable digits |
path | Geometric path in the plane | |
pg_lsn | AgensGraph log sequence number | |
point | Geometric points on a plane | |
polygon | Geometrically-closed path in plane | |
real | float4 | Single-precision floating-point number (4 bytes) |
smallint | int2 | Signed two-byte integer |
smallserial | serial2 | Auto-incrementing 2-byte integer |
serial | serial4 | Auto-incrementing 4-byte integer |
text | Variable-length character string | |
time [ (p) ] [ without time zone ] | Time (no time zone) | |
time [ (p) ] with time zone | timetz | Includes time and time zone |
timestamp [ (p) ] [ without time zone ] | Date and time (no timezone) | |
timestamp [ (p) ] with time zone | timestamptz | Date and time, including time zone |
tsquery | Text search query | |
tsvector | Text Search Document | |
txid_snapshot | User-level transaction ID snapshot | |
uuid | Universal unique identifier | |
xml | XML data |
Numeric Types
A numeric type consists of a 2/4/8 byte integer, a 4/8 byte floating-point number, and a selectable total number of digits.
The following numeric types are available:
Namesmallint |
Storage Size2 bytes |
DescriptionA small range of integers |
Range-32768 to +32767 |
|
integer | 4 bytes | Common integer | -2147483648 to +2147483647 | |
bigint | 8 bytes | A large range of integers | -9223372036854775808 to +9223372036854775807 | |
decimal | variable | Custom precision, correct | Up to 131072 digits before the decimal point, up to 16383 digits after the decimal point |
|
numeric | variable | Custom precision, correct | Up to 131072 digits before the decimal point, up to 16383 digits after the decimal point |
|
real | 4 bytes | Variable precision, incorrect | 6 digits precision | |
double precision | 8 bytes | Variable precision, incorrect | 15 digits precision | |
smallserial | 2 bytes | Automatic incremental constant (small) | 1 to 32767 | |
serial | 4 bytes | Automatic incremental constant | 1 to 2147483647 | ||||
bigserial | 8 bytes | Automatic incremental integer (large) | 1 to 9223372036854775807 |
Integer Types
smallint, integer, and bigint types store a wide range of integers without decimal fractions. If you try to store a value beyond the allowable range, an error will occur.
- integer type: This type is generally chosen as it provides the best
balance point of range, storage size, and performance.
- smallint type: Typically used only when there is insufficient disk space.
- bigint type: To be used when the integer type range is insufficient.
SQL specifies only integer (or int), smallint, and bigint. (available as int2, int4, and int8 as well).
Arbitrary Precision Numbers
Numeric types may store a very large number of digits and perform calculations correctly. It is especially recommended when storing amounts and quantities that should be accurate. The arithmetic of numeric values, however, is much slower than the integer types or floating-point types described in the next section.
Scale in the numeric type means the number of digits to the right of the decimal point. Precision means the total number of significant digits of the total number. That is the total number of digits on both sides of the decimal point. Thus, the precision and scale of the number 23.5141 are 6 and 4, respectively. The scale of the whole number can be considered 0 (Scale 0).
You may configure both the maximum precision and the maximum scale of a numeric column.
To declare a column of numeric type, use the following syntax:
NUMERIC(precision, scale)
Precision must be positive and scale must be zero or positive.
NUMERIC(precision)
If you specify numeric without precision or scale as follows, it selects Scale 0.
NUMERIC
If you create a numeric column that can store precision and scale values without specifying them, you may store the precision value. This kind of column can be used without restriction if it does not specify a specific scale. However, a numeric column with a scale value specified will be limited by the scale value. (When transferring data, make sure to specify the precision and scale always).
Note: The maximum allowable precision is 1000 if explicitly specified in the type declaration. NUMERICs that do not specify precision are limited to the ranges described in the table.
In the case where the scale in the value to be stored is greater than
the scale declared in the column, the system rounds off the value to the
specified scale; after rounding-off, if the number of digits to the
right of the decimal point exceeds “the declared scale subtracted from
the declared precision,” an error will occur. Numeric values are
physically stored without extra 0
values. Therefore, the
precision and scale of the declared column are the maximum (not a fixed
allocation). In this sense, numeric types are closer to varchar (n) than
to char (n). The actual storage requirement is 2 bytes for each 4-digit
group plus 3 for 8-byte overhead.
The decimal and numeric types are the same and both are SQL standards.
Floating-Point Types
The real and double precision data types are inaccurate variable-precision numeric types. Inaccuracy means that some values cannot be accurately converted to their internal form and are stored as approximate values, making the storage and retrieval of values somewhat inconsistent.
- If you need accurate storage and computation (e.g. amount), use the
numeric type instead.
- If you need to perform complex calculations using this type for some
unavoidable reason (e.g. when you need a specific behavior in boundary
cases (infinity, underflow)), you should be careful with the
implementation.
- Comparing two floating-point values to see if they are equal may not always work as expected.
On most platforms, the real type has a minimum range of 1E-37 to 1E+37, with a precision of at least 6. The double-precision type generally has a precision of at least 15, ranging from 1E-307 to 1E+308. Too large or too small values will generate an error. If the precision of the entered number is too large, it may be rounded up. An underflow error occurs if the number is so close to zero that it cannot be marked as non-zero.
Serial Types
The smallserial, serial, and bigserial data types are not actual types, but are international notations for creating unique identifier columns (similar to the AUTO_INCREMENT attribute supported by some other databases).
The following two statements work in the same manner:
-- SERIAL
CREATE TABLE tablename (
colname SERIAL
);
-- SEQUENCE
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
integer NOT NULL DEFAULT nextval ('tablename_colname_seq')
colname
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
Create an integer column and sort it by default assigned in the sequence. A NOT NULL constraint is applied to prevent null values from being inserted. (In most cases, it is possible to prevent duplicate values from being accidentally entered with a UNIQUE or PRIMARY KEY constraint; such a constraint is not automatically generated.)
Finally, the sequence is marked as column “owned by,” so that it is not deleted unless the column or table is deleted.
The serial column default is specified in order to insert the next value of the sequence into the serial column. This can be done by excluding columns from the column list of the INSERT statement or by using the DEFAULT keyword.
- The serial type is the same as serial4; both generate an integer
column.
- The bigserial and serial8 types work the same except when creating a
bigint column. bigserial should be used if you expect to use more than
231 identifiers throughout the lifetime of the table.
- The smallserial and serial2 types operate the same except when creating a smallint column.
The sequence created for the serial column is automatically deleted when the owning column is deleted. You can delete the sequence without deleting the column, but the column base expression is forcibly deleted.
Character Types
The following character types are available:
Namecharacter varying(n), varchar(n) |
DescriptionVariable with limit |
|
character(n), char(n) | Fixed length, fill in the blank | |
text | Unlimited variable length |
The two basic character types define character variation(n) and character(n). The value of n is a positive integer, and both can store up to n length characters (not bytes).
If you store a string that is longer than n, an error occurs if the excess string is not empty; if it is blank, it is truncated to the length of the specified n value. If you store a string that is shorter than n characters, it is filled with blanks for the character type. For character varying, the string except blanks is stored.
Trailing blanks in character types are treated as not syntactically significant and are ignored when comparing two values of the character type. Trailing blanks are syntactically significant when using pattern-matching regular expressions such as character varying, text, and LIKE.
char(n) and varchar(n) are aliases of character variation(n) and character(n). A character without a specifier is equivalent to a character(1), and a character varying without a specifier stores strings regardless of its size. It also provides a text type for storing strings, regardless of length.
An example of using the character type is shown below:
create table test1 (a character (4));
CREATE TABLE
insert into test1 values ('ok');
INSERT 0 1
select a, char_length(a) from test1;
a | char_length ------+-------------
2
ok |
create table test2 (b varchar(5));
CREATE TABLE
insert into test2 values ('ok');
INSERT 0 1
insert into test2 values ('good ');
INSERT 0 1
insert into test2 values ('too long');
character varying(5) tries to store data that is too long for the data type.
Error: insert into test2 values ('too long'::varchar(5));
INSERT 0 1
select b, char_length(b) from test2;
b | char_length -------+-------------
2
ok | 5
good | 5 too l |
Date/Time Types
The following date/time types are available:
Name | Storage Size | Description | Low Value | High Value | Resolution |
---|---|---|---|---|---|
timestamp [ (p) ] [ without time zone ] | 8 bytes | Both date and time (no timezone) | 4713 BC | 294276 AD | 1 microsecond / 14 digits |
timestamp [ (p) ] with time zone | 8 bytes | Both date and time, including timezone | 4713 BC | 294276 AD | 1 microsecond / 14 digits |
date | 4 bytes | Date (no time) | 4713 BC | 5874897 AD | 1 day |
time [ (p) ] [ without time zone ] | 8 bytes | Time (no date) | 00:00:00 | 24:00:00 | 1 microsecond / 14 digits |
time [ (p) ] with time zone | 12 bytes | Include time of day, time zone | 00:00:00 +1459 | 24:00:00-1459 | 1 microsecond / 14 digits |
interval [ fields ] [ (p) ] | 16 bytes | Time interval | -178000000 years | 178000000 years | 1 microsecond / 14 digits |
Note: The SQL standard uses timestamp and timestamp without time zone equally, and timestamptz is the abbreviation for timestamp with time zone.
time, timestamp, and interval may set the scale (the number of digits of the decimal fraction) on the second field as the p value, and there is no explicit restriction on precision (total number of digits) by default. The allowable range of p is 0 to 6 for timestamp and interval type.
For the time type, the allowable range of p is 0 to 6 when using 8-byte integer storage, and 0 to 10 when using floating-point storage.
The interval type has an additional option of limiting the set of stored fields by writing one of the following statements:
YEAR
MONTH
DAY
HOUR
MINUTE
SECOND
YEAR TO MONTH
DAY TO HOUR
DAY TO MINUTE
DAY TO SECOND
HOUR TO MINUTE
HOUR TO SECOND
MINUTE TO SECOND
Date/Time Input
The date and time input can be specified in the order of the day, month, and year as follows:
set datestyle to sql, mdy;
set datestyle to sql, dmy;
set datestyle to sql, ymd;
Set the DateStyle parameter to MDY to select the month-day-year interpretation, DMY to select the day-month-year interpretation, or YMD to select the year-month-day interpretation.
The date or time input must be preceded and followed by single quotation marks, like a text string.
- Date
Available date types:
Example1999-01-08 |
DescriptionISO 8601. January 8 in random mode (recommended format) |
|
January 8, 1999 | Ambiguous in datestyle input mode | |
1/8/1999 | January 8 in MDY mode. August 1 in DMY mode | |
1/18/1999 | January 18 in MDY mode. Rejected in other modes | |
01/02/03 | January 2, 2003 in MDY mode February 1, 2003 in DMY mode February 3, 2001 in YMD mode |
|
1999-Jan-08 | January 8 in random mode | ||
Jan-08-1999 | January 8 in random mode | |
08-Jan-1999 | January 8 in random mode | ||
99-Jan-08 | January 8 in YMD mode; others are errors | |
08-Jan-99 | January 8, except error in YMD mode | |
Jan-08-99 | January 8, except error in YMD mode | |
19990108 | ISO 8601. January 8, 1999 in random mode | |
990108 | ISO 8601. January 8, 1999 in random mode | ||
1999.008 | Year and day of the year | |
J2451187 | Julian date | |
January 8, 99 BC | Year 99 BC |
- Time
The visual type is time [(p)] without the time zone and time [(p)] with the time zone. time alone is the same as time without time zone. A valid entry of this type consists of time, followed by an optional time zone. (See the table below.) If the time zone is specified as an input for time without time zone, it is ignored. You can specify the date, but ignore it except when using the time zone name associated with daylight saving time, such as America/New_York. In this case, a date specification is required to determine whether the standard time or daylight saving time period is applied. The appropriate time zone offset is recorded in the time with the time zone value.
Table - [Enter Time]
Example | Description |
---|---|
04:05:06.789 | ISO 8601 |
04:05:06 | ISO 8601 |
04:05 | ISO 8601 |
040506 | ISO 8601 |
04:05 AM | Same as 04:05. AM does not affect the value. |
04:05 PM | Same as 16:05. Input must be <= 12. |
04:05:06.789-8 | ISO 8601 |
04:05:06-08:00 | ISO 8601 |
04:05-08:00 | ISO 8601 |
040506-08 | ISO 8601 |
04:05:06 PST | Time zone specified by abbreviation |
2003-04-12 04:05:06 America/New_York | Time zone specified by full name |
Table - [En ter Time Slot]
Example | Description |
---|---|
PST | Abbreviation (for Pacific Time) |
America/New_York | All time zone names |
PST8PDT | POSIX style time zone specification |
-8:00 | ISO-8601 Offset for PST |
-800 | ISO-8601 Offset for PST |
-8 | ISO-8601 Offset for PST |
zulu | Military acronym for UTC |
See the Time Zones section below for how to specify the time zone.
Timestamp
The valid input of timestamp type consists of a connection of date and time followed by an optional time zone and optional AD or BC. (AD/BC may appear before the time zone, which is not the preferred order.)1999-01-08 04:05:06 1999-01-08 04:05:06 -8:00
These are valid values in accordance with the ISO 8601 standard. The following command format is also supported:
8 04:05:06 1999 PST January
The SQL standard distinguishes timestamp without time zone and timestamp with time zone literals by the presence of a “+” or “-” sign and the time zone offset after that time.
-- timestamp without time zone TIMESTAMP '2004-10-19 10:23:54' -- timestamp with time zone TIMESTAMP '2004-10-19 10:23:54+02'
If you do not specify timestamp with time zone, it is treated as timestamp without time zone; thus, if you use timestamp with time zone, you must specify an explicit type.
TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
Special values
Some special date/time input values are supported for convenience as shown in the table. The values infinity and -infinity are simple abbreviations that are specially represented within the system, without modification, but otherwise converted to the default date/time value when read. (Note the now and related strings are converted to specific time values at the moment they are read.) If you use all of these values as constants in your SQL command, you must use single quotation marks around the constants.
Input String | Valid Type | Description |
---|---|---|
epoch | date, timestamp | 1970-01-01 00: 00: 00 + 00 (Unix system time 0) |
infinity | date, timestamp | After all other timestamps |
-infinity | date, timestamp | Before all other timestamps |
now | date, time, timestamp | Start time of current transaction |
today | date, timestamp | Midnight today |
tomorrow | date, timestamp | Tomorrow midnight |
yesterday | date, timestamp | Yesterday midnight |
allballs | time | 00:00:00.00 UTC |
You can also use the following SQL-compatible functions to get the current time values of the data types such as CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME, and LOCALTIMESTAMP.
Date/Time Output
The output format of the date/time type can be set to one of four styles: ISO 8601, SQL (Ingres), typical POSTGRES (Unix date format), or German. The default is ISO format.
The following table shows an example of each output style. The output of date/time type has usually only the date or time depending on the example given.
Style Specification | Description | Example |
---|---|---|
ISO | ISO 8601, SQL standard | 1997-12-17 07:37:16-08 |
SQL | Traditional style | 12/17/1997 07:37:16.00 PST |
Postgres | Original style | Wed Dec 17 07:37:16 1997 PST |
German | Local style | 17.12.1997 07:37:16.00 PST |
If the DMY field order is specified, it is output in the order of month, day. In other cases, it is output in the order of day and month. The following table is an example:
datestyle Setting | Input Ordering | Example Output |
---|---|---|
SQL, DMY | day/month/year | 17/12/1997 15:37:16.00 CET |
SQL, MDY | month/day/year | 12/17/1997 07:37:16.00 PST |
Postgres, DMY | day/month/year | Wed 17 Dec 07:37:16 1997 PST |
The date/time style can be selected by the user using SET datestyle command, DateStyle parameter in the postgresql.conf configuration file, or PGDATESTYLE environment variables of the server or client. The formatting function to_char allows you to specify date/time output formats in a more flexible manner.
Time Zones
Time zones and notations are affected by political decisions in addition to topographical features. Worldwide time zones have been standardized in the 1900s but are constantly changing due to daylight time regulations. AgensGraph uses the IANA (Olson) timezone database. For future times, it considers that the latest known rules for a specified time zone will be complied with indefinitely in the distant future. However, it has a peculiar mix of dates, time types, and features.
Two obvious problems are:
Date type does not have an associated time zone (only time type has). In the real world, the time zone has no meaning unless it is associated with date and time, since the offset can vary over the year containing the daylight saving time boundary.
The default time zone is specified as a constant numeric offset from UTC. Thus, it may not be possible to adapt to daylight saving time when performing date/time calculations across DST boundaries.
When using time zone to solve this problem, we recommend using a date/time type that includes both date and time (this is supported for compatibility but we do not recommend using the time with time zone type). Assume a local time zone for types that only contain dates or times. The date and time in the time zone are internally stored in UTC. Then, they are converted to a local time in the Time Zone specified by the TimeZone configuration parameters before being displayed to the client. Allow the time zone to be specified in three different formats.
The full names of time zone (e.g. America/New_York). The recognized time zone names are listed in the
pg_timezone_names view. (Identical time zone names are recognized by many other software applications as well.)
Time zone abbreviations (e.g. PST). In contrast to the full names of the time zone that can imply the daylight time conversion date rule set, the corresponding specification simply defines a specific offset from UTC. The recognized abbreviations are listed in the pg_timezone_abbrevs view. You cannot set the configuration parameters TimeZone or log_timezone as a time zone abbreviation, but may use an abbreviation and AT TIME ZONE operator as date/time input values.
In addition to time zone names and abbreviations, it accepts POSIX style time zone specifications of STDoffset or STDoffsetDST; STD is a regional abbreviation, offsetUTC is the numerical offset for the time of the west, and DST is the optional summertime local abbreviation that is assumed to be one hour earlier than the specified offset. For instance, if EST5EDT is not yet a recognized local name, it is accepted and becomes functionally identical to the US East Coast time. In this syntax, local abbreviations can be any string of characters or any string using angle brackets (<>). If a daylight saving area abbreviation is present, it is assumed to be used in accordance with the same daylight saving time conversion rules as those used in the posixrules entry in the IANA time zone database. As posixrules are identical with US/Eastern in a standard AgensGraph installation, the POSIX style time zone specification complies with the USA Daylight Saving Time rules. You can adjust this behavior by replacing the posixrules file, if necessary.
Simply put, this is the difference between abbreviations and full names. Time zone abbreviations represent a specific offset from UTC, while many time zone full names imply a local daylight time rule and have two possible UTC offsets. For instance, “2014-06-04 12:00 America/New_York” representing the noon in the New York area was Eastern Daylight Time (UTC-4) for the day. Accordingly, “2014-06-04 12:00 EDT” specifies the same time instance. However, “2014-06-04 12:00 EST” specifies noon Eastern Standard Time (UTC-5) regardless of whether daylight saving time is nominally in effect on that date.
To complicate the problem, some areas use the same time zone abbreviations meaning different UTC offsets at different times. For example, MSK in Moscow meant UTC+3 for several years and UTC+4 for other cases. Even if these abbreviations are interpreted according to their meanings for a given date (or most recent meaning), as in the above EST example, this does not necessarily match the local time of the date. Note that the POSIX style time zone function does not check for the correctness of local abbreviations; this means you may silently accept false input. For example, SET TIMEZONE TO FOOBAR0 works by letting the system use specific abbreviations for UTC.
Another problem to keep in mind is that positive offset is used for Greenwich’s position west in the POSIX time zone region name. Elsewhere, AgensGraph conforms to the ISO-8601 notation, where the positive time-zone offset is east of Greenwich. Time zone names and abbreviations are case sensitive and are not embedded in the server; they are to be searched from the configuration files stored in the installation directory (…/share/timezone/and …/share/timezonesets/). TimeZone configuration parameters can be set in other standard ways, which is different from postgresql.conf as follows:
- The SQL command SET TIME ZONE sets a time zone for the session. You
can use SET TIMEZONE TO, which is more compatible with the SQL
specification.
- The PGTZ environment variable is used by the libpq client to send SET TIME ZONE command to the server when connected.
Interval Input
The interval value can be written using the following detailed syntax:
...] [direction] [@] quantity unit [quantity unit
Where quantity is a number and unit can be microsecond, millisecond, second, minute, hour, day, week, month, year, decade, century, millennium, or their abbreviations, singular or plural; direction can be ago or empty. The at (@) sign is optional noise. Quantities in different units are implicitly added using an appropriate sign accounting. This syntax is also used for interval output when IntervalStyle is set to postgres_verbose.
Days, hours, minutes, and seconds can be specified without explicitly marking units. For example, “1 12:59:10” is read the same as “1 day 12 hours 59 min 10 sec.”
Combinations of years and months can be specified using dashes as well. For example, “200-10” is read the same as “200 years 10 months.” (This short format is actually the only one allowed by the SQL standards, and is used for output if IntervalStyle is set to sql_standard).
The format using specifiers:
...] [ T [ quantity unit ...]] P quantity unit [ quantity unit
The string must contain P, and may contain T to include the unit of
time. Available unit abbreviations are listed in the table below. Units
can be omitted and can be specified in any order, but units of less than
one day must appear after T. In particular, the meaning of M varies
depending on whether it is before or after T.
Table [ISO 8601 Interval Unit Abbreviations]
Abbreviation | Meaning |
---|---|
Y | Year |
M | Month(in the date part) |
W | Week |
D | Day |
H | Hour |
M | Minute(in the time part) |
S | Second |
Alternative format:
-months-days ] [ T hours:minutes:seconds ] P [ years
The string must start with P, and T separates the date and time of the interval. The value is specified as a number similar to the ISO 8601 date. If you create an interval constant with the fields specification, or if you assign a string to an interval column defined by the fields specification, the interpretation of the unmarked quantity varies depending on the fields. For example, INTERVAL ‘1’ YEAR is interpreted as a year, whereas INTERVAL ‘1’ means 1 second. The lowest right field value allowed by the fields specification is ignored.
For example, INTERVAL ‘1 day 2:03:04’ HOUR TO MINUTE will eventually delete the “seconds” field (not the date field). As all fields of interval values must have the same signs according to the SQL standards, the leading negative signs apply to all fields. For example, the negative sign in the interval literal ‘-1 2:03:04’ applies to both date and hour/minute/second parts. As the fields are allowed to have different signs and the signs of each field are independently processed in a text representation, the hour/minute/second part is regarded as a positive value in this example. If IntervalStyle is set to sql_standard, the leading sign is assumed to be applied to all fields (if there is no additional sign).
If the field is negative, it is better to explicitly append the
(negative) sign to avoid ambiguity. Internally, interval values are
stored as months, days, and seconds. This is because the number of days
in the month is different, and a day can be 23 or 25 hours depending on
the implementation of daylight saving time. The month and day fields are
integers, and the second field can be stored as decimals. Since the
interval is usually generated by constant strings or timestamp
subtraction, this way of storage is not problematic in most cases. The
functions justify_days and justify_hours are useful when you want to
control overflowing days and times in the normal range. Field values in
some fields of the detailed input format and the simpler input field may
have a decimal fraction (e.g. “1.5 weeks” or “01:02:03.45”). These
inputs are converted to an appropriate number of months, days, and
seconds for storage. This results in the decimal(s) of months or days
being added to a subfield using the conversion factor Jan=30 days and 1
day=24 hour. For example, “1.5 months” is one month and 15 days. Only
the seconds are displayed with a decimal fraction. The table below shows
some examples of valid interval inputs.
Table [Interval Input]
Example | Description |
---|---|
1-2 | SQL standard format: 1 year 2 months |
3 4:05:06 | SQL standard format: 3 days 4 hours 5 minutes 6 seconds |
1 year 2 months 3 days 4 hours 5 minutes 6 seconds | Typical Postgres format: 1 year 2 months 3 days 4 hours 5 minutes 6 seconds |
P1Y2M3DT4H5M6S | ISO 8601 “format with designators”: same as above |
P0001-02-03T04:05:06 | ISO 8601 “alternative format”: same as above |
Interval Output
The output format of interval type can be set to one of the four
styles sql_standard, postgres, postgres_verbose, or iso_8601 using the
command SET intervalstyle. The default is postgres. The table below
shows an example of each output style. The sql_standard style generates
an output that conforms to the SQL standard specification for the
interval literal string if the interval value satisfies the standard
limit (year-month or day-minute only if positive and negative values are
not mixed). Otherwise, a sign is explicitly added to eliminate the
confusion of the sign mixing interval; the output appears as if the
standard year-month literal string is followed by a day-time literal
string.
Table [Example of interval output style]
Style Specification | Year-Month Interval | Day-Time Interval | Mixed Interval |
---|---|---|---|
sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 |
postgres | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06 |
postgres_verbose | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago |
iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3DT-4H-5M-6S |
Boolean Type
It provides a standard SQL type boolean; on top of “true” and “false” states, it has “unknown,” a third state that is expressed as SQL null.
Name | Storage Size | Description |
---|---|---|
boolean | 1 byte | True or False state |
- Valid literal values in the true state are:
TRUE
't'
'true'
'y'
'yes'
'on'
'1'
- In the false state, you may use the following values:
FALSE
'f'
'false'
'n'
'no'
'off'
'0'
Leading or trailing blanks are ignored and it is not case sensitive. Using the keywords TRUE and FALSE is preferred. The following example shows that a boolean value is displayed (output) using the characters t and f.
An example of using the boolean type:
CREATE TABLE test1 (a boolean, b text);
INSERT INTO test1 VALUES (TRUE, 'sic est');
INSERT INTO test1 VALUES (FALSE, 'non est');
SELECT * FROM test1;
a | b---+---------
t | sic est
f | non est
SELECT * FROM test1 WHERE a;
a | b---+---------
t | sic est
Geometric Types
Geometric types display two-dimensional spatial objects and the available geometric types are as follows:
Name | Storage Size | Description | Representation |
---|---|---|---|
point | 16bytes | Point on the plane | (x,y) |
line | 32bytes | Infinite straight line | {A,B,C} |
lseg | 32bytes | Infinite segment | ((x1,y1),(x2,y2)) |
box | 32bytes | Square box | ((x1,y1),(x2,y2)) |
path | 16+16n bytes | Closed path (similar to a polygon) | ((x1,y1),…) |
path | 16+16n bytes | Open path | [(x1,y1),…] |
polygon | 40+16n bytes | Polygon (similar to a closed path) | ((x1,y1),…) |
circle | 24bytes | Circle | <(x,y),r> (Center point and radius) |
Points
Points are the basic two-dimensional building blocks for geometric types. The value of point type is specified using one of the following syntaxes:
( x , y ) x , y
Where x and y are the floating-point coordinates, respectively. Points are output using the first syntax.
Lines
Lines are expressed by a linear equation Ax+By+C=0; where A and B are both nonzero. The value of line type is the input and output in the following format.
{ A, B, C }
Alternatively, you can use one of the following formats for input:
[ ( x1 , y1 ) , ( x2 , y2 ) ]
( ( x1 , y1 ) , ( x2 , y2 ) )
( x1 , y1 ) , ( x2 , y2 ) x1 , y1 , x2 , y2
Where (x1, y1) and (x2, y2) are two different points on a straight line.
Line Segments
A line segment is represented by a pair of points that form the two endpoints of a line segment. The value of lseg type is specified using one of the following syntaxes.
[ ( x1 , y1 ) , ( x2 , y2 ) ]
( ( x1 , y1 ) , ( x2 , y2 ) )
( x1 , y1 ) , ( x2 , y2 ) x1 , y1 , x2 , y2
Where (x1, y1) and (x2, y2) are the two endpoints of a line segment. The Line Segment is output using the first syntax.
Boxes
A box is represented by a pair of points that form the opposite corners of the box. The value of box type is specified using one of the following syntaxes:
( ( x1 , y1 ) , ( x2 , y2 ) )
( x1 , y1 ) , ( x2 , y2 ) x1 , y1 , x2 , y2
Where (x1, y1) and (x2, y2) are the two opposite corners of the box. A box is an output using the second syntax. Two opposite corners are provided as inputs, but values are reordered as needed to be saved as upper right corner and lower left corner.
Paths
A path is represented by a list of connected points. If the first and last points of the list are considered unconnected, it is an open path. If the first and last points are considered to be connected, it is a closed path. The value of path type is specified using one of the following syntaxes:
... , ( xn , yn ) ]
[ ( x1 , y1 ) , ... , ( xn , yn ) )
( ( x1 , y1 ) , ... , ( xn , yn )
( x1 , y1 ) , ... , xn , yn )
( x1 , y1 , ... , xn , yn x1 , y1 ,
Where the points are the two endpoints of a line segment constituting the path. Square brackets ([]) indicate open paths and parentheses (()) indicate closed paths. If the outermost parentheses are omitted, as in the third through fifth statements, they are considered closed paths. The path is output using the second syntax properly.
Polygons
Polygons are represented by a list of points (polygon vertices). Polygons are very similar to closed paths, but are stored differently and have their own set of routines supported. The value of polygon type is specified using one of the following syntaxes:
... , ( xn , yn ) )
( ( x1 , y1 ) , ... , ( xn , yn )
( x1 , y1 ) , ... , xn , yn )
( x1 , y1 , ... , xn , yn x1 , y1 ,
Where the points are the two endpoints of a line segment constituting the boundary of the polygon. The polygon is output using the first syntax.
Circles
A circle is represented by the center point and radius. The value of circle type is specified using one of the following syntaxes:
< ( x , y ) , r >
( ( x , y ) , r )
( x , y ) , r x , y , r
Where (x, y) is the center of the circle and r is the radius. The circle is output using the first syntax.
XML Type
The XML type is used to store XML data. It allows you to inspect input values in a well-formed format rather than storing XML data in a text field and has functions that supports safe operations. This data type requires an installation built with configure –with-libxml.
Creating XML Values
To generate an xml type value from character data, use the function below:
value) XMLPARSE ( { DOCUMENT | CONTENT }
Examples:
'<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (DOCUMENT 'abc<foo>bar</foo><bar>foo</bar>') XMLPARSE (CONTENT
The XML type does not check the input value for the document type definition (DTD) even if the input value is specified as DTD. It does not support validation of other XML schema languages (e.g. XML schema).
The inverse operation to generate a string value in xml uses the following function:
value AS type ) XMLSERIALIZE ( { DOCUMENT | CONTENT }
type can be character, character varying, text (or alias in it). According to the SQL standard, this is the only way to convert XML and character types, but may simply cast the values.
Choosing DOCUMENT and CONTENT is determined by the “XML Option” session configuration parameters, which can be set using standard commands when a string value is cast to xml type or passes through XMLSARIALIZE without going through XMLPARSE or XMLSERIALIZE.
SET xmloption TO { DOCUMENT | CONTENT };
As the default is CONTENT, XML data in any format are allowed.
Note: You cannot directly convert a string containing DTD to an XML format, since the definition of an XML content fragment does not allow XML if the default XML option settings are used. You should use XMLPARSE or change the XML option.
Encoding Handling
Care should be taken when you process multiple character encodings on the client and when XML data is passed through it. If you use text mode to pass a query to the server and pass a query result to the client (normal mode), convert all character data passed between the client and server, and convert the character encoding backward at each end. It contains a text representation of the XML value as shown in the example above. This usually this implies that the encoding declaration contained in the XML data can be invalidated, as the embedded encoding declaration does not change, if the character data is converted to another encoding during transmission between the client and server. To cope with this behavior, the encoding declaration contained in the character string that exists for the XML type input is ignored and CONTENT is regarded as the current server encoding. As a result, strings of XML data must be transmitted from the client through the current client encoding for proper processing. It is the client’s responsibility to convert the document to the current client encoding or to properly adjust the client encoding before sending it to the server. The value of type XML in the output does not have an encoding declaration, and the client considers all data to be the current client encoding.
If you use binary mode to pass query parameters to the server and pass the query results back to the client, the character set conversion is not performed, making things more difficult. In this case, the encoding declaration of the XML data is complied with; if absent, the data is assumed to be UTF-8 (note that this is required by the XML standard and does not support UTF-16). At the output, the data has an encoding declaration specifying the client encoding, if it is not the client encoding is UTF-8; if it is, the encoding declaration will be omitted.
Processing XML data is less likely to cause errors and is more efficient when the XML data encoding, client encoding, and server encoding are all identical. Since XML data is internally processed as UTF-8, the calculation is most efficient when the server is UTF-8 as well.
Note: Some XML-related functions may not work with non-ASCII data if the server encoding is not UTF-8. This is especially known as a problem in xpath ().
Accessing XML Values
The XML data type is unique in that it does not provide a comparison operator. This is because there is no well-defined and universally useful comparison algorithm for XML data. As a result, you cannot retrieve a row by comparing the XML column with the search value. You must use XML with a separate key field (e.g. ID). An alternative solution to compare XML values is to convert to a string first. Note, however, that string comparisons have nothing to do with useful XML comparison methods.
Since there is no comparison operator for XML data types, it is not possible to create an index directly on this type of column. If you need to retrieve XML data fast, the possible solutions include casting and indexing expressions to character string types or indexing XPath expressions. Of course, the search should be adjusted by the indexed expressions in actual querying.
The text search feature can also be used to speed up the retrieval of entire documents in XML data. However, the necessary preprocessing support is not yet available.
JSON Types
The JSON data type is for storing JavaScript Object Notation (JSON) data as specified in RFC 71591. The applicable data can also be saved as text, but the JSON data type has the advantage of enforcing each stored value to be valid according to the JSON rules. There are also a number of JSON-specific functions and operators available for these types of stored data.
There are two JSON data types: JSON and JSONB. These two types accept almost the same set of values as input. A substantial difference between the two is efficiency. The JSON data type stores an exact copy of the input text, and its processing function must be re-parsed for each execution. On the other hand, the JSONB data is stored in decomposed binary format, which is a bit slower on input due to the added conversion overhead, but much faster during processing because no re-parsing is required. JSONB also supports indexing, which can be a significant advantage.
The JSON type stores exact copies of the input text, preserving
syntactically insignificant whitespace between tokens and key sequences
in the JSON object. In addition, if a JSON object inside a value
contains the same key more than once, all key/value pairs are retained.
(Processing functions assume the last value is valid.) Conversely, JSONB
does not retain whitespace, the order of the object keys, and duplicate
object keys. If a duplicate key is specified in the input, only the last
value is retained. In general, most applications should store JSON data
as JSONB unless there is a specific reason such as existing assumptions
about object key ordering. Only one character set encoding per database
is allowed. Therefore, when the database encoding is not UTF8, it is
impossible for the JSON type to strictly comply with the JSON
specification. Attempts to directly include characters that cannot be
represented in the database encoding would fail. In contrast, characters
that cannot be represented by UTF8 but can be represented by database
encoding are allowed. RFC 7159 allows a JSON string to contain a Unicode
escape sequence denoted by \uXXXX
. In a JSON type input
function, Unicode escapes are allowed regardless of the database
encoding and are checked for syntactical correctness
(i.e. \u
followed by four hexadecimal digits). However, the
input function for JSONB is stricter. When the database encoding is not
UTF8, it does not allow Unicode escapes for non-ASCII characters (U+007F
and above). In addition, in JSONB types, the use of a Unicode surrogate
pair that denies \u0000
(as it cannot be represented as a
text type) and specifies characters out of the Unicode Basic
Multilingual Plane (BMT) must be correct; it is converted to ASCII or
UTF8 characters corresponding to a valid Unicode escape and stored
(overlapping surrogate pairs are included as a single character).
Note: Many JSON processing functions convert Unicode escapes to regular characters, and thus return an error even if the input is of type json rather than jsonb. In general, it is best not to mix Unicode escapes with UTF8 database encodings in JSON whenever possible.
If you convert the text JSON input to JSONB, the primitive types
described in RFC 7159 are effectively mapped to the native AgensGraph
types, as shown in Table 8-23. Accordingly, several local constraints
that do not apply to the JSON type and JSON (even abstractly) and that
constitute valid JSONB data are added; this corresponds to a restriction
on whether it can be represented as a primitive data type or not. In
particular, JSONB rejects numbers that are outside the range of the
AgensGraph numeric data type and that does not leave JSON. Constraints
on which the corresponding implementations are defined are allowed by
RFC 7159. In practice, however, this problem is much more common in
other implementations, as JSON’s number base type is commonly used to
represent IEEE 754 double floating-point (explicitly predicted and
allowed in RFC 7159). If you use JSON in interchange format with the
system, you should consider the risk of loss of numeric precision when
compared to the original data stored in AgensGraph. Conversely, there
are some local constraints on the input type of the JSON base type that
do not apply to the corresponding AgensGraph type, as shown in the
table.
[JSON basic type and corresponding AgensGraph type]
JSON primitive typestring |
Type | Notes | ============+=================================================================================================+ text | If the database encoding is not UTF8, 000 is not allowed as it is a non-ASCII Unicode escape | ||
number | numeric | NaN and infinity values are not allowed | |
boolean | boolean | Only lowercase spelling true and false are accepted | |
null | (없음) | SQL NULL is conceptually different |
JSON Input and Output Syntax
The input/output syntaxes in the JSON data type can be specified as in RFC 7159. The following example shows all valid JSON (or JSONB) expressions.
-- Simple scalar/primitive value
-- Primitive values can be numbers, quoted strings, true, false, or null
SELECT '5'::json;
-- Array of zero or more elements (elements need not be of same type)
SELECT '[1, 2, "foo", null]'::json;
-- Object containing pairs of keys and values
-- Note that object keys must always be quoted strings
SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;
-- Arrays and objects can be nested arbitrarily
SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;
As mentioned earlier, when a JSON value is input and printed without further processing, JSON outputs the same text as the input, and JSONB does not retain syntactically insignificant content (e.g. spaces). Refer to the differences presented below.
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
json -------------------------------------------------
"bar": "baz", "balance": 7.77, "active":false}
{1 row)
(
SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
jsonb --------------------------------------------------
"bar": "baz", "active": false, "balance": 7.77}
{1 row) (
One thing to note, though not syntactically-significant, is that it is in JSONB, where numbers are printed according to the default numeric type. In practice, this means that the number marked as “e” will be omitted when printed. Here is an example:
SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
json | jsonb -----------------------+-------------------------
"reading": 1.230e-5} | {"reading": 0.00001230}
{1 row) (
As shown in this example, however, JSONB preserves the trailing zero (0) for a checkup even if it is syntactically insignificant.
Designing JSON documents effectively
Expressing data in JSON can be much more flexible than that in traditional relational data models where requirements are enforced in a variable environment. Both methods may coexist and complement each other in the same application. However, in applications that require maximum flexibility, it is recommended that the JSON documents have a slightly fixed structure. Structures are not generally applicable (you can also apply some business rules declaratively), but using a predictable structure makes it easier to write queries that usefully summarize a “document” (datum) set of tables. JSON data is affected by the same concurrency control considerations as other data types when stored in tables. It should be noted that, even though it is feasible to store a large document, updates obtain row-level locking for the entire row. You should consider limiting the JSON document to a manageable size in order to reduce lock contention between update transactions. In principle, JSON documents indicate that the atomic data pointed by business rules cannot be segmented into smaller datums, each of which can be modified independently.
JSONB Containment and Existence
Testing containment is an important feature of JSONB. There is no feature set similar to the JSON type. Containment tests whether a single JSONB document is contained in another document. This example returns true except where noted.
-- Simple scalar/primitive values contain only the identical value:
SELECT '"foo"'::jsonb @> '"foo"'::jsonb;
-- The array on the right side is contained within the one on the left:
SELECT '[1, 2, 3]'::jsonb @> '[1, 3]'::jsonb;
-- Order of array elements is not significant, so this is also true:
SELECT '[1, 2, 3]'::jsonb @> '[3, 1]'::jsonb;
-- Duplicate array elements don't matter either:
SELECT '[1, 2, 3]'::jsonb @> '[1, 2, 2]'::jsonb;
-- The object with a single pair on the right side is contained
-- within the object on the left side:
SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb
> '{"version": 9.4}'::jsonb;
@
-- The array on the right side is not considered contained within the
-- array on the left, even though a similar array is nested within it:
SELECT '[1, 2, [1, 3]]'::jsonb @> '[1, 3]'::jsonb; -- yields false
-- But with a layer of nesting, it is contained:
SELECT '[1, 2, [1, 3]]'::jsonb @> '[[1, 3]]'::jsonb;
-- Similarly, containment is not reported here:
SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields false
-- A top-level key and an empty object is contained:
SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"foo": {}}'::jsonb;
The general principle is that the structure and data content of the contained objects are consistent with the containing objects. It may be possible after discarding unmatched (inconsistent) array elements or object key/value pairs from the containing object. However, when comparing containments, the order of array elements is not important, and duplicate array elements are actually considered only once.
As a special exception to the general principle that structures must be matched, arrays may contain primitive values.
-- This array contains the primitive string value:
SELECT '["foo", "bar"]'::jsonb @> '"bar"'::jsonb;
-- This exception is not reciprocal -- non-containment is reported here:
SELECT '"bar"'::jsonb @> '["bar"]'::jsonb; -- yields false
JSONB has the existence operator that is a variation of the containing theme, which tests whether a string (specified as a text value) appears at the top level of the JSONB value as an object key or array element. This example returns true, except where noted.
-- String exists as array element:
SELECT '["foo", "bar", "baz"]'::jsonb ? 'bar';
-- String exists as object key:
SELECT '{"foo": "bar"}'::jsonb ? 'foo';
-- Object values are not considered:
SELECT '{"foo": "bar"}'::jsonb ? 'bar'; -- yields false
-- As with containment, existence must match at the top level:
SELECT '{"foo": {"bar": "baz"}}'::jsonb ? 'bar'; -- yields false
-- A string is considered to exist if it matches a primitive JSON string:
SELECT '"foo"'::jsonb ? 'foo';
Unlike arrays, JSON objects are optimized internally for search and do not perform linear searches. This means that they are more suitable than arrays that test for containment or existence when there are many related keys and elements.
JSONB Indexing
The GIN index can be used to efficiently search for a key or a key/value pair in a number of JSONB documents (datums). Two GIN “operator classes” with different performance and flexibility tradeoffs are provided. The default GIN operator classes for JSONB support queries using operators such as @>, ?, ?&, and ?|. Here is an example of creating an index within this operator class:
CREATE INDEX idxgin ON api USING GIN (jdoc);
jsonb_path_ops, which is not a default GIN operator class, supports indexing of @> operator only. Here is an example of creating an index within this operator class:
CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops);
Consider a table example that stores a JSON document retrieved from a third-party Web service using a documented schema definition. The general document will be as follows:
{"guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
"name": "Angela Barton",
"is_active": true,
"company": "Magnafone",
"address": "178 Howard Place, Gulf, Washington, 702",
"registered": "2009-11-07T08:53:22 +08:00",
"latitude": 19.793713,
"longitude": 86.513373,
"tags": [
"enim",
"aliquip",
"qui"
] }
Save this document as a JSONB column called jdoc in a table called api. When a GIN index is created in this column, the following query uses the index.
-- Find documents in which the key "company" has value "Magnafone"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}';
However, even though the operator “?” can be indexed, it is not directly applied to the indexed column jdoc. Thus, the index cannot be used in the following query.
-- Find documents in which the key "tags" contains key or array element "qui"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
Still, the above query can use the index, if an expression index is properly used. If a query for a particular item is common within the “tags” key, an index definition like the one below is useful.
CREATE INDEX idxgintags ON api USING GIN ((jdoc -> 'tags'));
WHERE clause jdoc->‘tags’ ? ‘qui’ is an application of the indexable operator “?” and the indexed expression jdoc -> ‘tags’ is recognized.
Another way to query is to make the best use of containment. For example, a simple GIN index on a jdoc column can support this query.
-- Find documents in which the key "tags" contains array element "qui"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
However, while these indexes store copies of all the keys and values of the jdoc column, the expression index in the previous example stores only the data found under the tags key. It is true that the simple index approach is much more flexible (as it supports queries on arbitrary keys), but the targeted expression index is much smaller and more fast-searched than the simple index.
The jsonb_path_ops operator class only supports queries using @> operator, but it has a good performance advantage over the default operator class, jsonb_ops. With the same data, the size and search specificity of the jsonb_path_ops index are generally much smaller and better than those of the jsonb_ops index, respectively. This is especially true for queries that contain keys that appear frequently in the data. Searches with this class are therefore generally much better than using the default operator class.
A technical difference between jsonb_ops and jsonb_path_ops GIN indexes is that the former creates index entries that are independent for each key and value of the data, while the latter only creates index entries for the data values. By default, each jsonb_path_ops index entry is a hash of values and keys leading to it. Let’s take a look at an index {“foo”: {“bar”: “baz”} as an example; a single index entry is generated by combining all three of foo, bar, and baz into a hash value. Thus, a constraint query that looks for such a structure results in an extremely specific index search. However, there is no way to know at all whether foo will appear as a key. Conversely, the jsonb_ops index creates three index entries that represent foo, bar, and baz, respectively. Then, to execute a constraint query, it looks up a row that contains all three of these items. A GIN index can perform its AND search very efficiently, but is less specific and slower than an equivalent jsonb_path_ops search, especially when there are many rows containing one of the three index entries. A disadvantage of the jsonb_path_ops approach is that it does not create index entries for JSON structures that do not contain values such as {“a”: {}}. A full index scan is required if a document search containing the structure is requested, which is very slow. Thus, jsonb_path_ops is not suitable for applications that perform frequent searches. JSONB also supports btree and hash indexes, which is useful only when checking the equivalence of the entire JSON document. The B-tree ordering of JSONB data is not that important, but is necessary for completeness.
Object > Array > Boolean > Number > String > Null
Object with n pairs > object with n - 1 pairs
Array with n elements > array with n - 1 elements
Objects that have the same number of pairs are compared in the following order:
key-1, value-1, key-2 ...
Object keys are compared in the order of storage; in particular, storing short keys in front of long keys leads to non-intuitive results:
"aa": 1, "c": 1} > {"b": 1, "d": 1} {
Similarly, arrays with the same number of elements are compared in the following order:
-1, element-2 ... element
The native JSON values are compared using the comparison rules, which also apply to the primitive data types. Strings are compared using the default database collation.
Arrays
Arrays allow the column type of the table to be defined as a variable length multidimensional array. You can create arrays of built-in or user-defined base types, enum types, or composite types. Arrays of domains are not yet supported.
Declaration of Array Types
In order to explain use of array types, let’s create a table as follows:
CREATE TABLE sal_emp (
name text,integer[],
pay_by_quarter
schedule text[][] );
As indicated, the array data type is named by adding square brackets ([]) to the array element’s data type name. The above command creates a table called sal_emp with a column of type text (name), where a one-dimensional array of type integer (pay_by_quarter) represents the employee’s quarterly salary and a two-dimensional array of text (schedule) indicates the employee’s weekly schedule. CREATE TABLE allows the exact size of the array to be specified. For example:
CREATE TABLE tictactoe (
integer[3][3]
squares );
However, the current implementation ignores the array size limits provided. That is, the operation is the same as an array of unspecified length. The current implementation does not enforce the declared number of dimensions. Arrays of particular element types are considered to be of the same type, regardless of their size or the number of dimensions. Therefore, declaring an array size or the number of dimensions in CREATE TABLE is simply documentation and does not affect runtime behavior.
You can utilize the keyword ARRAY to use an alternative syntax that conforms to the SQL standard for one-dimensional arrays. pay_by_quarter may have been defined as:
integer ARRAY[4], pay_by_quarter
If the array size is not specified:
integer ARRAY, pay_by_quarter
In any case, however, size constraints are not enforced.
Array Value Input
To create an array value as a literal constant, place the value in braces and separate it with a comma. You can use double quotes around the value; you should do this if it contains a comma or brace. The general form of an array constant:
'{ val1 delim val2 delim ... }'
In the example above, delim is the delimiter for the type recorded in the pg_type entry. All of the standard data types provided by the AgensGraph distribution use commas, except for the type box that uses semicolons (;). Each val is a constant of the array element type or subarray. For example:
'{{1,2,3},{4,5,6},{7,8,9}}'
This constant is a two-dimensional 3x3 array consisting of three integer sub-arrays. To set an element of an array constant to NULL, create NULL for the element value. (NULL case can be changed.) If you want the actual string value “NULL,” use double quotation marks before and after NULL. (Constants are initially processed as strings and passed to the array input conversion routine, which may require explicit type specifications.)
The following is an example of INSERT statement and its execution result:
INSERT INTO sal_emp
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'{{"meeting", "lunch"}, {"training", "presentation"}}');
INSERT INTO sal_emp
VALUES ('Carol',
'{20000, 25000, 25000, 25000}',
'{{"breakfast", "consulting"}, {"meeting", "lunch"}}');
SELECT * FROM sal_emp;
name | pay_by_quarter | schedule-------+---------------------------+-------------------------------------------
10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}}
Bill | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}}
Carol | {2 rows) (
A multidimensional array must have a matching range for each dimension, and an inconsistency will cause the following error:
INSERT INTO sal_emp
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'{{"meeting", "lunch"}, {"meeting"}}');
array expressions with matching dimensions ERROR: multidimensional arrays must have
The constructor syntax of ARRAY can also be used.
INSERT INTO sal_emp
VALUES ('Bill',
ARRAY[10000, 10000, 10000, 10000],
ARRAY[['meeting', 'lunch'], ['training', 'presentation']]);
INSERT INTO sal_emp
VALUES ('Carol',
ARRAY[20000, 25000, 25000, 25000],
ARRAY[['breakfast', 'consulting'], ['meeting', 'lunch']]);
An array element is a regular SQL constant or expression. A string literal is enclosed in single quotes instead of double quotes as in an array literal.
Accessing Arrays
You can run some queries from the table created above. Access a single element of an array. The following query retrieves the name of the employee whose salary has been changed in the second quarter.
SELECT name FROM sal_emp WHERE pay_by_quarter[1] <> pay_by_quarter[2];
name-------
Carol1 row) (
Array numbers are enclosed in square brackets; use array notation starting from 1. That is, the array of n elements starts at array[1] and ends at array[n].
This query retrieves the salary of all employees for the third quarter.
SELECT pay_by_quarter[3] FROM sal_emp;
pay_by_quarter----------------
10000
25000
2 rows) (
You can also access any rectangular slice in an array or subarray. An array slice is represented using lower-bound:upper-bound for one or more array dimensions.
For example, the following query retrieves the first item in Bill’s schedule on the first two days of the week.
SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
schedule------------------------
{{meeting},{training}}1 row) (
If you create a dimension as a slice (for example, including a colon), all dimensions are processed as slices. A dimension with only a single number (no colon) is processed as being from 1 to the specified number. For example, [2] is processed as [1: 2], as follows:
SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
schedule-------------------------------------------
{{meeting,lunch},{training,presentation}}1 row) (
To avoid confusion in non-slice cases, it is best to use the slice syntax for all dimensions such as [1:2] [1:1] rather than [2] [1:1].
You can omit the lower-bound or upper-bound of the slice specifier. The missing bounds are replaced by lower or upper of the array, as shown in the following example:
SELECT schedule[:2][2:] FROM sal_emp WHERE name = 'Bill';
schedule------------------------
{{lunch},{presentation}}1 row)
(
SELECT schedule[:][1:1] FROM sal_emp WHERE name = 'Bill';
schedule------------------------
{{meeting},{training}}1 row) (
The array subscript expression returns null if the array itself or subscript expression is null. In addition, null is returned if the subscript is out of the bounds of the array (in which case no errors are produced). For example, schedule [3][3], which is referenced when the schedule is the current dimension [1:3] [1:2], prints NULL. Similarly, an array referencing an incorrect number of subscripts prints null, not an error.
Array slice expressions similarly return null if the array itself or the subscript expression is null. However, in other cases (e.g. selecting an array slice that is completely out of the bounds of the current array), the slice expression outputs an empty (zero-dimensional) array instead of null. If the requested slice partially overlaps the array bounds, it is reduced to an overlap region instead of returning null.
The current dimensions of array values can be retrieved using the array_dims function.
SELECT array_dims(schedule) FROM sal_emp WHERE name = 'Carol';
array_dims------------
1:2][1:2]
[1 row) (
array_dims produces a text result, which is more readable to humans, but inconvenient to the program. Dimensions can also be retrieved using array_upper and array_lower, which return the upper and lower bounds of the specified array dimension, respectively.
SELECT array_upper(schedule, 1) FROM sal_emp WHERE name = 'Carol';
array_upper-------------
2
1 row) (
array_length returns the length of the specified array dimension.
SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol';
array_length--------------
2
1 row) (
cardinality returns the total number of elements in an array of all dimensions; it is actually the number of rows generated by the call on unnest.
SELECT cardinality(schedule) FROM sal_emp WHERE name = 'Carol';
cardinality
-------------
4
1 row) (
Modifying Arrays
You may update the array value as a whole;
UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}'
WHERE name = 'Carol';
or use ARRAY expression syntax.
UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000]
WHERE name = 'Carol';
An array can update a single element;
UPDATE sal_emp SET pay_by_quarter[4] = 15000
WHERE name = 'Bill';
or update it only partially.
UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
WHERE name = 'Carol';
The omitted lower-bound or upper-bound slice syntax can be used only when updating NULL or nonzero array values.
The stored array value can be expanded by assigning it to an element that does not yet exist. The position between the previously existing element and the newly allocated element is filled with null. For example, if the array myarray currently has 4 elements, it will have 6 elements after an update of assigning to myarray [6]. myarray [5] contains null. Currently, the expansion in this manner is only allowed for one-dimensional arrays (not multidimensional arrays). Subscripted assignments allow you to create arrays whose subscripts do not start at one (1). For example, to create an array with subscript values -2 through 7, you may assign it to myarray [-2:7].
The new array value can also be created using the concatenation operator ||.
SELECT ARRAY[1,2] || ARRAY[3,4] as array;
array
-----------
1,2,3,4}
{1 row)
(
SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]] as array;
array
---------------------
5,6},{1,2},{3,4}}
{{1 row) (
The concatenation operator lets you push a single element into the beginning or end of a one-dimensional array. It accommodates two N-dimensional arrays (or N-dimensional and N+1-dimensional arrays).
If you push a single element to the beginning or end of a one-dimensional array as shown in the following example, the result is an array filled with the same lower bound subscript as the array operand.
SELECT array_dims(1 || '[0:1]={2,3}'::int[]);
array_dims------------
0:2]
[1 row)
(
SELECT array_dims(ARRAY[1,2] || 3);
array_dims------------
1:3]
[1 row) (
When concatenating two arrays having the same number of dimensions, the result holds the lower bound of the outer dimension of the left operand. The result is that all the elements of the right operand are followed by an array of all the elements of the left operand, as the following example shows:
SELECT array_dims(ARRAY[1,2] || ARRAY[3,4,5]);
array_dims------------
1:5]
[1 row)
(
SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]);
array_dims------------
1:5][1:2]
[1 row) (
If you push an N-dimensional array from the beginning to the end of an N+1-dimensional array, the result is similar to the element array example above. Each N-dimensional subarray is essentially an element of the outer dimension of the N+1-dimensional array, as shown in the following example:
SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]);
array_dims------------
1:3][1:2]
[1 row) (
You can also create functions using the functions array_prepend, array_append, or array_cat; while the first two only support one-dimensional arrays, array_cat supports multidimensional arrays. The concatenation operator discussed above prefers the direct use of these functions. In effect, these functions exist primarily for use when implementing a concatenation operator. However, they can also be useful when creating user-defined aggregates. For example:
SELECT array_prepend(1, ARRAY[2,3]);
array_prepend---------------
1,2,3}
{1 row)
(
SELECT array_append(ARRAY[1,2], 3);
array_append--------------
1,2,3}
{1 row)
(
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]);
array_cat-----------
1,2,3,4}
{1 row)
(
SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]);
array_cat---------------------
1,2},{3,4},{5,6}}
{{1 row)
(
SELECT array_cat(ARRAY[5,6], ARRAY[[1,2],[3,4]]);
array_cat---------------------
5,6},{1,2},{3,4}} {{
In a simple case, the concatenation operator described above is preferred over using these functions directly. However, using one of these functions may help avoid ambiguity, since the concatenation operator is overloaded to process all three cases.
SELECT ARRAY[1, 2] || '{3, 4}' as array; -- the untyped literal is taken as an array
array
-----------
1,2,3,4}
{
SELECT ARRAY[1, 2] || '7'; -- so is this one
array literal: "7"
ERROR: malformed
SELECT ARRAY[1, 2] || NULL as array; -- so is an undecorated NULL
array
-------
1,2}
{1 row)
(
SELECT array_append(ARRAY[1, 2], NULL); -- this might have been meant
array_append--------------
1,2,NULL} {
In the above example, parser sees an integer array on one side of the concatenation operator, and a constant of indeterminate type on the other. An empirical method used to analyze the constant type is to assume it is the same type as the other inputs of the operator (in this case, an integer array). So the concatenation operator is considered array_cat, not array_append. If that is a wrong choice, you can modify the constant by casting it to an element type of the array. Using array_append can be a desirable solution.
Searching in Arrays
To retrieve the value of an array, you should check each value; you may do this if you know the size of the array. For example:
SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR
2] = 10000 OR
pay_by_quarter[3] = 10000 OR
pay_by_quarter[4] = 10000; pay_by_quarter[
However, in large arrays, it quickly gets bored and is not helpful when the array size is unknown. The above query can be replaced by:
SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter);
You can also find all the rows with an array value equal to 10000:
SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);
Alternatively, you can use the generate_subscripts function.
SELECT * FROM
SELECT pay_by_quarter,
(1) AS s
generate_subscripts(pay_by_quarter, FROM sal_emp) AS foo
WHERE pay_by_quarter[s] = 10000;
It is also possible to search for an array using && operator, which checks whether the left operand overlaps with the right operand.
SELECT * FROM sal_emp WHERE pay_by_quarter && ARRAY[10000];
You can also use array_position and array_positions functions to retrieve a specific value in an array. The former returns the subscript of the first value in the array, and the latter returns an array with all the subscripts of the values in the array.
SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon');
array_positions-----------------
2
SELECT array_positions(ARRAY[1, 4, 3, 1, 3, 4, 2, 1], 1);
array_positions-----------------
1,4,8} {
Array Input and Output Syntax
The external text expression of an array value consists of the I/O conversion rules for the array element type and the items that are interpreted according to the decoration denoting the array structure. The decoration consists of braces at both ends of the value of an array and delimiters between adjacent items. The delimiters are usually commas (,), but can be something else. It is determined by the typedelim setting for the element type of the array. All of the standard data types use commas, except for type box that uses semicolons (;). In a multidimensional array, each dimension (row, plane, cube, etc.) has its own level of braces and delimiters must be used between adjacent levels of brace entities.
Array output routines use double quotes around element values if they are empty strings, contain braces, delimiters, double quotes, backslashes, or whitespace, or match the word NULL. Double quotes and backslashes embedded in element values are escaped by a backslash. In the case of numeric data types, it is safe to assume that double quotes never appear. However, for text data types you must cope with the presence or absence of quotation marks. By default, the lower bound index value is set to 1 in the dimension of the array. If you specify an array using another lower bound, the range of array subscripts can be explicitly specified before creating the array content. This type of decoration consists of brackets ([]) before and after the lower/upper limits of each array dimension and colons (:) as space separator s. An array dimension decoration is followed by an equal sign (=).
SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;
e1 | e2----+----
1 | 6
1 row) (
The array output routine includes an explicit dimension in the result only if there is more than one lower bound.
If the value created for an element is NULL (in the case of variation), the element is considered to be NULL. The presence of quotes or backslashes disables this and allows input of the literal string value “NULL.” You may also set the array_nulls configuration parameter to off to prevent NULL from being recognized as NULL. As indicated earlier, you can use double quotes around individual array elements when creating array values. This should be done in the case where the element values can be confused by the array value parser. For example, elements that contain braces, commas (or data type separators), double quotes, backslashes, and leading or trailing whitespace must use double-quotes. Empty strings and strings that match NULL must also be quoted. To add double quotes or backslashes into the quoted array element values, use an escape string syntax and precede it with a backslash. You may also use backslash escaping to avoid quotation marks and protect all data characters that might be processed incorrectly as array syntax.
You may add a space before the left brace or after the right brace. You can also add a space before or after the individual item string. Spaces are ignored in all these cases. Whitespaces within double-quote elements and spaces at both ends of non-whitespace characters in elements are ignored.
Range Types
The range type is a data type that represents the range of values of some element type. For example, the range of timestamps can be used to indicate the reserved time range of a meeting room. In this case, the data type is tsrange (short for “timestamp range”) and timestamp is subtype. The subtype must have a total order so that whether the element value is within, before, or after the value range can be well-defined.
The range types are useful in that they can represent multiple element values as a single range value and clearly express concepts like the overlap range. One of the most obvious examples is to use time and date ranges for scheduling. These types can also be useful for price ranges, measuring ranges of instruments, etc.
Built-in Range Types
The following built-in range types are provided:
int4range - Range of integer
int8range - Range of bigint
numrange - Range of numeric
tsrange - Range of timestamp without time zone
tstzrange - Range of timestamp with time zone
daterange - Range of date
You can also define your own range types. See User-defined Type for more information.
Examples
CREATE TABLE reservation (room int, during tsrange);
INSERT INTO reservation VALUES
1108, '[2010-01-01 14:30, 2010-01-01 15:30)');
(
-- Containment
SELECT int4range(10, 20) @> 3;
-- Overlaps
SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0);
-- Extract the upper bound
SELECT upper(int8range(15, 25));
-- Compute the intersection
SELECT int4range(10, 20) * int4range(15, 25);
-- Is the range empty?
SELECT isempty(numrange(1, 5));
Inclusive and Exclusive Bounds
All non-empty ranges have two bounds, a lower bound and an upper bound. All points between these values are included in the range. Inclusive bounds mean that the boundary points themselves are included in the range, and exclusive bounds mean that the boundary points are not included in the range. In the text form of the range, the inclusive lower bound is expressed as “[” and the exclusive lower bound is expressed as ”(.” Similarly, the inclusive upper bound is expressed as ”]”, and the exclusive upper bound is expressed as “).”
The functions lower_inc and upper_inc test the lower and upper bounds of the range value, respectively.
Infinite (Unbounded) Ranges
The lower bound of the range can be omitted, meaning that all points below the upper bound are included in the range. Likewise, if the upper bound of the range is omitted, all points above the lower bound are included in the range. If both the lower and upper bounds are omitted, all values of the element type are considered to be included in the range.
This corresponds to considering that the lower bound is “negative infinity” or the upper bound is “positive infinity.” Note, however, that this infinite value is never a value of the element type of the range, and cannot be part of the range. (Therefore, there is no such thing as inclusive infinite bounds; when you try to create one, it is automatically converted to an exclusive bound).
It is true that some element types have an “infinite” notation, but it is another different value in relation to the range type mechanism. For example, in the timestamp range, [today,] is the same as [today,). However, [today, infinity] can be sometimes different from [today, infinity). The latter excludes the special timestamp value infinity.
The functions lower_inf and upper_inf test infinite lower/upper bounds of each range, respectively.
Range Input/Output
The input for the range value should follow one of the following patterns:
lower-bound,upper-bound)
(lower-bound,upper-bound]
(lower-bound,upper-bound)
[lower-bound,upper-bound]
[empty
The parentheses or square brackets indicate whether the lower and upper bounds are excluded or included as described above. The last pattern is empty, indicating an empty range (a range with no points). The lower-bound can be a string that is a valid input to a subtype, or can be left empty if there is no lower bound. Similarly, upper-bound can be a string that is a valid input to a subtype or can be left empty if there is no upper bound. Each boundary value can be quoted using “(double quote) characters; this is a must since, if the boundary value contains parentheses, square brackets, commas, double quotes, or backslashes, these characters may be mistaken for part of the range syntax. To insert double quotes or backslashes to quoted boundary values, you must precede them with a backslash. (Double quotation pairs within boundary values in double-quotes are also processed as double quotation marks, similar to the rules for single quotation marks in SQL literal strings.) To protect all data characters that might be processed incorrectly with the range syntax, you may avoid quoting and use backslash escaping. In addition, when creating a boundary value that is an empty string, you should write”“; if you do not enter anything, it will mean an infinite boundary. Whitespaces are allowed before and after the range values, but spaces between parentheses or square brackets are considered to be part of the lower or upper bound value. (It may or may not be important depending on the element type).
Examples:
-- includes 3, does not include 7, and does include all points in between
SELECT '[3,7)'::int4range;
-- does not include either 3 or 7, but includes all points in between
SELECT '(3,7)'::int4range;
-- includes only the single point 4
SELECT '[4,4]'::int4range;
-- includes no points (and will be normalized to 'empty')
SELECT '[4,4)'::int4range;
Constructing Ranges
Each range type has a constructor function with the same name as the range type. Using a constructor function is more convenient than writing a range literal constant, because you do not need to quote additional boundary values. A constructor function accepts two or three arguments. While the three-argument form creates a range from the third argument to the boundary of the form specified, the two-argument form creates a range of standard forms (lower bound, excluding upper bound). The third argument must be one of the followings strings: “()”, “(]”, “[]” or “[]”
Examples:
-- The full form is: lower bound, upper bound, and text argument indicating
-- inclusivity/exclusivity of bounds.
SELECT numrange(1.0, 14.0, '(]');
-- If the third argument is omitted, '[)' is assumed.
SELECT numrange(1.0, 14.0);
-- Although '(]' is specified here, on display the value will be converted to
-- canonical form, since int8range is a discrete range type (see below).
SELECT int8range(1, 14, '(]');
-- Using NULL for either bound causes the range to be unbounded on that side.
SELECT numrange(NULL, 2.2);
Discrete Range Types
The discrete range is a well-defined “step-by-step” type of which element type is integer or date. In this type, if there is no valid value between two elements, they can be said to be adjacent. In contrast to the continuous range, this is always (or almost always) possible to recognize different element values between the two given values. For example, a range beyond the numeric type, like the range beyond timestamp, is continuous. (timestamp can be processed discretely in theory because of its precision limitations, but it is better to regard it as a sequence when the size of the step is not of interest.) Another way to think about the discrete range type is to have a clear idea of the “next” or “previous” value for each element value. It should be noted that, by selecting the next or previous element value rather than the given original, it is possible to convert between expressions including the boundaries of the ranges and expressions excluding the boundaries of the ranges. For example, integer range types [4,8] and (3,9) denote the same set of values. This is not the case, however, for numerical ranges. The discrete range type must have a canonicalization function that recognizes the desired step size for the element type. The canonicalization function is especially responsible for converting the values equal to the range types that have an identity representation of a consistent inclusion or exclusion range. Unless a canonicalization function is specified, the ranges of different types are always processed as non-equivalence, even though they actually denote the same set of values. The built-in range types, int4range, int8range, and daterange, use the canonical form, which includes the lower bound and excludes the upper bound (i.e.”[)“). User-defined range types may use other notations.
Defining New Range Types
You may define your own range type. The most common reason for doing this is to use a subtype range that is not provided as a built-in range type. This is an example of defining a new range type for the subtype float8.
CREATE TYPE floatrange AS RANGE (
= float8,
subtype = float8mi
subtype_diff
);
SELECT '[1.234, 5.678]'::floatrange;
Since float8 is not a meaningful “step”, we do not define a canonicalization function in this example. If the subtype has a discrete value rather than a continuous value, CREATE TYPE command must specify a canonical function. The canonicalization function must take an input range value and return an equivalent range value that may be different from the boundary type. The canonical outputs of the two ranges representing the same set of values (e.g. integer range [1, 7] and [1, 8)) should be the same. It does not matter which expression is chosen to be canonical, as long as two equivalent values of the same type are always mapped to the same value of the same type. Besides controlling inclusive/exclusive bounds format, the canonicalization function can process boundary values well if the desired step size is greater than the subtype’s storable size. For example, the step size of a range type beyond timestamp can be defined as time. On this occasion, the canonicalization function may require rounding-off if it is not a multiple of the time, or an error may occur instead. If you define your own range type, you may specify different subtype B-tree operator classes or collations to use in order to change the sort order that determines which values belong to a given range. In addition, a range type to be used in a GiST or SP-GiST index should define a subtype difference or subtype_diff, a function(An index works without subtype_diff, but is much less efficient when a difference function is provided). The subtype difference function takes two input values of a subtype and returns the difference expressed as a float8 value (e.g. X minus Y). In the above example, you may use a function that underlies the normal float8 subtraction operator, but for other subtypes, type conversions may be required. Several creative ideas about how to represent differences in numbers may be needed. To the greatest range possible, the subtype_diff function must agree on the sort order implied by the selected operator class es and collations. That is, the result of this should always be a positive value when the first argument is greater than the second argument according to the sort order.
CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS
'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;
CREATE TYPE timerange AS RANGE (
= time,
subtype = time_subtype_diff
subtype_diff
);
SELECT '[11:10, 23:00]'::timerange;
For more information on creating range types, see User-defined Type.
Indexing
GiST and SP-GiST indexes are able to generate table columns of range type. The following is an example of creating a GiST index.
CREATE INDEX reservation_idx ON reservation USING GIST (during);
GiST or SP-GiST indexes can speed up queries involving range operators such as =, &&, <@, @>, <<, >>, -|-, &<, and &>.
B-tree and hash indexes may create table columns of range type as well. For these index types, the only useful range operation is basically “=”. Even if there is a B-tree sort order that uses “<” and “>” operators and is defined for range values, the order itself is arbitrary and not very useful in the real world. The B-tree and hash support for range types is intended primarily to allow sorting and hashing inside queries rather than creating actual indexes.
Constraints on Ranges
UNIQUE is a natural constraint on scalar values. However, it is appropriate not for range types but for exclusion constraints, mainly. An exclusion constraint allows the specification of constraints such as “nonoverlap” in range types.
Examples:
CREATE TABLE reservation (
during tsrange,USING GIST (during WITH &&)
EXCLUDE );
The constraint prevents overlapping values from being simultaneously present in the table.
INSERT INTO reservation VALUES
'[2010-01-01 11:30, 2010-01-01 15:00)');
(INSERT 0 1
INSERT INTO reservation VALUES
'[2010-01-01 14:45, 2010-01-01 15:45)');
(key value violates exclusion constraint "reservation_during_excl"
ERROR: conflicting Key (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00")) conflicts
DETAIL: with existing key (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")).
You can use the btree_gist extension to define an exclusion constraint on a regular scalar data type, which makes it possible to exclude/combine the range with the maximum flexibility. For instance, after btree_gist is installed, the following constraint rejects overlapping ranges only when the number of meeting rooms is equal.
CREATE EXTENSION btree_gist;
CREATE TABLE room_reservation (
room text,
during tsrange,USING GIST (room WITH =, during WITH &&)
EXCLUDE
);
INSERT INTO room_reservation VALUES
'123A', '[2010-01-01 14:00, 2010-01-01 15:00)');
(INSERT 0 1
INSERT INTO room_reservation VALUES
'123A', '[2010-01-01 14:30, 2010-01-01 15:30)');
(key value violates exclusion constraint "room_reservation_room_during_excl"
ERROR: conflicting Key (room, during)=(123A, ["2010-01-01 14:30:00","2010-01-01 15:30:00")) conflicts
DETAIL: with existing key (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")).
INSERT INTO room_reservation VALUES
'123B', '[2010-01-01 14:30, 2010-01-01 15:30)');
(INSERT 0 1
User-defined Type
You can add a new type using CREATE TYPE command. There are five types of CREATE TYPE: Composite Type, Enum Type, Range Type, Base Type, and Shell Type.
Syntex :
CREATE TYPE name AS
... ] ] )
( [ attribute_name data_type [ COLLATE collation ] [,
CREATE TYPE name AS ENUM
'label' [, ... ] ] )
( [
CREATE TYPE name AS RANGE (
= subtype
SUBTYPE = subtype_operator_class ]
[ , SUBTYPE_OPCLASS = collation ]
[ , COLLATION = canonical_function ]
[ , CANONICAL = subtype_diff_function ]
[ , SUBTYPE_DIFF
)
CREATE TYPE name (
= input_function,
INPUT = output_function
OUTPUT = receive_function ]
[ , RECEIVE = send_function ]
[ , SEND = type_modifier_input_function ]
[ , TYPMOD_IN = type_modifier_output_function ]
[ , TYPMOD_OUT ANALYZE = analyze_function ]
[ , = { internallength | VARIABLE } ]
[ , INTERNALLENGTH
[ , PASSEDBYVALUE ]= alignment ]
[ , ALIGNMENT STORAGE = storage ]
[ , LIKE = like_type ]
[ , CATEGORY = category ]
[ , = preferred ]
[ , PREFERRED DEFAULT = default ]
[ , = element ]
[ , ELEMENT = delimiter ]
[ , DELIMITER = collatable ]
[ , COLLATABLE
)
CREATE TYPE name
Examples :
This is an example of creating a composite type and using it for function definition.
CREATE TYPE compfoo AS (f1 int, f2 text);
CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$
SELECT fooid, fooname FROM foo
$$ LANGUAGE SQL;
This is an example of creating an enum type and using it for table definition.
CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');
CREATE TABLE bug (
id serial,
description text,
status bug_status );
This is an example of creating a range type.
CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
This is an example of creating a base type and then using it for table definition.
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 (
= 16,
INTERNALLENGTH = my_box_in_function,
INPUT = my_box_out_function
OUTPUT
);
CREATE TABLE myboxes (
id integer,
description box );
functions
Comparison functions
num_nonnulls(VARIADIC “any”)
Returns the number of non-null arguments.SELECT num_nonnulls(1, NULL, 2); Result: num_nonnulls------------ 2 1 row) (
num_nulls(VARIADIC “any”)
Returns the number of null arguments.SELECT num_nulls(1, NULL, 2); Result: num_nonnulls------------ 1 1 row) (
Mathematics functions
It provides various functions related to numbers, and the argument specified as dp indicates double precision.
abs(x)
Returns absolute value of the argument.SELECT abs(-17.4); Result:abs ----- 17.4 1 row) (
cbrt(dp)
Returns cube root of the argument.SELECT cbrt(27.0); Result: cbrt------ 3 1 row) (
ceil(dp or numeric) or ceiling(dp or numeric)
Returns nearest integer greater than or equal to argument.SELECT ceil(-42.8); Result:ceil ------ -42 1 row) (
degrees(dp)
Converts radians to degrees.SELECT degrees(0.5); Result: degrees ------------------ 28.6478897565412 1 row) (
div(y numeric, x numeric)
Returns integer quotient of y/x.SELECT div(9,4); Result: div----- 2 1 row) (
exp(dp or numeric)
Returns exponential.SELECT exp(1.0); Result:exp -------------------- 2.7182818284590452 1 row) (
floor(dp or numeric)
Returns nearest integer less than or equal to the argument.SELECT floor(-42.8); Result:floor ------- -43 1 row) (
ln(dp or numeric)
Returns natural logarithm of the argument.SELECT ln(2.0); Result:ln ------------------- 0.693147180559945 1 row) (
log(dp or numeric)
Returns base 10 logarithm.SELECT log(100.0); Result:log -------------------- 2.0000000000000000 1 row) (
log(b numeric, x numeric)
Returns logarithm to base b.SELECT log(2.0, 64.0); Result:log -------------------- 6.0000000000000000 1 row) (
mod(y, x)
Returns remainder of y/x.SELECT mod(9,4); Result:mod ----- 1 1 row) (
pi()
Returns “π” constant.SELECT pi(); Result: pi------------------ 3.14159265358979 1 row) (
power(a dp, b dp) or power(a numeric, b numeric)
Returns a raised to the power of b.SELECT power(9.0, 3.0); Result:power -------------------- 729.00000000000000 1 row) (
radians(dp)
Converts degrees to radians.SELECT radians(45.0); Result: radians ------------------- 0.785398163397448 1 row) (
round(dp or numeric)
Rounds to nearest integer.SELECT round(42.4); Result:round ------- 42 1 row) (
round(v numeric, s int)
Rounds to s decimal places of v argument.SELECT round(42.4382, 2); Result:round ------- 42.44 1 row) (
scale(numeric)
Returns scale of the argument.SELECT scale(8.41); Result: scale------- 2 1 row) (
sign(dp or numeric)
Returns the sign (-1, 0, 1) of the argument.SELECT sign(-8.4); Result:sign ------ -1 1 row) (
sqrt(dp or numeric)
Returns square root of the argument.SELECT sqrt(2.0); Result:sqrt ------------------- 1.414213562373095 1 row) (
trunc(dp or numeric)
Truncates toward zero.SELECT trunc(42.8); Result:trunc ------- 42 1 row) (
trunc(v numeric, s int)
Truncates to s decimal places.SELECT trunc(42.4382, 2); Result:trunc ------- 42.43 1 row) (
width_bucket(operand dp, b1 dp, b2 dp, count int) or width_bucket(operand numeric, b1 numeric, b2 numeric, count int)
Returns the bucket number to which operand would be assigned in a histogram having count equal-width buckets spanning the range b1 to b2; returns 0 or count+1 for an input outside the range.SELECT width_bucket(5.35, 0.024, 10.06, 5); Result:width_bucket -------------- 3 1 row) (
width_bucket(operand anyelement, thresholds anyarray)
Returns the bucket number to which operand would be assigned given an array listing the lower bounds of the buckets; returns 0 for an input less than the first lower bound; the thresholds array must be sorted, smallest first.SELECT width_bucket(now(), array['yesterday', 'today', 'tomorrow']::timestamptz[]); Result:width_bucket -------------- 2 1 row) (
String functions
ascii(string)
ASCII code of the first character of the argument. For UTF8 returns the Unicode code point of the character. For other multibyte encodings, the argument must be an ASCII character.SELECT ascii('x'); Result:ascii ------- 120 1 row) (
btrim(string text [, characters text])
Removes the longest string consisting only of characters in characters (a space by default) from the start and end of string.SELECT btrim('xyxtrimyyx', 'xyz'); Result: btrim------- trim 1 row) (
chr(int)
Character with the given code. For UTF8 the argument is treated as a Unicode code point. For other multibyte encodings, the argument must designate an ASCII character. The NULL (0) character is not allowed because text data types cannot store such bytes.SELECT chr(65); Result:chr ----- A1 row) (
concat(str “any” [, str “any” [, …] ])
Concatenates the text representations of all the arguments. NULL arguments are ignored.SELECT concat('abcde', 2, NULL, 22); Result:concat ---------- abcde2221 row) (
concat_ws(sep text, str “any” [, str “any” [, …] ])
Concatenates all but the first argument with separators. The first argument is used as the separator string. NULL arguments are ignored.SELECT concat_ws(',', 'abcde', 2, NULL, 22); Result: concat_ws------------ 2,22 abcde,1 row) (
convert(string bytea, src_encoding name, dest_encoding name)
Converts string to dest_encoding. The original encoding is specified by src_encoding. The string must be valid in this encoding. Conversions can be defined by CREATE CONVERSION. Also, there are some predefined conversions. See this link for available conversions.SELECT convert('text_in_utf8', 'UTF8', 'LATIN1'); Result:convert ---------------------------- x746578745f696e5f757466381 row) (
convert_from(string bytea, src_encoding name)
Converts string to the database encoding. The original encoding is specified by src_encoding. The string must be valid in this encoding.SELECT convert_from('text_in_utf8', 'UTF8'); Result: convert_from-------------- by the current database encoding) text_in_utf8 (A string represented 1 row) (
convert_to(string text, dest_encoding name)
Converts string to dest_encoding.SELECT convert_to('some text', 'UTF8'); Result: convert_to---------------------- x736f6d6520746578741 row) (
decode(string text, format text)
Decodes binary data from textual representation in string. Options for format are same as inencode
.SELECT decode('MTIzAAE=', 'base64'); Result:decode -------------- x31323300011 row) (
encode(data bytea, format text)
Encode binary data into a textual representation. Supported formats are:base64
,hex
,escape
.escape
converts zero bytes and high-bit-set bytes to octal sequences (\nnn
) and doubles backslashes.SELECT encode(E'123\\000\\001', 'base64'); Result: encode---------- = MTIzAAE1 row) (
format(formatstr text [, formatarg “any” [, …] ])
Formats arguments according to a format string. This function is similar to the C functionsprintf
.SELECT format('Hello %s, %1$s', 'World'); Result: format-------------------- Hello World, World1 row) (
initcap(string)
Converts the first letter of each word to upper case and the rest to lower case. Words are sequences of alphanumeric characters separated by non-alphanumeric characters.SELECT initcap('hi THOMAS'); Result:initcap ----------- Hi Thomas1 row) (
length(string)
Returns the number of characters in string.SELECT length('jose'); Result:length -------- 4 1 row) (
length(string bytea, encoding name)
Returns the number of characters in string in the given encoding. The string must be valid in this encoding.SELECT length('jose', 'UTF8'); Result:length -------- 4 1 row) (
lpad(string text, length int [, fill text])
Fills up the string to length length by prepending the characters fill (a space by default). If the string is already longer than length then it is truncated (on the right).SELECT lpad('hi', 5, 'xy'); Result:lpad ------- xyxhi1 row) (
ltrim(string text [, characters text])
Removes the longest string containing only characters from characters (a space by default) from the start of string.SELECT ltrim('zzzytest', 'xyz'); Result:ltrim ------- test1 row) (
md5(string)
Calculates the MD5 hash of string, returning the result in hexadecimal.SELECT md5('abc'); Result: md5---------------------------------- 900150983cd24fb0d6963f7d28e17f721 row) (
parse_ident(qualified_identifier text [, strictmode boolean DEFAULT true])
Splits qualified_identifier into an array of identifiers, removing any quoting of individual identifiers. By default, extra characters after the last identifier are considered an error; but if the second parameter isfalse
, then such extra characters are ignored. (This behavior is useful for parsing names for objects like functions). Note that this function does not truncate over-length identifiers. If you want truncation you can cast the result toname[]
.SELECT parse_ident('"SomeSchema".someTable'); Result: parse_ident------------------------ {SomeSchema,sometable}1 row) (
pg_client_encoding()
Returns current client encoding name.SELECT pg_client_encoding(); Result: pg_client_encoding-------------------- SQL_ASCII1 row) (
quote_ident(string text)
Returns the given string suitably quoted to be used as an identifier in an SQL statement string. Quotes are added only if necessary (i.e., if the string contains non-identifier characters or would be case-folded). Embedded quotes are properly doubled.SELECT quote_ident('Foo bar'); Result: quote_ident------------- "Foo bar" 1 row) (
quote_literal(string text)
Returns the given string suitably quoted to be used as a string literal in a statement string. Embedded single-quotes and backslashes are properly doubled. Note thatquote_literal
returns null on null input; if the argument might be null,quote_nullable
is often more suitable.SELECT quote_literal(E'O\'Reilly'); Result: quote_literal --------------- 'O''Reilly' (1 row)
quote_literal(value anyelement)
Coerces the given value to text and then quote it as a literal. Embedded single-quotes and backslashes are properly doubled.SELECT quote_literal(42.5); Result: quote_literal--------------- '42.5' 1 row) (
quote_nullable(string text)
Returns the given string suitably quoted to be used as a string literal in an statement string; or, if the argument is null, returnNULL
. Embedded single-quotes and backslashes are properly doubled.SELECT quote_nullable(NULL); Result: quote_nullable--------------- NULL 1 row) (
quote_nullable(value anyelement)
Coerces the given value to text and then quote it as a literal; or, if the argument is null, returnNULL
. Embedded single-quotes and backslashes are properly doubled.SELECT quote_nullable(42.5); Result: quote_nullable---------------- '42.5' 1 row) (
regexp_matches(string text, pattern text [, flags text])
Returns captured substring(s) resulting from the first match of a POSIX regular expression to the string.SELECT regexp_matches('foobarbequebaz', '(bar)(beque)'); Result: regexp_matches---------------- {bar,beque}1 row) (
regexp_replace(string text, pattern text, replacement text [, flags text])
Replaces substring(s) matching a POSIX regular expression.SELECT regexp_replace('Thomas', '.[mN]a.', 'M'); Result:regexp_replace ---------------- ThM1 row) (
regexp_split_to_array(string text, pattern text [, flags text])
Splits string using a POSIX regular expression as the delimiter.SELECT regexp_split_to_array('hello world', E'\\s+'); Result: regexp_split_to_array----------------------- {hello,world}1 row) (
regexp_split_to_table(string text, pattern text [, flags text])
Splits string using a POSIX regular expression as the delimiter.SELECT regexp_split_to_table('hello world', E'\\s+'); Result: regexp_split_to_array----------------------- hello world2 rows) (
repeat(string text, number int)
Repeats string the specified number of times.SELECT repeat('Pg', 4); Result: repeat---------- PgPgPgPg1 row) (
replace(string text, from text, to text)
Replaces all occurrences in string of substring from with substring to.SELECT replace('abcdefabcdef', 'cd', 'XX'); Result:replace -------------- abXXefabXXef1 row) (
reverse(str)
Return reversed string.SELECT reverse('abcde'); Result:reverse --------- edcba1 row) (
right(str text, n int)
Returns last n characters in the string. When n is negative, it returns all but first |n| characters.SELECT right('abcde', 2); Result:right ------- de1 row) (
rpad(string text, length int [, fill text])
Fills up the string to length by appending the characters fill (a space by default). If the string is already longer than length then it is truncated.SELECT rpad('hi', 5, 'xy'); Result:rpad ------- hixyx1 row) (
rtrim(string text [, characters text])
Removes the longest string containing only characters from characters (a space by default) from the end of string.SELECT rtrim('testxxzx', 'xyz'); Result:rtrim ------- test1 row) (
split_part(string text, delimiter text, field int)
Splits string on delimiter and return the given field (counting from one).SELECT split_part('abc~@~def~@~ghi', '~@~', 2); Result: split_part------------ def1 row) (
strpos(string, substring)
Location of specified substring (same as position (substring in string), but note the reversed argument order).SELECT strpos('high', 'ig'); Result: strpos-------- 2 1 row) (
substr(string, from [, count])
Extracts substring (same assubstring
(string from from for count)).SELECT substr('alphabet', 3, 2); Result:substr -------- ph1 row) (
to_ascii(string text [, encoding text])
Converts string to ASCII from another encoding (only supports conversion fromLATIN1
,LATIN2
,LATIN9
, andWIN1250
encodings).SELECT to_ascii('Karel'); Result: to_ascii---------- Karel1 row) (
to_hex(number int or bigint)
Converts a number to its equivalent hexadecimal representation.SELECT to_hex(2147483647); Result: to_hex---------- 7fffffff1 row) (
translate(string text, from text, to text)
Any character in the string that matches a character in the from set is replaced by the corresponding character in the to set. If from is longer than to, occurrences of the extra characters in from are removed.SELECT translate('12345', '143', 'ax'); Result:translate ----------- a2x51 row) (
Binary String functions
Defines some string functions that use key words, rather than commas, to separate arguments.
octet_length(string)
Returns the number of bytes in binary string.SELECT octet_length(E'jo\\000se'::bytea); Result: octet_length-------------- 5 1 row) (
overlay(string placing string from int [for int])
Replaces substring.SELECT overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea FROM 2 for 3); Result: overlay---------------- x5402036d61731 row) (
position(substring in string)
Returns the location of specified substring.SELECT position(E'\\000om'::bytea in E'Th\\000omas'::bytea); Result: position---------- 3 1 row) (
substring(string [from int] [for int])
Extracts substring.SELECT substring(E'Th\\000omas'::bytea FROM 2 for 3); Result: substring----------- x68006f1 row) (
trim([both] bytes from string)
Removes the longest string containing only bytes appearing in bytes from the start and end of string.SELECT trim(E'\\000\\001'::bytea FROM E'\\000Tom\\001'::bytea); Result:trim ---------- x546f6d1 row) (
btrim(string bytea, bytes bytea)
Removes the longest string containing only bytes appearing in bytes from the start and end of string.SELECT btrim(E'\\000trim\\001'::bytea, E'\\000\\001'::bytea); Result: btrim------------ x7472696d1 row) (
decode(string text, format text)
Decodes binary data from textual representation in string. Options for format are same as inencode
.SELECT decode(E'123\\000456', 'escape'); Result:decode ------------------ x313233003435361 row) (
encode(data bytea, format text)
Encodes binary data into a textual representation. Supported formats are:base64
,hex
,escape
.escape
converts zero bytes and high-bit-set bytes to octal sequences (\nnn
) and doubles backslashes.SELECT encode(E'123\\000456'::bytea, 'escape'); Result: encode------------ 123\000456 1 row) (
get_bit(string, offset)
Extracts bit from string.SELECT get_bit(E'Th\\000omas'::bytea, 45); Result: get_bit--------- 1 1 row) (
get_byte(string, offset)
Extract byte from string.SELECT get_byte(E'Th\\000omas'::bytea, 4); Result: get_byte---------- 109 1 row) (
length(string)
Returns the length of binary string.SELECT length(E'jo\\000se'::bytea); Result:length -------- 5 1 row) (
md5(string)
Calculates the MD5 hash of string, returning the result in hexadecimal.SELECT md5(E'Th\\000omas'::bytea); Result: md5---------------------------------- 8ab2d3c9689aaf18b4958c334c82d8b11 row) (
set_bit(string, offset, newvalue)
Returns the set bit in string.SELECT set_bit(E'Th\\000omas'::bytea, 45, 0); Result: set_bit------------------ x5468006f6d41731 row) (
set_byte(string, offset, newvalue)
Returns the set byte in string.SELECT set_byte(E'Th\\000omas'::bytea, 4, 64); Result: set_byte------------------ x5468006f4061731 row) (
Date Type Formatting functions
The formatting functions provide a powerful set of tools for converting various data types (date/time, integer, floating point, and numeric to formatted strings and for converting from formatted strings to specific data types. These functions all follow a common calling convention: the first argument is the value to be formatted and the second argument is a template that defines the output or input format.
to_char(timestamp, text)
Converts timestamp to string.SELECT to_char(current_timestamp, 'HH12:MI:SS'); Result:to_char ---------- 04:56:02 1 row) (
to_char(interval, text)
Converts interval to string.SELECT to_char(interval '15h 2m 12s', 'HH24:MI:SS'); Result:to_char ---------- 15:02:12 1 row) (
to_char(int, text)
Converts integer to string.SELECT to_char(125, '999'); Result:to_char ---------- 125 1 row) (
to_char(double precision, text)
Converts real/double precision to string.SELECT to_char(125.8::real, '999D9'); Result:to_char ---------- 125.8 1 row) (
to_char(numeric, text)
Converts numeric to string.SELECT to_char(-125.8, '999D99S'); Result:to_char ---------- 125.80- 1 row) (
to_date(text, text)
Converts string to date.SELECT to_date('05 Dec 2000', 'DD Mon YYYY'); Result:to_date ------------ 2000-12-05 1 row) (
to_number(text, text)
Converts string to numeric.SELECT to_number('12,454.8-', '99G999D9S'); Result:to_number ----------- -12454.8 1 row) (
to_timestamp(text, text)
Converts string to timestamp.SELECT to_timestamp('05 Dec 2000', 'DD Mon YYYY'); Result:to_timestamp ------------------------ 2000-12-05 00:00:00+09 1 row) (
Date/Time functions
All the functions and operators described below that take the time or timestamp inputs actually come in two variants: one that takes time with time zone or timestamp with time zone, and one that takes time without time zone or timestamp without a time zone. For brevity, these variants are not shown separately. Also, + and * operators come in commutative pairs (for example both date + integer and integer + date); we show only one of each such pair.
age(timestamp, timestamp)
Subtracts arguments, producing a result that uses years and months, rather than just days.SELECT age(timestamp '2001-04-10', timestamp '1957-06-13'); Result: age------------------------- 43 years 9 mons 27 days 1 row) (
age(timestamp)
Subtracts from current_date (at midnight).SELECT age(timestamp '1957-06-13'); Result: age------------------------- 60 years 3 mons 15 days 1 row) (
clock_timestamp()
Returns current date and time (changes during statement execution).SELECT clock_timestamp(); Result: clock_timestamp------------------------------- 2017-09-28 17:47:31.208076+09 1 row) (
current_date
Returns current date.SELECT current_date; Result:date ------------ 2017-09-28 1 row) (
current_time
Returns current time of day.SELECT current_time; Result: timetz-------------------- 17:53:23.972231+09 1 row) (
current_timestamp
Returns current date and time.SELECT current_timestamp; Result: now------------------------------- 2017-09-28 18:01:43.890977+09 1 row) (
date_part(text, timestamp)
Returns subfield specified in text.SELECT date_part('hour', timestamp '2001-02-16 20:38:40'); Result: date_part----------- 20 1 row) (
date_part(text, interval)
Returns subfield specified in text.SELECT date_part('month', interval '2 years 3 months'); Result: date_part----------- 3 1 row) (
date_trunc(text, timestamp)
Truncates to specified precision.SELECT date_trunc('hour', timestamp '2001-02-16 20:38:40'); Result: date_trunc--------------------- 2001-02-16 20:00:00 1 row) (
date_trunc(text, interval)
Truncates to specified precision.SELECT date_trunc('hour', interval '2 days 3 hours 40 minutes'); Result: date_trunc----------------- 2 days 03:00:00 1 row) (
extract(field from timestamp)
Extracts the specified field.SELECT extract(hour FROM timestamp '2001-02-16 20:38:40'); Result: date_part----------- 20 1 row) (
extract(field from interval)
Extracts the specified field.SELECT extract(month FROM interval '2 years 3 months'); Result: date_part----------- 3 1 row) (
isfinite(date)
Returns the result of testing whether the input argument is finite (no +/- infinite).SELECT isfinite(date '2001-02-16'); Result: isfinite---------- t1 row) (
isfinite(timestamp)
Returns the result of testing whether the input argument is finite (no +/- infinite).SELECT isfinite(timestamp '2001-02-16 21:28:30'); Result: isfinite---------- t1 row) (
isfinite(interval)
Returns the result of testing whether the input argument is finite.SELECT isfinite(interval '4 hours'); Result: isfinite---------- t1 row) (
justify_days(interval)
Adjusts interval so 30-day time periods are represented as months.SELECT justify_days(interval '35 days'); Result: justify_days-------------- 1 mon 5 days 1 row) (
justify_hours(interval)
Adjusts interval so 24-hour time periods are represented as days.SELECT justify_hours(interval '27 hours'); Result: justify_hours---------------- 1 day 03:00:00 1 row) (
justify_interval(interval)
Adjusts interval using justify_days and justify_hours, with additional sign adjustments.SELECT justify_interval(interval '1 mon -1 hour'); Result: justify_interval------------------ 29 days 23:00:00 1 row) (
localtime
Returns current time of day.SELECT localtime; Result:time ---------------- 11:27:04.72722 1 row) (
localtimestamp
Returns current date and time (start of current transaction).SELECT localtimestamp; Result:timestamp ---------------------------- 2017-09-29 11:29:52.230028 1 row) (
make_date(year int, month int, day int)
Creates date from year, month and day fields.SELECT make_date(2013, 7, 15); Result: make_date------------ 2013-07-15 1 row) (
make_interval(years int DEFAULT 0, months int DEFAULT 0, weeks int DEFAULT 0, days int DEFAULT 0, hours int DEFAULT 0, mins int DEFAULT 0, secs double precision DEFAULT 0.0)
Creates interval from years, months, weeks, days, hours, minutes and seconds fields.SELECT make_interval(days => 10); Result: make_interval--------------- 10 days 1 row) (
make_time(hour int, min int, sec double precision)
Creates time from hour, minute and seconds fields.SELECT make_time(8, 15, 23.5); Result: make_time------------ 08:15:23.5 1 row) (
make_timestamp(year int, month int, day int, hour int, min int, sec double precision)
Creates timestamp from year, month, day, hour, minute and seconds fields.SELECT make_timestamp(2013, 7, 15, 8, 15, 23.5); Result: make_timestamp----------------------- 2013-07-15 08:15:23.5 1 row) (
make_timestamptz(year int, month int, day int, hour int, min int, sec double precision, [ timezone text ])
Creates timestamp with time zone from year, month, day, hour, minute and seconds fields; if timezone is not specified, the current time zone is used.SELECT make_timestamptz(2013, 7, 15, 8, 15, 23.5); Result: make_timestampz-------------------------- 2013-07-15 08:15:23.5+01 1 row) (
now()
Returns current date and time (start of current transaction).SELECT now(); Result: now ------------------------------- 2017-10-11 16:09:51.154262+09 1 row) (
statement_timestamp()
Returns current date and time.SELECT statement_timestamp(); Result: statement_timestamp ------------------------------- 2017-10-11 16:08:59.641426+09 1 row) (
timeofday()
Returns current date and time.SELECT timeofday(); Result: timeofday ------------------------------------- 11 16:09:26.934061 2017 KST Wed Oct 1 row) (
transaction_timestamp()
Returns current date and time.SELECT transaction_timestamp(); Result: transaction_timestamp ------------------------------- 2017-10-11 16:10:21.530521+09 1 row) (
to_timestamp(double precision)
Converts Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp.SELECT to_timestamp(1284352323); Result:to_timestamp ------------------------ 2010-09-13 13:32:03+09 1 row) (
Enum Support functions
For enum types, there are several functions that allow cleaner programming without hard-coding particular values of an enum type.
To execute the example in the function description, create an enum type as shown below first.
CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
enum_first(anyenum)
Returns the first value of the input enum type.SELECT enum_first(null::rainbow); Result: enum_first ------------ red1 row) (
enum_last(anyenum)
Returns the last value of the input enum type.SELECT enum_last(null::rainbow); Result: enum_last----------- purple1 row) (
enum_range(anyenum)
Returns all values of the input enum type in an ordered array.SELECT enum_range(null::rainbow); Result: enum_range --------------------------------------- {red,orange,yellow,green,blue,purple}1 row) (
enum_range(anyenum, anyenum)
Returns the range between the two given enum values, as an ordered array. The values must be from the same enum type. If the first parameter is null, the result will start with the first value of the enum type. If the second parameter is null, the result will end with the last value of the enum type.SELECT enum_range('orange'::rainbow, 'green'::rainbow); Result: enum_range----------------------- {orange,yellow,green}1 row) ( SELECT enum_range(NULL, 'green'::rainbow); Result: enum_range--------------------------- {red,orange,yellow,green}1 row) ( SELECT enum_range('orange'::rainbow, NULL); Result: enum_range----------------------------------- {orange,yellow,green,blue,purple}1 row) (
Geometric Functions
area(object)
Returns area.SELECT area(box '((0,0),(1,1))'); Result: area------ 1 1 row) (
center(object)
Returns the center coordinates of object.SELECT center(box '((0,0),(1,2))'); Result: center-------- 0.5,1) (1 row) (
diameter(circle)
Returns the diameter of circle.SELECT diameter(circle '((0,0),2.0)'); Result: diameter---------- 4 1 row) (
height(box)
Returns the vertical size of box.SELECT height(box '((0,0),(1,1))'); Result: height-------- 1 1 row) (
isclosed(path)
Returns a logical value indicating whether the input path is a closed path.SELECT isclosed(path '((0,0),(1,1),(2,0))'); Result: isclosed---------- t1 row) (
isopen(path)
Returns a logical value indicating whether the input path is an open path.SELECT isopen(path '[(0,0),(1,1),(2,0)]'); Result: isopen-------- t1 row) (
length(object)
Returns length of the path.SELECT length(path '((-1,0),(1,0))'); Result:length -------- 4 1 row) (
npoints(path)
Returns the number of points of the input path.SELECT npoints(path '[(0,0),(1,1),(2,0)]'); Result: npoints--------- 3 1 row) (
npoints(polygon)
Returns the number of polygon points.SELECT npoints(polygon '((1,1),(0,0))'); Result: npoints--------- 2 1 row) (
pclose(path)
Converts the input path to closed.SELECT pclose(path '[(0,0),(1,1),(2,0)]'); Result: pclose --------------------- 0,0),(1,1),(2,0)) ((1 row) (
popen(path)
Converts the input path to open.SELECT popen(path '((0,0),(1,1),(2,0))'); Result: popen --------------------- 0,0),(1,1),(2,0)] [(1 row) (
radius(circle)
Returns the radius of circle.SELECT radius(circle '((0,0),2.0)'); Result: radius -------- 2 1 row) (
width(box)
Returns the radius of circle.SELECT width(box '((0,0),(1,1))'); Result: width ------- 1 1 row) (
box(circle)
Returns a box circumscribed about circle.SELECT box(circle '((0,0),2.0)'); Result: box --------------------------------------------------------------------------- 1.41421356237309,1.41421356237309),(-1.41421356237309,-1.41421356237309) (1 row) (
box(point)
Returns a box whose width is zero (empty box) centered on the input point.SELECT box(point '(0,0)'); Result: box ------------- 0,0),(0,0) (1 row) (
box(point, point)
Returns a box whose vertices are the two input points.SELECT box(point '(0,0)', point '(1,1)'); Result: box ------------- 1,1),(0,0) (1 row) (
box(polygon)
Returns a box circumscribed about polygon.SELECT box(polygon '((0,0),(1,1),(2,0))'); Result: box ------------- 2,1),(0,0) (1 row) (
bound_box(box, box)
Returns the smallest box that contains the two boxes entered.SELECT bound_box(box '((0,0),(1,1))', box '((3,3),(4,4))'); Result: bound_box ------------- 4,4),(0,0) (1 row) (
circle(box)
Returns a circle circumscribed about box.SELECT circle(box '((0,0),(1,1))'); Result: circle ------------------------------- <(0.5,0.5),0.707106781186548> 1 row) (
circle(point, double precision)
Returns the circle created using the center coordinates and radius of the input circle.SELECT circle(point '(0,0)', 2.0); Result: circle ----------- <(0,0),2> 1 row) (
circle(polygon)
Returns a circle with the average of the input coordinate pairs as the center of the circle and the average distance from the point to the input coordinate pair as the radius.SELECT circle(polygon '((0,0),(1,1),(2,0))'); Result: circle ------------------------------------------- <(1,0.333333333333333),0.924950591148529> 1 row) (
line(point, point)
Returns the value of the line.SELECT line(point '(-1,0)', point '(1,0)'); Result: line ---------- 0,-1,0} {1 row) (
lseg(box)
Returns box diagonal to line segment.SELECT lseg(box '((-1,0),(1,0))'); Result: lseg ---------------- 1,0),(-1,0)] [(1 row) (
lseg(point, point)
Returns a line segment with two input points taken as start and end points.SELECT lseg(point '(-1,0)', point '(1,0)'); Result: lseg ---------------- 1,0),(-1,0)] [(1 row) (
path(polygon)
Returns a polygon path.SELECT path(polygon '((0,0),(1,1),(2,0))'); Result: path --------------------- 0,0),(1,1),(2,0)) ((1 row) (
point(double precision, double precision)
Returns the value that construct the point.SELECT point(23.4, -44.5); Result: point -------------- 23.4,-44.5) (1 row) (
point(box)
Returns center of box.SELECT point(box '((-1,0),(1,0))'); Result: point ------- 0,0) (1 row) (
point(circle)
Returns center of circle.SELECT point(circle '((0,0),2.0)'); Result: point ------- 0,0) (1 row) (
point(lseg)
Returns center of line segment.SELECT point(lseg '((-1,0),(1,0))'); Result: point ------- 0,0) (1 row) (
point(polygon)
Returns center of polygon.SELECT point(polygon '((0,0),(1,1),(2,0))'); Result: point ----------------------- 1,0.333333333333333) (1 row) (
polygon(box)
Returns box to 4-point polygon.SELECT polygon(box '((0,0),(1,1))'); Result: polygon --------------------------- 0,0),(0,1),(1,1),(1,0)) ((1 row) (
polygon(circle)
Returns circle to 12-point polygon.SELECT polygon(circle '((0,0),2.0)'); Result: polygon ----------------------------------------------------------------------------------------- -2,0),(-1.73205080756888,1),(-1,1.73205080756888),(-1.22464679914735e-16,2), ((1,1.73205080756888),(1.73205080756888,1),(2,2.44929359829471e-16), (1.73205080756888,-0.999999999999999),(1,-1.73205080756888),(3.67394039744206e-16,-2), (-0.999999999999999,-1.73205080756888),(-1.73205080756888,-1)) (1 row) (
polygon(npts, circle)
Returns circle to npts-point polygon.SELECT polygon(12, circle '((0,0),2.0)'); polygon ----------------------------------------------------------------------------------------- -2,0),(-1.73205080756888,1),(-1,1.73205080756888),(-1.22464679914735e-16,2), ((1,1.73205080756888),(1.73205080756888,1),(2,2.44929359829471e-16), (1.73205080756888,-0.999999999999999),(1,-1.73205080756888),(3.67394039744206e-16,-2), (-0.999999999999999,-1.73205080756888),(-1.73205080756888,-1)) (1 row) (
polygon(path)
Converts path into a polygon.SELECT polygon(path '((0,0),(1,1),(2,0))'); Result: polygon --------------------- 0,0),(1,1),(2,0)) ((1 row) (
Network Address Functions
abbrev(inet)
Returns abbreviated display format as text.SELECT abbrev(inet '10.1.0.0/16'); Result: abbrev ------------- 10.1.0.0/16 1 row) (
abbrev(cidr)
Returns abbreviated display format as text.SELECT abbrev(cidr '10.1.0.0/16'); Result: abbrev --------- 10.1/16 1 row) (
broadcast(inet)
Returns broadcast address for network.SELECT broadcast('192.168.1.5/24'); Result:broadcast ------------------ 192.168.1.255/24 1 row) (
family(inet)
Extracts family of address; 4 for IPv4, 6 for IPv6.SELECT family('::1'); Result: family -------- 6 1 row) (
host(inet)
Extracts IP address as text.SELECT host('192.168.1.5/24'); Result: host ------------- 192.168.1.5 1 row) (
hostmask(inet)
Constructs host mask for network.SELECT hostmask('192.168.23.20/30'); Result: hostmask ---------- 0.0.0.3 1 row) (
masklen(inet)
Extracts netmask length.SELECT masklen('192.168.1.5/24'); Result: masklen --------- 24 1 row) (
netmask(inet)
Constructs netmask for network.SELECT netmask('192.168.1.5/24'); Result: netmask --------------- 255.255.255.0 1 row) (
network(inet)
Extracts network part of address.SELECT network('192.168.1.5/24'); Result:network ---------------- 192.168.1.0/24 1 row) (
set_masklen(inet, int)
Returns the set netmask length for inet value.SELECT set_masklen('192.168.1.5/24', 16); Result: set_masklen ---------------- 192.168.1.5/16 1 row) (
set_masklen(cidr, int)
Returns the set netmask length for cidr value.SELECT set_masklen('192.168.1.0/24'::cidr, 16); Result: set_masklen ---------------- 192.168.0.0/16 1 row) (
text(inet)
Returns IP address and netmask length as text.SELECT text(inet '192.168.1.5'); Result: text ---------------- 192.168.1.5/32 1 row) (
inet_same_family(inet, inet)
Returns a logical value indicating whether the address is a family value.SELECT inet_same_family('192.168.1.5/24', '::1'); Result: inet_same_family ------------------ f1 row) (
inet_merge(inet, inet)
Returns the smallest network which includes all of the entered networks.SELECT inet_merge('192.168.1.5/24', '192.168.2.5/24'); Result: inet_merge ---------------- 192.168.0.0/22 1 row) (
trunc(macaddr)
Sets the last 3 bytes to zero.SELECT trunc(macaddr '12:34:56:78:90:ab'); Result:trunc ------------------- 12:34:56:00:00:00 1 row) (
Text Search Functions
array_to_tsvector(text[])
Converts array of lexemes to tsvector.SELECT array_to_tsvector('{fat,cat,rat}'::text[]); Result: array_to_tsvector ------------------- 'cat' 'fat' 'rat' 1 row) (
get_current_ts_config()
Returns the default text search configuration.SELECT get_current_ts_config(); Result: get_current_ts_config ----------------------- english1 row) (
length(tsvector)
Returns number of lexemes in tsvector.SELECT length('fat:2,4 cat:3 rat:5A'::tsvector); Result:length -------- 3 1 row) (
numnode(tsquery)
Returns the number of lexemes plus operators in tsquery.SELECT numnode('(fat & rat) | cat'::tsquery); Result: numnode --------- 5 1 row) (
plainto_tsquery([ config regconfig , ] query text)
Produces tsquery ignoring punctuation.SELECT plainto_tsquery('english', 'The Fat Rats'); Result: plainto_tsquery ----------------- 'fat' & 'rat' 1 row) (
phraseto_tsquery([ config regconfig , ] query text)
Produces tsquery that searches for a phrase, ignoring punctuation.SELECT phraseto_tsquery('english', 'The Fat Rats'); Result: phraseto_tsquery ------------------ 'fat' <-> 'rat' 1 row) (
querytree(query tsquery)
Returns indexable part of a tsquery.SELECT querytree('foo & ! bar'::tsquery); Result: querytree ----------- 'foo' 1 row) (
setweight(vector tsvector, weight “char”)
Assigns weight to each element of vector.SELECT setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A'); Result: setweight ------------------------------- 'cat':3A 'fat':2A,4A 'rat':5A 1 row) (
setweight(vector tsvector, weight “char”, lexemes text[])
Assigns weight to elements of vector that are listed in lexemes.SELECT setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A', '{cat,rat}'); Result: setweight ----------------------------- 'cat':3A 'fat':2,4 'rat':5A 1 row) (
strip(tsvector)
Removes positions and weights fromtsvector
.SELECT strip('fat:2,4 cat:3 rat:5A'::tsvector); Result: strip ------------------- 'cat' 'fat' 'rat' 1 row) (
to_tsquery([ config regconfig , ] query text)
Normalizes words and converts totsquery
.SELECT to_tsquery('english', 'The & Fat & Rats'); Result: to_tsquery --------------- 'fat' & 'rat' 1 row) (
to_tsvector([ config regconfig , ] document text)
Reduce document text totsvector
.SELECT to_tsvector('english', 'The Fat Rats'); Result: to_tsvector ----------------- 'fat':2 'rat':3 1 row) (
ts_delete(vector tsvector, lexeme text)
Removes given lexeme from vector.SELECT ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat'); Result: ts_delete ------------------ 'cat':3 'rat':5A 1 row) (
ts_delete(vector tsvector, lexemes text[])
Removes any occurrence of lexemes in lexemes from vector.SELECT ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']); Result: ts_delete ----------- 'cat':3 1 row) (
ts_filter(vector tsvector, weights “char”[])
Selects only elements with given weights from vector.SELECT ts_filter('fat:2,4 cat:3b rat:5A'::tsvector, '{a,b}'); Result: ts_filter ------------------- 'cat':3B 'rat':5A 1 row) (
ts_headline([ config regconfig, ] document text, query tsquery [, options text ])
Displays a query match.SELECT ts_headline('x y z', 'z'::tsquery); Result: ts_headline -------------- <b>z</b> x y 1 row) (
ts_rank([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ])
Ranks documents for query.SELECT ts_rank(to_tsvector('This is an example of document'), to_tsquery('example')); Result: ts_rank ----------- 0.0607927 1 row) (
ts_rank_cd([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ])
Ranks documents for query using cover density.SELECT ts_rank_cd(to_tsvector('This is an example of document'), to_tsquery('example')); Result: ts_rank_cd ------------ 0.1 1 row) (
ts_rewrite(query tsquery, target tsquery, substitute tsquery)
Replaces target with substitute within query.SELECT ts_rewrite('a & b'::tsquery, 'a'::tsquery, 'foo|bar'::tsquery); Result: ts_rewrite ------------------------- 'b' & ( 'foo' | 'bar' ) 1 row) (
ts_rewrite(query tsquery, select text)
Replaces the first column value of the SELECT result with the second column value of the SELECT result.create table aliases (t tsquery primary key, s tsquery); insert into aliases values ('a', 'foo|bar'); SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases'); Result: ts_rewrite ------------------------- 'b' & ( 'bar' | 'foo' ) 1 row) (
tsquery_phrase(query1 tsquery, query2 tsquery)
Makes query that searches for query1 followed by query2 (same as <-> operator).SELECT tsquery_phrase(to_tsquery('fat'), to_tsquery('cat')); Result: tsquery_phrase ----------------- 'fat' <-> 'cat' 1 row) (
tsquery_phrase(query1 tsquery, query2 tsquery, distance integer)
Makes query that searches for query1 followed by query2 at distance distance.SELECT tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10); Result: tsquery_phrase ------------------ 'fat' <10> 'cat' 1 row) (
tsvector_to_array(tsvector)
Convertstsvector
to array of lexemes.SELECT tsvector_to_array('fat:2,4 cat:3 rat:5A'::tsvector); Result: tsvector_to_array ------------------- {cat,fat,rat} 1 row) (
tsvector_update_trigger()
Triggers the function for automatictsvector
column update.CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON messages FOR EACH ROW EXECUTE PROCEDURE 'pg_catalog.english', title, body); tsvector_update_trigger(tsv, INSERT INTO messages VALUES ('title here', 'the body text is here'); SELECT * FROM messages; Result:body | tsv title | ------------+-----------------------+---------------------------- the body text is here | 'bodi':4 'text':5 'titl':1 title here | 1 row) (
tsvector_update_trigger_column()
Triggers the function for automatictsvector
column update.CREATE TRIGGER ... tsvector_update_trigger_column(tsv, configcol, title, body);
unnest(tsvector, OUT lexeme text, OUT positions smallint[], OUT weights text)
Expands a tsvector to a set of rows.SELECT unnest('fat:2,4 cat:3 rat:5A'::tsvector); Result: unnest ----------------------- 3},{D}) (cat,{"{2,4}","{D,D}") (fat,5},{A}) (rat,{3 row) (
ts_debug([ config regconfig, ] document text, OUT alias text, OUT description text, OUT token text, OUT dictionaries regdictionary[], OUT dictionary regdictionary, OUT lexemes text[])
Tests a configuration.SELECT ts_debug('english', 'The Brightest supernovaes'); Result: ts_debug ----------------------------------------------------------------------------------- "Word, all ASCII",The,{english_stem},english_stem,{}) (asciiword,"Space symbols"," ",{},,) (blank,"Word, all ASCII",Brightest,{english_stem},english_stem,{brightest}) (asciiword,"Space symbols"," ",{},,) (blank,"Word, all ASCII",supernovaes,{english_stem},english_stem,{supernova}) (asciiword,5 row) (
ts_lexize(dict regdictionary, token text)
Tests a dictionary.SELECT ts_lexize('english_stem', 'stars'); Result: ts_lexize ----------- {star}1 row) (
ts_parse(parser_name text, document text, OUT tokid integer, OUT token text)
Tests a parser.SELECT ts_parse('default', 'foo - bar'); Result: ts_parse ----------- 1,foo) (12," ") (12,"- ") (1,bar) (4 row) (
ts_parse(parser_oid oid, document text, OUT tokid integer, OUT token text)
Tests a parser with oid.SELECT ts_parse(3722, 'foo - bar'); Result: ts_parse ----------- 1,foo) (12," ") (12,"- ") (1,bar) (4 row) (
ts_token_type(parser_name text, OUT tokid integer, OUT alias text, OUT description text)
Gets token types defined by parser.SELECT ts_token_type('default'); Result: ts_token_type --------------------------------- 1,asciiword,"Word, all ASCII") (... 23 row) (
ts_token_type(parser_oid oid, OUT tokid integer, OUT alias text, OUT description text)
Gets token types defined by parser.SELECT ts_token_type(3722); Result: ts_token_type --------------------------------- 1,asciiword,"Word, all ASCII") (... 23 row) (
ts_stat(sqlquery text, [ weights text, ] OUT word text, OUT ndoc integer, OUT nentry integer)
Returns statistics of atsvector
column.SELECT ts_stat('SELECT vector FROM apod'); Result: ts_stat ------------ 10,15) (foo,... 4 row) (
JSON Functions
to_json(anyelement), to_jsonb(anyelement)
Returns the value asjson
orjsonb
. Arrays and composites are converted to arrays and objects; otherwise, if there is a cast from the type to json, the cast function will be used to perform the conversion or a scalar value is produced. For any scalar type other than a number, a Boolean, or a null value, the text representation will be used, in such a fashion that it is a validjson
orjsonb
value.SELECT to_json('Fred said "Hi."'::text); Result: to_json--------------------- "Fred said "Hi.\"" 1 row) (
array_to_json(anyarray [, pretty_bool])
Returns the array as a JSON array. Line feeds will be added between dimension-1 elements if returnspretty_bool
is true.SELECT array_to_json('{{1,5},{99,100}}'::int[]); Result: array_to_json ------------------ 1,5],[99,100]] [[1 row) ( SELECT array_to_json('{{1,5},{99,100}}'::int[], true); Result: array_to_json --------------- 1,5], + [[99,100]] [1 row) (
row_to_json(record [, pretty_bool])
Returns the row as a JSON object. Line feeds will be added between level-1 elements ifpretty_bool
is true.SELECT row_to_json(row(1,'foo')); Result: row_to_json --------------------- "f1":1,"f2":"foo"} {1 row) (
json_build_array(VARIADIC “any”), jsonb_build_array(VARIADIC “any”)
Builds a possibly-heterogeneously-typed JSON array out of a variable argument list.SELECT json_build_array(1,2,'3',4,5); Result: json_build_array ------------------- 1, 2, "3", 4, 5] [1 row) (
json_build_object(VARIADIC “any”), jsonb_build_object(VARIADIC “any”)
Builds a JSON object out of a variable argument list. By convention, the argument list consists of alternating keys and values.SELECT json_build_object('foo',1,'bar',2); Result: json_build_object ------------------------ "foo" : 1, "bar" : 2} {1 row) (
json_object(text[]), jsonb_object(text[])
Builds a JSON object out of a text array. The array must have either exactly one dimension with an even number of members, in which case they are taken as alternating key/value pairs, or two dimensions such that each inner array has exactly two elements, which are taken as a key/value pair.SELECT json_object('{a, 1, b, "def", c, 3.5}'); SELECT json_object('{{a, 1},{b, "def"},{c, 3.5}}'); Result: json_object --------------------------------------- "a" : "1", "b" : "def", "c" : "3.5"} {1 row) (
json_object(keys text[], values text[]), jsonb_object(keys text[], values text[])
This form ofjson_object
takes keys and values pairwise from two separate arrays. In all other respects it is identical to the one-argument form.SELECT json_object('{a, b}', '{1,2}'); Result: json_object ------------------------ "a" : "1", "b" : "2"} {1 row) (
json_array_length(json), jsonb_array_length(jsonb)
Returns the number of elements in the outermost JSON array.SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]'); Result: json_array_length ------------------- 5 1 row) (
json_each(json), jsonb_each(jsonb)
Expands the outermost JSON object into a set of key/value pairs.SELECT * FROM json_each('{"a":"foo", "b":"bar"}'); Result:key | value -----+------- "foo" a | "bar" b | 2 row) (
json_each_text(json), jsonb_each_text(jsonb)
Expands the outermost JSON object into a set of key/value pairs. The returned values will be of typetext
.SELECT * FROM json_each_text('{"a":"foo", "b":"bar"}'); Result:key | value -----+------- a | foo b | bar2 row) (
json_extract_path(from_json json, VARIADIC path_elems text[]), jsonb_extract_path(from_json jsonb, VARIADIC path_elems text[])
Returns JSON value pointed to bypath_elems
(equivalent to#>
operator).SELECT * FROM json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4'); Result: json_extract_path ---------------------- "f5":99,"f6":"foo"} {1 row) (
json_extract_path_text(from_json json, VARIADIC path_elems text[]), jsonb_extract_path_text(from_json jsonb, VARIADIC path_elems text[])
Returns JSON value pointed to bypath_elems
astext
(equivalent to#>>
operator).SELECT json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6'); Result: json_extract_path_text ------------------------ foo1 row) (
json_object_keys(json), jsonb_object_keys(jsonb)
Returns set of keys in the outermost JSON object.SELECT json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}'); Result: json_object_keys ------------------ f1 f22 row) (
json_populate_record(base anyelement, from_json json), jsonb_populate_record(base anyelement, from_json jsonb)
Expands the object infrom_json
to a row whose columns match the record type defined bybase
.CREATE TABLE myrowtype (a int, b int); SELECT * FROM json_populate_record(null::myrowtype, '{"a":1,"b":2}'); Result: a | b ---+--- 1 | 2 1 row) (
json_populate_recordset(base anyelement, from_json json), jsonb_populate_recordset(base anyelement, from_json jsonb)
Expands the outermost array of objects infrom_json
to a set of rows whose columns match the record type defined bybase
.SELECT * FROM json_populate_recordset(null::myrowtype, '[{"a":1,"b":2},{"a":3,"b":4}]'); Result: a | b ---+--- 1 | 2 3 | 4 2 row) (
json_array_elements(json), jsonb_array_elements(jsonb)
Expands a JSON array to a set of JSON values.SELECT * FROM json_array_elements('[1,true, [2,false]]'); Result: value ----------- 1 true 2,false]] [3 row) (
json_array_elements_text(json), jsonb_array_elements_text(jsonb)
Expands a JSON array to a set oftext
values.SELECT * FROM json_array_elements_text('["foo", "bar"]'); Result: value ------- foo bar2 row) (
json_typeof(json), jsonb_typeof(jsonb)
Returns the type of the outermost JSON value as a text string. Possible types areobject
,array
,string
,number
,boolean
, andnull
.SELECT json_typeof('-123.4'); Result: json_typeof ------------- number 1 row) (
json_to_record(json), jsonb_to_record(jsonb)
Builds an arbitrary record from a JSON object. As with all functions returningrecord
, the caller must explicitly define the structure of the record with anAS
clause.SELECT * FROM json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}') as x(a int, b text, d text); Result: a | b | d ---+---------+--- 1 | [1,2,3] | 1 row) (
json_to_recordset(json), jsonb_to_recordset(jsonb)
Builds an arbitrary set of records from a JSON array of objects. As with all functions returningrecord
, the caller must explicitly define the structure of the record with anAS
clause.SELECT * FROM json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text); Result: a | b ---+----- 1 | foo 2 | 2 row) (
json_strip_nulls(from_json json), jsonb_strip_nulls(from_json jsonb)
Returnsfrom_json
with all object fields that have null values omitted. Other null values are unchanged.SELECT json_strip_nulls('[{"f1":1,"f2":null},2,null,3]'); Result: json_strip_nulls --------------------- "f1":1},2,null,3] [{1 row) (
jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean])
Returnstarget
with the section designated bypath
replaced bynew_value
, or withnew_value
added
ifcreate_missing
is true (default istrue
) and the item designated bypath
does not exist. As with thepath
orientated operators, negative integers that appear in path count from the end of JSON arrays.SELECT jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false); Result: jsonb_set --------------------------------------------- "f1": [2, 3, 4], "f2": null}, 2, null, 3] [{1 row) ( SELECT jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}','[2,3,4]'); Result: jsonb_set --------------------------------------------- "f1": 1, "f2": null, "f3": [2, 3, 4]}, 2] [{1 row) (
jsonb_insert(target jsonb, path text[], new_value jsonb, [insert_after boolean])
Returns target withnew_value
inserted. If target section designated bypath
is in a JSONB array,new_value
will be inserted beforetarget
or after ifinsert_after
is true (default isfalse
). If target section designated bypath
is in JSONB object,new_value
will be inserted only iftarget
does not exist. As with thepath
orientated operators, negative integers that appear in path count from the end of JSON arrays.SELECT jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"'); Result: jsonb_insert ------------------------------- "a": [0, "new_value", 1, 2]} {1 row) ( SELECT jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true); Result: jsonb_insert ------------------------------- "a": [0, 1, "new_value", 2]} {1 row) (
jsonb_pretty(from_json jsonb)
Returnsfrom_json
as indented JSON text.SELECT jsonb_pretty('[{"f1":1,"f2":null},2,null,3]'); Result: jsonb_pretty -------------------- + [ + { "f1": 1, + "f2": null+ + }, 2, + null, + 3 + ]1 row) (
Sequence Manipulation Functions
This section describes functions for operating on sequences. Sequences can be created with CREATE SEQUENCE.
CREATE SEQUENCE serial increment by 1 start 101;
nextval(regclass)
Advances sequence and returns new value.SELECT nextval('serial'); Result: nextval --------- 101 1 row) (
currval(regclass)
Returns value most recently obtained withnextval
for specified sequence.SELECT currval('serial'); Result: currval --------- 101 1 row) (
lastval()
Returns value most recently obtained withnextval
for any sequence.SELECT lastval(); Result: lastval --------- 101 1 row) (
setval(regclass, bigint)
Sets sequence’s current value.SELECT setval('serial', 101); Result: setval -------- 101 1 row) (
setval(regclass, bigint, boolean)
Sets sequence’s current value andis_called
flag.-- true SELECT setval('serial', 101, true); Result: setval -------- 101 1 row) ( SELECT nextval('serial'); Result: nextval --------- 102 1 row) ( -- false SELECT setval('serial', 101, false); Result: setval -------- 101 1 row) ( SELECT nextval('serial'); Result: nextval --------- 101 1 row) (
Array Functions
array_append(anyarray, anyelement)
Appendsanyelement
to the end of an array.SELECT array_append(ARRAY[1,2], 3); Result: array_append -------------- 1,2,3} {1 row) (
array_cat(anyarray, anyarray)
Concatenates two arrays.SELECT array_cat(ARRAY[1,2,3], ARRAY[4,5]); Result: array_cat ------------- 1,2,3,4,5} {1 row) (
array_ndims(anyarray)
Returns the number of dimensions of the array.SELECT array_ndims(ARRAY[[1,2,3], [4,5,6]]); Result: array_ndims ------------- 2 1 row) (
array_dims(anyarray)
Returns a text representation of array’s dimensions.SELECT array_dims(ARRAY[[1,2,3], [4,5,6]]); Result: array_dims ------------ 1:2][1:3] [1 row) (
array_fill(anyelement, int[], [, int[]])
Returns an array initialized with optionally-supplied value and dimensions.SELECT array_fill(7, ARRAY[3], ARRAY[2]); Result: array_fill --------------- 2:4]={7,7,7} [1 row) (
array_length(anyarray, int)
Returns the length of the requested array dimension.SELECT array_length(array[1,2,3], 1); Result: array_length -------------- 3 1 row) (
array_lower(anyarray, int)
Returns the lower bound of the requested array dimension.SELECT array_lower('[0:2]={1,2,3}'::int[], 1); Result: array_lower ------------- 0 1 row) (
array_position(anyarray, anyelement [, int])
Returns the index of the first occurrence of the second argument in the array, starting at the element indicated by the third argument or at the first element (array must be one-dimensional).SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon'); Result: array_position ---------------- 2 1 row) (
array_positions(anyarray, anyelement)
Returns an array of indexes of all occurrences of the second argument in the array given as first argument (array must be one-dimensional).SELECT array_positions(ARRAY['A','A','B','A'], 'A'); Result: array_positions ----------------- 1,2,4} {1 row) (
array_prepend(anyelement, anyarray)
Appendsanyelement
to the beginning of an array.SELECT array_prepend(1, ARRAY[2,3]); Result: array_prepend --------------- 1,2,3} {1 row) (
array_remove(anyarray, anyelement)
Removes all elements equal to the given value from the array.SELECT array_remove(ARRAY[1,2,3,2], 2); Result: array_remove -------------- 1,3} {1 row) (
array_replace(anyarray, anyelement, anyelement)
Replaces each array element equal to the given value with a new value.SELECT array_replace(ARRAY[1,2,5,4], 5, 3); Result: array_replace --------------- 1,2,3,4} {1 row) (
array_to_string(anyarray, text [, text])
Concatenates array elements using specified delimiter and optional null string.SELECT array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*'); Result: array_to_string ----------------- 1,2,3,*,5 1 row) (
array_upper(anyarray, int)
Returns upper bound of the requested array dimension.SELECT array_upper(ARRAY[1,8,3,7], 1); Result: array_upper ------------- 4 1 row) (
cardinality(anyarray)
Returns the total number of elements in the array, or 0 if the array is empty.SELECT cardinality(ARRAY[[1,2],[3,4]]); Result:cardinality ------------- 4 1 row) (
string_to_array(text, text [, text])
Splits string into array elements using supplied delimiter and optional null string.SELECT string_to_array('xx~^~yy~^~zz', '~^~', 'yy'); Result: string_to_array ----------------- NULL,zz} {xx,1 row) (
unnest(anyarray)
Expands an array to a set of rows.SELECT unnest(ARRAY[1,2]); Result: unnest -------- 1 2 2 row) (
unnest(anyarray, anyarray [, …])
Expands multiple arrays (possibly of different types) to a set of rows. This is only allowed in the FROM clause.SELECT * FROM unnest(ARRAY[1,2],ARRAY['foo','bar','baz']); Result: unnest | unnest --------+-------- 1 | foo 2 | bar | baz 1 row) (
Range Functions and Operators
lower(anyrange)
Returns the lower bound of the input numeric range.SELECT * FROM lower(numrange(1.1,2.2)); Result: lower ------- 1.1 1 row) (
upper(anyrange)
Returns upper of the input numeric range.SELECT * FROM upper(numrange(1.1,2.2)); Result: upper ------- 2.2 1 row) (
isempty(anyrange)
Returns a boolean value indicating whether the entered number range is empty.SELECT * FROM isempty(numrange(1.1,2.2)); Result: isempty --------- f1 row) (
lower_inc(anyrange)
Returns whether the lower bound of the entered number range exists.SELECT * FROM lower_inc(numrange(1.1,2.2)); Result: lower_inc ----------- t1 row) (
upper_inc(anyrange)
Returns a logical value indicating whether the upper bound of the input numeral range exists.SELECT * FROM upper_inc(numrange(1.1,2.2)); Result: lower_inc ----------- f1 row) (
lower_inf(anyrange)
Returns a logical value indicating whether the lower bound of the entered number range is infinite.SELECT * FROM lower_inf('(,)'::daterange); Result: lower_inf ----------- t1 row) (
upper_inf(anyrange)
Returns a logical value indicating whether the upper bound of the entered number range is infinite.SELECT * FROM upper_inf('(,)'::daterange); Result: upper_inf ----------- t1 row) (
range_merge(anyrange, anyrange)
Returns the smallest range which includes both of the given ranges.SELECT * FROM range_merge('[1,2)'::int4range, '[3,4)'::int4range); Result: range_merge ------------- 1,4) [1 row) (
Aggregate Functions
array_agg(expression)
Returns input values, including nulls, concatenated into an array.
Argument Type(s):any non-array type
Return Type:array of the argument type
array_agg(expression)
Returns input arrays concatenated into array of one higher dimension (note: inputs must all have same dimensionality, and cannot be empty or NULL). Argument Type(s):any array type
Return Type:same as argument data type
avg(expression)
Returns the average (arithmetic mean) of all input values.
Argument Type(s):smallint, int, bigint, real, double precision, numeric, or interval
Return Type:numeric for any integer-type argument, double precision for a floating-point argument, otherwise the same as the argument data type
bit_and(expression)
Returns the bitwise AND of all non-null input values, or null if none.
Argument Type(s):smallint, int, bigint, or bit
Return Type:same as argument data type
bit_or(expression)
Returns the bitwise OR of all non-null input values, or null if none.
Argument Type(s):smallint, int, bigint, or bit
Return Type:same as argument data type
bool_and(expression)
Returns true if all input values are true, otherwise false.
Argument Type(s):bool
Return Type:bool
bool_or(expression)
Returns true if at least one input value is true, otherwise false.
Argument Type(s):bool
Return Type:bool
count(anything)
Returns the number of input rows.
Argument Type(s):any
Return Type:bigint
count(expression)
Returns the number of input rows for which the value of expression is not null.
Argument Type(s):any
Return Type:bigint
every(expression)
Equivalent to bool_and.
Argument Type(s):bool
Return Type:bool
json_agg(expression)
Aggregates values as a JSON array.
Argument Type(s):any
Return Type:json
jsonb_agg(expression)
Aggregates values as a JSON array.
Argument Type(s):any
Return Type:jsonb
json_object_agg(name, value)
Aggregates name/value pairs as a JSON object.
Argument Type(s):(any, any)
Return Type:json
jsonb_object_agg(name, value)
Aggregates name/value pairs as a JSON object.
Argument Type(s):(any, any)
Return Type:jsonb
max(expression)
Returns the maximum value of expression across all input values.
Argument Type(s):any numeric, string, date/time, network, or enum type, or arrays of these types
Return Type:same as argument type
min(expression)
Returns the minimum value of expression across all input values.
Argument Type(s):any numeric, string, date/time, network, or enum type, or arrays of these types
Return Type:same as argument type
string_agg(expression, delimiter)
Returns the input values concatenated into a string, separated by delimiter.
Argument Type(s):(text, text) or (bytea, bytea)
Return Type:same as argument types
sum(expression)
Returns the sum of expression across all input values.
Argument Type(s):smallint, int, bigint, real, double precision, numeric, interval, or money
Return Type:bigint for smallint or int arguments, numeric for bigint arguments, otherwise the same as the argument data type
xmlagg(expression)
Returns the concatenation of XML values.
Argument Type(s):xml
Return Type:xml
corr(Y, X)
Returns correlation coefficient of the two entered numbers.
Argument Type(s):double precision
Return Type:double precision
covar_pop(Y, X)
Returns population covariance of the two entered numbers.
Argument Type(s):double precision
Return Type:double precision
covar_samp(Y, X)
Returns sample covariance of the two entered numbers.
Argument Type(s):double precision
Return Type:double precision
regr_avgx(Y, X)
Returns average of the independent variable X (sum(X)/N).
Argument Type(s):double precision
Return Type:double precision
regr_avgy(Y, X)
Returns average of the dependent variable Y (sum(Y)/N).
Argument Type(s):double precision
Return Type:double precision
regr_count(Y, X)
Returns the number of input rows in which both expressions are nonnull.
Argument Type(s):double precision
Return Type:bigint
regr_intercept(Y, X)
Returns y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs.
Argument Type(s):double precision
Return Type:double precision
regr_r2(Y, X)
Returns square of the correlation coefficient of the two entered numbers.
Argument Type(s):double precision
Return Type:double precision
regr_slope(Y, X)
Returns slope of the least-squares-fit linear equation determined by the (X, Y) pairs.
Argument Type(s):double precision
Return Type:double precision
regr_sxx(Y, X)
Returns sum(X^2) - sum(X)^2/N (“sum of squares” of the independent variable).
Argument Type(s):double precision
Return Type:double precision
regr_sxy(Y, X)
Returns sum(XY) - sum(X) sum(Y)/N (“sum of products” of independent times dependent variable).
Argument Type(s):double precision
Return Type:double precision
regr_syy(Y, X)
Returns sum(Y^2) - sum(Y)^2/N (“sum of squares” of the dependent variable).
Argument Type(s):double precision
Return Type:double precision
stddev(expression)
Returns historical alias for stddev_samp.
Argument Type(s):smallint, int, bigint, real, double precision, or numeric
Return Type:double precision for floating-point arguments, otherwise numeric
stddev_pop(expression)
Returns population standard deviation of the input values.
Argument Type(s):smallint, int, bigint, real, double precision, or numeric
Return Type:double precision for floating-point arguments, otherwise numeric
stddev_samp(expression)
Returns sample standard deviation of the input values.
Argument Type(s):smallint, int, bigint, real, double precision, or numeric
Return Type:double precision for floating-point arguments, otherwise numeric
variance(expression)
Returns historical alias for var_samp.
Argument Type(s):smallint, int, bigint, real, double precision, or numeric
Return Type:double precision for floating-point arguments, otherwise numeric
var_pop(expression)
Returns population variance of the input values (square of the population standard deviation).
Argument Type(s):smallint, int, bigint, real, double precision, or numeric
Return Type:double precision for floating-point arguments, otherwise numeric
var_samp(expression)
Returns sample variance of the input values (square of the sample standard deviation).
Argument Type(s):smallint, int, bigint, real, double precision, or numeric
Return Type:double precision for floating-point arguments, otherwise numeric
mode() WITHIN GROUP (ORDER BY sort_expression)
Returns the most frequent input value (arbitrarily choosing one if there are multiple equally-frequent results).
Argument Type(s):any sortable type
Return Type:same as sort expression
percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression)
Returns a value corresponding to the specified fraction in the ordering, interpolating between adjacent input items if needed.
Argument Type(s):double precision or interval
Return Type:same as sort expression
percentile_cont(fractions) WITHIN GROUP (ORDER BY sort_expression)
Returns an array of results matching the shape of the fractions parameter, with each non-null element replaced by the value corresponding to that percentile
Argument Type(s):double precision or interval
Return Type:array of sort expression's type
percentile_disc(fraction) WITHIN GROUP (ORDER BY sort_expression)
Returns the first input value whose position in the ordering equals or exceeds the specified fraction.
Argument Type(s):any sortable type
Return Type:same as sort expression
percentile_disc(fractions) WITHIN GROUP (ORDER BY sort_expression)
Returns an array of results matching the shape of the fractions parameter, with each non-null element replaced by the input value corresponding to that percentile.
Argument Type(s):any sortable type
Return Type:array of sort expression's type
rank(args) WITHIN GROUP (ORDER BY sorted_args)
Returns rank of the argument, with gaps for duplicate rows.
Argument Type(s):VARIADIC "any"
Return Type:bigint
dense_rank(args) WITHIN GROUP (ORDER BY sorted_args)
Returns rank of the argument, without gaps for duplicate rows.
Argument Type(s):VARIADIC "any"
Return Type:bigint
percent_rank(args) WITHIN GROUP (ORDER BY sorted_args)
Returns relative rank of the argument, ranging from 0 to 1.
Argument Type(s):VARIADIC "any"
Return Type:double precision
cume_dist(args) WITHIN GROUP (ORDER BY sorted_args)
Returns relative rank of the argument, ranging from 1/N to 1.
Argument Type(s):VARIADIC "any"
Return Type:double precision
GROUPING(args…)
Returns integer bit mask indicating which arguments are not being included in the current grouping set.
Return Type:integer
Window Functions
row_number()
Returns the number of the current row within its partition, counting from 1.
Return Type:bigint
rank()
Returns rank of the current row with gaps; same as row_number of its first peer.
Return Type:bigint
dense_rank()
Returns rank of the current row without gaps; this function counts peer groups.
Return Type:bigint
percent_rank()
Returns relative rank of the current row: (rank - 1)/(total partition rows - 1).
Return Type:double precision
cume_dist()
Returns cumulative distribution: (number of partition rows preceding or peer with current row)/total partition rows.
Return Type:double precision
ntile(num_buckets integer)
Returns integer ranging from 1 to the argument value, dividing the partition as equally as possible.
Return Type:integer
lag(value anyelement [, offset integer [, default anyelement ]])
Returns value evaluated at the row that is offset rows before the current row within the partition; if there is no such row, instead return default (which must be of the same type as value). Both offset and default are evaluated with respect to the current row. If omitted, offset defaults to 1 and default to null.
Return Type:same type as value
lead(value anyelement [, offset integer [, default anyelement ]])
Returns value evaluated at the row that is offset rows after the current row within the partition; if there is no such row, instead return default (which must be of the same type as value). Both offset and default are evaluated with respect to the current row. If omitted, offset defaults to 1 and default to null.
Return Type:same type as value
first_value(value any)
Returns the value evaluated at the row that is the first row of the window frame.
Return Type:same type as value
last_value(value any)
Returns the value evaluated at the row that is the last row of the window frame.
Return Type:same type as value
nth_value(value any, nth integer)
Returns the value evaluated at the row that is the nth row of the window frame (counting from 1); null if there is no such row.
Return Type:same type as value
System Information Functions
current_catalog
Name of current database (called “catalog” in the SQL standard).SELECT current_catalog; Result: current_database ------------------ test1 row) (
current_database()
Returns name of current database.SELECT current_database(); Result: current_database ------------------ test1 row) (
current_query()
Returns text of the currently executing query, as submitted by the client (might contain more than one statement).SELECT current_query(); Result: current_query ------------------------- SELECT current_query(); 1 row) (
current_role
Returns equivalent tocurrent_user
.SELECT current_role; Result: current_user -------------- agens1 row) (
current_schema[()]
Returns name of current schema.SELECT current_schema(); Result: current_schema ---------------- public 1 row) (
current_schemas(boolean)
Returns names of schemas in search path, optionally including implicit schemas.SELECT current_schemas(true); Result: current_schemas --------------------- public} {pg_catalog,1 row) (
current_user
Returns user name of current execution context.SELECT current_user; Result: current_user -------------- agens1 row) (
inet_client_addr()
Returns address of the remote connection.SELECT inet_client_addr(); Result: inet_client_addr------------------ :1 :1 row) (
inet_client_port()
Returns port of the remote connection.SELECT inet_client_port(); Result: inet_client_port ------------------ 64427 1 row) (
inet_server_addr()
Returns address of the local connection.SELECT inet_server_addr(); Result: inet_server_addr ------------------ :1 :1 row) (
inet_server_port()
Returns port of the local connection.SELECT inet_server_port(); Result: inet_server_port ------------------ 5432 1 row) (
pg_backend_pid()
Returns the process ID of the server process attached to the current session.SELECT pg_backend_pid(); Result: pg_backend_pid ---------------- 61675 1 row) (
pg_blocking_pids(int)
Returns the process ID(s) that are blocking specified server process ID.SELECT pg_blocking_pids(61675); Result: pg_blocking_pids ------------------ {}1 row) (
pg_conf_load_time()
Returns configuration load time.SELECT pg_conf_load_time(); Result: pg_conf_load_time ------------------------------ 2017-10-18 13:36:51.99984+09 1 row) (
pg_my_temp_schema()
Returns OID of session’s temporary schema, or 0 if none.SELECT pg_my_temp_schema(); Result: pg_my_temp_schema ------------------- 0 1 row) (
pg_is_other_temp_schema(oid)
Returns whether schema is another session’s temporary schema.SELECT pg_is_other_temp_schema(61675); Result: pg_is_other_temp_schema ------------------------- f1 row) (
pg_listening_channels()
Returns channel names that the session is currently listening on.SELECT pg_listening_channels(); Result: pg_listening_channels ----------------------- 0 row) (
pg_notification_queue_usage()
Returns fraction of the asynchronous notification queue currently occupied (0-1).SELECT pg_notification_queue_usage(); Result: pg_notification_queue_usage ----------------------------- 0 1 row) (
pg_postmaster_start_time()
Returns server start time.SELECT pg_postmaster_start_time(); Result: pg_postmaster_start_time ------------------------------- 2017-10-18 13:36:52.019037+09 1 row) (
pg_trigger_depth()
Returns current nesting level of PostgreSQL triggers (0 if not called, directly or indirectly, from inside a trigger).SELECT pg_trigger_depth(); Result: pg_trigger_depth ------------------ 0 1 row) (
session_user
Returns session user name.SELECT session_user; Result: session_user -------------- agens1 row) (
user
Returns the equivalent to current_user.SELECT user; Result: current_user -------------- agens1 row) (
version()
Returns AgensGraph’s version info.SELECT version(); Result: version ------------------------------------------------------------------------------- 9.6.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 PostgreSQL 4.4.7-17), 64-bit (Red Hat 1 row) (
has_any_column_privilege(user, table, privilege)
Returns a boolean value indicating whether the user has the same privileges on all columns of the table as others.SELECT has_any_column_privilege('agens', 'myschema.mytable', 'SELECT'); Result: has_any_column_privilege -------------------------- t1 row) (
has_any_column_privilege(table, privilege)
Returns whether current user has privilege for all columns of table.SELECT has_any_column_privilege('myschema.mytable', 'SELECT'); Result: has_any_column_privilege -------------------------- t 1 row) (
has_column_privilege(user, table, column, privilege)
Returns whether user has privilege for table’s column.SELECT has_column_privilege('agens', 'myschema.mytable', 'col1', 'SELECT'); Result: has_column_privilege ---------------------- t1 row) (
has_column_privilege(table, column, privilege)
Returns whether current user has privilege for table’s column.SELECT has_column_privilege('myschema.mytable', 'col1', 'SELECT'); Result: has_column_privilege ---------------------- t1 row) (
has_database_privilege(user, database, privilege)
Returns whether user has privilege for database.SELECT has_database_privilege('agens', 'test', 'connect'); Result: has_database_privilege ------------------------ t1 row) (
has_database_privilege(database, privilege)
Returns whether current user has privilege for database.SELECT has_database_privilege('test', 'connect'); Result: has_database_privilege ------------------------ t1 row) (
has_foreign_data_wrapper_privilege(user, fdw, privilege)
Returns whether user has privilege for foreign-data wrapper.CREATE EXTENSION postgres_fdw; SELECT has_foreign_data_wrapper_privilege('agens', 'postgres_fdw', 'usage'); Result: has_foreign_data_wrapper_privilege ------------------------------------ t1 row) (
has_foreign_data_wrapper_privilege(fdw, privilege)
Returns whether current user has privilege for foreign-data wrapper.SELECT has_foreign_data_wrapper_privilege('postgres_fdw', 'usage'); Result: has_foreign_data_wrapper_privilege ------------------------------------ t1 row) (
has_function_privilege(user, function, privilege))
Returns whether user has privilege for function.SELECT has_function_privilege('agens', 'getfoo()', 'execute'); Result: has_function_privilege ------------------------ t1 row) (
has_function_privilege(function, privilege)
Returns whether current user has privilege for function.SELECT has_function_privilege('getfoo()', 'execute'); Result: has_function_privilege ------------------------ t1 row) (
has_language_privilege(user, language, privilege)
Returns whether the user has privilege for language.SELECT has_language_privilege('agens', 'c', 'usage'); Result: has_language_privilege ------------------------ t1 row) (
has_language_privilege(language, privilege)
Returns whether current user has privilege for language.SELECT has_language_privilege('c', 'usage'); Result: has_language_privilege ------------------------ t1 row) (
has_schema_privilege(user, schema, privilege)
Returns whether user has privilege for schema.SELECT has_schema_privilege('agens', 'myschema', 'usage'); Result: has_schema_privilege ---------------------- t1 row) (
has_schema_privilege(schema, privilege)
Returns whether current user has privilege for schema.SELECT has_schema_privilege('myschema', 'usage'); Result: has_schema_privilege ---------------------- t1 row) (
has_sequence_privilege(user, sequence, privilege)
Returns whether the user has privilege for sequence.SELECT has_sequence_privilege('agens', 'serial', 'usage'); Result: has_sequence_privilege ------------------------ t1 row) (
has_sequence_privilege(sequence, privilege)
Returns whether user has privilege for sequence.SELECT has_sequence_privilege('serial', 'usage'); Result: has_sequence_privilege ------------------------ t1 row) (
has_server_privilege(user, server, privilege)
Returns whether user has privilege for server.CREATE SERVER app_database_server FOREIGN DATA WRAPPER postgres_fdw '127.0.0.1', dbname 'agens'); OPTIONS (host SELECT has_server_privilege('agens', 'app_database_server', 'usage'); Result: has_server_privilege ---------------------- t1 row) (
has_server_privilege(server, privilege)
Returns whether current user has privilege for server.SELECT has_server_privilege('app_database_server', 'usage'); Result: has_server_privilege ---------------------- t1 row) (
has_table_privilege(user, table, privilege)
Returns whether user has privilege for table.SELECT has_table_privilege('agens', 'myschema.mytable', 'SELECT'); Result: has_table_privilege --------------------- t1 row) (
has_table_privilege(table, privilege)
Returns whether current user has privilege for table.SELECT has_table_privilege('myschema.mytable', 'SELECT'); Result: has_table_privilege --------------------- t1 row) (
has_tablespace_privilege(user, tablespace, privilege)
Returns whether user has privilege for tablespace.SELECT has_tablespace_privilege('agens', 'pg_default', 'create'); Result: has_tablespace_privilege -------------------------- t1 row) (
has_tablespace_privilege(tablespace, privilege)
Returns whether current user has privilege for tablespace.SELECT has_tablespace_privilege('pg_default', 'create'); Result: has_tablespace_privilege -------------------------- t1 row) (
has_type_privilege(user, type, privilege)
Returns whether user has privilege for type.SELECT has_type_privilege('agens', 'rainbow', 'usage'); Result: has_type_privilege -------------------- t1 row) (
has_type_privilege(type, privilege)
Returns whether current user has privilege for type.SELECT has_type_privilege('rainbow', 'usage'); Result: has_type_privilege -------------------- t1 row) (
pg_has_role(user, role, privilege)
Returns whether user has privilege for role.SELECT pg_has_role('agens', 'agens', 'usage'); Result: pg_has_role ------------- t1 row) (
pg_has_role(role, privilege)
Returns whether current user has privilege for role.SELECT pg_has_role('agens', 'usage'); Result: pg_has_role ------------- t1 row) (
row_security_active(table)
Returns whether current user has row level security active for table.SELECT row_security_active('myschema.mytable'); Result: row_security_active --------------------- f1 row) (
pg_collation_is_visible(collation_oid)
Returns whether collation is visible in search path.SELECT pg_collation_is_visible(100); Result: pg_collation_is_visible ------------------------- t1 row) (
pg_conversion_is_visible(conversion_oid)
Returns whether conversion is visible in search path.SELECT pg_conversion_is_visible(12830); Result: pg_conversion_is_visible -------------------------- t1 row) (
pg_function_is_visible(function_oid)
Returns whether function is visible in search path.SELECT pg_function_is_visible(16716); Result: pg_function_is_visible ------------------------ t 1 row) (
pg_opclass_is_visible(opclass_oid)
Returns whether opclass is visible in search path.SELECT pg_opclass_is_visible(10007); Result: pg_opclass_is_visible ----------------------- t1 row) (
pg_operator_is_visible(operator_oid)
Returns whether operator is visible in search path.SELECT pg_operator_is_visible(15); Result: pg_operator_is_visible ------------------------ t1 row) (
pg_opfamily_is_visible(opclass_oid)
Returns whether opfamily is visible in search path.SELECT pg_opfamily_is_visible(421); Result: pg_opfamily_is_visible ------------------------ t1 row) (
pg_table_is_visible(table_oid)
Returns whether table is visible in search path.SELECT pg_table_is_visible(16553); Result: pg_table_is_visible --------------------- t1 row) (
pg_ts_config_is_visible(config_oid)
Returns whether text search configuration is visible in search path.SELECT pg_ts_config_is_visible(3748); Result: pg_ts_config_is_visible ------------------------- t1 row) (
pg_ts_dict_is_visible(dict_oid)
Returns whether text search dictionary is visible in search path.SELECT pg_ts_dict_is_visible(3765); Result: pg_ts_dict_is_visible ----------------------- t1 row) (
pg_ts_parser_is_visible(parser_oid)
Returns whether text search parser is visible in search path.SELECT pg_ts_parser_is_visible(3722); Result: pg_ts_parser_is_visible ------------------------- t1 row) (
pg_ts_template_is_visible(template_oid)
Returns whether text search template is visible in search path.SELECT pg_ts_template_is_visible(3727); Result: pg_ts_template_is_visible --------------------------- t1 row) (
pg_type_is_visible(type_oid)
Returns whether type or domain is visible in search path.SELECT pg_type_is_visible(16); Result: pg_type_is_visible -------------------- t1 row) (
format_type(type_oid, typemod)
Gets the name of a data type.SELECT format_type(16, 1); Result: format_type ------------- boolean 1 row) (
pg_get_constraintdef(constraint_oid)
Gets definition of a constraint.SELECT pg_get_constraintdef(13096); Result: pg_get_constraintdef ---------------------- CHECK ((VALUE >= 0)) 1 row) (
pg_get_constraintdef(constraint_oid, pretty_bool)
Gets definition of a constraint.SELECT pg_get_constraintdef(13096, true); Result: pg_get_constraintdef ---------------------- CHECK ((VALUE >= 0)) 1 row) (
pg_get_functiondef(func_oid)
Gets definition of a function.SELECT pg_get_functiondef(16716); Result: pg_get_functiondef -------------------------------------------- CREATE OR REPLACE FUNCTION public.getfoo()+ ... 1 row) (
pg_get_function_arguments(func_oid)
Gets argument list of function’s definition (with default values).SELECT pg_get_function_arguments(16739); Result: pg_get_function_arguments ------------------------------------ double precision, double precision 1 row) (
pg_get_function_identity_arguments(func_oid)
Gets argument list to identify a function (without default values).SELECT pg_get_function_identity_arguments(16739); Result: pg_get_function_identity_arguments ------------------------------------ double precision, double precision 1 row) (
pg_get_function_result(func_oid)
Gets RETURNS clause for function.SELECT pg_get_function_result(16739); Result: pg_get_function_result ------------------------ float8_range1 row) (
pg_get_indexdef(index_oid)
GetsCREATE INDEX
command for index.SELECT pg_get_indexdef(828); Result: pg_get_indexdef ---------------------------------------------------------------------------------- CREATE UNIQUE INDEX pg_default_acl_oid_index ON pg_default_acl USING btree (oid) 1 row) (
pg_get_indexdef(index_oid, column_no, pretty_bool)
Gets CREATE INDEX command for index, or definition of just one index column when column_no is not zero.SELECT pg_get_indexdef(828, 1, true); Result: pg_get_indexdef ----------------- oid 1 row) (
pg_get_keywords()
Gets list of SQL keywords and their categories.SELECT pg_get_keywords(); Result: pg_get_keywords --------------------------- (abort,U,unreserved) (absolute,U,unreserved)... 434 row) (
pg_get_ruledef(rule_oid)
GetsCREATE RULE
command for rule.SELECT pg_get_ruledef(11732); Result: pg_get_ruledef --------------------------------------- CREATE RULE "_RETURN" AS ... 1 row) (
pg_get_ruledef(rule_oid, pretty_bool)
GetsCREATE RULE
command for rule.SELECT pg_get_ruledef(11732, true); Result: pg_get_ruledef --------------------------------------- CREATE RULE "_RETURN" AS ... 1 row) (
pg_get_serial_sequence(table_name, column_name)
Returns the name of the sequence usingserial
,smallserial
, andbigserial
columns.SELECT pg_get_serial_sequence('serial_t', 'col1'); Result: pg_get_serial_sequence -------------------------- public.serial_t_col1_seq 1 row) (
pg_get_triggerdef(trigger_oid)
GetsCREATE [ CONSTRAINT ] TRIGGER
command for trigger.SELECT pg_get_triggerdef(16887); Result: pg_get_triggerdef ------------------------------------------------------------------------- CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON messages FOR EACH ROW EXECUTE PROCEDURE 'tsv', 'configcol', 'title', 'body') tsvector_update_trigger_column(1 row) (
pg_get_triggerdef(trigger_oid, pretty_bool)
GetsCREATE [ CONSTRAINT ] TRIGGER
command for trigger.SELECT pg_get_triggerdef(16887, true); Result: pg_get_triggerdef ------------------------------------------------------------------------- CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE ON messages FOR EACH ROW EXECUTE PROCEDURE 'tsv', 'configcol', 'title', 'body') tsvector_update_trigger_column(1 row) (
pg_get_userbyid(role_oid)
Gets role name with given OID.SELECT pg_get_userbyid(13096); Result: pg_get_userbyid ----------------- agens1 row) (
pg_get_viewdef(view_oid)
Gets underlyingSELECT
command for view or mview.SELECT pg_get_viewdef(17046); Result: pg_get_viewdef ----------------------------------- SELECT pg_class.relname, + + pg_class.relnamespace, ... FROM pg_class; 1 row) (
pg_get_viewdef(view_oid, pretty_bool)
Gets underlyingSELECT
command for view or mview.SELECT pg_get_viewdef(17046, true); Result: pg_get_viewdef ----------------------------------- SELECT pg_class.relname, + + pg_class.relnamespace, ... FROM pg_class; 1 row) (
pg_get_viewdef(view_oid, wrap_column_int)
Gets underlyingSELECT
command for view or mview; lines with fields are wrapped to specified number of columns.SELECT pg_get_viewdef(17046,50); Result: pg_get_viewdef ----------------------------------------------------- SELECT pg_class.relname, pg_class.relnamespace, + + pg_class.reltype, pg_class.reloftype, + pg_class.relowner, pg_class.relam, + pg_class.relfilenode, pg_class.reltablespace, + pg_class.relpages, pg_class.reltuples, + pg_class.relallvisible, pg_class.reltoastrelid,+ pg_class.relhasindex, pg_class.relisshared, + pg_class.relpersistence, pg_class.relkind, + pg_class.relnatts, pg_class.relchecks, + pg_class.relhasoids, pg_class.relhaspkey, + pg_class.relhasrules, pg_class.relhastriggers, + pg_class.relhassubclass, + pg_class.relrowsecurity, + pg_class.relforcerowsecurity, + pg_class.relispopulated, pg_class.relreplident,+ pg_class.relfrozenxid, pg_class.relminmxid, + pg_class.relacl, pg_class.reloptions FROM pg_class; 1 row) (
pg_index_column_has_property(index_oid, column_no, prop_name)
Tests whether an index column has a specified property.SELECT pg_index_column_has_property(17134, 1, 'orderable'); Result: pg_index_column_has_property ------------------------------ t1 row) (
pg_index_has_property(index_oid, prop_name)
Tests whether an index has a specified property.SELECT pg_index_has_property(17134, 'clusterable'); Result: pg_index_has_property ----------------------- t1 row) (
pg_indexam_has_property(am_oid, prop_name)
Tests whether an index access method has a specified property.SELECT pg_indexam_has_property(403, 'can_order'); Result: pg_indexam_has_property ------------------------- t1 row) (
pg_options_to_table(reloptions)
Gets name/value pairs of the set of storage option.SELECT pg_options_to_table(reloptions) FROM pg_class; Result: pg_options_to_table ------------------------- true) (security_barrier,1 row) (
pg_tablespace_databases(tablespace_oid)
Gets the set of database OIDs that have objects in the tablespace.SELECT pg_tablespace_databases(1663); Result: pg_tablespace_databases ------------------------- 1 13372 13373 16384 16482 5 row) (
pg_tablespace_location(tablespace_oid)
Gets the path in the file system that this tablespace is located in.SELECT pg_tablespace_location(1663); Result: pg_tablespace_location ---------------------------------- /home/agens/AgensGraph/db_cluster 1 row) (
pg_typeof(any)
Gets the data type of any value.SELECT pg_typeof(1); Result: pg_typeof ----------- integer 1 row) (
collation for (any)
Gets the collation of the argument.SELECT collation for ('foo' COLLATE "de_DE"); Result: pg_collation_for ------------------ "de_DE" 1 row) (
pg_describe_object(catalog_id, object_id, object_sub_id)
Gets description of a database object.SELECT pg_describe_object(1255, 16716, 0); Result: pg_describe_object -------------------- function 16716 1 row) (
pg_identify_object(catalog_id oid, object_id oid, object_sub_id integer)
Gets identity info of a database object.SELECT pg_identify_object(1255, 16716, 0); Result: pg_identify_object -------------------------------------- function,public,,"public.getfoo()") (1 row) (
pg_identify_object_as_address(catalog_id oid, object_id oid, object_sub_id integer)
Gets external representation of a database object’s address.SELECT pg_identify_object_as_address(1255, 16716, 0); Result: pg_identify_object_as_address --------------------------------- function,"{public,getfoo}",{}) (1 row) (
pg_get_object_address(type text, name text[], args text[])
Gets address of a database object, from its external representation.SELECT pg_get_object_address('type', '{public.comp}', '{}'); Result: pg_get_object_address ----------------------- 1247,17063,0) (1 row) (
col_description(table_oid, column_number)
Gets comment for a table column.SELECT col_description(17064, 1); Result: col_description ----------------- code_number1 row) (
obj_description(object_oid, catalog_name)
Gets comment for a database object.SELECT obj_description(16887, 'pg_trigger'); Result: obj_description -------------------- comment on trigger 1 row) (
obj_description(object_oid)
Gets comment for a database object (no longer used).SELECT obj_description(16887); Result: obj_description -------------------- comment on trigger 1 row) (
shobj_description(object_oid, catalog_name)
Gets comment for a shared database object.SELECT shobj_description(1262,'pg_database'); Result: shobj_description ------------------- 1 row) (
txid_current()
Gets current transaction ID, assigning a new one if the current transaction does not have one.SELECT txid_current(); Result: txid_current -------------- 2061 1 row) (
txid_current_snapshot()
Gets current snapshot.SELECT txid_current_snapshot(); Result: txid_current_snapshot ----------------------- 2062:2062: 1 row) (
txid_snapshot_xip(txid_snapshot)
Gets in-progress transaction IDs in snapshot.SELECT txid_snapshot_xip('2095:2095:'); Result: txid_snapshot_xip ------------------- 1 row) (
txid_snapshot_xmax(txid_snapshot)
Gets xmax of snapshot.SELECT txid_snapshot_xmax('2094:2095:'); Result: txid_snapshot_xmax -------------------- 2095 1 row) (
txid_snapshot_xmin(txid_snapshot)
Gets xmin of snapshot.SELECT txid_snapshot_xmin('2094:2095:'); Result: txid_snapshot_xmin -------------------- 2094 1 row) (
txid_visible_in_snapshot(bigint, txid_snapshot)
Returns whether transaction ID is visible in snapshot (do not use with subtransaction ids).SELECT txid_visible_in_snapshot(2099, '2100:2100:'); Result: txid_visible_in_snapshot -------------------------- t1 row) (
pg_xact_commit_timestamp(xid)
Gets commit timestamp of a transaction (track_commit_timestamp
parameter should be set to on).SELECT pg_xact_commit_timestamp('2097'::xid); Result: pg_xact_commit_timestamp ------------------------------- 2017-10-18 13:38:09.738211+09 1 row) (
pg_last_committed_xact()
Gets transaction ID and commit timestamp of latest committed transaction (track_commit_timestamp
parameter should be set to on).SELECT pg_last_committed_xact(); Result: pg_last_committed_xact ---------------------------------------- 2097,"2017-10-18 13:38:09.738211+09") (1 row) (
pg_control_checkpoint()
Returns information about current checkpoint state.SELECT pg_control_checkpoint(); Result: pg_control_checkpoint ------------------------------------------------------------------- 0/1D4B0D0,0/1D4B038,0/1D4B0D0,000000010000000000000001, (1,1,t,0:2063,24576,1,0,1751,1,0,1,1,0,0,"2017-10-16 16:26:21+09") 1 row) (
pg_control_system()
Returns information about current control file state.SELECT pg_control_system(); Result: pg_control_system -------------------------------------------------------------- 960,201608131,6469891178207434037,"2017-10-16 16:26:21+09") (1 row) (
pg_control_init()
Returns information about cluster initialization state.SELECT pg_control_init(); Result: pg_control_init ------------------------------------------------------- 8,8192,131072,8192,16777216,64,32,1996,2048,t,t,t,0) (1 row) (
pg_control_recovery()
Returns information about recovery state.SELECT pg_control_recovery(); Result: pg_control_recovery --------------------- 0/0,0,0/0,0/0,f) (1 row) (
System Administration Functions
current_setting(setting_name [, missing_ok ])
Gets current value of setting.SELECT current_setting('datestyle'); Result: current_setting ----------------- ISO, YMD1 row) (
set_config(setting_name, new_value, is_local)
Sets parameter and returns new value.SELECT set_config('log_statement_stats', 'off', false); Result: set_config ------------ off 1 row) (
pg_cancel_backend(pid int)
Cancels a backend’s current query. This is also allowed if the calling role is a member of the role whose backend is being canceled or the calling role has been grantedpg_signal_backend
. However, only superusers can cancel superuser backends.SELECT pg_cancel_backend(30819); Cancel operation by user request. Error:
pg_reload_conf()
Causes server processes to reload their configuration files.SELECT pg_reload_conf(); Result: pg_reload_conf ---------------- t1 row) (
pg_rotate_logfile()
Signals the log-file manager to switch to a new log file immediately (This works only when the built-in log collector is running).SELECT pg_rotate_logfile(); pg_rotate_logfile ------------------- f1 row) (
pg_terminate_backend(pid int)
Terminates a backend. This is also allowed if the calling role is a member of the role whose backend is being terminated or the calling role has been grantedpg_signal_backend
. However, only superusers can terminate superuser backends.SELECT pg_terminate_backend(30819); Result:is terminated by an administrator request. Fatal error: Connection The server suddenly closed the connection. type of processing means the server was abruptly terminated This while or before processing the client's request. The server connection has been lost. Attempt to reconnect: Success.
pg_create_restore_point(name text)
Creates a named point for performing restore (restricted to superusers by default, but other users can be granted EXECUTE to run the function).SELECT pg_create_restore_point( 'important_moment' ); Result: pg_create_restore_point ------------------------- 0/1D72DC0 1 row) (
pg_current_xlog_flush_location()
Returns the transaction log flush location.SELECT pg_current_xlog_flush_location(); Result: pg_current_xlog_flush_location --------------------------------- 0/1D72ED8 1 row) (
pg_current_xlog_insert_location()
Returns the location of the current transaction log insert.SELECT pg_current_xlog_insert_location(); Result: pg_current_xlog_insert_location --------------------------------- 0/1D72ED8 1 row) (
pg_current_xlog_location()
Returns the location of the current transaction log write.SELECT pg_current_xlog_location(); Result: pg_current_xlog_location -------------------------- 0/1D72ED8 1 row) (
pg_start_backup(label text [, fast boolean [, exclusive boolean ]])
Prepares for performing on-line backup (restricted to superusers by default, but other users can be granted EXECUTE to run the function).SELECT pg_start_backup('my_backup', true, false); Result: pg_start_backup ----------------- 0/2000028 1 row) (
pg_stop_backup()
Finishes performing exclusive on-line backup (restricted to superusers by default, but other users can be granted EXECUTE to run the function).SELECT pg_stop_backup(); Result:The pg_stop_backup operation is finished. NOTICE: All necessary WAL pieces have been archived. pg_stop_backup ---------------- 0/50000F8,,) (1 row) (
pg_stop_backup(exclusive boolean)
Finishes performing exclusive or non-exclusive on-line backup (restricted to superusers by default, but other users can be granted EXECUTE to run the function).SELECT pg_stop_backup(false); Result:is not enabled; you must ensure that all required WAL NOTICE: WAL archiving through other means to complete the backup segments are copied pg_stop_backup --------------------------------------------------------------------------- 0/3000088,"START WAL LOCATION: 0/2000028 (file 000000010000000000000002)+ (CHECKPOINT LOCATION: 0/2000060 + BACKUP METHOD: streamed + BACKUP FROM: master + START TIME: 2017-10-17 10:00:18 KST + LABEL: my_backup + ","17060 /home/agens/AgensGraph/db_cluster/data + ") 1 row) (
pg_is_in_backup()
Returns true if an on-line exclusive backup is still in progress.SELECT pg_is_in_backup(); Result: pg_is_in_backup ----------------- t1 row) (
pg_backup_start_time()
Gets start time of an on-line exclusive backup in progress.SELECT pg_backup_start_time(); Result: pg_backup_start_time ------------------------ 2017-10-17 10:29:26+09 1 row) (
pg_switch_xlog()
Forces switch to a new transaction log file (restricted to superusers by default, but other users can be granted EXECUTE to run the function).SELECT pg_switch_xlog(); Result: pg_switch_xlog ---------------- 0/9000120 1 row) (
pg_xlogfile_name(location pg_lsn)
Converts the transaction log location string to file name.SELECT pg_xlogfile_name('0/9000028'); Result: pg_xlogfile_name -------------------------- 000000010000000000000009 1 row) (
pg_xlogfile_name_offset(location pg_lsn)
Converts the transaction log location string to file name and decimal byte offset within file.SELECT pg_xlogfile_name_offset('0/9000028'); Result: pg_xlogfile_name_offset ------------------------------- 000000010000000000000009,40) (1 row) (
pg_xlog_location_diff(location pg_lsn, location pg_lsn)
Calculates the difference between two transaction log locations.SELECT pg_xlog_location_diff('0/9000120', '0/9000028'); Result: pg_xlog_location_diff ----------------------- 1 row) (
pg_is_in_recovery()
Returns true if recovery is still in progress.SELECT pg_is_in_recovery(); Result: pg_is_in_recovery ------------------- t 1 row) (
pg_last_xlog_receive_location()
Gets the last transaction log location received and synced to disk by streaming replication. While streaming replication is in progress this will increase monotonically. If recovery has been completed this will remain static at the value of the last WAL record received and synced to disk during recovery. If streaming replication is disabled, or if it has not yet started, the function returns NULL.SELECT pg_last_xlog_receive_location(); Result: pg_last_xlog_receive_location ------------------------------- 1 row) (
pg_last_xlog_replay_location()
Gets the last transaction log location replayed during recovery. If recovery is still in progress this will increase monotonically. If recovery has been completed then this value will remain static at the value of the last WAL record applied during that recovery. When the server has been started normally without recovery the function returns NULL.SELECT pg_last_xlog_replay_location(); Result: pg_last_xlog_replay_location ------------------------------ 1 row) (
pg_last_xact_replay_timestamp()
Gets timestamp of last transaction replayed during recovery. This is the time at which the commit or abort WAL record for that transaction was generated on the primary. If no transactions have been replayed during recovery, this function returns NULL. Otherwise, if recovery is still in progress this will increase monotonically. If recovery has been completed then this value will remain static at the value of the last transaction applied during that recovery. When the server has been started normally without recovery the function returns NULL.SELECT pg_last_xact_replay_timestamp(); Result: pg_last_xact_replay_timestamp ------------------------------- 1 row) (
pg_export_snapshot()
Saves the current snapshot and returns its identifier.SELECT pg_export_snapshot(); Result: pg_export_snapshot -------------------- 00000816-1 1 row) (
pg_create_physical_replication_slot(slot_name name [, immediately_reserve boolean ])
Creates a new physical replication slot namedslot_name
. The optional second parameter, whentrue
, specifies that the LSN for this replication slot is reserved immediately; otherwise, the LSN is reserved on the first connection from a streaming replication client. Streaming changes from a physical slot are only possible with the streaming-replication protocol (see this link for more technical info). This function corresponds to the replication protocol commandCREATE_REPLICATION_SLOT ... PHYSICAL
.SELECT pg_create_physical_replication_slot('test_slot', 'true'); Result: pg_create_physical_replication_slot ------------------------------------- 0/D000220) (test_slot,1 row) (
pg_drop_replication_slot(slot_name name)
Drops the physical or logical replication slot namedslot_name
. Same as replication protocol command
DROP_REPLICATION_SLOT
.SELECT pg_drop_replication_slot('test_slot'); Result: pg_drop_replication_slot -------------------------- 1 row) (
pg_create_logical_replication_slot(slot_name name, plugin name)
Creates a new logical (decoding) replication slot namedslot_name
using the outputplugin
plugin. A call to this function has the same effect as the replication protocol commandCREATE_REPLICATION_SLOT ... LOGICAL
.SELECT pg_create_logical_replication_slot('test_slot', 'test_decoding'); Result: pg_create_logical_replication_slot ------------------------------------ 0/D000338) (test_slot,1 row) (
pg_logical_slot_get_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])
Returns changes in the slotslot_name
, starting from the point at which since changes have been consumed last. Ifupto_lsn
andupto_nchanges
are NULL, logical decoding will continue until the end of WAL. Ifupto_lsn
is non-NULL, decoding will include only those transactions which commit prior to the specified LSN.
Ifupto_nchanges
is non-NULL, decoding will stop when the number of rows produced by decoding exceeds the specified value. Note, however, that the actual number of rows returned may be larger since this limit is only checked after adding the rows produced when decoding each new transaction commit.SELECT pg_logical_slot_get_changes('regression_slot',null, null); Result: pg_logical_slot_get_changes -------------------------------- 0/F000190,2079,"BEGIN 2079") (0/F028360,2079,"COMMIT 2079") (2 row) (
pg_logical_slot_peek_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])
Behaves just like thepg_logical_slot_get_changes()
function, except that changes are not consumed.SELECT pg_logical_slot_peek_changes('regression_slot',null, null); Result: pg_logical_slot_peek_changes ---------------------------------------------------------------------------- 0/F028398,2080,"BEGIN 2080") (0/F028468,2080,"table public.data: INSERT: id[integer]:1 data[text]:'3'") (0/F028568,2080,"COMMIT 2080") (3 row) (
pg_logical_slot_get_binary_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])
Behaves just like thepg_logical_slot_get_changes()
function, except that changes are returned as bytea.SELECT pg_logical_slot_get_binary_changes('regression_slot',null, null); Result: pg_logical_slot_get_binary_changes-------------------------------------------------------------------- 0/F028398,2080,"\\x424547494e2032303830") (0/F028468,2080,"\\x7461626c65207075626c69632e646174613a20494e5345 (") 52543a2069645b696e74656765725d3a3120646174615b746578745d3a2733270/F028568,2080,"\\x434f4d4d49542032303830") (3 row) (
pg_logical_slot_peek_binary_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])
Behaves just like thepg_logical_slot_get_changes()
function, except that changes are returned as bytea and that changes are not consumed.SELECT pg_logical_slot_peek_binary_changes('regression_slot',null, null); Result: pg_logical_slot_peek_binary_changes-------------------------------------------------------------------- 0/F028398,2080,"\\x424547494e2032303830") (0/F028468,2080,"\\x7461626c65207075626c69632e646174613a20494e5345 (") 52543a2069645b696e74656765725d3a3120646174615b746578745d3a2733270/F028568,2080,"\\x434f4d4d49542032303830") (3 row) (
pg_replication_origin_create(node_name text)
Creates a replication origin with the given external name, and returns the internal id assigned to it.SELECT pg_replication_origin_create('test_decoding: regression_slot'); Result: pg_replication_origin_create ------------------------------ 1 1 row) (
pg_replication_origin_drop(node_name text)
Deletes a previously created replication origin, including any associated replay progress.SELECT pg_replication_origin_drop('test_decoding: temp'); Result: pg_replication_origin_drop ---------------------------- 1 row) (
pg_replication_origin_oid(node_name text)
Look ups a replication origin by name and returns the internal id. If no corresponding replication origin is found an error is thrown.SELECT pg_replication_origin_oid('test_decoding: temp'); Result: pg_replication_origin_oid --------------------------- 2 1 row) (
pg_replication_origin_session_setup(node_name text)
Marks the current session as replaying from the given origin, allowing replay progress to be tracked.
Usepg_replication_origin_session_reset
to revert. Can only be used if no previous origin is configured.SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); Result: pg_replication_origin_session_setup ------------------------------------- 1 row) (
pg_replication_origin_session_reset()
Cancels the configuration of pg_replication_origin_session_setup().SELECT pg_replication_origin_session_reset(); Result: pg_replication_origin_session_reset ------------------------------------- 1 row) (
pg_replication_origin_session_is_setup()
Returns whether a replication origin has been configured in the current session.SELECT pg_replication_origin_session_is_setup(); Result: pg_replication_origin_session_is_setup ---------------------------------------- t1 row) (
pg_replication_origin_session_progress(flush bool)
Returns the replay location for the replication origin configured in the current session. The parameterflush
determines whether the corresponding local transaction will be guaranteed to have been flushed to disk or not.SELECT pg_replication_origin_session_progress(false); Result: pg_replication_origin_session_progress ---------------------------------------- 0/AABBCCDD 1 row) (
pg_replication_origin_xact_setup(origin_lsn pg_lsn, origin_timestamp timestamptz)
Current transaction as replaying a transaction that has committed at the given LSN and timestamp. Can only be called when a replication origin has previously been configured usingpg_replication_origin_session_setup()
.SELECT pg_replication_origin_xact_setup('0/AABBCCDD', '2017-01-01 00:00'); Result: pg_replication_origin_xact_setup ---------------------------------- 1 row) (
pg_replication_origin_xact_reset()
Cancels the configuration ofpg_replication_origin_xact_setup()
.SELECT pg_replication_origin_xact_reset(); Result: pg_replication_origin_xact_reset ---------------------------------- 1 row) (
pg_replication_origin_advance(node_name text, pos pg_lsn)
Sets replication progress for the given node to the given location. This primarily is useful for setting up the initial location or a new location after configuration changes and similar. Be aware that careless use of this function can lead to inconsistently replicated data.SELECT pg_replication_origin_advance('test_decoding: regression_slot', '0/1'); Result: pg_replication_origin_advance ------------------------------- 1 row) (
pg_replication_origin_progress(node_name text, flush bool)
Returns the replay location for the given replication origin. The parameterflush
determines whether the corresponding local transaction will be guaranteed to have been flushed to disk or not.SELECT pg_replication_origin_progress('test_decoding: temp', true); Result: pg_replication_origin_progress -------------------------------- 0/AABBCCDD 1 row) (
pg_logical_emit_message(transactional bool, prefix text, content text)
Emits a text logical decoding message. This can be used to pass generic messages to logical decoding plugins through WAL. The parametertransactional
specifies if the message should be part of the current transaction or if it should be written immediately and decoded as soon as the logical decoding reads the record. The prefix is the textualprefix
used by the logical decoding plugins to easily recognize interesting messages for them. Thecontent
is the text of the message.SELECT pg_logical_emit_message(false, 'test', 'this message will not be decoded'); Result: pg_logical_emit_message ------------------------- 0/F05E1D0 1 row) (
pg_logical_emit_message(transactional bool, prefix text, content bytea)
Emits binary logical decoding message. This can be used to pass generic messages to logical decoding plugins through WAL. The parametertransactional
specifies if the message should be part of the current transaction or if it should be written immediately and decoded as soon as the logical decoding reads the record. The prefix is the textualprefix
used by the logical decoding plugins to easily recognize interesting messages for them. Thecontent
is the binary content of the message.SELECT pg_logical_emit_message(false, 'test', '0/F05E1D0'); Result: pg_logical_emit_message ------------------------- 0/F05E2C8 1 row) (
pg_column_size(any)
Returns the number of bytes used to store a particular value.SELECT pg_column_size('SELECT fooid FROM foo'); Result: pg_column_size ---------------- 22 1 row) (
pg_database_size(oid)
Returns disk space used by the database with the specified OID.SELECT pg_database_size(16482); Result: pg_database_size ------------------ 9721508 1 row) (
pg_database_size(name)
Returns disk space used by the database with the specified name.SELECT pg_database_size('test'); Result: pg_database_size ------------------ 9721508 1 row) (
pg_indexes_size(regclass)
Returns total disk space used by indexes attached to the specified table.SELECT pg_indexes_size(2830); Result: pg_indexes_size ----------------- 8192 1 row) (
pg_relation_size(relation regclass, fork text)
Returns disk space used by the specified fork (‘main’, ‘fsm’, ‘vm’, or ‘init’) of the specified table or index.SELECT pg_relation_size(16881, 'main'); Result: pg_relation_size ------------------ 0 1 row) (
pg_relation_size(relation regclass)
Shorthand forpg_relation_size(..., 'main')
.SELECT pg_relation_size(16881); Result: pg_relation_size ------------------ 0 1 row) (
pg_size_bytes(text)
Converts a size in human-readable format with size units into bytes.SELECT pg_size_bytes('100'); Result: pg_size_bytes --------------- 100 1 row) (
pg_size_pretty(bigint)
Converts a size in bytes expressed as a 64-bit integer into a human-readable format with size units.SELECT pg_size_pretty(10::bigint); Result: pg_size_pretty ---------------- 10 bytes 1 row) (
pg_size_pretty(numeric)
Converts a size in bytes expressed as a numeric value into a human-readable format with size units.SELECT pg_size_pretty(10::numeric); Result: pg_size_pretty ---------------- 10 bytes 1 row) (
pg_table_size(regclass)
Returns disk space used by the specified table, excluding indexes (but including TOAST, free space map, and visibility map).SELECT pg_table_size('myschema.mytable'); Result: pg_table_size --------------- 8192 1 row) (
pg_tablespace_size(oid)
Returns disk space used by the tablespace with the specified OID.SELECT pg_tablespace_size(1663); Result: pg_tablespace_size -------------------- 40859636 1 row) (
pg_tablespace_size(name)
Returns disk space used by the tablespace with the specified name.SELECT pg_tablespace_size('pg_default'); Result: pg_tablespace_size -------------------- 40859636 1 row) (
pg_total_relation_size(regclass)
Returns total disk space used by the specified table, including all indexes and TOAST data.SELECT pg_total_relation_size(16881); Result: pg_total_relation_size ------------------------ 8192 1 row) (
pg_relation_filenode(relation regclass)
Returns the filenode number of the specified relation.SELECT pg_relation_filenode('pg_database'); Result: pg_relation_filenode ---------------------- 1262 1 row) (
pg_relation_filepath(relation regclass)
Returns file path name of the specified relation.SELECT pg_relation_filepath('pg_database'); Result: pg_relation_filepath ---------------------- global/1262 1 row) (
pg_filenode_relation(tablespace oid, filenode oid)
Finds the relation associated with a given tablespace and filenode.SELECT pg_filenode_relation(1663, 16485); Result: pg_filenode_relation ---------------------- test.ag_label_seq1 row) (
brin_summarize_new_values(index regclass)
Summarizes page ranges not already summarized.SELECT brin_summarize_new_values('brinidx'); Result: brin_summarize_new_values --------------------------- 0 1 row) (
gin_clean_pending_list(index regclass)
Moves GIN pending list entries into main index structure.SELECT gin_clean_pending_list('gin_test_idx'); Result: gin_clean_pending_list ------------------------ 0 1 row) (
pg_ls_dir(dirname text [, missing_ok boolean, include_dot_dirs boolean])
Lists the content of a directory.SELECT pg_ls_dir('.'); Result: pg_ls_dir ---------------------- pg_xlogglobal ... 28 row) (
pg_read_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ])
Returns the content of a text file.SELECT pg_read_file('test.sql'); Result: pg_read_file -------------- + test 1 row) (
pg_read_binary_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ])
Returns the content of a file.SELECT pg_read_binary_file('test'); Result: pg_read_binary_file --------------------- x6161610a 1 row) (
pg_stat_file(filename text[, missing_ok boolean])
Returns information about a file.SELECT pg_stat_file('test'); Result: pg_stat_file ----------------------------------------------------------------------------------- 4,"2017-10-18 11:05:09+09","2017-10-18 11:04:55+09","2017-10-18 11:04:55+09",,f) (1 row) (
pg_advisory_lock(key bigint)
Obtains exclusive session level advisory lock.SELECT pg_advisory_lock(1); SELECT locktype, classid, objid, mode FROM pg_locks where objid=1; Result:mode locktype | classid | objid | ----------+---------+-------+--------------- 0 | 1 | ExclusiveLock advisory | 1 row) (
pg_advisory_lock(key1 int, key2 int)
Obtains exclusive session level advisory lock.SELECT pg_advisory_lock(1,2); SELECT locktype, classid, objid, mode FROM pg_locks where objid=2; Result:mode locktype | classid | objid | ----------+---------+-------+--------------- 1 | 2 | ExclusiveLock advisory | 1 row) (
pg_advisory_lock_shared(key bigint)
Obtains shared session level advisory lock.SELECT pg_advisory_lock_shared(10); SELECT locktype, classid, objid, mode FROM pg_locks where objid=10; Result:mode locktype | classid | objid | ----------+---------+-------+----------- 0 | 10 | ShareLock advisory | 1 row) (
pg_advisory_lock_shared(key1 int, key2 int)
Obtains shared session level advisory lock.SELECT pg_advisory_lock_shared(10,20); SELECT locktype, classid, objid, mode FROM pg_locks where objid=20; Result:mode locktype | classid | objid | ----------+---------+-------+----------- 10 | 20 | ShareLock advisory | 1 row) (
pg_advisory_unlock(key bigint)
Releases an exclusive session level advisory lock.SELECT pg_advisory_unlock(1); Result: pg_advisory_unlock -------------------- t1 row) (
pg_advisory_unlock(key1 int, key2 int)
Releases an exclusive session level advisory lock.SELECT pg_advisory_unlock(1,2); Result: pg_advisory_unlock -------------------- t1 row) (
pg_advisory_unlock_all()
Releases all session level advisory locks held by the current session.SELECT pg_advisory_unlock_all(); Result: pg_advisory_unlock_all ------------------------ 1 row) (
pg_advisory_unlock_shared(key bigint)
Releases a shared session level advisory lock.SELECT pg_advisory_unlock_shared(10); Result: pg_advisory_unlock_shared --------------------------- t1 row) (
pg_advisory_unlock_shared(key1 int, key2 int)
Releases a shared session level advisory lock.SELECT pg_advisory_unlock_shared(10,20); Result: pg_advisory_unlock_shared --------------------------- t1 row) (
pg_advisory_xact_lock(key bigint)
Obtains exclusive transaction level advisory lock.SELECT pg_advisory_xact_lock(1); Result: pg_advisory_xact_lock ------------------------ 1 row) (
pg_advisory_xact_lock(key1 int, key2 int)
Obtains exclusive transaction level advisory lock.SELECT pg_advisory_xact_lock(1,2); Result: pg_advisory_xact_lock ------------------------ 1 row) (
pg_advisory_xact_lock_shared(key bigint)
Obtains shared transaction level advisory lock.SELECT pg_advisory_xact_lock_shared(10); Result: pg_advisory_xact_lock_shared ------------------------------ 1 row) (
pg_advisory_xact_lock_shared(key1 int, key2 int)
Obtains shared transaction level advisory lock.SELECT pg_advisory_xact_lock_shared(10,20); Result: pg_advisory_xact_lock_shared ------------------------------ 1 row) (
pg_try_advisory_lock(key bigint)
Obtains exclusive session level advisory lock if available.SELECT pg_try_advisory_lock(100); Result: pg_try_advisory_lock ---------------------- t1 row) (
pg_try_advisory_lock(key1 int, key2 int)
Obtains exclusive session level advisory lock if available.SELECT pg_try_advisory_lock(100,200); Result: pg_try_advisory_lock ---------------------- t1 row) (
pg_try_advisory_lock_shared(key bigint)
Obtains shared session level advisory lock if available.SELECT pg_try_advisory_lock_shared(1000); Result: pg_try_advisory_lock_shared ----------------------------- t1 row) (
pg_try_advisory_lock_shared(key1 int, key2 int)
Obtains shared session level advisory lock if available.SELECT pg_try_advisory_lock_shared(1000,2000); Result: pg_try_advisory_lock_shared ----------------------------- t1 row) (
pg_try_advisory_xact_lock(key bigint)
Obtains exclusive transaction level advisory lock if available.SELECT pg_try_advisory_xact_lock(1000); Result: pg_try_advisory_xact_lock --------------------------- t1 row) (
pg_try_advisory_xact_lock(key1 int, key2 int)
Obtains exclusive transaction level advisory lock if available.SELECT pg_try_advisory_xact_lock(1000,2000); Result: pg_try_advisory_xact_lock --------------------------- t1 row) (
pg_try_advisory_xact_lock_shared(key bigint)
Obtains shared transaction level advisory lock if available.SELECT pg_try_advisory_xact_lock_shared(10000); Result: pg_try_advisory_xact_lock_shared ---------------------------------- t1 row) (
pg_try_advisory_xact_lock_shared(key1 int, key2 int)
Obtains shared transaction level advisory lock if available.SELECT pg_try_advisory_xact_lock_shared(10000,20000); Result: pg_try_advisory_xact_lock_shared ---------------------------------- t1 row) (
User-defined function
AgensGraph enables you to create and use the functions you need.
As AgensGraph can use SQL and Cypher query statements at the same
time, it is easy to create functions using them, and the created
functions can be confirmed with \df
command. The generated
functions can also be called using SELECT or RETURN syntax.
You may refer to PostgreSQL documentation for more information on creation and grammars of user-defined functions.
User-defined function
CREATE FUNCTION func_name (integer, integer) RETURNS integer AS 'SELECT $1 + $2;' LANGUAGE SQL IMMUTABLENULL ON NULL INPUT; RETURNS SELECT func_name (1, 1); Result:add ----- 2 1 row) ( RETURN func_name (1, 1); Result:add ----- 2 1 row) ( DROP FUNCTION func_name (integer, integer);
Hybrid Query Language
Introduction
This section explains how to use a SQL query and a Cypher query statement together as shown in the example below.
Through the SQL statement used in the RDB, table and column aggregation, statistical processing, and GDB’s Cypher syntax replace the RDB’s join operation to support better data queries.
CREATE GRAPH bitnine;
CREATE VLABEL dev;
CREATE (:dev {name: 'someone', year: 2015});
CREATE (:dev {name: 'somebody', year: 2016});
CREATE TABLE history (year, event)
AS VALUES (1996, 'PostgreSQL'), (2016, 'AgensGraph');
Syntax
Cypher in SQL
It is possible to use a Cypher syntax inside the FROM clause to utilize the dataset of the vertices or edges stored in the graph DB as a data set in the SQL statement.
Syntex :
SELECT [column_name]
FROM ({table_name|SQLquery|CYPHERquery})
WHERE [column_name operator value];
It can be used as the following example:
SELECT n->>'name' as name
FROM history, (MATCH (n:dev) RETURN n) as dev
WHERE history.year > (n->>'year')::int;
name---------
someone1 row) (
SQL in Cypher
When querying the content of graph DB through Cypher syntax, it is possible to use Match and Where syntaxes for search by specific data of RDB. However, the resulting dataset in the SQL statement should be configured to return a single row of results.
Syntex :
MATCH [table_name]WHERE (column_name operator {value|SQLquery|CYPHERquery})
RETURN [column_name];
It can be used as the following example:
:dev)
MATCH (nWHERE n.year < (SELECT year FROM history WHERE event = 'AgensGraph')
RETURN properties(n) AS n;
n-----------------------------------
"name": "someone", "year": 2015}
{1 row) (
Drivers
Introduction
AgensGraph supports a DB connection using a client driver. Bitnine’s
official drivers and existing PostgreSQL drivers support various
languages.
AgensGraph officially provides the JDBC and Python drivers.
Usage of the Java Driver
This section describes how the graph data of AgensGraph is processed and handled in Java applications. AgensGraph’s JDBC driver is based on the PostgreSQL JDBC driver and allows Java applications to access the AgensGraph database. APIs of the AgensGraph Java driver are similar to those of the Postgres JDBC driver. The only difference is that the AgensGraph JDBC driver supports the Cypher query language as well as SQL, utilizing graph data (vertices, edges, and paths) as data types (Java classes and instances).
How to use the AgensGraph JDBC driver is described throughout this section with examples.
Get the Driver
Download the driver (jar) from AgensGraph JDBC Download or use maven as follows:
<dependency>
<groupId>net.bitnine</groupId>
<artifactId>agensgraph-jdbc</artifactId>
<version>1.4.2</version>
</dependency>
Connection
There are two things to consider when connecting to AgensGraph using the Java driver: Class name and connection string, which are to be loaded into the Java driver.
- class name :
net.bitnine.agensgraph.Driver
. - Connection string consisting of sub-protocol, server, port, and
database.
- sub-protocol :
jdbc:agensgraph://
. - connection string(including sub-protocol) :
jdbc:agensgraph://server:port/database
.
- sub-protocol :
The following code is an example of a connection to AgensGraph. Connect to AgensGraph through the Connection object.
import java.sql.DriverManager;
import java.sql.Connection;
public class AgensGraphTest {
public static void main(String[] args) {
try{
Class.forName("net.bitnine.agensgraph.Driver");
Connection conn = DriverManager.getConnection
("jdbc:agensgraph://127.0.0.1:5432/agens","agens","agens");
System.out.println("connection success");
} catch (Exception e) {
.printStackTrace();
e}
}
}
Retrieving Data
This section describes how to query graph data in AgensGraph using
the MATCH
clause.
The result of the query is a vertex
of AgensGraph. You
may get the attributes by importing the result as a vertex
object.
import net.bitnine.agensgraph.util.*;
import java.sql.*;
import net.bitnine.agensgraph.graph.Vertex;
public class AgensGraphSelect {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Class.forName("net.bitnine.agensgraph.Driver");
Connection conn = DriverManager.getConnection
("jdbc:agensgraph://127.0.0.1:5432/agens","agens","agens");
try{
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery
("MATCH (:person {name: 'John'})-[:knows]-(friend:person) RETURN friend");
while (rs.next()) {
= (Vertex) rs.getObject(1);
Vertex person System.out.println(person.getString("name"));
}
} catch(Exception e) {
.printStackTrace();
e}
}
}
Creating Data
This section describes how to insert graph data into AgensGraph.
The following example creates a vertex with a vlabel named Person. We
used JsonObject
to add the property of the corresponding
vertex.
import net.bitnine.agensgraph.util.*;
import java.sql.*;
public class AgensGraphCreate {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Class.forName("net.bitnine.agensgraph.Driver");
Connection conn = DriverManager.getConnection
("jdbc:agensgraph://127.0.0.1:5432/agens","agens","agens");
try{
PreparedStatement pstmt = conn.prepareStatement("CREATE (:person ?)");
= JsonbUtil.createObjectBuilder()
Jsonb j .add("name", "John")
.add("from", "USA")
.add("age", 17)
.build();
.setObject(1, j);
pstmt.execute();
pstmt} catch(Exception e) {
.printStackTrace();
e}
finally{
.close();
conn}
}
}
The final string created:
CREATE (:Person {name: 'John', from: 'USA', age: 17})
[Reference]
In JDBC, the question mark (?) is a placeholder for the positional
parameter of the PreparedStatement. You may be confused with this mark
as it is also being used in other SQL operators. To avoid confusion,
there should be a space between the question mark (?) and a character
when used in the prepared statement.
Graph Object Classes
Class | Description |
---|---|
GraphId | A Java class corresponding to AgensGraph graphid type. |
Vertex | A Java class corresponding to AgenceGraph vertex type. Supports access to labels and properties. |
Edge | A Java class corresponding to AgensGraph edge type. Supports access to labels and properties. |
Path | A Java class corresponding to AgensGraph graphpath type. Support how to access path length and vertex/edge in the path. |
Jsonb | A Java class corresponding to AgensGraph jsonb type. Vertex and edge use Jsonb to store properties(attributes). Supports access to JSON scalar type, array type, and object types. |
JsonbUtil | Provides various ways to create a jsonb object as in the
CREATE clause examples above. |
Usage of the Python Driver
This section shows how to use the AgensGraph Python driver with examples. Python driver is a Psycopg2 type extension module for AgensGraph, and supports additional data types such as Vertex, Edge, and Path to express graph data.
Get the Driver
You can download AgensGraph Python driver from the Bitnine website’s Download - Developer Resources or our Github’s agensgraph-python.
git clone https://github.com/bitnine-oss/agensgraph-python.git
Install
$ pip install -U pip
$ pip install psycopg2
$ python /path/to/agensgraph/python/setup.py install
Connection
This is an example of a connection string for accessing AgensGraph using a Python driver.
import psycopg2
import agensgraph
conn = psycopg2.connect("dbname=agens host=127.0.0.1 user=agens")
print "Opened database successfully"
Creating Data
This section explains how to insert graph data into AgensGraph. The following code (example) creates a vertex with a vlabel “Person”.
import psycopg2
import agensgraph
conn = psycopg2.connect("dbname=agens host=127.0.0.1 user=agens")
print "Opened database successfully"
cur = conn.cursor()
cur.execute("DROP GRAPH IF EXISTS test CASCADE")
cur.execute("CREATE GRAPH test")
cur.execute("SET graph_path = test")
cur.execute("CREATE (:person {name: 'John', from: 'USA', age: 17})")
cur.execute("CREATE (:person {name: 'Daniel', from: 'Korea', age: 20})")
cur.execute("MATCH (p:person {name: 'John'}),(k:person{name: 'Daniel'}) CREATE (p)-[:knows]->(k)")
conn.commit()
conn.close()
Retrieving Data
This section explains how to query graph data in AgensGraph using a
MATCH
clause. The result of the query is a vertex of
AgensGraph. You can get the properties by importing the result as a
vertex object.
import psycopg2
import agensgraph
conn = psycopg2.connect("dbname=agens host=127.0.0.1 user=agens")
print "Opened database successfully"
cur = conn.cursor()
cur.execute("SET graph_path = test")
cur.execute("MATCH (:person {name: 'John'})-[:knows]-(friend:person) RETURN friend")
friend = cur.fetchone()
print str(friend[0])
conn.commit()
conn.close()
Usage of the Node.js Driver
AgensGraph client for node.js. To be used concurrently with node-postgres. Adds AgensGraph compatibility for node-postgres. Support for the Cypher query language, and vertex, edge and path graph data types.
Install
The driver can be downloaded from github agensgraph-nodejs or installed using yarn.
# if you are using yarn
$ yarn add pg @bitnine-oss/ag-driver
# or npm
$ npm install pg @bitnine-oss/ag-driver
Connection
To connect to AgensGraph via node-js, one can connect via environment variables, programatically, or using a connection URI.
Connecting programmatically can be done by passing an object with config values to your AgensGraph client and using client.connect() to establish a connection:
var ag = require('@bitnine-oss/ag-driver');
var config = {
user: 'username',
password: 'password',
database: 'database name of agensgraph',
host: '127.0.0.1',
port: 5432
;
}
const client = new ag.Client(config);
.connect();
client.end(); client
Queries
To retrieve data from AgensGraph, use the query() API function to query the database. There are multiple ways to send queries, including passing text directly, using parameters, passing in objects, and using prepared statements. The following examples illustrate the different possible methods of querying.
Users can retrieve Cypher data by passing text directly to client.query():
var ag = require('@bitnine-oss/ag-driver');
const client = new ag.Client(Config);
.connect();
client.query('SET graph_path = gpt'); //set graph path to gpt
client.query("MATCH (a:person)-[r:knows]->(b:person) WHERE b.name = 'Adam' RETURN a,r,b;", function (err, res) {
clientif (err) {
throw err;
else {
} console.log(res.rows);
};
}).end(); client
Users can also send parameterized queries:
const text = "MATCH (a:person)-[:knows]->(b:person) WHERE b.name = $1 RETURN a;"
const values = ['Adam'];
.connect();
client.query('SET graph_path = gpt'); //set graph path to gpt
client.query(text, values, function (err, res) {
clientif (err) {
throw err;
else {
} console.log(res.rows);
}; })
Passing a config object:
const query = {
text: "MATCH (a:person)-[:knows]->(b:person) WHERE b.name = $1 RETURN a;",
values: ['Adam']
}
.connect();
client.query('SET graph_path = gpt'); //set graph path to gpt
client.query(query, function (err, res) {
clientif (err) {
throw err;
else {
} console.log(res.rows);
}; })
Users can also use named prepared statements. Using prepared statements allows query execution plans to be cached on the server on a per connection statement. Once a query name is sent to the server, it will be parsed and executed. On subsequent sends the query will skip the parse request and instead send the name of the query:
const query = {
name: 'fetch-data',
text: "MATCH(n) WHERE n.name = 'Eve' RETURN n"
}
.query(query, (err, res) => {
clientif (err) {
throw err;
else {
} console.log(res.rows);
}; })
Creating Data
To create data in AgensGraph, the query() API function is again used to query the database. Below is an example of creating Cypher data by passing text directly to client.query():
var ag = require('@bitnine-oss/ag-driver');
const client = new ag.Client(Config);
.connect();
client.query('CREATE GRAPH gpt');
client.query('SET graph_path = gpt');
client.query("CREATE (a:person {name:'Alice'})-[r:knows {from: 'school'}]->(b:person {name: 'Bob'}) RETURN a,r,b", function (err, res) {
clientif (err) {
throw err;
else {
} = res.rows[0].a;
a = res.rows[0].r;
r = res.rows[0].b;
b console.log(a.label);
console.log(a.id);
console.log(a.props.name);
console.log(r.label);
console.log(r.id);
console.log(r.startVertexId);
console.log(r.endVertexID);
console.log(r.props.from);
console.log(b.label);
console.log(b.id);
console.log(b.props.name);
}; })
Graph Data Types
The following is a brief explanation detailing the different datatypes handled by agensgraph-nodejs extension.
Class Function | Description | Properties |
---|---|---|
GraphId |
Corresponds to the graphid type in AgensGraph. |
oid, id |
Vertex |
Corresponds to vertex type in AgensGraph. It supports
access methods for the label and properties. |
label, id, props |
Edge |
Corresponds to edge type in AgensGraph. It supports
access methods for the label and properties. |
label, id, start, end, props |
Path |
Corresponds to graphpath type in AgensGraph. It
supports access methods for the length of the path, and accessing for
vertexes and edges in the path. |
vertices, edges, start, end, len |
TODO
- Typescript Refactoring
Procedural language
Procedural language
AgensGraph can also write user-defined functions in languages other than SQL and C. These other languages are generally referred to as procedural languages (PLs). In the case of functions written in procedural languages, the database server cannot interpret the function’s source text. Thus, the task is passed to a special handler that knows the details of the language. The handler performs all the tasks, including parsing, syntax analysis, and execution. The handler itself is a C language function that, like any C other functions, is compiled into a shared object and loaded on demand. Current AgensGraph has four procedural languages: PL/pgSQL, PL/Tcl, PL/Perl, and PL/Python.
Installing Procedural Languages
Procedural languages must be installed in each database to be used. However, the procedural languages installed in the template1 database will be automatically available in all subsequent databases created, as the entries in template1 are copied by CREATE DATABASE. The database administrator can determine which languages can be used in which databases and can make only certain languages available, if needed.
In the case of languages provided with the standard distribution, you
only need to run CREATE EXTENSION
language_name to
install them in the current database. Alternatively, you may use the
program createlang to do this from the shell command line. For example,
to install a language called PL/Python in the template1
database, see the following example:
createlang plpython template1
The manual procedure described below is recommended only if you are installing a language that is not packaged into extension.
Manual Procedural Language Installation
Procedural languages can be installed in a database in five steps and
must be done by the database superuser. In most cases, the necessary SQL
commands can be packaged into an extension’s install script and executed
using CREATE EXTENSION.
The shared object of the language handler should be compiled and installed in an appropriate library directory. It works the same way as building and installing modules with regular user-defined C functions. Often the language handler relies on external libraries that provide the actual programming language engine; in such a case, the shared object must be installed.
The handler must be declared as a command.
CREATE FUNCTION handler_function_name() RETURNS language_handlerAS 'path-to-shared-object' LANGUAGE C;
The special return type of
language_handler
tells the database system that this function does not return one of the defined SQL data types and cannot be used directly in the SQL statement.Optionally, the language handler can provide an “inline” handler function that executes anonymous code blocks (DO commands) written in this language. If an inline handler function is provided by the language, it must be declared with the following command:
CREATE FUNCTION inline_function_name(internal) RETURNS voidAS 'path-to-shared-object' LANGUAGE C;
Optionally, the language handler can provide a “validator” function that checks the accuracy of the function definition without actually executing it. The validator function is called CREATE FUNCTION. If the validator function is provided by the language, you must declare it with the following command:
CREATE FUNCTION validator_function_name(oid) RETURNS voidAS 'path-to-shared-object' LANGUAGE C STRICT;
Finally, PL must be declared with the following command:
CREATE [TRUSTED] [PROCEDURAL] LANGUAGE language-name HANDLER handler_function_name [INLINE inline_function_name] [VALIDATOR validator_function_name] ;
The optional keyword
TRUSTED
specifies that the language does not grant access rights to data that will not be used by the user. Trusted languages are designed for general database users (i.e. users without superuser privileges) and can safely create functions and trigger procedures. As the PL function is executed within the database server, theTRUSTED
flag should only be provided for languages that do not allow access to the database server or file system. PL/pgSQL, PL/Tcl, and PL/Perl languages are considered to be trusted. Languages PL/TclU, PL/PerlU, and PL/PythonU are designed to provide unlimited functionality and should not be marked as trusted.In the default AgensGraph installation, a handler for the PL/pgSQL language is built and installed in the “library” directory. The PL/pgSQL language itself is installed in every database. Although Tcl support is configured and handlers for PL/Tcl and PL/TclU are built and installed in the library directory, the languages themselves are not installed by default in the database. Likewise, even if Perl support is configured, PL/Perl and PL/PerlU handlers are built and installed, Python support is configured, and a PL/PythonU handler is installed, these languages are not installed by default.
PL/pgSQL
Introduction
PL/pgSQL is a loadable procedural language in AgensGraph. The design objective of PL/pgSQL is to be a loadable procedural language with the following features:
- Can be used to create functions and trigger procedures;
- Adds control structures to the SQL language;
- Can perform complex computations;
- Inherits all user-defined types, functions, and operators;
- Can be defined to be trusted by the server;
- Is easy to use.
Functions created in PL/pgSQL can be used wherever built-in functions can be used. For example, you can create a function that processes complex conditions, and later define the function as an operator or use it in index expression.
In AgensGraph, PL/pgSQL is installed by default. However, as it is still a loadable module, administrators who are strictly security-conscious can remove PL/pgSQL.
Advantages of PL/pgSQL
SQL is a query language used in databases. Although SQL is easy to
learn, all SQL statements must be executed separately per statement in
the database server.
In other words, a client application sends a query to the database
server individually, waits until each query is processed, takes the
result, computes it, and then sends the next query to the server. These
processes generate internal processing and cause network load if the
database and client are on different machines.
As PL/pgSQL is easy to use in procedural languages and SQL is easy to
use, you can group queries and operations within a database server and
save on client/server communications loads.
- Eliminate unnecessary communications between client and
server.
- Clients do not have to hold unnecessary intermediate results or
transfer them between client and server.
- You do not need to do repeated query parsing.
Because of these factors, you can expect a noticeable performance
improvement over applications that do not use stored functions.
In addition, PL/pgSQL may use all data types, operations, and functions
of SQL.
Supported argument and result data types
Functions written in PL/pgSQL can accept scalar or array data types
supported by the server as arguments and can return results. You can
also use or return a specified complex type (row type). PL/pgSQL
functions can also return records.
PL/pgSQL functions can be declared using the VARIADIC marker to allow arguments of varying numbers. This works in exactly the same way as SQL functions.
PL/pgSQL functions can be declared to accept and return various
types, such as anyelement
, anyarray
,
anynonarray
, anyenum
, and
anyrange
. The actual data types handled by the polymorphic
function may vary from call to call.
Structure of PL/pgSQL
Functions written in PL/pgSQL are defined in the server by executing CREATE FUNCTION (command) as follows:
CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'function body text'
LANGUAGE plpgsql;
The function body is simply a literal string associated with CREATE FUNCTION. It is more helpful to use dollar ($) quotes to write function bodies than to use a usual single quotes syntax. If there is no dollar citation mark, you should escape it by doubling single quotes or backslashes of the function body. Almost all examples in this section use dollar quote literals in function bodies.
PL/pgSQL is a block-structured language. The full text of a function definition should be a block. The block is defined as follows:
<<label>> ]
[ DECLARE
[
declarations ]BEGIN
statementsEND [ label ];
Each declaration and each statement within a block ends with a semicolon. A block appearing within other blocks, as shown above, should have a semicolon after END. However, a semicolon is not required at the end of the function body.
Tip : In general, they mistakenly use a semicolon immediately after BEGIN very often. This is incorrect and causes a syntax error.
Label is needed only if you want to identify a block to use in an EXIT statement or to restrict the name of a variable declared in a block. If the label is positioned after END, it must match the label at the beginning of the block. Identifiers, like regular SQL commands, are converted to lower case by default if they do not have double-quotes.
Annotations work the same way in PL/pgSQL code as in regular SQL. Two dashes (–) are recognized as a comment (from the beginning to the end of the line). To process a comment as a block, including the comment between /* and */.
Every statement in a statement section of a block can be a sub-block. Subblocks may be used for logical grouping or localization of a small group of variables. A variable declared in a subblock masks a variable of a similar name in an outer block for the duration of the subblock. By specifying a block name, you may access an external variable.
CREATE FUNCTION somefunc() RETURNS integer AS $$
DECLARE
integer := 30;
quantity BEGIN
'Quantity here is %', quantity; -- Prints 30
RAISE NOTICE := 50;
quantity --
-- Create a subblock
--
DECLARE
integer := 80;
quantity BEGIN
'Quantity here is %', quantity; -- Prints 80
RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Prints 50
RAISE NOTICE END;
'Quantity here is %', quantity; -- Prints 50
RAISE NOTICE
RETURN quantity;
END;
$$ LANGUAGE plpgsql;
Note : Actually there is a hidden “outer block” surrounding the body of the PL/pgSQL function. This block provides the function’s parameter declarations (if any) and special variables such as FOUND. The outer block is labeled with the name of the function. That is, you can limit parameters and special variables to the name of the function.
It is important that using BEGIN/END to group statements in PL/pgSQL is not to be confused with similarly-named SQL commands for transaction control. BEGIN/END in PL/pgSQL is only used for grouping; it does not start/end any transaction. Functions and trigger procedures are always executed within a transaction set by an outer query. You cannot start or commit a transaction because there is no context to start the transaction. However, you may construct a sub-transaction that can be rolled back without affecting external transactions since a block contains an EXCEPTION clause.