Syntactic sugar in PostgreSQL
by Anton Abramchenko
Serial Data Type & Sequence
-- Create autoincrement
CREATE SEQUENCE example_seq
START WITH 3
INCREMENT BY 3
MINVALUE 3
NO MAXVALUE;
-- After table creation, the sequence entity_id_seq will be created
CREATE TABLE entity (
id SERIAL PRIMARY KEY,
value VARCHAR(255)
);
-- Check available sequences
SELECT * FROM pg_statio_user_sequences;
Sequence Control
-- Set next increment as current and return it
SELECT nextval('entity_id_seq'); -- 1
SELECT nextval('entity_id_seq'); -- 2
SELECT nextval('entity_id_seq'); -- 3
INSERT INTO entity(value) VALUES ('some foo') RETURNING id; -- 4
-- Update sequence and return updated value;
SELECT nextval('entity_id_seq');
-- Get current value
SELECT currval('entity_id_seq');
-- Get last inserted value
SELECT lastval();
-- Update sequence value
SELECT setval('entity_id_seq', 99);
One Sequence for Two Tables
CREATE SEQUENCE multi_entity_seq;
CREATE TABLE multi_entity_a(
id INTEGER DEFAULT nextval('multi_entity_seq') PRIMARY KEY,
value VARCHAR(255)
);
CREATE TABLE multi_entity_b(
id INTEGER DEFAULT nextval('multi_entity_seq') PRIMARY KEY,
value VARCHAR(255)
);
INSERT INTO multi_entity_a (value) VALUES ('some value of ' || currval('multi_entity_seq'))
RETURNING id; -- 1
INSERT INTO multi_entity_a (value) VALUES ('some value of ' || currval('multi_entity_seq'))
RETURNING id; -- 2
Reset Sequence
-- Truncate operation does not update the sequence
TRUNCATE TABLE entity;
-- Reset sequence
TRUNCATE TABLE entity RESTART IDENTITY;
-- Alter reset sequence
ALTER SEQUENCE entity_id_seq RESTART;
-- or
SELECT setval('entity_id_seq', 1, false);
Array Data Type
CREATE TABLE book (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
tags VARCHAR(255) [],
authors INT []
);
INSERT INTO book (title, tags, authors)
VALUES ( 'PostgreSQL 9.6 High Performance', '{PostgreSQL,9.6,High,Performance}', '{1, 2}'),
( 'Mastering PostgreSQL 9.6', '{PostgreSQL,9.6,Mastering}', '{10,12,3}'),
('PostgreSQL Administration Cookbook', 'Some info', '{9.5,Administration}', '{29,41,36}'),
( 'PostgreSQL High Performance Cookbook', '{PostgreSQL,High,Performance}','{18,35}');
Array Functions and Operands
-- in array
SELECT * FROM book WHERE '9.6' = ANY (tags);
-- not in array
SELECT * FROM book WHERE id != ALL (SELECT eq FROM (VALUES (1), (2)) AS t(eq));
-- select all rows with ‘high’ or 9.5 version
SELECT * FROM book WHERE '{9.5,High}' && tags;
-- select all rows with ‘high’ and 9.6 version
SELECT * FROM book WHERE '{9.6,High}' <@ tags;
-- Get books where title is like one of array title values
SELECT * FROM book WHERE book.title ~~* ANY (ARRAY ['%Perfor%', '%Admin%']);
-- Array to string conversion
SELECT array_to_string(tags, ',') FROM book;
-- Array to json conversion
SELECT array_to_json(tags) FROM book;
Extension hStore
CREATE EXTENSION hstore;
CREATE TABLE product (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(12, 2) NOT NULL,
attributes HSTORE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE
'UTC'),
updated_at TIMESTAMP
);
Adding data to hStore
INSERT INTO product (title, description, price, attributes)
VALUES ('Product A', 'Description', 35.00, 'color => red, weight => 1000, sku => LPT123'),
('Product B', 'Description', 70.00, 'color => blue, weight => 2500, sku => LPT145'),
('Product C', 'Description', 100.00, 'color => withe, weight => 1500, sku => LPT245,
is_something => true'),
('Product D', 'Description', 85.00,
'color => withe, weight => 3500, sku => LPT125, is_something => false, hidden => true'),
('Product E', 'Description', 10.00, 'color => red, weight => 1500, sku => LPT37')
RETURNING *;
Retrieving data from hStore
SELECT
title,
price :: MONEY,
attributes -> 'color' AS color,
attributes -> 'weight' AS weight,
attributes -> 'sku' AS sku
FROM product
WHERE (attributes -> 'weight') :: INT > 1500
ORDER BY replace(attributes -> 'sku', 'LPT', ' ');
hStore Data Manipulation
-- hstore key exists
SELECT * FROM product WHERE attributes ? 'is_something';
-- hstore contains all specified keys
SELECT * FROM product WHERE attributes ?& string_to_array('is_something,hidden', ',');
-- hstore to data records
SELECT
id,
(each(attributes)).key AS attribute,
(each(attributes)).value AS value
FROM product;
Creating XML data
-- Books to xml
CREATE TABLE book_as_xml (
id SERIAL PRIMARY KEY,
content XML NOT NULL
);
-- Transform all books to xml
INSERT INTO book_as_xml (content)
SELECT xmlroot(
xmlelement(NAME book, xmlforest(id, title, authors, tags)),
VERSION '1.1',
STANDALONE YES
) FROM book
RETURNING content;
XML2 - Transform XML to Presentable view
CREATE EXTENSION xml2;
CREATE OR REPLACE FUNCTION xml_pretty(TEXT)
RETURNS XML AS $body$
SELECT xslt_process($1,
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*" />
<xsl:output method="xml" indent="yes" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>' :: TEXT) :: XML
$body$ LANGUAGE SQL IMMUTABLE STRICT;
XML Manipulation
-- Show pretty xml
SELECT xml_pretty(content) FROM book_as_xml;
-- Xpath
SELECT array_to_string(xpath('//title/text()', content), '; ') FROM book_as_xml;
-- Get all tags values
SELECT array_to_string(xpath('//tags/element/text()', content), '; ') FROM book_as_xml;
-- Return all table content as xml
SELECT xmlroot(
xmlelement(name body, table_to_xml('book', TRUE, TRUE, '')),
VERSION '1.1',
STANDALONE YES
) FROM book;
JSON & JSONB
CREATE TABLE entity_as_jsonb (
id SERIAL PRIMARY KEY,
content JSONB
);
INSERT INTO entity_as_jsonb (type, content)
SELECT json_build_object(
'title', title,
id', id,
'description', description,
'price', price :: MONEY,
'attributes', attributes
) FROM product RETURNING * ;
JSON Data Retrieving
SELECT
content ->> 'id' AS id, -- like text
content ->> 'title' AS title, -- like text
content -> 'attributes' AS attributes, -- like json
content #>> '{attributes,sku}' AS sky -- by path
FROM entity_as_json
WHERE type = 'product' AND content #>> '{attributes,sku}' LIKE '%45';
-- Aggregate all table data
SELECT json_agg(content) FROM entity_as_json;
-- Array to json conversion
SELECT array_to_json(tags) FROM book;
JSON Append Function
CREATE OR REPLACE FUNCTION json_append(data JSON, insert_data JSON)
RETURNS JSON
IMMUTABLE LANGUAGE SQL AS $$
SELECT ('{' || string_agg(to_json(key) || ':' || value, ',') || '}') :: JSON
FROM (
SELECT * FROM json_each(data)
UNION ALL
SELECT * FROM json_each(insert_data)
) t;
$$;
JSON Merge Function
CREATE OR REPLACE FUNCTION json_merge(data JSON, merge_data JSON)
RETURNS JSON
IMMUTABLE LANGUAGE SQL AS $$
SELECT ('{' || string_agg(to_json(key) || ':' || value, ',') || '}') :: JSON
FROM (
WITH to_merge AS (
SELECT * FROM json_each(merge_data)
)
SELECT * FROM json_each(data) WHERE key NOT IN (SELECT key FROM to_merge)
UNION ALL
SELECT * FROM to_merge
) t;
$$;
Check Constraint
CREATE TABLE web_user (
id SERIAL PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL CHECK (trim(username) <> ''),
email VARCHAR(255) UNIQUE NOT NULL CHECK (valid_email(email)),
password CHARACTER(40) NOT NULL CHECK (char_length(password) = 40),
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated TIMESTAMP
);
CREATE EXTENSION pgcrypto;
INSERT INTO web_user VALUES (
'2', 'foo', 'abramchenkoa@bar.com', ENCODE(DIGEST('test', 'sha1'), 'hex')
);
Domain and Citext Extension
CREATE EXTENSION citext;
-- Create data type like email RFC5322
CREATE DOMAIN email AS citext
CHECK ( value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]' ||
'+@[a-zA-Z0-9](?:[a-zA-Z0-9-]' ||
'{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9]' ||
'(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'
);
Write functions on Perl, Python, JS, Ruby, PHP
CREATE EXTENSION plperlu;
CREATE FUNCTION valid_email(text)
RETURNS boolean
LANGUAGE plperlu
IMMUTABLE LEAKPROOF STRICT AS
$$
use Email::Valid;
my $email = shift;
Email::Valid->address($email) or die "Invalid email address: $emailn";
return 'true';
$$;
Full Text Search
-- Add a new column
ALTER TABLE book ADD COLUMN search_fields TSVECTOR;
-- Fill the column for searching
UPDATE book
SET search_fields = to_tsvector(
'english',
book.title || ' ' || array_to_string(book.tags, ' ')
);
-- Add index
CREATE INDEX textsearch_idx ON book USING GIN (search_fields);
Search Queries
-- Get current text search config
SELECT get_current_ts_config(); -- english
-- Show all available text search configs
SELECT * FROM pg_ts_config;
-- Search examples
SELECT * FROM book
WHERE search_fields @@ to_tsquery('high & postgre:* & 9.6');
SELECT * FROM book
WHERE search_fields @@ plainto_tsquery(get_current_ts_config(), 'postgresql performance')
;
-- Displays query matching, how title matches the query
SELECT id, title, ts_headline(title, q) FROM book, to_tsquery('postgre:* & performance') AS q
WHERE setweight(to_tsvector('english', title),'A')
|| setweight(to_tsvector('english', content), 'B') @@ q;
Search By Trigrams
-- Enable extension
CREATE EXTENSION pg_trgm;
-- Add index
CREATE INDEX trgm_idx ON book USING GIST (title gist_trgm_ops);
-- How similar are the arguments
SELECT title, similarity(title, 'Postgre') AS sml
FROM book WHERE title % 'Postgre'
ORDER BY sml DESC;
-- How similar are the first string and the most similar word of the second string
SELECT title, word_similarity(title, 'Postgre') AS sml
FROM book WHERE title %> 'Postgre'
ORDER BY sml DESC;
Ltree Hierarchical Data Type
-- Enable extension
CREATE EXTENSION ltree;
-- Store branch like
CREATE TABLE comment (
id SERIAL PRIMARY KEY,
message TEXT,
branch LTREE NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Add index
CREATE INDEX ON comment USING GIST (branch);
Ltree Data Manipulation
INSERT INTO comment (message, branch) VALUES ('Comment 1', '0');
INSERT INTO comment (message, branch) VALUES ('Comment 1.1', '0.1');
INSERT INTO comment (message, branch) VALUES ('Comment 2', '0');
INSERT INTO comment (message, branch) VALUES ('Comment 2.1', '0.3');
INSERT INTO comment (message, branch) VALUES ('Comment 2.2', '0.3');
INSERT INTO comment (message, branch) VALUES ('Comment 2.2.1', '0.3.4');
-- Сhildren of the third message
SELECT * FROM comment WHERE branch <@ '0.3';
-- Get by lquery
SELECT * FROM comment WHERE branch ~ '*.3.*'::lquery;
Thank You For Attention!

Syntactic sugar in postgre sql

  • 1.
    Syntactic sugar inPostgreSQL by Anton Abramchenko
  • 2.
    Serial Data Type& Sequence -- Create autoincrement CREATE SEQUENCE example_seq START WITH 3 INCREMENT BY 3 MINVALUE 3 NO MAXVALUE; -- After table creation, the sequence entity_id_seq will be created CREATE TABLE entity ( id SERIAL PRIMARY KEY, value VARCHAR(255) ); -- Check available sequences SELECT * FROM pg_statio_user_sequences;
  • 3.
    Sequence Control -- Setnext increment as current and return it SELECT nextval('entity_id_seq'); -- 1 SELECT nextval('entity_id_seq'); -- 2 SELECT nextval('entity_id_seq'); -- 3 INSERT INTO entity(value) VALUES ('some foo') RETURNING id; -- 4 -- Update sequence and return updated value; SELECT nextval('entity_id_seq'); -- Get current value SELECT currval('entity_id_seq'); -- Get last inserted value SELECT lastval(); -- Update sequence value SELECT setval('entity_id_seq', 99);
  • 4.
    One Sequence forTwo Tables CREATE SEQUENCE multi_entity_seq; CREATE TABLE multi_entity_a( id INTEGER DEFAULT nextval('multi_entity_seq') PRIMARY KEY, value VARCHAR(255) ); CREATE TABLE multi_entity_b( id INTEGER DEFAULT nextval('multi_entity_seq') PRIMARY KEY, value VARCHAR(255) ); INSERT INTO multi_entity_a (value) VALUES ('some value of ' || currval('multi_entity_seq')) RETURNING id; -- 1 INSERT INTO multi_entity_a (value) VALUES ('some value of ' || currval('multi_entity_seq')) RETURNING id; -- 2
  • 5.
    Reset Sequence -- Truncateoperation does not update the sequence TRUNCATE TABLE entity; -- Reset sequence TRUNCATE TABLE entity RESTART IDENTITY; -- Alter reset sequence ALTER SEQUENCE entity_id_seq RESTART; -- or SELECT setval('entity_id_seq', 1, false);
  • 6.
    Array Data Type CREATETABLE book ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, tags VARCHAR(255) [], authors INT [] ); INSERT INTO book (title, tags, authors) VALUES ( 'PostgreSQL 9.6 High Performance', '{PostgreSQL,9.6,High,Performance}', '{1, 2}'), ( 'Mastering PostgreSQL 9.6', '{PostgreSQL,9.6,Mastering}', '{10,12,3}'), ('PostgreSQL Administration Cookbook', 'Some info', '{9.5,Administration}', '{29,41,36}'), ( 'PostgreSQL High Performance Cookbook', '{PostgreSQL,High,Performance}','{18,35}');
  • 7.
    Array Functions andOperands -- in array SELECT * FROM book WHERE '9.6' = ANY (tags); -- not in array SELECT * FROM book WHERE id != ALL (SELECT eq FROM (VALUES (1), (2)) AS t(eq)); -- select all rows with ‘high’ or 9.5 version SELECT * FROM book WHERE '{9.5,High}' && tags; -- select all rows with ‘high’ and 9.6 version SELECT * FROM book WHERE '{9.6,High}' <@ tags; -- Get books where title is like one of array title values SELECT * FROM book WHERE book.title ~~* ANY (ARRAY ['%Perfor%', '%Admin%']); -- Array to string conversion SELECT array_to_string(tags, ',') FROM book; -- Array to json conversion SELECT array_to_json(tags) FROM book;
  • 8.
    Extension hStore CREATE EXTENSIONhstore; CREATE TABLE product ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, description TEXT, price DECIMAL(12, 2) NOT NULL, attributes HSTORE, created_at TIMESTAMP WITH TIME ZONE DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'), updated_at TIMESTAMP );
  • 9.
    Adding data tohStore INSERT INTO product (title, description, price, attributes) VALUES ('Product A', 'Description', 35.00, 'color => red, weight => 1000, sku => LPT123'), ('Product B', 'Description', 70.00, 'color => blue, weight => 2500, sku => LPT145'), ('Product C', 'Description', 100.00, 'color => withe, weight => 1500, sku => LPT245, is_something => true'), ('Product D', 'Description', 85.00, 'color => withe, weight => 3500, sku => LPT125, is_something => false, hidden => true'), ('Product E', 'Description', 10.00, 'color => red, weight => 1500, sku => LPT37') RETURNING *;
  • 10.
    Retrieving data fromhStore SELECT title, price :: MONEY, attributes -> 'color' AS color, attributes -> 'weight' AS weight, attributes -> 'sku' AS sku FROM product WHERE (attributes -> 'weight') :: INT > 1500 ORDER BY replace(attributes -> 'sku', 'LPT', ' ');
  • 11.
    hStore Data Manipulation --hstore key exists SELECT * FROM product WHERE attributes ? 'is_something'; -- hstore contains all specified keys SELECT * FROM product WHERE attributes ?& string_to_array('is_something,hidden', ','); -- hstore to data records SELECT id, (each(attributes)).key AS attribute, (each(attributes)).value AS value FROM product;
  • 12.
    Creating XML data --Books to xml CREATE TABLE book_as_xml ( id SERIAL PRIMARY KEY, content XML NOT NULL ); -- Transform all books to xml INSERT INTO book_as_xml (content) SELECT xmlroot( xmlelement(NAME book, xmlforest(id, title, authors, tags)), VERSION '1.1', STANDALONE YES ) FROM book RETURNING content;
  • 13.
    XML2 - TransformXML to Presentable view CREATE EXTENSION xml2; CREATE OR REPLACE FUNCTION xml_pretty(TEXT) RETURNS XML AS $body$ SELECT xslt_process($1, '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*" /> <xsl:output method="xml" indent="yes" /> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*" /> </xsl:copy> </xsl:template> </xsl:stylesheet>' :: TEXT) :: XML $body$ LANGUAGE SQL IMMUTABLE STRICT;
  • 14.
    XML Manipulation -- Showpretty xml SELECT xml_pretty(content) FROM book_as_xml; -- Xpath SELECT array_to_string(xpath('//title/text()', content), '; ') FROM book_as_xml; -- Get all tags values SELECT array_to_string(xpath('//tags/element/text()', content), '; ') FROM book_as_xml; -- Return all table content as xml SELECT xmlroot( xmlelement(name body, table_to_xml('book', TRUE, TRUE, '')), VERSION '1.1', STANDALONE YES ) FROM book;
  • 15.
    JSON & JSONB CREATETABLE entity_as_jsonb ( id SERIAL PRIMARY KEY, content JSONB ); INSERT INTO entity_as_jsonb (type, content) SELECT json_build_object( 'title', title, id', id, 'description', description, 'price', price :: MONEY, 'attributes', attributes ) FROM product RETURNING * ;
  • 16.
    JSON Data Retrieving SELECT content->> 'id' AS id, -- like text content ->> 'title' AS title, -- like text content -> 'attributes' AS attributes, -- like json content #>> '{attributes,sku}' AS sky -- by path FROM entity_as_json WHERE type = 'product' AND content #>> '{attributes,sku}' LIKE '%45'; -- Aggregate all table data SELECT json_agg(content) FROM entity_as_json; -- Array to json conversion SELECT array_to_json(tags) FROM book;
  • 17.
    JSON Append Function CREATEOR REPLACE FUNCTION json_append(data JSON, insert_data JSON) RETURNS JSON IMMUTABLE LANGUAGE SQL AS $$ SELECT ('{' || string_agg(to_json(key) || ':' || value, ',') || '}') :: JSON FROM ( SELECT * FROM json_each(data) UNION ALL SELECT * FROM json_each(insert_data) ) t; $$;
  • 18.
    JSON Merge Function CREATEOR REPLACE FUNCTION json_merge(data JSON, merge_data JSON) RETURNS JSON IMMUTABLE LANGUAGE SQL AS $$ SELECT ('{' || string_agg(to_json(key) || ':' || value, ',') || '}') :: JSON FROM ( WITH to_merge AS ( SELECT * FROM json_each(merge_data) ) SELECT * FROM json_each(data) WHERE key NOT IN (SELECT key FROM to_merge) UNION ALL SELECT * FROM to_merge ) t; $$;
  • 19.
    Check Constraint CREATE TABLEweb_user ( id SERIAL PRIMARY KEY, username VARCHAR(255) UNIQUE NOT NULL CHECK (trim(username) <> ''), email VARCHAR(255) UNIQUE NOT NULL CHECK (valid_email(email)), password CHARACTER(40) NOT NULL CHECK (char_length(password) = 40), created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated TIMESTAMP ); CREATE EXTENSION pgcrypto; INSERT INTO web_user VALUES ( '2', 'foo', 'abramchenkoa@bar.com', ENCODE(DIGEST('test', 'sha1'), 'hex') );
  • 20.
    Domain and CitextExtension CREATE EXTENSION citext; -- Create data type like email RFC5322 CREATE DOMAIN email AS citext CHECK ( value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]' || '+@[a-zA-Z0-9](?:[a-zA-Z0-9-]' || '{0,61}[a-zA-Z0-9])?(?:.[a-zA-Z0-9]' || '(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$' );
  • 21.
    Write functions onPerl, Python, JS, Ruby, PHP CREATE EXTENSION plperlu; CREATE FUNCTION valid_email(text) RETURNS boolean LANGUAGE plperlu IMMUTABLE LEAKPROOF STRICT AS $$ use Email::Valid; my $email = shift; Email::Valid->address($email) or die "Invalid email address: $emailn"; return 'true'; $$;
  • 22.
    Full Text Search --Add a new column ALTER TABLE book ADD COLUMN search_fields TSVECTOR; -- Fill the column for searching UPDATE book SET search_fields = to_tsvector( 'english', book.title || ' ' || array_to_string(book.tags, ' ') ); -- Add index CREATE INDEX textsearch_idx ON book USING GIN (search_fields);
  • 23.
    Search Queries -- Getcurrent text search config SELECT get_current_ts_config(); -- english -- Show all available text search configs SELECT * FROM pg_ts_config; -- Search examples SELECT * FROM book WHERE search_fields @@ to_tsquery('high & postgre:* & 9.6'); SELECT * FROM book WHERE search_fields @@ plainto_tsquery(get_current_ts_config(), 'postgresql performance') ; -- Displays query matching, how title matches the query SELECT id, title, ts_headline(title, q) FROM book, to_tsquery('postgre:* & performance') AS q WHERE setweight(to_tsvector('english', title),'A') || setweight(to_tsvector('english', content), 'B') @@ q;
  • 24.
    Search By Trigrams --Enable extension CREATE EXTENSION pg_trgm; -- Add index CREATE INDEX trgm_idx ON book USING GIST (title gist_trgm_ops); -- How similar are the arguments SELECT title, similarity(title, 'Postgre') AS sml FROM book WHERE title % 'Postgre' ORDER BY sml DESC; -- How similar are the first string and the most similar word of the second string SELECT title, word_similarity(title, 'Postgre') AS sml FROM book WHERE title %> 'Postgre' ORDER BY sml DESC;
  • 25.
    Ltree Hierarchical DataType -- Enable extension CREATE EXTENSION ltree; -- Store branch like CREATE TABLE comment ( id SERIAL PRIMARY KEY, message TEXT, branch LTREE NOT NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- Add index CREATE INDEX ON comment USING GIST (branch);
  • 26.
    Ltree Data Manipulation INSERTINTO comment (message, branch) VALUES ('Comment 1', '0'); INSERT INTO comment (message, branch) VALUES ('Comment 1.1', '0.1'); INSERT INTO comment (message, branch) VALUES ('Comment 2', '0'); INSERT INTO comment (message, branch) VALUES ('Comment 2.1', '0.3'); INSERT INTO comment (message, branch) VALUES ('Comment 2.2', '0.3'); INSERT INTO comment (message, branch) VALUES ('Comment 2.2.1', '0.3.4'); -- Сhildren of the third message SELECT * FROM comment WHERE branch <@ '0.3'; -- Get by lquery SELECT * FROM comment WHERE branch ~ '*.3.*'::lquery;
  • 27.
    Thank You ForAttention!