From b23f62a9db31243c4f95150d7e1bd2cc0d3fed2c Mon Sep 17 00:00:00 2001 From: "David G. Johnston" Date: Mon, 31 Mar 2025 21:36:42 -0700 Subject: [PATCH 1/2] v3-0001 substring --- doc/src/sgml/func.sgml | 111 +++++++++++++++++++++-- src/backend/catalog/system_functions.sql | 2 +- src/include/catalog/pg_proc.dat | 12 +++ 3 files changed, 118 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 574a544d9fa4..8ed7a3ca1387 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -3796,6 +3796,58 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in + + + + substring ( string text, pattern text ) + text + + + Extracts the first substring matching POSIX regular expression; see + . + + + substring('Thomas', '...$') + mas + + + + + + substring ( string text, pattern text, escape_character text) + text + + + Extracts the first substring matching SQL regular expression; + see . + + + substring('Thomas', '%#"o_a#"_', '#') + oma + + + + + + + substring + + substring ( string text, start integer , count integer ) + text + + + Extracts the substring of string starting at + the start'th character, + and stopping after count characters if that is + specified. + + + + substring('Thomas', 2, 3) + hom + + + @@ -4849,6 +4901,27 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); \x5678 + + + + + substring + + substring ( bytes bytea, start integer , count integer ) + bytea + + + Extracts the substring of bytes starting at + the start'th byte, + and stopping after count bytes if that is + specified. + + + substring('\x1234567890'::bytea, 3, 2) + \x5678 + + + @@ -5351,6 +5424,26 @@ cast(-1234 as bytea) \xfffffb2e + + + + substring + + substring ( bits bit, start integer , count integer ) + bit + + + Extracts the substring of bits starting at + the start'th bit, + and stopping after count bits if that is + specified. + + + substring(B'110010111111', 3, 2) + 00 + + + @@ -5854,7 +5947,7 @@ substring(string from pattern or as a plain three-argument function: -substring(string, pattern, escape-character) +substring(string, pattern, escape_character) As with SIMILAR TO, the specified pattern must match the entire data string, or else the @@ -6058,11 +6151,17 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL - The substring function with two parameters, - substring(string from - pattern), provides extraction of a - substring - that matches a POSIX regular expression pattern. It returns null if + The substring function with two parameters provides extraction of a + substring that matches a POSIX regular expression pattern. + It has syntax: + +substring(string from pattern) + + It can also written as a plain two-argument function: + +substring(string, pattern) + + It returns null if there is no match, otherwise the first portion of the text that matched the pattern. But if the pattern contains any parentheses, the portion of the text that matched the first parenthesized subexpression (the diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 566f308e4439..5ea9d786b60f 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -42,7 +42,7 @@ CREATE OR REPLACE FUNCTION rpad(text, integer) IMMUTABLE PARALLEL SAFE STRICT COST 1 RETURN rpad($1, $2, ' '); -CREATE OR REPLACE FUNCTION "substring"(text, text, text) +CREATE OR REPLACE FUNCTION "substring"(string text, pattern text, escape_character text) RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT COST 1 diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 62beb71da288..271f60cc37c8 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3705,6 +3705,7 @@ prosrc => 'rtrim' }, { oid => '877', descr => 'extract portion of string', proname => 'substr', prorettype => 'text', proargtypes => 'text int4 int4', + proargnames => '{string, start, count}', prosrc => 'text_substr' }, { oid => '878', descr => 'map a set of characters appearing in string', proname => 'translate', prorettype => 'text', proargtypes => 'text text text', @@ -3723,6 +3724,7 @@ prosrc => 'rtrim1' }, { oid => '883', descr => 'extract portion of string', proname => 'substr', prorettype => 'text', proargtypes => 'text int4', + proargnames => '{string, start}', prosrc => 'text_substr_no_len' }, { oid => '884', descr => 'trim selected characters from both ends of string', proname => 'btrim', prorettype => 'text', proargtypes => 'text text', @@ -3733,9 +3735,11 @@ { oid => '936', descr => 'extract portion of string', proname => 'substring', prorettype => 'text', proargtypes => 'text int4 int4', + proargnames => '{string, start, count}', prosrc => 'text_substr' }, { oid => '937', descr => 'extract portion of string', proname => 'substring', prorettype => 'text', proargtypes => 'text int4', + proargnames => '{string, start}', prosrc => 'text_substr_no_len' }, { oid => '2087', descr => 'replace all occurrences in string of old_substr with new_substr', @@ -4153,6 +4157,7 @@ prosrc => 'bitcat' }, { oid => '1680', descr => 'extract portion of bitstring', proname => 'substring', prorettype => 'bit', proargtypes => 'bit int4 int4', + proargnames => '{bits, start, count}', prosrc => 'bitsubstr' }, { oid => '1681', descr => 'bitstring length', proname => 'length', prorettype => 'int4', proargtypes => 'bit', @@ -4182,6 +4187,7 @@ prosrc => 'bitposition' }, { oid => '1699', descr => 'extract portion of bitstring', proname => 'substring', prorettype => 'bit', proargtypes => 'bit int4', + proargnames => '{bits, start}', prosrc => 'bitsubstr_no_len' }, { oid => '3030', descr => 'substitute portion of bitstring', @@ -6279,15 +6285,19 @@ prosrc => 'byteacat' }, { oid => '2012', descr => 'extract portion of string', proname => 'substring', prorettype => 'bytea', + proargnames => '{bytes, start, count}', proargtypes => 'bytea int4 int4', prosrc => 'bytea_substr' }, { oid => '2013', descr => 'extract portion of string', proname => 'substring', prorettype => 'bytea', proargtypes => 'bytea int4', + proargnames => '{bytes, start}', prosrc => 'bytea_substr_no_len' }, { oid => '2085', descr => 'extract portion of string', proname => 'substr', prorettype => 'bytea', proargtypes => 'bytea int4 int4', + proargnames => '{bytes, start, count}', prosrc => 'bytea_substr' }, { oid => '2086', descr => 'extract portion of string', proname => 'substr', prorettype => 'bytea', proargtypes => 'bytea int4', + proargnames => '{bytes, start}', prosrc => 'bytea_substr_no_len' }, { oid => '2014', descr => 'position of substring', proname => 'position', prorettype => 'int4', proargtypes => 'bytea bytea', @@ -6479,9 +6489,11 @@ { oid => '2073', descr => 'extract text matching regular expression', proname => 'substring', prorettype => 'text', proargtypes => 'text text', + proargnames => '{string, pattern}', prosrc => 'textregexsubstr' }, { oid => '2074', descr => 'extract text matching SQL regular expression', proname => 'substring', prolang => 'sql', prorettype => 'text', + proargnames => '{string, pattern, escape_character}', proargtypes => 'text text text', prosrc => 'see system_functions.sql' }, { oid => '2075', descr => 'convert int8 to bitstring', From 545c39501c6652019fabc0d54a53fc266611b6dd Mon Sep 17 00:00:00 2001 From: "David G. Johnston" Date: Mon, 31 Mar 2025 21:54:44 -0700 Subject: [PATCH 2/2] v3 delta --- doc/src/sgml/func.sgml | 46 ++++++++++++------------ src/backend/catalog/system_functions.sql | 2 +- src/include/catalog/pg_proc.dat | 1 + 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 8ed7a3ca1387..2341edc33447 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -2875,7 +2875,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in Extracts the first substring matching POSIX regular expression; see - . + . (Same as + substring(string text, pattern text).) substring('Thomas' from '...$') @@ -2888,19 +2889,18 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in substring ( string text SIMILAR pattern text ESCAPE escape text ) text - - substring ( string text FROM pattern text FOR escape text ) - text - Extracts the first substring matching SQL regular expression; - see . The first form has - been specified since SQL:2003; the second form was only in SQL:1999 - and should be considered obsolete. + see . (Same as + substring(string text, pattern text, escape text).) substring('Thomas' similar '%#"o_a#"_' escape '#') oma + + + Obsolescence note: SQL:1999 introduced this function with FROM + and FOR as the keywords but switched to this in SQL:2003. @@ -3804,7 +3804,8 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in Extracts the first substring matching POSIX regular expression; see - . + . (Same as + substring(string text FROM pattern text).) substring('Thomas', '...$') @@ -3814,12 +3815,13 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in - substring ( string text, pattern text, escape_character text) + substring ( string text, pattern text, escape text) text Extracts the first substring matching SQL regular expression; - see . + see . (Same as + substring(string text SIMILAR pattern text ESCAPE escape text).) substring('Thomas', '%#"o_a#"_', '#') @@ -5631,8 +5633,8 @@ cast(-44 as bit(12)) 111111010100 -string LIKE pattern ESCAPE escape-character -string NOT LIKE pattern ESCAPE escape-character +string LIKE pattern ESCAPE escape +string NOT LIKE pattern ESCAPE escape @@ -5804,8 +5806,8 @@ cast(-44 as bit(12)) 111111010100 -string SIMILAR TO pattern ESCAPE escape-character -string NOT SIMILAR TO pattern ESCAPE escape-character +string SIMILAR TO pattern ESCAPE escape +string NOT SIMILAR TO pattern ESCAPE escape @@ -5939,15 +5941,11 @@ cast(-44 as bit(12)) 111111010100 regular expression pattern. The function can be written according to standard SQL syntax: -substring(string similar pattern escape escape-character) - - or using the now obsolete SQL:1999 syntax: - -substring(string from pattern for escape-character) +substring(string SIMILAR pattern ESCAPE escape) - or as a plain three-argument function: + It can also written as a plain three-argument function: -substring(string, pattern, escape_character) +substring(string, pattern, escape) As with SIMILAR TO, the specified pattern must match the entire data string, or else the @@ -6153,9 +6151,9 @@ substring('foobar' similar '#"o_b#"%' escape '#') NULL The substring function with two parameters provides extraction of a substring that matches a POSIX regular expression pattern. - It has syntax: + The function can be written according to standard SQL syntax: -substring(string from pattern) +substring(string FROM pattern) It can also written as a plain two-argument function: diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 5ea9d786b60f..544b549ae74d 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -42,7 +42,7 @@ CREATE OR REPLACE FUNCTION rpad(text, integer) IMMUTABLE PARALLEL SAFE STRICT COST 1 RETURN rpad($1, $2, ' '); -CREATE OR REPLACE FUNCTION "substring"(string text, pattern text, escape_character text) +CREATE OR REPLACE FUNCTION "substring"(string text, pattern text, escape text) RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT COST 1 diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 271f60cc37c8..65e79c0bb41f 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6494,6 +6494,7 @@ { oid => '2074', descr => 'extract text matching SQL regular expression', proname => 'substring', prolang => 'sql', prorettype => 'text', proargnames => '{string, pattern, escape_character}', + proargnames => '{string, pattern, escape}', proargtypes => 'text text text', prosrc => 'see system_functions.sql' }, { oid => '2075', descr => 'convert int8 to bitstring',