Clean up grammar a bit
authorPeter Eisentraut
Mon, 29 Jun 2020 08:36:52 +0000 (10:36 +0200)
committerPeter Eisentraut
Mon, 29 Jun 2020 09:05:00 +0000 (11:05 +0200)
Simplify the grammar specification of substring() and overlay() a bit,
simplify and update some comments.

Reviewed-by: Pavel Stehule
Reviewed-by: Vik Fearing
Reviewed-by: Fabien COELHO
Discussion: https://www.postgresql.org/message-id/flat/a15db31c-d0f8-8ce0-9039-578a31758adb%402ndquadrant.com

src/backend/parser/gram.y

index e669d75a5af36550ac20609fd993f8af3d02e4f3..1a843049f05517b2015b282bddca573daf9b394d 100644 (file)
@@ -452,7 +452,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type    extract_list overlay_list position_list
 %type    substr_list trim_list
 %type    opt_interval interval_second
-%type    overlay_placing substr_from substr_for
 %type         unicode_normal_form
 
 %type  opt_instead
@@ -13797,11 +13796,6 @@ func_expr_common_subexpr:
                }
            | OVERLAY '(' overlay_list ')'
                {
-                   /* overlay(A PLACING B FROM C FOR D) is converted to
-                    * overlay(A, B, C, D)
-                    * overlay(A PLACING B FROM C) is converted to
-                    * overlay(A, B, C)
-                    */
                    $$ = (Node *) makeFuncCall(SystemFuncName("overlay"), $3, @1);
                }
            | POSITION '(' position_list ')'
@@ -14437,63 +14431,45 @@ unicode_normal_form:
            | NFKD                                  { $$ = "nfkd"; }
        ;
 
-/* OVERLAY() arguments
- * SQL99 defines the OVERLAY() function:
- * o overlay(text placing text from int for int)
- * o overlay(text placing text from int)
- * and similarly for binary strings
- */
+/* OVERLAY() arguments */
 overlay_list:
-           a_expr overlay_placing substr_from substr_for
+           a_expr PLACING a_expr FROM a_expr FOR a_expr
                {
-                   $$ = list_make4($1, $2, $3, $4);
+                   /* overlay(A PLACING B FROM C FOR D) is converted to overlay(A, B, C, D) */
+                   $$ = list_make4($1, $3, $5, $7);
                }
-           | a_expr overlay_placing substr_from
+           | a_expr PLACING a_expr FROM a_expr
                {
-                   $$ = list_make3($1, $2, $3);
+                   /* overlay(A PLACING B FROM C) is converted to overlay(A, B, C) */
+                   $$ = list_make3($1, $3, $5);
                }
        ;
 
-overlay_placing:
-           PLACING a_expr
-               { $$ = $2; }
-       ;
-
 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
-
 position_list:
            b_expr IN_P b_expr                      { $$ = list_make2($3, $1); }
            | /*EMPTY*/                             { $$ = NIL; }
        ;
 
-/* SUBSTRING() arguments
- * SQL9x defines a specific syntax for arguments to SUBSTRING():
- * o substring(text from int for int)
- * o substring(text from int) get entire string from starting point "int"
- * o substring(text for int) get first "int" characters of string
- * o substring(text from pattern) get entire string matching pattern
- * o substring(text from pattern for escape) same with specified escape char
- * We also want to support generic substring functions which accept
- * the usual generic list of arguments. So we will accept both styles
- * here, and convert the SQL9x style to the generic list for further
- * processing. - thomas 2000-11-28
- */
+/* SUBSTRING() arguments */
 substr_list:
-           a_expr substr_from substr_for
+           a_expr FROM a_expr FOR a_expr
                {
-                   $$ = list_make3($1, $2, $3);
+                   $$ = list_make3($1, $3, $5);
                }
-           | a_expr substr_for substr_from
+           | a_expr FOR a_expr FROM a_expr
                {
-                   /* not legal per SQL99, but might as well allow it */
-                   $$ = list_make3($1, $3, $2);
+                   /* not legal per SQL, but might as well allow it */
+                   $$ = list_make3($1, $5, $3);
                }
-           | a_expr substr_from
+           | a_expr FROM a_expr
                {
-                   $$ = list_make2($1, $2);
+                   $$ = list_make2($1, $3);
                }
-           | a_expr substr_for
+           | a_expr FOR a_expr
                {
+                   /* not legal per SQL */
+
                    /*
                     * Since there are no cases where this syntax allows
                     * a textual FOR value, we forcibly cast the argument
@@ -14504,9 +14480,13 @@ substr_list:
                     * is unknown or doesn't have an implicit cast to int4.
                     */
                    $$ = list_make3($1, makeIntConst(1, -1),
-                                   makeTypeCast($2,
+                                   makeTypeCast($3,
                                                 SystemTypeName("int4"), -1));
                }
+           /*
+            * We also want to support generic substring functions that
+            * accept the usual generic list of arguments.
+            */
            | expr_list
                {
                    $$ = $1;
@@ -14515,13 +14495,6 @@ substr_list:
                { $$ = NIL; }
        ;
 
-substr_from:
-           FROM a_expr                             { $$ = $2; }
-       ;
-
-substr_for: FOR a_expr                             { $$ = $2; }
-       ;
-
 trim_list: a_expr FROM expr_list                   { $$ = lappend($3, $1); }
            | FROM expr_list                        { $$ = $2; }
            | expr_list                             { $$ = $1; }