github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/parser/parse_test.go (about)

     1  // Copyright 2015 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package parser_test
    12  
    13  import (
    14  	"fmt"
    15  	"go/constant"
    16  	"reflect"
    17  	"regexp"
    18  	"strings"
    19  	"testing"
    20  
    21  	"github.com/cockroachdb/cockroach/pkg/sql/parser"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    23  	_ "github.com/cockroachdb/cockroach/pkg/sql/sem/builtins"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    25  	"github.com/cockroachdb/cockroach/pkg/testutils"
    26  	"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
    27  	_ "github.com/cockroachdb/cockroach/pkg/util/log" // for flags
    28  	"github.com/cockroachdb/errors"
    29  	"github.com/stretchr/testify/assert"
    30  )
    31  
    32  // TestParse verifies that we can parse the supplied SQL and regenerate the SQL
    33  // string from the syntax tree.
    34  func TestParse(t *testing.T) {
    35  	testData := []struct {
    36  		sql string
    37  	}{
    38  		{``},
    39  		{`VALUES ("")`},
    40  
    41  		{`BEGIN TRANSACTION`},
    42  		{`BEGIN TRANSACTION READ ONLY`},
    43  		{`BEGIN TRANSACTION READ WRITE`},
    44  		{`BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE`},
    45  		{`BEGIN TRANSACTION PRIORITY LOW`},
    46  		{`BEGIN TRANSACTION PRIORITY NORMAL`},
    47  		{`BEGIN TRANSACTION PRIORITY HIGH`},
    48  		{`BEGIN TRANSACTION AS OF SYSTEM TIME '2018-12-18'`},
    49  		{`BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE, AS OF SYSTEM TIME '2018-12-18'`},
    50  		{`BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY LOW, AS OF SYSTEM TIME '2018-12-18'`},
    51  		{`BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY LOW, READ ONLY, AS OF SYSTEM TIME '-1ns'`},
    52  		{`BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY HIGH`},
    53  		{`BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY HIGH, READ WRITE`},
    54  		{`COMMIT TRANSACTION`},
    55  		{`ROLLBACK TRANSACTION`},
    56  		{`SAVEPOINT foo`},
    57  		{`SAVEPOINT "foo bar"`},
    58  
    59  		{`CREATE DATABASE a`},
    60  		{`EXPLAIN CREATE DATABASE a`},
    61  		{`CREATE DATABASE a TEMPLATE = 'template0'`},
    62  		{`CREATE DATABASE a TEMPLATE = 'invalid'`},
    63  		{`CREATE DATABASE a ENCODING = 'UTF8'`},
    64  		{`CREATE DATABASE a ENCODING = 'INVALID'`},
    65  		{`CREATE DATABASE a LC_COLLATE = 'C.UTF-8'`},
    66  		{`CREATE DATABASE a LC_COLLATE = 'INVALID'`},
    67  		{`CREATE DATABASE a LC_CTYPE = 'C.UTF-8'`},
    68  		{`CREATE DATABASE a LC_CTYPE = 'INVALID'`},
    69  		{`CREATE DATABASE a TEMPLATE = 'template0' ENCODING = 'UTF8' LC_COLLATE = 'C.UTF-8' LC_CTYPE = 'INVALID'`},
    70  		{`CREATE DATABASE IF NOT EXISTS a`},
    71  		{`CREATE DATABASE IF NOT EXISTS a TEMPLATE = 'template0'`},
    72  		{`CREATE DATABASE IF NOT EXISTS a TEMPLATE = 'invalid'`},
    73  		{`CREATE DATABASE IF NOT EXISTS a ENCODING = 'UTF8'`},
    74  		{`CREATE DATABASE IF NOT EXISTS a ENCODING = 'INVALID'`},
    75  		{`CREATE DATABASE IF NOT EXISTS a LC_COLLATE = 'C.UTF-8'`},
    76  		{`CREATE DATABASE IF NOT EXISTS a LC_COLLATE = 'INVALID'`},
    77  		{`CREATE DATABASE IF NOT EXISTS a LC_CTYPE = 'C.UTF-8'`},
    78  		{`CREATE DATABASE IF NOT EXISTS a LC_CTYPE = 'INVALID'`},
    79  		{`CREATE DATABASE IF NOT EXISTS a TEMPLATE = 'template0' ENCODING = 'UTF8' LC_COLLATE = 'C.UTF-8' LC_CTYPE = 'INVALID'`},
    80  		{`CREATE SCHEMA IF NOT EXISTS foo`},
    81  		{`CREATE SCHEMA foo`},
    82  
    83  		{`CREATE INDEX a ON b (c)`},
    84  		{`CREATE INDEX CONCURRENTLY a ON b (c)`},
    85  		{`EXPLAIN CREATE INDEX a ON b (c)`},
    86  		{`CREATE INDEX a ON b.c (d)`},
    87  		{`CREATE INDEX ON a (b)`},
    88  		{`CREATE INDEX ON a (b) STORING (c)`},
    89  		{`CREATE INDEX ON a (b) WHERE c > 3`},
    90  		{`CREATE INDEX ON a (b) INTERLEAVE IN PARENT c (d)`},
    91  		{`CREATE INDEX ON a (b) INTERLEAVE IN PARENT c.d (e)`},
    92  		{`CREATE INDEX ON a (b ASC, c DESC)`},
    93  		{`CREATE INDEX ON a (b NULLS FIRST, c ASC NULLS FIRST, d DESC NULLS LAST)`},
    94  		{`CREATE INDEX IF NOT EXISTS i ON a (b) WHERE c > 3`},
    95  		{`CREATE UNIQUE INDEX a ON b (c)`},
    96  		{`CREATE UNIQUE INDEX a ON b (c) STORING (d)`},
    97  		{`CREATE UNIQUE INDEX a ON b (c) WHERE d > 3`},
    98  		{`CREATE UNIQUE INDEX a ON b (c) INTERLEAVE IN PARENT d (e, f)`},
    99  		{`CREATE UNIQUE INDEX a ON b (c) INTERLEAVE IN PARENT d.e (f, g)`},
   100  		{`CREATE UNIQUE INDEX a ON b.c (d)`},
   101  		{`CREATE INVERTED INDEX a ON b (c)`},
   102  		{`CREATE INVERTED INDEX a ON b.c (d)`},
   103  		{`CREATE INVERTED INDEX a ON b (c) STORING (d)`},
   104  		{`CREATE INVERTED INDEX a ON b (c) WHERE d > 3`},
   105  		{`CREATE INVERTED INDEX a ON b (c) INTERLEAVE IN PARENT d (e)`},
   106  		{`CREATE INVERTED INDEX IF NOT EXISTS a ON b (c) WHERE d > 3`},
   107  
   108  		{`CREATE TABLE a ()`},
   109  		{`CREATE TEMPORARY TABLE a (b INT8)`},
   110  		{`EXPLAIN CREATE TABLE a ()`},
   111  		{`CREATE TABLE a (b INT8)`},
   112  		{`CREATE TABLE a (b INT8, c INT8)`},
   113  		{`CREATE TABLE a (b CHAR)`},
   114  		{`CREATE TABLE a (b CHAR(3))`},
   115  		{`CREATE TABLE a (b VARCHAR)`},
   116  		{`CREATE TABLE a (b VARCHAR(3))`},
   117  		{`CREATE TABLE a (b STRING)`},
   118  		{`CREATE TABLE a (b STRING(3))`},
   119  		{`CREATE TABLE a (b FLOAT4)`},
   120  		{`CREATE TABLE a (b FLOAT8)`},
   121  		{`CREATE TABLE a (b SERIAL8)`},
   122  		{`CREATE TABLE a (b TIME)`},
   123  		{`CREATE TABLE a (b TIMETZ)`},
   124  		{`CREATE TABLE a (b TIME(3))`},
   125  		{`CREATE TABLE a (b TIMETZ(3))`},
   126  		{`CREATE TABLE a (b GEOGRAPHY)`},
   127  		{`CREATE TABLE a (b GEOGRAPHY(POINT))`},
   128  		{`CREATE TABLE a (b GEOGRAPHY(POINT,4326))`},
   129  		{`CREATE TABLE a (b GEOGRAPHY(LINESTRING,4326))`},
   130  		{`CREATE TABLE a (b GEOGRAPHY(POLYGON,4326))`},
   131  		{`CREATE TABLE a (b GEOGRAPHY(MULTIPOINT,4326))`},
   132  		{`CREATE TABLE a (b GEOGRAPHY(MULTILINESTRING,4326))`},
   133  		{`CREATE TABLE a (b GEOGRAPHY(MULTIPOLYGON,4326))`},
   134  		{`CREATE TABLE a (b GEOGRAPHY(GEOMETRY,4326))`},
   135  		{`CREATE TABLE a (b GEOGRAPHY(GEOMETRYCOLLECTION,4326))`},
   136  		{`CREATE TABLE a (b GEOMETRY)`},
   137  		{`CREATE TABLE a (b GEOMETRY(POINT))`},
   138  		{`CREATE TABLE a (b GEOMETRY(POINT,4326))`},
   139  		{`CREATE TABLE a (b UUID)`},
   140  		{`CREATE TABLE a (b INET)`},
   141  		{`CREATE TABLE a (b "char")`},
   142  		{`CREATE TABLE a (b INT8 NULL)`},
   143  		{`CREATE TABLE a (b INT8 CONSTRAINT maybe NULL)`},
   144  		{`CREATE TABLE a (b INT8 NOT NULL)`},
   145  		{`CREATE TABLE a (b INT8 CONSTRAINT always NOT NULL)`},
   146  		{`CREATE TABLE a (b INT8 PRIMARY KEY)`},
   147  		{`CREATE TABLE a (b INT8 UNIQUE)`},
   148  		{`CREATE TABLE a (b INT8 NULL PRIMARY KEY)`},
   149  		{`CREATE TABLE a (b INT8 DEFAULT 1)`},
   150  		{`CREATE TABLE a (b INT8 CONSTRAINT one DEFAULT 1)`},
   151  		{`CREATE TABLE a (b INT8 DEFAULT now())`},
   152  		{`CREATE TABLE a (a INT8 CHECK (a > 0))`},
   153  		{`CREATE TABLE a (a INT8 CONSTRAINT positive CHECK (a > 0))`},
   154  		{`CREATE TABLE a (a INT8 DEFAULT 1 CHECK (a > 0))`},
   155  		{`CREATE TABLE a (a INT8 CONSTRAINT one DEFAULT 1 CHECK (a > 0))`},
   156  		{`CREATE TABLE a (a INT8 DEFAULT 1 CONSTRAINT positive CHECK (a > 0))`},
   157  		{`CREATE TABLE a (a INT8 CONSTRAINT one DEFAULT 1 CONSTRAINT positive CHECK (a > 0))`},
   158  		{`CREATE TABLE a (a INT8 CONSTRAINT one CHECK (a > 0) CONSTRAINT two CHECK (a < 10))`},
   159  		// "0" lost quotes previously.
   160  		{`CREATE TABLE a (b INT8, c STRING, PRIMARY KEY (b, c, "0"))`},
   161  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other)`},
   162  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON UPDATE RESTRICT)`},
   163  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE RESTRICT)`},
   164  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE RESTRICT ON UPDATE RESTRICT)`},
   165  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON UPDATE CASCADE)`},
   166  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE CASCADE)`},
   167  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE CASCADE ON UPDATE CASCADE)`},
   168  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON UPDATE SET NULL)`},
   169  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET NULL)`},
   170  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET NULL ON UPDATE SET NULL)`},
   171  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON UPDATE SET DEFAULT)`},
   172  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT)`},
   173  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT ON UPDATE SET DEFAULT)`},
   174  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE RESTRICT ON UPDATE SET DEFAULT)`},
   175  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT ON UPDATE CASCADE)`},
   176  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE CASCADE ON UPDATE SET NULL)`},
   177  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET NULL ON UPDATE RESTRICT)`},
   178  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH FULL ON DELETE SET DEFAULT ON UPDATE SET DEFAULT)`},
   179  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH FULL ON DELETE RESTRICT ON UPDATE SET DEFAULT)`},
   180  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH FULL ON DELETE SET DEFAULT ON UPDATE CASCADE)`},
   181  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH FULL ON DELETE CASCADE ON UPDATE SET NULL)`},
   182  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH FULL ON DELETE SET NULL ON UPDATE RESTRICT)`},
   183  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other MATCH FULL)`},
   184  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH FULL)`},
   185  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other)`},
   186  		{`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y))`},
   187  		{`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y))`},
   188  		{`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH FULL)`},
   189  		{`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH FULL ON UPDATE SET NULL)`},
   190  		{`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH FULL ON DELETE SET DEFAULT)`},
   191  		{`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH FULL ON DELETE SET DEFAULT ON UPDATE SET NULL)`},
   192  		{`CREATE TABLE a (b INT8, c STRING, INDEX (b, c))`},
   193  		{`CREATE TABLE a (b INT8, c STRING, INDEX d (b, c))`},
   194  		{`CREATE TABLE a (b INT8, c STRING, CONSTRAINT d UNIQUE (b, c))`},
   195  		{`CREATE TABLE a (b INT8, c STRING, CONSTRAINT d UNIQUE (b, c) INTERLEAVE IN PARENT d (e, f))`},
   196  		{`CREATE TABLE a (b INT8, UNIQUE (b))`},
   197  		{`CREATE TABLE a (b INT8, UNIQUE (b) STORING (c))`},
   198  		{`CREATE TABLE a (b INT8, INDEX (b))`},
   199  		{`CREATE TABLE a (b INT8, INVERTED INDEX (b))`},
   200  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo)`},
   201  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE RESTRICT)`},
   202  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE RESTRICT)`},
   203  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE RESTRICT ON UPDATE RESTRICT)`},
   204  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE CASCADE)`},
   205  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE CASCADE)`},
   206  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE CASCADE ON UPDATE CASCADE)`},
   207  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE SET NULL)`},
   208  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE SET NULL)`},
   209  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE SET NULL ON UPDATE SET NULL)`},
   210  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE SET DEFAULT)`},
   211  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE SET DEFAULT)`},
   212  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE SET DEFAULT ON UPDATE SET DEFAULT)`},
   213  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE RESTRICT ON UPDATE SET DEFAULT)`},
   214  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE SET DEFAULT ON UPDATE CASCADE)`},
   215  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE CASCADE ON UPDATE SET NULL)`},
   216  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON DELETE SET NULL ON UPDATE RESTRICT)`},
   217  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE CASCADE)`},
   218  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE SET NULL)`},
   219  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE SET DEFAULT)`},
   220  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo (bar))`},
   221  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo MATCH FULL)`},
   222  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo MATCH FULL ON UPDATE RESTRICT)`},
   223  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo MATCH FULL ON DELETE RESTRICT)`},
   224  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo MATCH FULL ON DELETE RESTRICT ON UPDATE RESTRICT)`},
   225  		{`CREATE TABLE a (b INT8, c INT8 REFERENCES foo (bar) MATCH FULL)`},
   226  		{`CREATE TABLE a (b INT8, INDEX (b) STORING (c))`},
   227  		{`CREATE TABLE a (b INT8, INDEX (b) WHERE b > 3)`},
   228  		{`CREATE TABLE a (b INT8, INVERTED INDEX (b) WHERE b > 3)`},
   229  		{`CREATE TABLE a (b INT8, c STRING, INDEX (b ASC, c DESC) STORING (c))`},
   230  		{`CREATE TABLE a (b INT8, INDEX (b) INTERLEAVE IN PARENT c (d, e))`},
   231  		{`CREATE TABLE a (b INT8, FAMILY (b))`},
   232  		{`CREATE TABLE a (b INT8, c STRING, FAMILY foo (b), FAMILY (c))`},
   233  		{`CREATE TABLE a (b INT8) INTERLEAVE IN PARENT foo (c, d)`},
   234  		{`CREATE TABLE a (b INT8) INTERLEAVE IN PARENT foo (c) CASCADE`},
   235  		{`CREATE TABLE a.b (b INT8)`},
   236  		{`CREATE TABLE IF NOT EXISTS a (b INT8)`},
   237  		{`CREATE TABLE a (b INT8 AS (a + b) STORED)`},
   238  		{`CREATE TABLE view (view INT8)`},
   239  
   240  		{`CREATE TABLE a (b INT8 CONSTRAINT c PRIMARY KEY)`},
   241  		{`CREATE TABLE a (b INT8 CONSTRAINT c NULL)`},
   242  		{`CREATE TABLE a (b INT8 CONSTRAINT c UNIQUE)`},
   243  		{`CREATE TABLE a (b INT8 CONSTRAINT c DEFAULT d)`},
   244  		{`CREATE TABLE a (b INT8 CONSTRAINT c CHECK (d))`},
   245  		{`CREATE TABLE a (b INT8 CONSTRAINT c REFERENCES d)`},
   246  
   247  		{`CREATE TABLE a (b INT8) PARTITION BY LIST (b) (PARTITION p1 VALUES IN (1, DEFAULT), PARTITION p2 VALUES IN ((1, 2), (3, 4)))`},
   248  		// This monstrosity was added on the assumption that it's more readable
   249  		// than all on one line. Feel free to rip it out if you come across it
   250  		// and disagree.
   251  		{regexp.MustCompile(`\n\s*`).ReplaceAllLiteralString(
   252  			`CREATE TABLE a (b INT8, c INT8, d INT8) PARTITION BY LIST (b) (
   253  				PARTITION p1 VALUES IN (1) PARTITION BY LIST (c) (
   254  					PARTITION p1_1 VALUES IN (3), PARTITION p1_2 VALUES IN (4, 5)
   255  				), PARTITION p2 VALUES IN (6) PARTITION BY RANGE (c) (
   256  					PARTITION p2_1 VALUES FROM (7) TO (8) PARTITION BY LIST (d) (
   257  						PARTITION p2_1_1 VALUES IN (8)
   258  					)
   259  				)
   260  			)`, ``),
   261  		},
   262  		{`CREATE TABLE a () INTERLEAVE IN PARENT b (c) PARTITION BY LIST (d) (PARTITION e VALUES IN (1))`},
   263  		{`CREATE TABLE IF NOT EXISTS a () PARTITION BY LIST (b) (PARTITION c VALUES IN (1))`},
   264  		{`CREATE TABLE a (INDEX (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)))`},
   265  		{`CREATE TABLE a (UNIQUE (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)))`},
   266  		{`CREATE INDEX ON a (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1))`},
   267  		{`CREATE INDEX IF NOT EXISTS a ON b (c) PARTITION BY LIST (d) (PARTITION e VALUES IN (1))`},
   268  		{`ALTER TABLE a PARTITION BY LIST (b) (PARTITION p1 VALUES IN (1))`},
   269  		{`ALTER INDEX a@idx PARTITION BY LIST (b) (PARTITION p1 VALUES IN (1))`},
   270  
   271  		{`CREATE TABLE a AS SELECT * FROM b`},
   272  		{`CREATE TABLE IF NOT EXISTS a AS SELECT * FROM b`},
   273  		{`CREATE TABLE a AS SELECT * FROM b ORDER BY c`},
   274  		{`CREATE TABLE IF NOT EXISTS a AS SELECT * FROM b ORDER BY c`},
   275  		{`CREATE TABLE a AS SELECT * FROM b LIMIT 3`},
   276  		{`CREATE TABLE IF NOT EXISTS a AS SELECT * FROM b LIMIT 3`},
   277  		{`CREATE TABLE a AS VALUES ('one', 1), ('two', 2), ('three', 3)`},
   278  		{`CREATE TABLE IF NOT EXISTS a AS VALUES ('one', 1), ('two', 2), ('three', 3)`},
   279  		{`CREATE TABLE a (str, num) AS VALUES ('one', 1), ('two', 2), ('three', 3)`},
   280  		{`CREATE TABLE IF NOT EXISTS a (str, num) AS VALUES ('one', 1), ('two', 2), ('three', 3)`},
   281  		{`CREATE TABLE a AS SELECT * FROM b UNION SELECT * FROM c`},
   282  		{`CREATE TABLE IF NOT EXISTS a AS SELECT * FROM b UNION SELECT * FROM c`},
   283  		{`CREATE TABLE a AS SELECT * FROM b UNION VALUES ('one', 1) ORDER BY c LIMIT 5`},
   284  		{`CREATE TABLE IF NOT EXISTS a AS SELECT * FROM b UNION VALUES ('one', 1) ORDER BY c LIMIT 5`},
   285  		{`CREATE TABLE a (z PRIMARY KEY) AS SELECT * FROM b`},
   286  		{`CREATE TABLE IF NOT EXISTS a (z PRIMARY KEY) AS SELECT * FROM b`},
   287  		{`CREATE TABLE a (x, y, z, PRIMARY KEY (x, y, z)) AS SELECT * FROM b`},
   288  		{`CREATE TABLE IF NOT EXISTS a (x, y, z, PRIMARY KEY (x, y, z)) AS SELECT * FROM b`},
   289  		{`CREATE TABLE a (x, FAMILY (x)) AS SELECT * FROM b`},
   290  		{`CREATE TABLE IF NOT EXISTS a (x, FAMILY (x)) AS SELECT * FROM b`},
   291  		{`CREATE TABLE a (x, y FAMILY f1) AS SELECT * FROM b`},
   292  		{`CREATE TABLE IF NOT EXISTS a (x, y FAMILY f1) AS SELECT * FROM b`},
   293  
   294  		{`CREATE TABLE a (b STRING COLLATE de)`},
   295  		{`CREATE TABLE a (b STRING(3) COLLATE de)`},
   296  		{`CREATE TABLE a (b STRING[] COLLATE de)`},
   297  		{`CREATE TABLE a (b STRING(3)[] COLLATE de)`},
   298  
   299  		{`CREATE TABLE a (LIKE b)`},
   300  		{`CREATE TABLE a (LIKE b, c INT8)`},
   301  		{`CREATE TABLE a (LIKE b EXCLUDING INDEXES INCLUDING INDEXES)`},
   302  		{`CREATE TABLE a (LIKE b INCLUDING ALL EXCLUDING INDEXES, c INT8)`},
   303  
   304  		{`CREATE VIEW a AS SELECT * FROM b`},
   305  		{`CREATE OR REPLACE VIEW a AS SELECT * FROM b`},
   306  		{`EXPLAIN CREATE VIEW a AS SELECT * FROM b`},
   307  		{`CREATE VIEW a AS SELECT b.* FROM b LIMIT 5`},
   308  		{`CREATE VIEW a AS (SELECT c, d FROM b WHERE c > 0 ORDER BY c)`},
   309  		{`CREATE VIEW a (x, y) AS SELECT c, d FROM b`},
   310  		{`CREATE VIEW a AS VALUES (1, 'one'), (2, 'two')`},
   311  		{`CREATE VIEW a (x, y) AS VALUES (1, 'one'), (2, 'two')`},
   312  		{`CREATE VIEW a AS TABLE b`},
   313  		{`CREATE TEMPORARY VIEW a AS SELECT b`},
   314  
   315  		{`CREATE SEQUENCE a`},
   316  		{`EXPLAIN CREATE SEQUENCE a`},
   317  		{`CREATE SEQUENCE IF NOT EXISTS a`},
   318  		{`CREATE SEQUENCE a CYCLE`},
   319  		{`CREATE SEQUENCE a NO CYCLE`},
   320  		{`CREATE SEQUENCE a CACHE 0`},
   321  		{`CREATE SEQUENCE a CACHE 1`},
   322  		{`CREATE SEQUENCE a CACHE 2`},
   323  		{`CREATE SEQUENCE a INCREMENT 5`},
   324  		{`CREATE SEQUENCE a INCREMENT BY 5`},
   325  		{`CREATE SEQUENCE a NO MAXVALUE`},
   326  		{`CREATE SEQUENCE a MAXVALUE 1000`},
   327  		{`CREATE SEQUENCE a NO MINVALUE`},
   328  		{`CREATE SEQUENCE a MINVALUE 1000`},
   329  		{`CREATE SEQUENCE a START 1000`},
   330  		{`CREATE SEQUENCE a START WITH 1000`},
   331  		{`CREATE SEQUENCE a INCREMENT 5 NO MAXVALUE MINVALUE 1 START 3`},
   332  		{`CREATE SEQUENCE a INCREMENT 5 NO CYCLE NO MAXVALUE MINVALUE 1 START 3 CACHE 1`},
   333  		{`CREATE SEQUENCE a VIRTUAL`},
   334  		{`CREATE TEMPORARY SEQUENCE a`},
   335  		{`CREATE SEQUENCE a OWNED BY b`},
   336  		{`CREATE SEQUENCE a OWNED BY NONE`},
   337  
   338  		{`CREATE STATISTICS a ON col1 FROM t`},
   339  		{`EXPLAIN CREATE STATISTICS a ON col1 FROM t`},
   340  		{`CREATE STATISTICS a ON col1, col2 FROM t`},
   341  		{`CREATE STATISTICS a ON col1 FROM d.t`},
   342  		{`CREATE STATISTICS a ON col1 FROM t`},
   343  		{`CREATE STATISTICS a ON col1 FROM t WITH OPTIONS THROTTLING 0.9`},
   344  		{`CREATE STATISTICS a ON col1 FROM t WITH OPTIONS AS OF SYSTEM TIME '2016-01-01'`},
   345  		{`CREATE STATISTICS a ON col1 FROM t WITH OPTIONS THROTTLING 0.1 AS OF SYSTEM TIME '2016-01-01'`},
   346  
   347  		{`CREATE TYPE a AS ENUM ()`},
   348  		{`CREATE TYPE a AS ENUM ('a')`},
   349  		{`CREATE TYPE a AS ENUM ('a', 'b', 'c')`},
   350  		{`CREATE TYPE a.b AS ENUM ('a', 'b', 'c')`},
   351  		{`CREATE TYPE a.b.c AS ENUM ('a', 'b', 'c')`},
   352  
   353  		{`DROP TYPE a`},
   354  		{`DROP TYPE a, b, c`},
   355  		{`DROP TYPE db.sc.a, sc.a`},
   356  		{`DROP TYPE IF EXISTS db.sc.a, sc.a`},
   357  		{`DROP TYPE db.sc.a, sc.a CASCADE`},
   358  		{`DROP TYPE IF EXISTS db.sc.a, sc.a CASCADE`},
   359  		{`DROP TYPE IF EXISTS db.sc.a, sc.a RESTRICT`},
   360  
   361  		{`DELETE FROM a`},
   362  		{`EXPLAIN DELETE FROM a`},
   363  		{`DELETE FROM a.b`},
   364  		{`DELETE FROM a.b@c`},
   365  		{`DELETE FROM a WHERE a = b`},
   366  		{`DELETE FROM a WHERE a = b LIMIT c`},
   367  		{`DELETE FROM a WHERE a = b ORDER BY c`},
   368  		{`DELETE FROM a WHERE a = b ORDER BY c LIMIT d`},
   369  		{`DELETE FROM a WHERE a = b RETURNING a, b`},
   370  		{`DELETE FROM a WHERE a = b RETURNING 1, 2`},
   371  		{`DELETE FROM a WHERE a = b RETURNING a + b`},
   372  		{`DELETE FROM a WHERE a = b RETURNING NOTHING`},
   373  		{`DELETE FROM a WHERE a = b ORDER BY c LIMIT d RETURNING e`},
   374  
   375  		{`DISCARD ALL`},
   376  
   377  		{`DROP DATABASE a`},
   378  		{`EXPLAIN DROP DATABASE a`},
   379  		{`DROP DATABASE IF EXISTS a`},
   380  		{`DROP DATABASE a CASCADE`},
   381  		{`DROP DATABASE a RESTRICT`},
   382  		{`DROP TABLE a`},
   383  		{`EXPLAIN DROP TABLE a`},
   384  		{`DROP TABLE a.b`},
   385  		{`DROP TABLE a, b`},
   386  		{`DROP TABLE IF EXISTS a`},
   387  		{`DROP TABLE a RESTRICT`},
   388  		{`DROP TABLE a.b RESTRICT`},
   389  		{`DROP TABLE a, b RESTRICT`},
   390  		{`DROP TABLE IF EXISTS a RESTRICT`},
   391  		{`DROP TABLE a CASCADE`},
   392  		{`DROP TABLE a.b CASCADE`},
   393  		{`DROP TABLE a, b CASCADE`},
   394  		{`DROP TABLE IF EXISTS a CASCADE`},
   395  		{`DROP INDEX a.b@c`},
   396  		{`DROP INDEX a`},
   397  		{`DROP INDEX a.b`},
   398  		{`DROP INDEX IF EXISTS a.b@c`},
   399  		{`DROP INDEX a.b@c, d@f`},
   400  		{`DROP INDEX IF EXISTS a.b@c, d@f`},
   401  		{`DROP INDEX a.b@c CASCADE`},
   402  		{`DROP INDEX IF EXISTS a.b@c RESTRICT`},
   403  		{`DROP VIEW a`},
   404  		{`DROP VIEW a.b`},
   405  		{`DROP VIEW a, b`},
   406  		{`DROP VIEW IF EXISTS a`},
   407  		{`DROP VIEW a RESTRICT`},
   408  		{`DROP VIEW IF EXISTS a, b RESTRICT`},
   409  		{`DROP VIEW a.b CASCADE`},
   410  		{`DROP VIEW a, b CASCADE`},
   411  		{`DROP SEQUENCE a`},
   412  		{`EXPLAIN DROP SEQUENCE a`},
   413  		{`DROP SEQUENCE a.b`},
   414  		{`DROP SEQUENCE a, b`},
   415  		{`DROP SEQUENCE IF EXISTS a`},
   416  		{`DROP SEQUENCE a RESTRICT`},
   417  		{`DROP SEQUENCE IF EXISTS a, b RESTRICT`},
   418  		{`DROP SEQUENCE a.b CASCADE`},
   419  		{`DROP SEQUENCE a, b CASCADE`},
   420  
   421  		{`CANCEL JOBS SELECT a`},
   422  		{`EXPLAIN CANCEL JOBS SELECT a`},
   423  		{`CANCEL QUERIES SELECT a`},
   424  		{`EXPLAIN CANCEL QUERIES SELECT a`},
   425  		{`CANCEL SESSIONS SELECT a`},
   426  		{`EXPLAIN CANCEL SESSIONS SELECT a`},
   427  		{`CANCEL QUERIES IF EXISTS SELECT a`},
   428  		{`CANCEL SESSIONS IF EXISTS SELECT a`},
   429  		{`RESUME JOBS SELECT a`},
   430  		{`EXPLAIN RESUME JOBS SELECT a`},
   431  		{`PAUSE JOBS SELECT a`},
   432  		{`EXPLAIN PAUSE JOBS SELECT a`},
   433  		{`SHOW JOBS SELECT a`},
   434  		{`EXPLAIN SHOW JOBS SELECT a`},
   435  		{`SHOW JOBS WHEN COMPLETE SELECT a`},
   436  		{`EXPLAIN SHOW JOBS WHEN COMPLETE SELECT a`},
   437  
   438  		{`EXPLAIN SELECT 1`},
   439  		{`EXPLAIN EXPLAIN SELECT 1`},
   440  		{`EXPLAIN (OPT, VERBOSE) SELECT 1`},
   441  		{`EXPLAIN ANALYZE (DISTSQL) SELECT 1`},
   442  		{`EXPLAIN ANALYZE (DEBUG) SELECT 1`},
   443  		{`SELECT * FROM [EXPLAIN SELECT 1]`},
   444  		{`SELECT * FROM [SHOW TRANSACTION STATUS]`},
   445  
   446  		{`SHOW barfoo`},
   447  		{`EXPLAIN SHOW barfoo`},
   448  		{`SHOW database`},
   449  		{`SHOW timezone`},
   450  		{`SHOW "BLAH"`},
   451  
   452  		{`SHOW CLUSTER SETTING a`},
   453  		{`EXPLAIN SHOW CLUSTER SETTING a`},
   454  		{`SHOW ALL CLUSTER SETTINGS`},
   455  		{`SHOW PUBLIC CLUSTER SETTINGS`},
   456  
   457  		{`SHOW DATABASES`},
   458  		{`EXPLAIN SHOW DATABASES`},
   459  		{`SHOW SCHEMAS`},
   460  		{`EXPLAIN SHOW SCHEMAS`},
   461  		{`SHOW SCHEMAS FROM a`},
   462  		{`SHOW SEQUENCES`},
   463  		{`EXPLAIN SHOW SEQUENCES`},
   464  		{`SHOW SEQUENCES FROM a`},
   465  		{`SHOW TABLES`},
   466  		{`SHOW TABLES WITH COMMENT`},
   467  		{`EXPLAIN SHOW TABLES`},
   468  		{`SHOW TABLES FROM a`},
   469  		{`SHOW TABLES FROM a WITH COMMENT`},
   470  		{`SHOW TABLES FROM a.b`},
   471  		{`SHOW TABLES FROM a.b WITH COMMENT`},
   472  		{`SHOW COLUMNS FROM a`},
   473  		{`EXPLAIN SHOW COLUMNS FROM a`},
   474  		{`SHOW COLUMNS FROM a.b.c`},
   475  		{`SHOW INDEXES FROM a`},
   476  		{`EXPLAIN SHOW INDEXES FROM a`},
   477  		{`SHOW INDEXES FROM a WITH COMMENT`},
   478  		{`EXPLAIN SHOW INDEXES FROM a WITH COMMENT`},
   479  		{`SHOW INDEXES FROM a.b.c`},
   480  		{`SHOW INDEXES FROM a.b.c WITH COMMENT`},
   481  		{`SHOW INDEXES FROM DATABASE a`},
   482  		{`SHOW INDEXES FROM DATABASE a WITH COMMENT`},
   483  		{`SHOW CONSTRAINTS FROM a`},
   484  		{`SHOW CONSTRAINTS FROM a.b.c`},
   485  		{`EXPLAIN SHOW CONSTRAINTS FROM a.b.c`},
   486  		{`SHOW TABLES FROM a.b; SHOW COLUMNS FROM b`},
   487  		{`EXPLAIN SHOW TABLES FROM a`},
   488  		{`SHOW ROLES`},
   489  		{`EXPLAIN SHOW ROLES`},
   490  		{`SHOW USERS`},
   491  		{`EXPLAIN SHOW USERS`},
   492  		{`SHOW JOBS`},
   493  		{`EXPLAIN SHOW JOBS`},
   494  		{`SHOW AUTOMATIC JOBS`},
   495  		{`EXPLAIN SHOW AUTOMATIC JOBS`},
   496  		{`SHOW CLUSTER QUERIES`},
   497  		{`EXPLAIN SHOW CLUSTER QUERIES`},
   498  		{`SHOW ALL CLUSTER QUERIES`},
   499  		{`EXPLAIN SHOW ALL CLUSTER QUERIES`},
   500  		{`SHOW LOCAL QUERIES`},
   501  		{`EXPLAIN SHOW LOCAL QUERIES`},
   502  		{`SHOW ALL LOCAL QUERIES`},
   503  		{`EXPLAIN SHOW ALL LOCAL QUERIES`},
   504  		{`SHOW CLUSTER SESSIONS`},
   505  		{`EXPLAIN SHOW CLUSTER SESSIONS`},
   506  		{`SHOW ALL CLUSTER SESSIONS`},
   507  		{`EXPLAIN SHOW ALL CLUSTER SESSIONS`},
   508  		{`SHOW LOCAL SESSIONS`},
   509  		{`EXPLAIN SHOW LOCAL SESSIONS`},
   510  		{`SHOW ALL LOCAL SESSIONS`},
   511  		{`EXPLAIN SHOW ALL LOCAL SESSIONS`},
   512  		{`SHOW TRACE FOR SESSION`},
   513  		{`EXPLAIN SHOW TRACE FOR SESSION`},
   514  		{`SHOW KV TRACE FOR SESSION`},
   515  		{`EXPLAIN SHOW KV TRACE FOR SESSION`},
   516  		{`SHOW EXPERIMENTAL_REPLICA TRACE FOR SESSION`},
   517  		{`EXPLAIN SHOW EXPERIMENTAL_REPLICA TRACE FOR SESSION`},
   518  		{`SHOW STATISTICS FOR TABLE t`},
   519  		{`EXPLAIN SHOW STATISTICS FOR TABLE t`},
   520  		{`SHOW STATISTICS FOR TABLE d.t`},
   521  		{`SHOW HISTOGRAM 123`},
   522  		{`EXPLAIN SHOW HISTOGRAM 123`},
   523  		{`SHOW RANGE FROM TABLE t FOR ROW (1, 2)`},
   524  		{`SHOW RANGE FROM TABLE d.t FOR ROW (1, 2)`},
   525  		{`SHOW RANGE FROM INDEX d.t@i FOR ROW (1, 2)`},
   526  		{`SHOW RANGE FROM INDEX t@i FOR ROW (1, 2)`},
   527  		{`SHOW RANGE FROM INDEX i FOR ROW (1, 2)`},
   528  		{`SHOW RANGES FROM TABLE d.t`},
   529  		{`EXPLAIN SHOW RANGES FROM TABLE d.t`},
   530  		{`SHOW RANGES FROM TABLE t`},
   531  		{`SHOW RANGES FROM INDEX d.t@i`},
   532  		{`SHOW RANGES FROM INDEX t@i`},
   533  		{`SHOW RANGES FROM INDEX d.i`},
   534  		{`SHOW RANGES FROM INDEX i`},
   535  		{`SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE d.t`},
   536  		{`SHOW ZONE CONFIGURATIONS`},
   537  		{`EXPLAIN SHOW ZONE CONFIGURATIONS`},
   538  		{`SHOW ZONE CONFIGURATION FOR RANGE default`},
   539  		{`SHOW ZONE CONFIGURATION FOR RANGE meta`},
   540  		{`SHOW ZONE CONFIGURATION FOR DATABASE db`},
   541  		{`SHOW ZONE CONFIGURATION FOR TABLE db.t`},
   542  		{`SHOW ZONE CONFIGURATION FOR PARTITION p OF TABLE db.t`},
   543  		{`SHOW ZONE CONFIGURATION FOR TABLE t`},
   544  		{`SHOW ZONE CONFIGURATION FOR PARTITION p OF TABLE t`},
   545  		{`SHOW ZONE CONFIGURATION FOR INDEX db.t@i`},
   546  		{`SHOW ZONE CONFIGURATION FOR INDEX t@i`},
   547  		{`SHOW ZONE CONFIGURATION FOR INDEX i`},
   548  
   549  		// Tables are the default, but can also be specified with
   550  		// GRANT x ON TABLE y. However, the stringer does not output TABLE.
   551  		{`SHOW GRANTS`},
   552  		{`EXPLAIN SHOW GRANTS`},
   553  		{`SHOW GRANTS ON TABLE foo`},
   554  		{`SHOW GRANTS ON TABLE foo, db.foo`},
   555  		{`SHOW GRANTS ON DATABASE foo, bar`},
   556  		{`SHOW GRANTS ON DATABASE foo FOR bar`},
   557  		{`SHOW GRANTS FOR bar, baz`},
   558  
   559  		{`SHOW GRANTS ON ROLE`},
   560  		{`SHOW GRANTS ON ROLE foo`},
   561  		{`SHOW GRANTS ON ROLE foo, bar`},
   562  		{`SHOW GRANTS ON ROLE foo FOR bar`},
   563  		{`SHOW GRANTS ON ROLE FOR bar, baz`},
   564  
   565  		{`SHOW TRANSACTION STATUS`},
   566  		{`EXPLAIN SHOW TRANSACTION STATUS`},
   567  		{`SHOW SAVEPOINT STATUS`},
   568  		{`EXPLAIN SHOW SAVEPOINT STATUS`},
   569  
   570  		{`SHOW SYNTAX 'select 1'`},
   571  		{`EXPLAIN SHOW SYNTAX 'select 1'`},
   572  
   573  		{`PREPARE a AS SELECT 1`},
   574  		{`PREPARE a AS EXPLAIN SELECT 1`},
   575  		{`PREPARE a (INT8) AS SELECT $1`},
   576  		{`PREPARE a (STRING, STRING) AS SELECT $1, $2`},
   577  		{`PREPARE a AS INSERT INTO a VALUES (1)`},
   578  		{`PREPARE a (INT8) AS INSERT INTO a VALUES ($1)`},
   579  		{`PREPARE a AS UPDATE a SET b = 1`},
   580  		{`PREPARE a (INT8) AS UPDATE a SET b = $1`},
   581  		{`PREPARE a AS UPSERT INTO a VALUES (1)`},
   582  		{`PREPARE a (INT8) AS UPSERT INTO a VALUES ($1)`},
   583  		{`PREPARE a AS DELETE FROM a`},
   584  		{`PREPARE a (INT8) AS DELETE FROM a WHERE b = $1`},
   585  		{`PREPARE a AS BACKUP DATABASE a TO 'b'`},
   586  		{`PREPARE a (STRING) AS BACKUP DATABASE a TO $1`},
   587  		{`PREPARE a AS RESTORE DATABASE a FROM 'b'`},
   588  		{`PREPARE a (STRING) AS RESTORE DATABASE a FROM $1`},
   589  		{`PREPARE a AS CANCEL QUERIES SELECT 1`},
   590  		{`PREPARE a (STRING) AS CANCEL QUERIES SELECT $1`},
   591  		{`PREPARE a AS CANCEL QUERIES IF EXISTS SELECT 1`},
   592  		{`PREPARE a (STRING) AS CANCEL QUERIES IF EXISTS SELECT $1`},
   593  		{`PREPARE a AS CANCEL SESSIONS SELECT 1`},
   594  		{`PREPARE a (STRING) AS CANCEL SESSIONS SELECT $1`},
   595  		{`PREPARE a AS CANCEL SESSIONS IF EXISTS SELECT 1`},
   596  		{`PREPARE a (STRING) AS CANCEL SESSIONS IF EXISTS SELECT $1`},
   597  		{`PREPARE a AS CANCEL JOBS SELECT 1`},
   598  		{`PREPARE a (INT8) AS CANCEL JOBS SELECT $1`},
   599  		{`PREPARE a AS PAUSE JOBS SELECT 1`},
   600  		{`PREPARE a (INT8) AS PAUSE JOBS SELECT $1`},
   601  		{`PREPARE a AS RESUME JOBS SELECT 1`},
   602  		{`PREPARE a (INT8) AS RESUME JOBS SELECT $1`},
   603  		{`PREPARE a AS IMPORT TABLE a CREATE USING 'b' CSV DATA ('c') WITH temp = 'd'`},
   604  		{`PREPARE a (STRING, STRING, STRING) AS IMPORT TABLE a CREATE USING $1 CSV DATA ($2) WITH temp = $3`},
   605  
   606  		{`PREPARE a AS OPT PLAN 'some-string'`},
   607  		{`PREPARE a (STRING, INT8) AS OPT PLAN 'some-string'`},
   608  
   609  		{`EXECUTE a`},
   610  		{`EXECUTE a DISCARD ROWS`},
   611  		{`EXECUTE a (1)`},
   612  		{`EXECUTE a (1, 1)`},
   613  		{`EXECUTE a (1, 1) DISCARD ROWS`},
   614  		{`EXECUTE a (1 + 1)`},
   615  
   616  		{`DEALLOCATE a`},
   617  		{`DEALLOCATE ALL`},
   618  
   619  		// Tables are the default, but can also be specified with
   620  		// GRANT x ON TABLE y. However, the stringer does not output TABLE.
   621  		{`GRANT SELECT ON TABLE foo TO root`},
   622  		{`GRANT SELECT, DELETE, UPDATE ON TABLE foo, db.foo TO root, bar`},
   623  		{`GRANT DROP ON DATABASE foo TO root`},
   624  		{`GRANT ALL ON DATABASE foo TO root, test`},
   625  		{`GRANT SELECT, INSERT ON DATABASE bar TO foo, bar, baz`},
   626  		{`GRANT SELECT, INSERT ON DATABASE db1, db2 TO foo, bar, baz`},
   627  		{`GRANT SELECT, INSERT ON DATABASE db1, db2 TO "test-user"`},
   628  		{`GRANT rolea, roleb TO usera, userb`},
   629  		{`GRANT rolea, roleb TO usera, userb WITH ADMIN OPTION`},
   630  
   631  		// Tables are the default, but can also be specified with
   632  		// REVOKE x ON TABLE y. However, the stringer does not output TABLE.
   633  		{`REVOKE SELECT ON TABLE foo FROM root`},
   634  		{`REVOKE UPDATE, DELETE ON TABLE foo, db.foo FROM root, bar`},
   635  		{`REVOKE INSERT ON DATABASE foo FROM root`},
   636  		{`REVOKE ALL ON DATABASE foo FROM root, test`},
   637  		{`REVOKE SELECT, INSERT ON DATABASE bar FROM foo, bar, baz`},
   638  		{`REVOKE SELECT, INSERT ON DATABASE db1, db2 FROM foo, bar, baz`},
   639  		{`REVOKE rolea, roleb FROM usera, userb`},
   640  		{`REVOKE ADMIN OPTION FOR rolea, roleb FROM usera, userb`},
   641  
   642  		{`INSERT INTO a VALUES (1)`},
   643  		{`EXPLAIN INSERT INTO a VALUES (1)`},
   644  		{`INSERT INTO a.b VALUES (1)`},
   645  		{`INSERT INTO a VALUES (1, 2)`},
   646  		{`INSERT INTO a VALUES (1, DEFAULT)`},
   647  		{`INSERT INTO a VALUES (1, 2), (3, 4)`},
   648  		{`INSERT INTO a VALUES (a + 1, 2 * 3)`},
   649  		{`INSERT INTO a(a, b) VALUES (1, 2)`},
   650  		{`INSERT INTO a SELECT b, c FROM d`},
   651  		{`INSERT INTO a DEFAULT VALUES`},
   652  		{`INSERT INTO a VALUES (1) RETURNING a, b`},
   653  		{`INSERT INTO a VALUES (1, 2) RETURNING 1, 2`},
   654  		{`INSERT INTO a VALUES (1, 2) RETURNING a + b, c`},
   655  		{`INSERT INTO a VALUES (1, 2) RETURNING NOTHING`},
   656  
   657  		{`UPSERT INTO a VALUES (1)`},
   658  		{`EXPLAIN UPSERT INTO a VALUES (1)`},
   659  		{`UPSERT INTO a.b VALUES (1)`},
   660  		{`UPSERT INTO a VALUES (1, 2)`},
   661  		{`UPSERT INTO a VALUES (1, DEFAULT)`},
   662  		{`UPSERT INTO a VALUES (1, 2), (3, 4)`},
   663  		{`UPSERT INTO a VALUES (a + 1, 2 * 3)`},
   664  		{`UPSERT INTO a(a, b) VALUES (1, 2)`},
   665  		{`UPSERT INTO a SELECT b, c FROM d`},
   666  		{`UPSERT INTO a DEFAULT VALUES`},
   667  		{`UPSERT INTO a DEFAULT VALUES RETURNING a, b`},
   668  		{`UPSERT INTO a DEFAULT VALUES RETURNING 1, 2`},
   669  		{`UPSERT INTO a DEFAULT VALUES RETURNING a + b`},
   670  		{`UPSERT INTO a DEFAULT VALUES RETURNING NOTHING`},
   671  
   672  		{`INSERT INTO a VALUES (1) ON CONFLICT DO NOTHING`},
   673  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO NOTHING`},
   674  		{`INSERT INTO a VALUES (1) ON CONFLICT DO UPDATE SET a = 1`},
   675  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET a = 1`},
   676  		{`INSERT INTO a VALUES (1) ON CONFLICT (a, b) DO UPDATE SET a = 1`},
   677  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET a = 1, b = excluded.a`},
   678  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET a = 1 WHERE b > 2`},
   679  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET a = DEFAULT`},
   680  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET (a, b) = (SELECT 1, 2)`},
   681  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET (a, b) = (SELECT 1, 2) RETURNING a, b`},
   682  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET (a, b) = (SELECT 1, 2) RETURNING 1, 2`},
   683  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET (a, b) = (SELECT 1, 2) RETURNING a + b`},
   684  		{`INSERT INTO a VALUES (1) ON CONFLICT (a) DO UPDATE SET (a, b) = (SELECT 1, 2) RETURNING NOTHING`},
   685  
   686  		{`SELECT 1 + 1`},
   687  		{`SELECT -1`},
   688  		{`SELECT .1`},
   689  		{`SELECT 1.2e1`},
   690  		{`SELECT 1.2e+1`},
   691  		{`SELECT 1.2e-1`},
   692  		{`SELECT true AND false`},
   693  		{`SELECT true AND NULL`},
   694  		{`SELECT true = false`},
   695  		{`SELECT (true = false)`},
   696  		{`SELECT (ARRAY['a', 'b'])[2]`},
   697  		{`SELECT (ARRAY (VALUES (1), (2)))[1]`},
   698  		{`SELECT (SELECT 1)`},
   699  		{`SELECT ((SELECT 1))`},
   700  		{`SELECT (SELECT ARRAY['a', 'b'])[2]`},
   701  		{`SELECT ((SELECT ARRAY['a', 'b']))[2]`},
   702  		{`SELECT ((((VALUES (1)))))`},
   703  		{`SELECT EXISTS (SELECT 1)`},
   704  		{`SELECT (VALUES (1))`},
   705  		{`SELECT (1, 2, 3)`},
   706  		{`SELECT ((1, 2, 3) AS a, b, c)`},
   707  		{`SELECT ((1, 2, 3))`},
   708  		{`SELECT ((1, 2, 3) AS a, b, c)`},
   709  		{`SELECT (((1, 2, 3) AS a, b, c)).a`},
   710  		{`SELECT (((1, 2, 3) AS a, b, c)).*`},
   711  		{`SELECT ()`},
   712  		{`SELECT (() AS a)`},
   713  		{`SELECT ((() AS a)).a`},
   714  		{`SELECT ((() AS a)).*`},
   715  		{`SELECT ((() AS a)).@1`},
   716  		{`SELECT (TABLE a)`},
   717  		{`SELECT 0x1`},
   718  		{`SELECT 'Deutsch' COLLATE de`},
   719  		{`SELECT a @> b`},
   720  		{`SELECT a <@ b`},
   721  		{`SELECT a ? b`},
   722  		{`SELECT a ?| b`},
   723  		{`SELECT a ?& b`},
   724  		{`SELECT a->'x'`},
   725  		{`SELECT a#>'{x}'`},
   726  		{`SELECT a#>>'{x}'`},
   727  		{`SELECT (a->'x')->'y'`},
   728  		{`SELECT (a->'x')->>'y'`},
   729  		{`SELECT b && c`},
   730  		{`SELECT |/a`},
   731  		{`SELECT ||/a`},
   732  
   733  		{`SELECT 1 FROM t`},
   734  		{`SELECT 1, 2 FROM t`},
   735  		{`SELECT * FROM t`},
   736  		{`SELECT "*" FROM t`},
   737  		{`SELECT a, b FROM t`},
   738  		{`SELECT a AS b FROM t`},
   739  		{`SELECT a.* FROM t`},
   740  		{`SELECT a = b FROM t`},
   741  		{`SELECT $1 FROM t`},
   742  		{`SELECT $1, $2 FROM t`},
   743  		{`SELECT NULL FROM t`},
   744  		{`SELECT 0.1 FROM t`},
   745  		{`SELECT a FROM t`},
   746  		{`SELECT a.b FROM t`},
   747  		{`SELECT a.b.* FROM t`},
   748  		{`SELECT a.b[1] FROM t`},
   749  		{`SELECT a.b[1 + 1:4][3] FROM t`},
   750  		{`SELECT a.b[:4][3] FROM t`},
   751  		{`SELECT a.b[1 + 1:][3] FROM t`},
   752  		{`SELECT a.b[:][3] FROM t`},
   753  		{`SELECT 'a' FROM t`},
   754  		{`SELECT 'a' FROM t@bar`},
   755  		{`SELECT 'a' FROM t@primary`},
   756  		{`SELECT 'a' FROM t@like`},
   757  		{`SELECT 'a' FROM t@{NO_INDEX_JOIN}`},
   758  		{`SELECT 'a' FROM t@{IGNORE_FOREIGN_KEYS}`},
   759  		{`SELECT 'a' FROM t@{FORCE_INDEX=idx,ASC}`},
   760  		{`SELECT 'a' FROM t@{FORCE_INDEX=idx,DESC,IGNORE_FOREIGN_KEYS}`},
   761  		{`SELECT * FROM t AS "of" AS OF SYSTEM TIME '2016-01-01'`},
   762  
   763  		{`SELECT BOOL 'foo', 'foo'::BOOL`},
   764  		{`SELECT BIT '10', '10'::BIT`},
   765  		{`SELECT VARBIT '1', '1'::VARBIT`},
   766  		{`SELECT INT2 'foo', 'foo'::INT2`},
   767  		{`SELECT INT4 'foo', 'foo'::INT4`},
   768  		{`SELECT INT8 'foo', 'foo'::INT8`},
   769  		{`SELECT FLOAT4 'foo', 'foo'::FLOAT4`},
   770  		{`SELECT DECIMAL 'foo', 'foo'::DECIMAL`},
   771  		{`SELECT CHAR 'foo', 'foo'::CHAR`},
   772  		{`SELECT VARCHAR 'foo', 'foo'::VARCHAR`},
   773  		{`SELECT STRING 'foo', 'foo'::STRING`},
   774  		{`SELECT BYTES 'foo', 'foo'::BYTES`},
   775  		{`SELECT DATE 'foo', 'foo'::DATE`},
   776  		{`SELECT TIME 'foo', 'foo'::TIME`},
   777  		{`SELECT TIMESTAMP 'foo', 'foo'::TIMESTAMP`},
   778  		{`SELECT TIMESTAMPTZ 'foo', 'foo'::TIMESTAMPTZ`},
   779  		{`SELECT JSONB 'foo', 'foo'::JSONB`},
   780  
   781  		{`SELECT 'foo'::DECIMAL(1)`},
   782  		{`SELECT 'foo'::DECIMAL(2,1)`},
   783  		{`SELECT 'foo'::BIT(3)`},
   784  		{`SELECT 'foo'::VARBIT(3)`},
   785  		{`SELECT 'foo'::CHAR(3)`},
   786  		{`SELECT 'foo'::VARCHAR(3)`},
   787  		{`SELECT 'foo'::STRING(3)`},
   788  		{`SELECT 'foo'::TIMESTAMP(6)`},
   789  		{`SELECT 'foo'::TIMESTAMPTZ(6)`},
   790  		{`SELECT 'foo'::TIME(6)`},
   791  		{`SELECT '0'::INTERVAL`},
   792  
   793  		{`SELECT 'foo'::GEOGRAPHY`},
   794  		{`SELECT 'foo'::GEOGRAPHY(POINT,4326)`},
   795  		{`SELECT 'foo'::GEOGRAPHY(POINT)`},
   796  		{`SELECT 'foo'::GEOMETRY`},
   797  		{`SELECT 'foo'::GEOMETRY(POINT)`},
   798  		{`SELECT 'foo'::GEOMETRY(POINT,4326)`},
   799  
   800  		{`SELECT '192.168.0.1'::INET`},
   801  		{`SELECT '192.168.0.1':::INET`},
   802  		{`SELECT INET '192.168.0.1'`},
   803  
   804  		{`SELECT 1:::REGTYPE`},
   805  		{`SELECT 1:::REGPROC`},
   806  		{`SELECT 1:::REGPROCEDURE`},
   807  		{`SELECT 1:::REGCLASS`},
   808  		{`SELECT 1:::REGNAMESPACE`},
   809  
   810  		{`SELECT 'a' AS "12345"`},
   811  		{`SELECT 'a' AS clnm`},
   812  		{`SELECT 'a' AS primary`},
   813  		{`SELECT 'a' AS like`},
   814  
   815  		{`SELECT 0xf0 FROM t`},
   816  		{`SELECT 0xF0 FROM t`},
   817  
   818  		// Test various cases of qualified and not statically known types.
   819  		{`SELECT 1::notatype`},
   820  		{`SELECT 1::schem.typ`},
   821  		{`SELECT 1::int4.typ`},
   822  		{`SELECT 1::db.schem.typ`},
   823  		{`SELECT 1::db.int4.typ[]`},
   824  		{`CREATE TABLE t (x special.type)`},
   825  		{`CREATE TABLE t (x int4.type)`},
   826  		{`CREATE TABLE t (x notatype)`},
   827  		{`SELECT 1 IS OF (my.type, int4.type)`},
   828  		{`SELECT my.type ''`},
   829  		{`SELECT int4.type ''`},
   830  		{`SELECT foo ''`},
   831  		{`SELECT CAST(1.2 + 2.3 AS notatype)`},
   832  		{`SELECT ANNOTATE_TYPE(1.2 + 2.3, notatype)`},
   833  		{`SELECT 'f'::blah`},
   834  
   835  		// Escaping may change since the scanning process loses information
   836  		// (you can write e'\'' or ''''), but these are the idempotent cases.
   837  		// Generally, anything that needs to escape plus \ and ' leads to an
   838  		// escaped string.
   839  		{`SELECT e'a\'a' FROM t`},
   840  		{`SELECT e'a\\\\na' FROM t`},
   841  		{`SELECT e'\\\\n' FROM t`},
   842  		{`SELECT "a""a" FROM t`},
   843  		{`SELECT a FROM "t\n"`},  // no escaping in sql identifiers
   844  		{`SELECT a FROM "t"""`},  // no escaping in sql identifiers
   845  		{`SELECT "full" FROM t`}, // must quote column name keyword
   846  
   847  		{`SELECT "FROM" FROM t`},
   848  		{`SELECT CAST(1 AS STRING)`},
   849  		{`SELECT ANNOTATE_TYPE(1, STRING)`},
   850  		{`SELECT a FROM t AS bar`},
   851  		{`SELECT a FROM t AS bar (bar1)`},
   852  		{`SELECT a FROM t AS bar (bar1, bar2, bar3)`},
   853  		{`SELECT a FROM t WITH ORDINALITY`},
   854  		{`SELECT a FROM t WITH ORDINALITY AS bar`},
   855  		{`SELECT a FROM (SELECT 1 FROM t)`},
   856  		{`SELECT a FROM (SELECT 1 FROM t) AS bar`},
   857  		{`SELECT a FROM (SELECT 1 FROM t) AS bar (bar1)`},
   858  		{`SELECT a FROM (SELECT 1 FROM t) AS bar (bar1, bar2, bar3)`},
   859  		{`SELECT a FROM (SELECT 1 FROM t) WITH ORDINALITY`},
   860  		{`SELECT a FROM (SELECT 1 FROM t) WITH ORDINALITY AS bar`},
   861  		{`SELECT a FROM ROWS FROM (a(x), b(y), c(z))`},
   862  		{`SELECT a FROM t1, t2`},
   863  		{`SELECT a FROM t1, LATERAL (SELECT * FROM t2 WHERE a = b)`},
   864  		{`SELECT a FROM t1, LATERAL ROWS FROM (generate_series(1, t1.x))`},
   865  		{`SELECT a FROM t AS t1`},
   866  		{`SELECT a FROM t AS t1 (c1)`},
   867  		{`SELECT a FROM t AS t1 (c1, c2, c3, c4)`},
   868  		{`SELECT a FROM s.t`},
   869  
   870  		{`SELECT count(DISTINCT a) FROM t`},
   871  		{`SELECT count(ALL a) FROM t`},
   872  
   873  		{`SELECT a FROM t WHERE a = b`},
   874  		{`SELECT a FROM t WHERE NOT (a = b)`},
   875  		{`SELECT a FROM t WHERE EXISTS (SELECT 1 FROM t)`},
   876  		{`SELECT a FROM t WHERE NOT true`},
   877  		{`SELECT a FROM t WHERE NOT false`},
   878  		{`SELECT a FROM t WHERE a IN (b,)`},
   879  		{`SELECT a FROM t WHERE a IN (b, c)`},
   880  		{`SELECT a FROM t WHERE a IN (SELECT a FROM t)`},
   881  		{`SELECT a FROM t WHERE a NOT IN (b, c)`},
   882  		{`SELECT a FROM t WHERE a = ANY (ARRAY[b, c])`},
   883  		{`SELECT a FROM t WHERE a = ANY ARRAY[b, c]`},
   884  		{`SELECT a FROM t WHERE a != SOME (ARRAY[b, c])`},
   885  		{`SELECT a FROM t WHERE a != SOME ARRAY[b, c]`},
   886  		{`SELECT a FROM t WHERE a = ANY (SELECT 1)`},
   887  		{`SELECT a FROM t WHERE a LIKE ALL (ARRAY[b, c])`},
   888  		{`SELECT a FROM t WHERE a LIKE ALL ARRAY[b, c]`},
   889  		{`SELECT a FROM t WHERE a LIKE b`},
   890  		{`SELECT a FROM t WHERE a NOT LIKE b`},
   891  		{`SELECT a FROM t WHERE a ILIKE b`},
   892  		{`SELECT a FROM t WHERE a NOT ILIKE b`},
   893  		{`SELECT a FROM t WHERE a SIMILAR TO b`},
   894  		{`SELECT a FROM t WHERE a NOT SIMILAR TO b`},
   895  		{`SELECT a FROM t WHERE a ~ b`},
   896  		{`SELECT a FROM t WHERE a !~ b`},
   897  		{`SELECT a FROM t WHERE a ~* c`},
   898  		{`SELECT a FROM t WHERE a !~* c`},
   899  		{`SELECT a FROM t WHERE a BETWEEN b AND c`},
   900  		{`SELECT a FROM t WHERE a BETWEEN SYMMETRIC b AND c`},
   901  		{`SELECT a FROM t WHERE a NOT BETWEEN b AND c`},
   902  		{`SELECT a FROM t WHERE a NOT BETWEEN SYMMETRIC b AND c`},
   903  		{`SELECT a FROM t WHERE a IS NULL`},
   904  		{`SELECT a FROM t WHERE a IS NOT NULL`},
   905  		{`SELECT a FROM t WHERE (a, b) IS NULL`},
   906  		{`SELECT a FROM t WHERE (a, b) IS NOT NULL`},
   907  		{`SELECT a FROM t WHERE a IS true`},
   908  		{`SELECT a FROM t WHERE a IS NOT true`},
   909  		{`SELECT a FROM t WHERE a IS false`},
   910  		{`SELECT a FROM t WHERE a IS NOT false`},
   911  		{`SELECT a FROM t WHERE a IS OF (INT8)`},
   912  		{`SELECT a FROM t WHERE a IS NOT OF (FLOAT8, STRING)`},
   913  		{`SELECT a FROM t WHERE a IS DISTINCT FROM b`},
   914  		{`SELECT a FROM t WHERE a IS NOT DISTINCT FROM b`},
   915  		{`SELECT a FROM t WHERE (a, b) IS NOT DISTINCT FROM NULL`},
   916  		{`SELECT a FROM t WHERE (a, b) IS DISTINCT FROM NULL`},
   917  		{`SELECT a FROM t WHERE a < b`},
   918  		{`SELECT a FROM t WHERE a <= b`},
   919  		{`SELECT a FROM t WHERE a >= b`},
   920  		{`SELECT a FROM t WHERE a != b`},
   921  		{`SELECT a FROM t WHERE a = (SELECT a FROM t)`},
   922  		{`SELECT a FROM t WHERE a = (b)`},
   923  		{`SELECT a FROM t WHERE CASE WHEN a = b THEN c END`},
   924  		{`SELECT a FROM t WHERE CASE WHEN a = b THEN c ELSE d END`},
   925  		{`SELECT a FROM t WHERE CASE WHEN a = b THEN c WHEN b = d THEN d ELSE d END`},
   926  		{`SELECT a FROM t WHERE CASE aa WHEN a = b THEN c END`},
   927  		{`SELECT a FROM t WHERE a = b()`},
   928  		{`SELECT a FROM t WHERE a = b(c)`},
   929  		{`SELECT a FROM t WHERE a = b(c, d)`},
   930  		{`SELECT a FROM t WHERE a = count(*)`},
   931  		{`SELECT a FROM t WHERE a = IF(b, c, d)`},
   932  		{`SELECT a FROM t WHERE a = IFERROR(b, c, d)`},
   933  		{`SELECT a FROM t WHERE a = IFERROR(b, c)`},
   934  		{`SELECT a FROM t WHERE a = ISERROR(b)`},
   935  		{`SELECT a FROM t WHERE a = ISERROR(b, c)`},
   936  		{`SELECT a FROM t WHERE a = IFNULL(b, c)`},
   937  		{`SELECT a FROM t WHERE a = NULLIF(b, c)`},
   938  		{`SELECT a FROM t WHERE a = COALESCE(a, b, c, d, e)`},
   939  		{`SELECT (a.b) FROM t WHERE (b.c) = 2`},
   940  
   941  		{`SELECT a FROM t ORDER BY a`},
   942  		{`SELECT a FROM t ORDER BY a ASC`},
   943  		{`SELECT a FROM t ORDER BY a DESC`},
   944  		{`SELECT a FROM t ORDER BY PRIMARY KEY t`},
   945  		{`SELECT a FROM t ORDER BY PRIMARY KEY t ASC`},
   946  		{`SELECT a FROM t ORDER BY PRIMARY KEY t DESC`},
   947  		{`SELECT a FROM t ORDER BY INDEX t@foo`},
   948  		{`SELECT a FROM t ORDER BY INDEX t@foo ASC`},
   949  		{`SELECT a FROM t ORDER BY INDEX t@foo DESC`},
   950  		{`SELECT a FROM t ORDER BY INDEX t@primary`},
   951  		{`SELECT a FROM t ORDER BY INDEX t@like`},
   952  		{`SELECT a FROM t ORDER BY a NULLS FIRST`},
   953  		{`SELECT a FROM t ORDER BY a ASC NULLS FIRST`},
   954  		{`SELECT a FROM t ORDER BY a DESC NULLS LAST`},
   955  
   956  		{`SELECT 1 FROM t GROUP BY a`},
   957  		{`SELECT 1 FROM t GROUP BY a, b`},
   958  		{`SELECT sum(x ORDER BY y) FROM t`},
   959  		{`SELECT sum(x ORDER BY y, z) FROM t`},
   960  
   961  		{`SELECT a FROM t HAVING a = b`},
   962  
   963  		{`SELECT a FROM t WINDOW w AS ()`},
   964  		{`SELECT a FROM t WINDOW w AS (w2)`},
   965  		{`SELECT a FROM t WINDOW w AS (PARTITION BY b)`},
   966  		{`SELECT a FROM t WINDOW w AS (PARTITION BY b, 1 + 2)`},
   967  		{`SELECT a FROM t WINDOW w AS (ORDER BY c)`},
   968  		{`SELECT a FROM t WINDOW w AS (ORDER BY c, 1 + 2)`},
   969  		{`SELECT a FROM t WINDOW w AS (PARTITION BY b ORDER BY c)`},
   970  
   971  		{`SELECT avg(1) OVER w FROM t`},
   972  		{`SELECT avg(1) OVER () FROM t`},
   973  		{`SELECT avg(1) OVER (w) FROM t`},
   974  		{`SELECT avg(1) OVER (PARTITION BY b) FROM t`},
   975  		{`SELECT avg(1) OVER (ORDER BY c) FROM t`},
   976  		{`SELECT avg(1) OVER (PARTITION BY b ORDER BY c) FROM t`},
   977  		{`SELECT avg(1) OVER (w PARTITION BY b ORDER BY c) FROM t`},
   978  
   979  		{`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING) FROM t`},
   980  		{`SELECT avg(1) OVER (ROWS 1 PRECEDING) FROM t`},
   981  		{`SELECT avg(1) OVER (ROWS CURRENT ROW) FROM t`},
   982  		{`SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) FROM t`},
   983  		{`SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t`},
   984  		{`SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) FROM t`},
   985  		{`SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t`},
   986  		{`SELECT avg(1) OVER (ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) FROM t`},
   987  		{`SELECT avg(1) OVER (ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) FROM t`},
   988  		{`SELECT avg(1) OVER (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t`},
   989  		{`SELECT avg(1) OVER (ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) FROM t`},
   990  		{`SELECT avg(1) OVER (ROWS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t`},
   991  		{`SELECT avg(1) OVER (ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) FROM t`},
   992  		{`SELECT avg(1) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t`},
   993  		{`SELECT avg(1) OVER (ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) FROM t`},
   994  		{`SELECT avg(1) OVER (ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t`},
   995  		{`SELECT avg(1) OVER (w ROWS UNBOUNDED PRECEDING) FROM t`},
   996  		{`SELECT avg(1) OVER (PARTITION BY b ROWS UNBOUNDED PRECEDING) FROM t`},
   997  		{`SELECT avg(1) OVER (ORDER BY c ROWS UNBOUNDED PRECEDING) FROM t`},
   998  		{`SELECT avg(1) OVER (PARTITION BY b ORDER BY c ROWS UNBOUNDED PRECEDING) FROM t`},
   999  		{`SELECT avg(1) OVER (w PARTITION BY b ORDER BY c ROWS UNBOUNDED PRECEDING) FROM t`},
  1000  
  1001  		{`SELECT avg(1) OVER (RANGE UNBOUNDED PRECEDING) FROM t`},
  1002  		{`SELECT avg(1) OVER (RANGE 1 PRECEDING) FROM t`},
  1003  		{`SELECT avg(1) OVER (RANGE CURRENT ROW) FROM t`},
  1004  		{`SELECT avg(1) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) FROM t`},
  1005  		{`SELECT avg(1) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t`},
  1006  		{`SELECT avg(1) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) FROM t`},
  1007  		{`SELECT avg(1) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t`},
  1008  		{`SELECT avg(1) OVER (RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) FROM t`},
  1009  		{`SELECT avg(1) OVER (RANGE BETWEEN 1 PRECEDING AND CURRENT ROW) FROM t`},
  1010  		{`SELECT avg(1) OVER (RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t`},
  1011  		{`SELECT avg(1) OVER (RANGE BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) FROM t`},
  1012  		{`SELECT avg(1) OVER (RANGE BETWEEN CURRENT ROW AND CURRENT ROW) FROM t`},
  1013  		{`SELECT avg(1) OVER (RANGE BETWEEN CURRENT ROW AND 1 FOLLOWING) FROM t`},
  1014  		{`SELECT avg(1) OVER (RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t`},
  1015  		{`SELECT avg(1) OVER (RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING) FROM t`},
  1016  		{`SELECT avg(1) OVER (RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t`},
  1017  		{`SELECT avg(1) OVER (w RANGE UNBOUNDED PRECEDING) FROM t`},
  1018  		{`SELECT avg(1) OVER (PARTITION BY b RANGE UNBOUNDED PRECEDING) FROM t`},
  1019  		{`SELECT avg(1) OVER (ORDER BY c RANGE UNBOUNDED PRECEDING) FROM t`},
  1020  		{`SELECT avg(1) OVER (PARTITION BY b ORDER BY c RANGE UNBOUNDED PRECEDING) FROM t`},
  1021  		{`SELECT avg(1) OVER (w PARTITION BY b ORDER BY c RANGE UNBOUNDED PRECEDING) FROM t`},
  1022  
  1023  		{`SELECT avg(1) OVER (GROUPS UNBOUNDED PRECEDING) FROM t`},
  1024  		{`SELECT avg(1) OVER (GROUPS 1 PRECEDING) FROM t`},
  1025  		{`SELECT avg(1) OVER (GROUPS CURRENT ROW) FROM t`},
  1026  		{`SELECT avg(1) OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) FROM t`},
  1027  		{`SELECT avg(1) OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t`},
  1028  		{`SELECT avg(1) OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) FROM t`},
  1029  		{`SELECT avg(1) OVER (GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM t`},
  1030  		{`SELECT avg(1) OVER (GROUPS BETWEEN 1 PRECEDING AND 1 PRECEDING) FROM t`},
  1031  		{`SELECT avg(1) OVER (GROUPS BETWEEN 1 PRECEDING AND CURRENT ROW) FROM t`},
  1032  		{`SELECT avg(1) OVER (GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t`},
  1033  		{`SELECT avg(1) OVER (GROUPS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING) FROM t`},
  1034  		{`SELECT avg(1) OVER (GROUPS BETWEEN CURRENT ROW AND CURRENT ROW) FROM t`},
  1035  		{`SELECT avg(1) OVER (GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING) FROM t`},
  1036  		{`SELECT avg(1) OVER (GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM t`},
  1037  		{`SELECT avg(1) OVER (GROUPS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) FROM t`},
  1038  		{`SELECT avg(1) OVER (GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) FROM t`},
  1039  		{`SELECT avg(1) OVER (w GROUPS UNBOUNDED PRECEDING) FROM t`},
  1040  		{`SELECT avg(1) OVER (PARTITION BY b GROUPS UNBOUNDED PRECEDING) FROM t`},
  1041  		{`SELECT avg(1) OVER (ORDER BY c GROUPS UNBOUNDED PRECEDING) FROM t`},
  1042  		{`SELECT avg(1) OVER (PARTITION BY b ORDER BY c GROUPS UNBOUNDED PRECEDING) FROM t`},
  1043  		{`SELECT avg(1) OVER (w PARTITION BY b ORDER BY c GROUPS UNBOUNDED PRECEDING) FROM t`},
  1044  
  1045  		{`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING EXCLUDE CURRENT ROW) FROM t`},
  1046  		{`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING EXCLUDE GROUP) FROM t`},
  1047  		{`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING EXCLUDE TIES) FROM t`},
  1048  
  1049  		{`SELECT percentile_disc(0.50) WITHIN GROUP (ORDER BY c) FROM t`},
  1050  		{`SELECT percentile_disc(0.50) WITHIN GROUP (ORDER BY c DESC) FROM t`},
  1051  		{`SELECT percentile_cont(0.50) WITHIN GROUP (ORDER BY c) FROM t`},
  1052  		{`SELECT percentile_disc(ARRAY[0.95, 0.90]) WITHIN GROUP (ORDER BY c) FROM t`},
  1053  		{`SELECT percentile_cont(ARRAY[0.95, 0.90]) WITHIN GROUP (ORDER BY c) FROM t`},
  1054  
  1055  		{`SELECT avg(1) FILTER (WHERE a > b)`},
  1056  		{`SELECT avg(1) FILTER (WHERE a > b) OVER (ORDER BY c)`},
  1057  
  1058  		{`SELECT a FROM t UNION SELECT 1 FROM t`},
  1059  		{`SELECT a FROM t UNION SELECT 1 FROM t UNION SELECT 1 FROM t`},
  1060  		{`SELECT a FROM t UNION ALL SELECT 1 FROM t`},
  1061  		{`SELECT a FROM t EXCEPT SELECT 1 FROM t`},
  1062  		{`SELECT a FROM t EXCEPT ALL SELECT 1 FROM t`},
  1063  		{`SELECT a FROM t INTERSECT SELECT 1 FROM t`},
  1064  		{`SELECT a FROM t INTERSECT ALL SELECT 1 FROM t`},
  1065  
  1066  		{`SELECT a FROM t1 JOIN t2 ON a = b`},
  1067  		{`SELECT a FROM t1 JOIN t2 USING (a)`},
  1068  		{`SELECT a FROM t1 INNER MERGE JOIN t2 USING (a)`},
  1069  		{`SELECT a FROM t1 LEFT JOIN t2 ON a = b`},
  1070  		{`SELECT a FROM t1 LEFT LOOKUP JOIN t2 ON a = b`},
  1071  		{`SELECT a FROM t1 RIGHT JOIN t2 ON a = b`},
  1072  		{`SELECT a FROM t1 INNER JOIN t2 ON a = b`},
  1073  		{`SELECT a FROM t1 INNER HASH JOIN t2 ON a = b`},
  1074  		{`SELECT a FROM t1 CROSS JOIN t2`},
  1075  		{`SELECT a FROM t1 CROSS LOOKUP JOIN t2`},
  1076  		{`SELECT a FROM t1 NATURAL JOIN t2`},
  1077  		{`SELECT a FROM t1 NATURAL INNER MERGE JOIN t2`},
  1078  		{`SELECT a FROM t1 INNER JOIN t2 USING (a)`},
  1079  		{`SELECT a FROM t1 FULL JOIN t2 USING (a)`},
  1080  		{`SELECT a FROM t1 FULL MERGE JOIN t2 USING (a)`},
  1081  		{`SELECT * FROM (t1 WITH ORDINALITY AS o1 CROSS JOIN t2 WITH ORDINALITY AS o2) WITH ORDINALITY AS o3`},
  1082  
  1083  		{`SELECT a FROM t1 AS OF SYSTEM TIME '2016-01-01'`},
  1084  		{`SELECT a FROM t1, t2 AS OF SYSTEM TIME '2016-01-01'`},
  1085  		{`SELECT a FROM t1 AS OF SYSTEM TIME -('a' || 'b')::INTERVAL`},
  1086  
  1087  		{`SELECT * FROM t LIMIT ALL`},
  1088  		{`SELECT EXISTS ((((TABLE error FOR KEY SHARE)) LIMIT ALL FOR KEY SHARE)) AS is FROM ident`},
  1089  
  1090  		{`SELECT a FROM t LIMIT a`},
  1091  		{`SELECT a FROM t OFFSET b`},
  1092  		{`SELECT a FROM t LIMIT a OFFSET b`},
  1093  		{`SELECT DISTINCT * FROM t`},
  1094  		{`SELECT DISTINCT a, b FROM t`},
  1095  		{`SELECT DISTINCT ON (a, b) c FROM t`},
  1096  
  1097  		{`SET a = 3`},
  1098  		{`EXPLAIN SET a = 3`},
  1099  		{`SET a = 3, 4`},
  1100  		{`SET a = '3'`},
  1101  		{`SET a = 3.0`},
  1102  		{`SET a = $1`},
  1103  		{`SET a = off`},
  1104  		{`SET TRANSACTION READ ONLY`},
  1105  		{`SET TRANSACTION READ WRITE`},
  1106  		{`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE`},
  1107  		{`SET TRANSACTION PRIORITY LOW`},
  1108  		{`SET TRANSACTION PRIORITY NORMAL`},
  1109  		{`SET TRANSACTION PRIORITY HIGH`},
  1110  		{`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY HIGH`},
  1111  
  1112  		{`SET TRACING = off`},
  1113  		{`EXPLAIN SET TRACING = off`},
  1114  		{`SET TRACING = 'cluster', 'kv'`},
  1115  
  1116  		{`SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE`},
  1117  
  1118  		{`SET CLUSTER SETTING a = 3`},
  1119  		{`EXPLAIN SET CLUSTER SETTING a = 3`},
  1120  		{`SET CLUSTER SETTING a = '3s'`},
  1121  		{`SET CLUSTER SETTING a = '3'`},
  1122  		{`SET CLUSTER SETTING a = 3.0`},
  1123  		{`SET CLUSTER SETTING a = $1`},
  1124  		{`SET CLUSTER SETTING a = off`},
  1125  
  1126  		{`SELECT * FROM (VALUES (1, 2)) AS foo`},
  1127  		{`SELECT * FROM (VALUES (1, 2)) AS foo (a, b)`},
  1128  
  1129  		{`SELECT * FROM [123 AS t]`},
  1130  		{`SELECT * FROM [123(1, 2, 3) AS t]`},
  1131  		{`SELECT * FROM [123() AS t]`},
  1132  		{`SELECT * FROM t@[123]`},
  1133  		{`SELECT * FROM [123 AS t]@[456]`},
  1134  
  1135  		{`INSERT INTO [123 AS t] VALUES (1)`},
  1136  		{`INSERT INTO [123(1, 2) AS t] VALUES (1, 2)`},
  1137  		{`INSERT INTO [123 AS t](col1, col2) VALUES (1, 2)`},
  1138  		{`UPSERT INTO [123 AS t] VALUES (1)`},
  1139  		{`UPDATE [123 AS t] SET b = 3`},
  1140  		{`UPDATE [123 AS t]@idx SET b = 3`},
  1141  		{`DELETE FROM [123 AS t]`},
  1142  		{`DELETE FROM [123 AS t]@idx`},
  1143  
  1144  		{`SELECT (1 + 2).*`},
  1145  		{`SELECT (1 + 2).@1`},
  1146  		{`SELECT (1 + 2).col`},
  1147  		{`SELECT (abc.def).col`},
  1148  		{`SELECT (i.keys).col`},
  1149  		{`SELECT (i.keys).*`},
  1150  		{`SELECT (i.keys).@1`},
  1151  		{`SELECT (ARRAY['a', 'b', 'c']).name`},
  1152  
  1153  		{`SELECT 1 FOR UPDATE`},
  1154  		{`SELECT 1 FOR NO KEY UPDATE`},
  1155  		{`SELECT 1 FOR SHARE`},
  1156  		{`SELECT 1 FOR KEY SHARE`},
  1157  		{`SELECT 1 FOR UPDATE OF a`},
  1158  		{`SELECT 1 FOR NO KEY UPDATE OF a, b`},
  1159  		{`SELECT 1 FOR UPDATE SKIP LOCKED`},
  1160  		{`SELECT 1 FOR NO KEY UPDATE OF a, b NOWAIT`},
  1161  		{`SELECT 1 ORDER BY 1 FOR UPDATE`},
  1162  		{`SELECT 1 LIMIT 1 FOR UPDATE`},
  1163  		{`SELECT 1 ORDER BY 1 LIMIT 1 FOR UPDATE`},
  1164  		{`SELECT 1 FOR UPDATE FOR UPDATE`},
  1165  		{`SELECT 1 FOR SHARE OF a FOR KEY SHARE SKIP LOCKED`},
  1166  
  1167  		{`TABLE a`}, // Shorthand for: SELECT * FROM a; used e.g. in CREATE VIEW v AS TABLE t
  1168  		{`EXPLAIN TABLE a`},
  1169  		{`TABLE [123 AS a]`},
  1170  
  1171  		{`TRUNCATE TABLE a`},
  1172  		{`EXPLAIN TRUNCATE TABLE a`},
  1173  		{`TRUNCATE TABLE a, b.c`},
  1174  		{`TRUNCATE TABLE a CASCADE`},
  1175  
  1176  		{`UPDATE a SET b = 3`},
  1177  		{`EXPLAIN UPDATE a SET b = 3`},
  1178  		{`UPDATE a.b SET b = 3`},
  1179  		{`UPDATE a.b@c SET b = 3`},
  1180  		{`UPDATE a SET b = 3, c = DEFAULT`},
  1181  		{`UPDATE a SET b = 3, c = DEFAULT FROM b`},
  1182  		{`UPDATE a SET b = 3, c = DEFAULT FROM a AS other`},
  1183  		{`UPDATE a SET b = 3, c = DEFAULT FROM a AS other, b`},
  1184  		{`UPDATE a SET b = 3 + 4`},
  1185  		{`UPDATE a SET (b, c) = (3, DEFAULT)`},
  1186  		{`UPDATE a SET (b, c) = (SELECT 3, 4)`},
  1187  		{`UPDATE a SET b = 3 WHERE a = b`},
  1188  		{`UPDATE a SET b = 3 WHERE a = b LIMIT c`},
  1189  		{`UPDATE a SET b = 3 WHERE a = b ORDER BY c`},
  1190  		{`UPDATE a SET b = 3 WHERE a = b ORDER BY c LIMIT d`},
  1191  		{`UPDATE a SET b = 3 WHERE a = b RETURNING a`},
  1192  		{`UPDATE a SET b = 3 WHERE a = b RETURNING 1, 2`},
  1193  		{`UPDATE a SET b = 3 WHERE a = b RETURNING a, a + b`},
  1194  		{`UPDATE a SET b = 3 WHERE a = b RETURNING NOTHING`},
  1195  		{`UPDATE a SET b = 3 WHERE a = b ORDER BY c LIMIT d RETURNING e`},
  1196  		{`UPDATE a SET b = 3 FROM other WHERE a = b ORDER BY c LIMIT d RETURNING e`},
  1197  
  1198  		{`UPDATE t AS "0" SET k = ''`},                 // "0" lost its quotes
  1199  		{`SELECT * FROM "0" JOIN "0" USING (id, "0")`}, // last "0" lost its quotes.
  1200  
  1201  		{`ALTER DATABASE a RENAME TO b`},
  1202  		{`EXPLAIN ALTER DATABASE a RENAME TO b`},
  1203  
  1204  		{`ALTER INDEX b RENAME TO b`},
  1205  		{`EXPLAIN ALTER INDEX b RENAME TO b`},
  1206  		{`ALTER INDEX a@b RENAME TO b`},
  1207  		{`ALTER INDEX a@primary RENAME TO like`},
  1208  		{`ALTER INDEX IF EXISTS b RENAME TO b`},
  1209  		{`ALTER INDEX IF EXISTS a@b RENAME TO b`},
  1210  		{`ALTER INDEX IF EXISTS a@primary RENAME TO like`},
  1211  
  1212  		{`ALTER TABLE a RENAME TO b`},
  1213  		{`EXPLAIN ALTER TABLE a RENAME TO b`},
  1214  		{`ALTER TABLE IF EXISTS a RENAME TO b`},
  1215  		{`ALTER TABLE a RENAME COLUMN c1 TO c2`},
  1216  		{`ALTER TABLE IF EXISTS a RENAME COLUMN c1 TO c2`},
  1217  		{`ALTER TABLE a RENAME CONSTRAINT c1 TO c2`},
  1218  		{`ALTER TABLE IF EXISTS a RENAME CONSTRAINT c1 TO c2`},
  1219  		{`ALTER TABLE a RENAME CONSTRAINT c TO d, RENAME COLUMN e TO f`},
  1220  
  1221  		{`ALTER TABLE a ADD COLUMN b INT8, ADD CONSTRAINT a_idx UNIQUE (a)`},
  1222  		{`EXPLAIN ALTER TABLE a ADD COLUMN b INT8`},
  1223  		{`ALTER TABLE a ADD COLUMN IF NOT EXISTS b INT8, ADD CONSTRAINT a_idx UNIQUE (a)`},
  1224  		{`ALTER TABLE IF EXISTS a ADD COLUMN b INT8, ADD CONSTRAINT a_idx UNIQUE (a)`},
  1225  		{`ALTER TABLE IF EXISTS a ADD COLUMN IF NOT EXISTS b INT8, ADD CONSTRAINT a_idx UNIQUE (a)`},
  1226  		{`ALTER TABLE a ADD COLUMN b INT8, ADD CONSTRAINT a_idx UNIQUE (a)`},
  1227  		{`ALTER TABLE a ADD COLUMN IF NOT EXISTS b INT8, ADD CONSTRAINT a_idx UNIQUE (a) NOT VALID`},
  1228  		{`ALTER TABLE IF EXISTS a ADD COLUMN b INT8, ADD CONSTRAINT a_idx UNIQUE (a)`},
  1229  		{`ALTER TABLE IF EXISTS a ADD COLUMN IF NOT EXISTS b INT8, ADD CONSTRAINT a_idx UNIQUE (a)`},
  1230  		{`ALTER TABLE a ADD COLUMN b INT8 FAMILY fam_a`},
  1231  		{`ALTER TABLE a ADD COLUMN b INT8 CREATE FAMILY`},
  1232  		{`ALTER TABLE a ADD COLUMN b INT8 CREATE FAMILY fam_b`},
  1233  		{`ALTER TABLE a ADD COLUMN b INT8 CREATE IF NOT EXISTS FAMILY fam_b`},
  1234  
  1235  		{`ALTER TABLE t ALTER PRIMARY KEY USING COLUMNS (a, b, c)`},
  1236  
  1237  		{`ALTER TABLE a DROP COLUMN b, DROP CONSTRAINT a_idx`},
  1238  		{`ALTER TABLE a DROP COLUMN IF EXISTS b, DROP CONSTRAINT a_idx`},
  1239  		{`ALTER TABLE IF EXISTS a DROP COLUMN b, DROP CONSTRAINT a_idx`},
  1240  		{`ALTER TABLE IF EXISTS a DROP COLUMN IF EXISTS b, DROP CONSTRAINT a_idx`},
  1241  		{`ALTER TABLE a DROP COLUMN b, DROP CONSTRAINT a_idx`},
  1242  		{`ALTER TABLE a DROP COLUMN IF EXISTS b, DROP CONSTRAINT a_idx`},
  1243  		{`ALTER TABLE IF EXISTS a DROP COLUMN b, DROP CONSTRAINT a_idx`},
  1244  		{`ALTER TABLE IF EXISTS a DROP COLUMN IF EXISTS b, DROP CONSTRAINT a_idx`},
  1245  		{`ALTER TABLE a DROP COLUMN b CASCADE`},
  1246  		{`ALTER TABLE a DROP COLUMN b RESTRICT`},
  1247  		{`ALTER TABLE a DROP CONSTRAINT b CASCADE`},
  1248  		{`ALTER TABLE a DROP CONSTRAINT IF EXISTS b RESTRICT`},
  1249  		{`ALTER TABLE a VALIDATE CONSTRAINT a`},
  1250  		{`ALTER TABLE a ADD PRIMARY KEY (x, y, z)`},
  1251  		{`ALTER TABLE a ADD PRIMARY KEY (x, y, z) USING HASH WITH BUCKET_COUNT = 10 INTERLEAVE IN PARENT b (x, y)`},
  1252  		{`ALTER TABLE a ADD CONSTRAINT "primary" PRIMARY KEY (x, y, z)`},
  1253  		{`ALTER TABLE a ADD CONSTRAINT "primary" PRIMARY KEY (x, y, z) USING HASH WITH BUCKET_COUNT = 10 INTERLEAVE IN PARENT b (x, y)`},
  1254  
  1255  		{`ALTER TABLE a ALTER COLUMN b SET DEFAULT 42`},
  1256  		{`ALTER TABLE a ALTER COLUMN b SET DEFAULT NULL`},
  1257  		{`ALTER TABLE a ALTER COLUMN b DROP DEFAULT`},
  1258  		{`ALTER TABLE a ALTER COLUMN b DROP NOT NULL`},
  1259  		{`ALTER TABLE a ALTER COLUMN b DROP STORED`},
  1260  
  1261  		{`ALTER TABLE a ALTER COLUMN b SET DATA TYPE INT8`},
  1262  		{`ALTER TABLE a ALTER COLUMN b SET DATA TYPE STRING COLLATE en USING b::STRING`},
  1263  		{`ALTER TABLE a ALTER COLUMN b SET DATA TYPE DECIMAL(10)[]`},
  1264  
  1265  		{`COPY t FROM STDIN`},
  1266  		{`COPY t (a, b, c) FROM STDIN`},
  1267  		{`COPY crdb_internal.file_upload FROM STDIN WITH destination = 'filename'`},
  1268  
  1269  		{`ALTER TABLE a SPLIT AT VALUES (1)`},
  1270  		{`EXPLAIN ALTER TABLE a SPLIT AT VALUES (1)`},
  1271  		{`ALTER TABLE a SPLIT AT SELECT * FROM t`},
  1272  		{`ALTER TABLE d.a SPLIT AT VALUES ('b', 2)`},
  1273  		{`ALTER INDEX a@i SPLIT AT VALUES (1)`},
  1274  		{`ALTER INDEX d.a@i SPLIT AT VALUES (2)`},
  1275  		{`ALTER INDEX i SPLIT AT VALUES (1)`},
  1276  		{`ALTER INDEX d.i SPLIT AT VALUES (2)`},
  1277  		{`ALTER INDEX "primary" SPLIT AT VALUES (2)`},
  1278  		{`ALTER INDEX public.public."primary" SPLIT AT VALUES (2)`},
  1279  		{`ALTER TABLE a SPLIT AT VALUES (1) WITH EXPIRATION '1 day'`},
  1280  		{`ALTER TABLE a SPLIT AT VALUES (1) WITH EXPIRATION '1 day':::INTERVAL`},
  1281  		{`ALTER TABLE a SPLIT AT VALUES (1) WITH EXPIRATION '7258118400000000.0'`},
  1282  		{`ALTER TABLE a SPLIT AT VALUES (1) WITH EXPIRATION '2200-01-01 00:00:00.0'`},
  1283  		{`ALTER TABLE a SPLIT AT VALUES (1) WITH EXPIRATION TIMESTAMP '2200-01-01 00:00:00.0'`},
  1284  		{`ALTER TABLE a SPLIT AT VALUES (1) WITH EXPIRATION '2200-01-01 00:00:00.0':::TIMESTAMP`},
  1285  		{`ALTER TABLE a SPLIT AT VALUES (1) WITH EXPIRATION TIMESTAMPTZ '2200-01-01 00:00:00.0'`},
  1286  
  1287  		{`ALTER TABLE a UNSPLIT AT VALUES (1)`},
  1288  		{`EXPLAIN ALTER TABLE a UNSPLIT AT VALUES (1)`},
  1289  		{`ALTER TABLE a UNSPLIT AT SELECT * FROM t`},
  1290  		{`ALTER TABLE d.a UNSPLIT AT VALUES ('b', 2)`},
  1291  		{`ALTER INDEX a@i UNSPLIT AT VALUES (1)`},
  1292  		{`ALTER INDEX d.a@i UNSPLIT AT VALUES (2)`},
  1293  		{`ALTER INDEX i UNSPLIT AT VALUES (1)`},
  1294  		{`ALTER INDEX d.i UNSPLIT AT VALUES (2)`},
  1295  		{`ALTER INDEX "primary" UNSPLIT AT VALUES (2)`},
  1296  		{`ALTER INDEX public.public."primary" UNSPLIT AT VALUES (2)`},
  1297  
  1298  		{`ALTER TABLE a EXPERIMENTAL_RELOCATE VALUES (ARRAY[1], 1)`},
  1299  		{`EXPLAIN ALTER TABLE a EXPERIMENTAL_RELOCATE TABLE b`},
  1300  		{`ALTER TABLE a EXPERIMENTAL_RELOCATE SELECT * FROM t`},
  1301  		{`ALTER TABLE d.a EXPERIMENTAL_RELOCATE VALUES (ARRAY[1, 2, 3], 'b', 2)`},
  1302  		{`ALTER INDEX d.i EXPERIMENTAL_RELOCATE VALUES (ARRAY[1], 2)`},
  1303  
  1304  		{`ALTER TABLE a EXPERIMENTAL_RELOCATE LEASE VALUES (1, 1)`},
  1305  		{`ALTER TABLE a EXPERIMENTAL_RELOCATE LEASE SELECT * FROM t`},
  1306  		{`ALTER TABLE d.a EXPERIMENTAL_RELOCATE LEASE VALUES (1, 'b', 2)`},
  1307  		{`ALTER INDEX d.i EXPERIMENTAL_RELOCATE LEASE VALUES (1, 2)`},
  1308  
  1309  		{`ALTER TABLE a SCATTER`},
  1310  		{`EXPLAIN ALTER TABLE a SCATTER`},
  1311  		{`ALTER TABLE a SCATTER FROM (1, 2, 3) TO (4, 5, 6)`},
  1312  		{`ALTER TABLE d.a SCATTER`},
  1313  		{`ALTER INDEX d.i SCATTER FROM (1) TO (2)`},
  1314  
  1315  		{`ALTER RANGE default CONFIGURE ZONE = 'foo'`},
  1316  		{`EXPLAIN ALTER RANGE default CONFIGURE ZONE = 'foo'`},
  1317  		{`ALTER RANGE meta CONFIGURE ZONE = 'foo'`},
  1318  
  1319  		{`ALTER DATABASE db CONFIGURE ZONE = 'foo'`},
  1320  		{`EXPLAIN ALTER DATABASE db CONFIGURE ZONE = 'foo'`},
  1321  
  1322  		{`ALTER TABLE db.t CONFIGURE ZONE = 'foo'`},
  1323  		{`EXPLAIN ALTER TABLE db.t CONFIGURE ZONE = 'foo'`},
  1324  
  1325  		{`ALTER PARTITION p OF TABLE db.t CONFIGURE ZONE = 'foo'`},
  1326  		{`EXPLAIN ALTER PARTITION p OF TABLE db.t CONFIGURE ZONE = 'foo'`},
  1327  
  1328  		{`ALTER TABLE t CONFIGURE ZONE = 'foo'`},
  1329  		{`ALTER PARTITION p OF TABLE t CONFIGURE ZONE = 'foo'`},
  1330  
  1331  		{`ALTER INDEX i CONFIGURE ZONE = 'foo'`},
  1332  		{`EXPLAIN ALTER INDEX i CONFIGURE ZONE = 'foo'`},
  1333  		{`ALTER INDEX db.t@i CONFIGURE ZONE = 'foo'`},
  1334  		{`ALTER INDEX t@i CONFIGURE ZONE = 'foo'`},
  1335  
  1336  		{`ALTER PARTITION p OF INDEX db.t@idx CONFIGURE ZONE = 'foo'`},
  1337  		{`EXPLAIN ALTER PARTITION p OF INDEX db.t@idx CONFIGURE ZONE = 'foo'`},
  1338  
  1339  		{`ALTER TABLE t CONFIGURE ZONE = b'foo'`},
  1340  		{`ALTER TABLE t CONFIGURE ZONE = a || b`},
  1341  
  1342  		{`ALTER RANGE default CONFIGURE ZONE USING foo = bar, baz = yay`},
  1343  		{`ALTER RANGE meta CONFIGURE ZONE USING foo = bar, baz = yay`},
  1344  		{`ALTER DATABASE db CONFIGURE ZONE USING foo = bar, baz = yay`},
  1345  		{`ALTER TABLE db.t CONFIGURE ZONE USING foo = bar, baz = yay`},
  1346  		{`ALTER PARTITION p OF TABLE db.t CONFIGURE ZONE USING foo = bar, baz = yay`},
  1347  		{`ALTER TABLE t CONFIGURE ZONE USING foo = bar, baz = yay`},
  1348  		{`ALTER PARTITION p OF TABLE t CONFIGURE ZONE USING foo = bar, baz = yay`},
  1349  		{`ALTER INDEX db.t@i CONFIGURE ZONE USING foo = bar, baz = yay`},
  1350  		{`ALTER INDEX t@i CONFIGURE ZONE USING foo = bar, baz = yay`},
  1351  		{`ALTER INDEX i CONFIGURE ZONE USING foo = bar, baz = yay`},
  1352  		{`ALTER INDEX i CONFIGURE ZONE USING foo = COPY FROM PARENT`},
  1353  		{`ALTER INDEX i CONFIGURE ZONE USING foo = bar, baz = COPY FROM PARENT`},
  1354  		{`ALTER INDEX i CONFIGURE ZONE USING foo = COPY FROM PARENT, baz = COPY FROM PARENT`},
  1355  		{`ALTER INDEX i CONFIGURE ZONE USING foo = bar, other = COPY FROM PARENT, baz = yay`},
  1356  
  1357  		{`ALTER RANGE default CONFIGURE ZONE DISCARD`},
  1358  		{`ALTER RANGE meta CONFIGURE ZONE DISCARD`},
  1359  		{`ALTER DATABASE db CONFIGURE ZONE DISCARD`},
  1360  		{`ALTER TABLE db.t CONFIGURE ZONE DISCARD`},
  1361  		{`ALTER PARTITION p OF TABLE db.t CONFIGURE ZONE DISCARD`},
  1362  		{`ALTER TABLE t CONFIGURE ZONE DISCARD`},
  1363  		{`ALTER PARTITION p OF TABLE t CONFIGURE ZONE DISCARD`},
  1364  		{`ALTER INDEX db.t@i CONFIGURE ZONE DISCARD`},
  1365  		{`ALTER INDEX t@i CONFIGURE ZONE DISCARD`},
  1366  		{`ALTER INDEX i CONFIGURE ZONE DISCARD`},
  1367  
  1368  		{`ALTER RANGE default CONFIGURE ZONE USING DEFAULT`},
  1369  		{`ALTER RANGE meta CONFIGURE ZONE USING DEFAULT`},
  1370  		{`ALTER DATABASE db CONFIGURE ZONE USING DEFAULT`},
  1371  		{`ALTER TABLE db.t CONFIGURE ZONE USING DEFAULT`},
  1372  		{`ALTER PARTITION p OF TABLE db.t CONFIGURE ZONE USING DEFAULT`},
  1373  		{`ALTER TABLE t CONFIGURE ZONE USING DEFAULT`},
  1374  		{`ALTER PARTITION p OF TABLE t CONFIGURE ZONE USING DEFAULT`},
  1375  		{`ALTER INDEX db.t@i CONFIGURE ZONE USING DEFAULT`},
  1376  		{`ALTER INDEX t@i CONFIGURE ZONE USING DEFAULT`},
  1377  		{`ALTER INDEX i CONFIGURE ZONE USING DEFAULT`},
  1378  
  1379  		{`ALTER TABLE t EXPERIMENTAL_AUDIT SET READ WRITE`},
  1380  		{`EXPLAIN ALTER TABLE t EXPERIMENTAL_AUDIT SET READ WRITE`},
  1381  		{`ALTER TABLE t EXPERIMENTAL_AUDIT SET OFF`},
  1382  
  1383  		{`ALTER TYPE db.s.t ADD VALUE 'hi'`},
  1384  		{`ALTER TYPE s.t ADD VALUE 'hi' BEFORE 'hello'`},
  1385  		{`ALTER TYPE t ADD VALUE 'hi' AFTER 'howdy'`},
  1386  		{`ALTER TYPE s.t ADD VALUE IF NOT EXISTS 'hi' BEFORE 'hello'`},
  1387  		{`ALTER TYPE t RENAME VALUE 'value1' TO 'value2'`},
  1388  		{`ALTER TYPE t RENAME TO t2`},
  1389  		{`ALTER TYPE t SET SCHEMA newschema`},
  1390  
  1391  		{`COMMENT ON COLUMN a.b IS 'a'`},
  1392  		{`COMMENT ON COLUMN a.b IS NULL`},
  1393  		{`COMMENT ON COLUMN a.b.c IS 'a'`},
  1394  		{`COMMENT ON COLUMN a.b.c.d IS 'a'`},
  1395  		{`COMMENT ON DATABASE foo IS 'a'`},
  1396  		{`COMMENT ON DATABASE foo IS NULL`},
  1397  		{`COMMENT ON INDEX foo IS 'a'`},
  1398  		{`COMMENT ON INDEX foo IS NULL`},
  1399  		{`COMMENT ON TABLE foo IS 'a'`},
  1400  		{`COMMENT ON TABLE foo IS NULL`},
  1401  
  1402  		{`ALTER SEQUENCE a RENAME TO b`},
  1403  		{`EXPLAIN ALTER SEQUENCE a RENAME TO b`},
  1404  		{`ALTER SEQUENCE IF EXISTS a RENAME TO b`},
  1405  
  1406  		{`ALTER SEQUENCE a INCREMENT BY 5 START WITH 1000`},
  1407  		{`EXPLAIN ALTER SEQUENCE a INCREMENT BY 5 START WITH 1000`},
  1408  		{`ALTER SEQUENCE IF EXISTS a INCREMENT BY 5 START WITH 1000`},
  1409  		{`ALTER SEQUENCE IF EXISTS a NO CYCLE CACHE 1`},
  1410  		{`ALTER SEQUENCE a OWNED BY b`},
  1411  		{`ALTER SEQUENCE a OWNED BY NONE`},
  1412  
  1413  		{`EXPERIMENTAL SCRUB DATABASE x`},
  1414  		{`EXPLAIN EXPERIMENTAL SCRUB DATABASE x`},
  1415  		{`EXPERIMENTAL SCRUB DATABASE x AS OF SYSTEM TIME 1`},
  1416  		{`EXPERIMENTAL SCRUB TABLE x`},
  1417  		{`EXPLAIN EXPERIMENTAL SCRUB TABLE x`},
  1418  		{`EXPERIMENTAL SCRUB TABLE x AS OF SYSTEM TIME 1`},
  1419  		{`EXPERIMENTAL SCRUB TABLE x AS OF SYSTEM TIME 1 WITH OPTIONS INDEX ALL`},
  1420  		{`EXPERIMENTAL SCRUB TABLE x WITH OPTIONS INDEX (index_name)`},
  1421  		{`EXPERIMENTAL SCRUB TABLE x WITH OPTIONS PHYSICAL`},
  1422  		{`EXPERIMENTAL SCRUB TABLE x WITH OPTIONS CONSTRAINT ALL`},
  1423  		{`EXPERIMENTAL SCRUB TABLE x WITH OPTIONS CONSTRAINT (cst_name)`},
  1424  		{`EXPERIMENTAL SCRUB TABLE x WITH OPTIONS PHYSICAL, INDEX (index_name), CONSTRAINT (cst_name)`},
  1425  		{`EXPERIMENTAL SCRUB TABLE x WITH OPTIONS PHYSICAL, INDEX ALL, CONSTRAINT ALL`},
  1426  
  1427  		{`BACKUP TABLE foo TO 'bar'`},
  1428  		{`EXPLAIN BACKUP TABLE foo TO 'bar'`},
  1429  		{`BACKUP TABLE foo.foo, baz.baz TO 'bar'`},
  1430  
  1431  		{`SHOW BACKUP 'bar'`},
  1432  		{`SHOW BACKUP 'bar' WITH foo = 'bar'`},
  1433  		{`EXPLAIN SHOW BACKUP 'bar'`},
  1434  		{`SHOW BACKUP RANGES 'bar'`},
  1435  		{`SHOW BACKUP FILES 'bar'`},
  1436  		{`SHOW BACKUP FILES 'bar' WITH foo = 'bar'`},
  1437  
  1438  		{`BACKUP TABLE foo TO 'bar' AS OF SYSTEM TIME '1' INCREMENTAL FROM 'baz'`},
  1439  		{`BACKUP TABLE foo TO $1 INCREMENTAL FROM 'bar', $2, 'baz'`},
  1440  
  1441  		{`BACKUP DATABASE foo TO 'bar'`},
  1442  		{`EXPLAIN BACKUP DATABASE foo TO 'bar'`},
  1443  		{`BACKUP DATABASE foo, baz TO 'bar'`},
  1444  		{`BACKUP DATABASE foo TO 'bar' AS OF SYSTEM TIME '1' INCREMENTAL FROM 'baz'`},
  1445  
  1446  		{`BACKUP DATABASE foo TO ($1, $2)`},
  1447  		{`BACKUP DATABASE foo TO ($1, $2) INCREMENTAL FROM 'baz'`},
  1448  
  1449  		{`RESTORE TABLE foo FROM 'bar'`},
  1450  		{`EXPLAIN RESTORE TABLE foo FROM 'bar'`},
  1451  		{`RESTORE TABLE foo FROM $1`},
  1452  		{`RESTORE TABLE foo FROM $1, $2, 'bar'`},
  1453  		{`RESTORE TABLE foo, baz FROM 'bar'`},
  1454  		{`RESTORE TABLE foo, baz FROM 'bar' AS OF SYSTEM TIME '1'`},
  1455  
  1456  		{`RESTORE DATABASE foo FROM 'bar'`},
  1457  		{`EXPLAIN RESTORE DATABASE foo FROM 'bar'`},
  1458  		{`RESTORE DATABASE foo, baz FROM 'bar'`},
  1459  		{`RESTORE DATABASE foo, baz FROM 'bar' AS OF SYSTEM TIME '1'`},
  1460  
  1461  		{`RESTORE DATABASE foo FROM ($1, $2)`},
  1462  		{`RESTORE DATABASE foo FROM ($1, $2), $3`},
  1463  		{`RESTORE DATABASE foo FROM $1, ($2, $3)`},
  1464  		{`RESTORE DATABASE foo FROM ($1, $2), ($3, $4)`},
  1465  		{`RESTORE DATABASE foo FROM ($1, $2), ($3, $4) AS OF SYSTEM TIME '1'`},
  1466  
  1467  		{`BACKUP TABLE foo TO 'bar' WITH key1, key2 = 'value'`},
  1468  		{`RESTORE TABLE foo FROM 'bar' WITH key1, key2 = 'value'`},
  1469  
  1470  		{`IMPORT TABLE foo CREATE USING 'nodelocal://0/some/file' CSV DATA ('path/to/some/file', $1) WITH temp = 'path/to/temp'`},
  1471  		{`EXPLAIN IMPORT TABLE foo CREATE USING 'nodelocal://0/some/file' CSV DATA ('path/to/some/file', $1) WITH temp = 'path/to/temp'`},
  1472  		{`IMPORT TABLE foo CREATE USING 'nodelocal://0/some/file' DELIMITED DATA ('path/to/some/file', $1)`},
  1473  		{`IMPORT TABLE foo (id INT8 PRIMARY KEY, email STRING, age INT8) CSV DATA ('path/to/some/file', $1) WITH temp = 'path/to/temp'`},
  1474  		{`IMPORT TABLE foo (id INT8, email STRING, age INT8) CSV DATA ('path/to/some/file', $1) WITH comma = ',', "nullif" = 'n/a', temp = $2`},
  1475  		{`IMPORT TABLE foo FROM PGDUMPCREATE 'nodelocal://0/foo/bar' WITH temp = 'path/to/temp'`},
  1476  		{`IMPORT INTO foo(id, email) CSV DATA ('path/to/some/file', $1) WITH temp = 'path/to/temp'`},
  1477  		{`IMPORT INTO foo CSV DATA ('path/to/some/file', $1) WITH temp = 'path/to/temp'`},
  1478  
  1479  		{`IMPORT PGDUMP 'nodelocal://0/foo/bar' WITH temp = 'path/to/temp'`},
  1480  		{`EXPLAIN IMPORT PGDUMP 'nodelocal://0/foo/bar' WITH temp = 'path/to/temp'`},
  1481  
  1482  		{`EXPORT INTO CSV 'a' FROM TABLE a`}, // TODO(knz): Make this explainable.
  1483  		{`EXPORT INTO CSV 'a' FROM SELECT * FROM a`},
  1484  		{`EXPORT INTO CSV 's3://my/path/%part%.csv' WITH delimiter = '|' FROM TABLE a`},
  1485  		{`EXPORT INTO CSV 's3://my/path/%part%.csv' WITH delimiter = '|' FROM SELECT a, sum(b) FROM c WHERE d = 1 ORDER BY sum(b) DESC LIMIT 10`},
  1486  
  1487  		{`SET ROW (1, true, NULL)`},
  1488  
  1489  		{`EXPERIMENTAL CHANGEFEED FOR TABLE foo`},
  1490  		{`EXPLAIN CREATE CHANGEFEED FOR TABLE foo INTO 'sink'`},
  1491  		{`CREATE CHANGEFEED FOR TABLE foo, db.bar, schema.db.foo INTO 'sink'`},
  1492  		{`CREATE CHANGEFEED FOR TABLE foo INTO 'sink'`},
  1493  		// TODO(dan): Implement.
  1494  		// {`CREATE CHANGEFEED FOR TABLE foo VALUES FROM (1) TO (2) INTO 'sink'`},
  1495  		// {`CREATE CHANGEFEED FOR TABLE foo PARTITION bar, baz INTO 'sink'`},
  1496  		// {`CREATE CHANGEFEED FOR DATABASE foo INTO 'sink'`},
  1497  		{`CREATE CHANGEFEED FOR TABLE foo INTO 'sink' WITH bar = 'baz'`},
  1498  
  1499  		// Regression for #15926
  1500  		{`SELECT * FROM ((t1 NATURAL JOIN t2 WITH ORDINALITY AS o1)) WITH ORDINALITY AS o2`},
  1501  
  1502  		{`WITH cte AS (SELECT 1) SELECT * FROM cte`},
  1503  		{`WITH cte (x) AS (INSERT INTO abc VALUES (1, 2)), cte2 (y) AS (SELECT x + 1 FROM cte) SELECT * FROM cte, cte2`},
  1504  		{`WITH RECURSIVE cte (x) AS (SELECT 1), cte2 (y) AS (SELECT x + 1 FROM cte) SELECT 1`},
  1505  		{`WITH cte AS MATERIALIZED (SELECT 1) SELECT * FROM cte`},
  1506  		{`WITH RECURSIVE cte AS MATERIALIZED (SELECT 1) SELECT * FROM cte`},
  1507  		{`WITH cte AS NOT MATERIALIZED (SELECT 1) SELECT * FROM cte`},
  1508  		{`WITH cte (x) AS MATERIALIZED (INSERT INTO abc VALUES (1, 2)), cte2 (y) AS NOT MATERIALIZED (SELECT x + 1 FROM cte) SELECT * FROM cte, cte2`},
  1509  		{`WITH RECURSIVE cte (x) AS MATERIALIZED (INSERT INTO abc VALUES (1, 2)), cte2 (y) AS NOT MATERIALIZED (SELECT x + 1 FROM cte) SELECT * FROM cte, cte2`},
  1510  	}
  1511  	var p parser.Parser // Verify that the same parser can be reused.
  1512  	for _, d := range testData {
  1513  		stmts, err := p.Parse(d.sql)
  1514  		if err != nil {
  1515  			t.Fatalf("%s: expected success, but found %s", d.sql, err)
  1516  		}
  1517  		s := stmts.String()
  1518  		if d.sql != s {
  1519  			t.Errorf("expected \n%q\n, but found \n%q", d.sql, s)
  1520  		}
  1521  		sqlutils.VerifyStatementPrettyRoundtrip(t, d.sql)
  1522  	}
  1523  }
  1524  
  1525  // TestParse2 verifies that we can parse the supplied SQL and regenerate the
  1526  // expected SQL string from the syntax tree. Note that if the input and output
  1527  // SQL strings are the same, the test case should go in TestParse instead.
  1528  func TestParse2(t *testing.T) {
  1529  	testData := []struct {
  1530  		sql      string
  1531  		expected string
  1532  	}{
  1533  		{`CREATE DATABASE a WITH ENCODING = 'foo'`,
  1534  			`CREATE DATABASE a ENCODING = 'foo'`},
  1535  		{`CREATE DATABASE a TEMPLATE = template0`,
  1536  			`CREATE DATABASE a TEMPLATE = 'template0'`},
  1537  		{`CREATE DATABASE a TEMPLATE = invalid`,
  1538  			`CREATE DATABASE a TEMPLATE = 'invalid'`},
  1539  		{`CREATE TABLE a (b INT) WITH (fillfactor=100)`,
  1540  			`CREATE TABLE a (b INT8)`},
  1541  		{`CREATE TABLE a (b INT, UNIQUE INDEX foo (b))`,
  1542  			`CREATE TABLE a (b INT8, CONSTRAINT foo UNIQUE (b))`},
  1543  		{`CREATE TABLE a (b INT, UNIQUE INDEX foo (b) WHERE c > 3)`,
  1544  			`CREATE TABLE a (b INT8, CONSTRAINT foo UNIQUE (b) WHERE c > 3)`},
  1545  		{`CREATE TABLE a (b INT, UNIQUE INDEX foo (b) INTERLEAVE IN PARENT c (d))`,
  1546  			`CREATE TABLE a (b INT8, CONSTRAINT foo UNIQUE (b) INTERLEAVE IN PARENT c (d))`},
  1547  		{`CREATE TABLE a (UNIQUE INDEX (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)))`,
  1548  			`CREATE TABLE a (UNIQUE (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)))`},
  1549  		{`CREATE INDEX ON a (b) COVERING (c)`, `CREATE INDEX ON a (b) STORING (c)`},
  1550  		{`CREATE INDEX ON a (b) INCLUDE (c)`, `CREATE INDEX ON a (b) STORING (c)`},
  1551  
  1552  		{`CREATE INDEX a ON b USING GIN (c)`,
  1553  			`CREATE INVERTED INDEX a ON b (c)`},
  1554  		{`CREATE UNIQUE INDEX a ON b USING GIN (c)`,
  1555  			`CREATE UNIQUE INVERTED INDEX a ON b (c)`},
  1556  
  1557  		{`CREATE TABLE a (b BIGSERIAL, c SMALLSERIAL, d SERIAL)`,
  1558  			`CREATE TABLE a (b SERIAL8, c SERIAL2, d SERIAL8)`},
  1559  		{`CREATE TABLE a (b BIGINT, c SMALLINT, d INTEGER, e INT)`,
  1560  			`CREATE TABLE a (b INT8, c INT2, d INT8, e INT8)`},
  1561  		{`CREATE TABLE a (b FLOAT, c FLOAT(10), d FLOAT(40), e REAL, f DOUBLE PRECISION)`,
  1562  			`CREATE TABLE a (b FLOAT8, c FLOAT4, d FLOAT8, e FLOAT4, f FLOAT8)`},
  1563  		{`CREATE TABLE a (b NUMERIC, c NUMERIC(10), d DEC)`,
  1564  			`CREATE TABLE a (b DECIMAL, c DECIMAL(10), d DECIMAL)`},
  1565  		{`CREATE TABLE a (b BOOLEAN)`,
  1566  			`CREATE TABLE a (b BOOL)`},
  1567  		{`CREATE TABLE a (b TEXT)`,
  1568  			`CREATE TABLE a (b STRING)`},
  1569  		{`CREATE TABLE a (b JSON)`,
  1570  			`CREATE TABLE a (b JSONB)`},
  1571  		{`CREATE TABLE a (b TIMESTAMP WITH TIME ZONE)`,
  1572  			`CREATE TABLE a (b TIMESTAMPTZ)`},
  1573  		{`CREATE TABLE a (b BYTES, c BYTEA, d BLOB)`,
  1574  			`CREATE TABLE a (b BYTES, c BYTES, d BYTES)`},
  1575  		{`CREATE TABLE a (b CHAR(1), c CHARACTER(1), d CHARACTER(3))`,
  1576  			`CREATE TABLE a (b CHAR, c CHAR, d CHAR(3))`},
  1577  		{`CREATE TABLE a (b CHAR VARYING, c CHARACTER VARYING(3))`,
  1578  			`CREATE TABLE a (b VARCHAR, c VARCHAR(3))`},
  1579  		{`CREATE TABLE a (b BIT VARYING(2), c BIT(1))`,
  1580  			`CREATE TABLE a (b VARBIT(2), c BIT)`},
  1581  
  1582  		{`CREATE STATISTICS a ON col1 FROM t AS OF SYSTEM TIME '2016-01-01'`,
  1583  			`CREATE STATISTICS a ON col1 FROM t WITH OPTIONS AS OF SYSTEM TIME '2016-01-01'`},
  1584  
  1585  		{`SELECT TIMESTAMP WITHOUT TIME ZONE 'foo'`, `SELECT TIMESTAMP 'foo'`},
  1586  		{`SELECT CAST('foo' AS TIMESTAMP WITHOUT TIME ZONE)`, `SELECT CAST('foo' AS TIMESTAMP)`},
  1587  		{`SELECT CAST(1 AS "timestamp")`, `SELECT CAST(1 AS TIMESTAMP)`},
  1588  		{`SELECT CAST(1 AS _int8)`, `SELECT CAST(1 AS INT8[])`},
  1589  		{`SELECT CAST(1 AS "_int8")`, `SELECT CAST(1 AS INT8[])`},
  1590  		{`SELECT SERIAL8 'foo', 'foo'::SERIAL8`, `SELECT INT8 'foo', 'foo'::INT8`},
  1591  
  1592  		{`SELECT 'a'::TIMESTAMP(3)`, `SELECT 'a'::TIMESTAMP(3)`},
  1593  		{`SELECT 'a'::TIMESTAMP(3) WITHOUT TIME ZONE`, `SELECT 'a'::TIMESTAMP(3)`},
  1594  		{`SELECT 'a'::TIMESTAMPTZ(3)`, `SELECT 'a'::TIMESTAMPTZ(3)`},
  1595  		{`SELECT 'a'::TIMESTAMP(3) WITH TIME ZONE`, `SELECT 'a'::TIMESTAMPTZ(3)`},
  1596  		{`SELECT TIMESTAMP(3) 'a'`, `SELECT TIMESTAMP(3) 'a'`},
  1597  		{`SELECT TIMESTAMPTZ(3) 'a'`, `SELECT TIMESTAMPTZ(3) 'a'`},
  1598  
  1599  		{`SELECT 'a'::TIME(3)`, `SELECT 'a'::TIME(3)`},
  1600  		{`SELECT 'a'::TIME(3) WITHOUT TIME ZONE`, `SELECT 'a'::TIME(3)`},
  1601  		{`SELECT 'a'::TIMETZ(3)`, `SELECT 'a'::TIMETZ(3)`},
  1602  		{`SELECT 'a'::TIME(3) WITH TIME ZONE`, `SELECT 'a'::TIMETZ(3)`},
  1603  		{`SELECT TIME(3) 'a'`, `SELECT TIME(3) 'a'`},
  1604  		{`SELECT TIMETZ(3) 'a'`, `SELECT TIMETZ(3) 'a'`},
  1605  
  1606  		{`SELECT 'a' FROM t@{FORCE_INDEX=bar}`, `SELECT 'a' FROM t@bar`},
  1607  		{`SELECT 'a' FROM t@{ASC,FORCE_INDEX=idx}`, `SELECT 'a' FROM t@{FORCE_INDEX=idx,ASC}`},
  1608  
  1609  		{`SELECT 'a' FROM t@{FORCE_INDEX=[123]}`, `SELECT 'a' FROM t@[123]`},
  1610  		{`SELECT 'a' FROM [123 AS t]@{FORCE_INDEX=[456]}`, `SELECT 'a' FROM [123 AS t]@[456]`},
  1611  
  1612  		{`SELECT a FROM t WHERE a ISNULL`, `SELECT a FROM t WHERE a IS NULL`},
  1613  		{`SELECT a FROM t WHERE a NOTNULL`, `SELECT a FROM t WHERE a IS NOT NULL`},
  1614  		{`SELECT a FROM t WHERE a IS UNKNOWN`, `SELECT a FROM t WHERE a IS NOT DISTINCT FROM NULL`},
  1615  		{`SELECT a FROM t WHERE a IS NOT UNKNOWN`, `SELECT a FROM t WHERE a IS DISTINCT FROM NULL`},
  1616  
  1617  		{`SELECT +1`, `SELECT 1`},
  1618  		{`SELECT - - 5`, `SELECT 5`},
  1619  		{`SELECT - + 5`, `SELECT -5`},
  1620  		{`SELECT a FROM t WHERE b = - 2`, `SELECT a FROM t WHERE b = -2`},
  1621  		{`SELECT a FROM t WHERE a = b AND a = c`, `SELECT a FROM t WHERE (a = b) AND (a = c)`},
  1622  		{`SELECT a FROM t WHERE a = b OR a = c`, `SELECT a FROM t WHERE (a = b) OR (a = c)`},
  1623  		{`SELECT a FROM t WHERE NOT a = b`, `SELECT a FROM t WHERE NOT (a = b)`},
  1624  
  1625  		{`SELECT a FROM t WHERE a = b & c`, `SELECT a FROM t WHERE a = (b & c)`},
  1626  		{`SELECT a FROM t WHERE a = b | c`, `SELECT a FROM t WHERE a = (b | c)`},
  1627  		{`SELECT a FROM t WHERE a = b # c`, `SELECT a FROM t WHERE a = (b # c)`},
  1628  		{`SELECT a FROM t WHERE a = b ^ c`, `SELECT a FROM t WHERE a = (b ^ c)`},
  1629  		{`SELECT a FROM t WHERE a = b + c`, `SELECT a FROM t WHERE a = (b + c)`},
  1630  		{`SELECT a FROM t WHERE a = b - c`, `SELECT a FROM t WHERE a = (b - c)`},
  1631  		{`SELECT a FROM t WHERE a = b * c`, `SELECT a FROM t WHERE a = (b * c)`},
  1632  		{`SELECT a FROM t WHERE a = b / c`, `SELECT a FROM t WHERE a = (b / c)`},
  1633  		{`SELECT a FROM t WHERE a = b % c`, `SELECT a FROM t WHERE a = (b % c)`},
  1634  		{`SELECT a FROM t WHERE a = b || c`, `SELECT a FROM t WHERE a = (b || c)`},
  1635  		{`SELECT a FROM t WHERE a = + b`, `SELECT a FROM t WHERE a = b`},
  1636  		{`SELECT a FROM t WHERE a = - b`, `SELECT a FROM t WHERE a = (-b)`},
  1637  		{`SELECT a FROM t WHERE a = ~ b`, `SELECT a FROM t WHERE a = (~b)`},
  1638  
  1639  		{`SELECT b <<= c`, `SELECT inet_contained_by_or_equals(b, c)`},
  1640  		{`SELECT b >>= c`, `SELECT inet_contains_or_equals(b, c)`},
  1641  
  1642  		{`SELECT NUMERIC 'foo'`, `SELECT DECIMAL 'foo'`},
  1643  		{`SELECT REAL 'foo'`, `SELECT FLOAT4 'foo'`},
  1644  		{`SELECT DOUBLE PRECISION 'foo'`, `SELECT FLOAT8 'foo'`},
  1645  
  1646  		// Escaped string literals are not always escaped the same because
  1647  		// '''' and e'\'' scan to the same token. It's more convenient to
  1648  		// prefer escaping ' and \, so we do that.
  1649  		{`SELECT 'a''a'`,
  1650  			`SELECT e'a\'a'`},
  1651  		{`SELECT 'a\a'`,
  1652  			`SELECT e'a\\a'`},
  1653  		{`SELECT 'a\n'`,
  1654  			`SELECT e'a\\n'`},
  1655  		{"SELECT '\n'",
  1656  			`SELECT e'\n'`},
  1657  		{"SELECT '\n\\'",
  1658  			`SELECT e'\n\\'`},
  1659  		{`SELECT "a'a" FROM t`,
  1660  			`SELECT "a'a" FROM t`},
  1661  		// Hexadecimal literal strings are turned into regular strings.
  1662  		{`SELECT x'61'`, `SELECT b'a'`},
  1663  		{`SELECT X'61'`, `SELECT b'a'`},
  1664  		// Comments are stripped.
  1665  		{`SELECT 1 FROM t -- hello world`,
  1666  			`SELECT 1 FROM t`},
  1667  		{`SELECT /* hello world */ 1 FROM t`,
  1668  			`SELECT 1 FROM t`},
  1669  		{`SELECT /* hello */ 1 FROM /* world */ t`,
  1670  			`SELECT 1 FROM t`},
  1671  		// Alias expressions are always output using AS.
  1672  		{`SELECT 1 FROM t t1`,
  1673  			`SELECT 1 FROM t AS t1`},
  1674  		{`SELECT 1 FROM t t1 (c1, c2)`,
  1675  			`SELECT 1 FROM t AS t1 (c1, c2)`},
  1676  		// Alternate not-equal operator.
  1677  		{`SELECT a FROM t WHERE a <> b`,
  1678  			`SELECT a FROM t WHERE a != b`},
  1679  		// BETWEEN ASYMMETRIC is noise for BETWEEN.
  1680  		{`SELECT a FROM t WHERE a BETWEEN ASYMMETRIC b AND c`,
  1681  			`SELECT a FROM t WHERE a BETWEEN b AND c`},
  1682  		// OUTER is syntactic sugar.
  1683  		{`SELECT a FROM t1 LEFT OUTER JOIN t2 ON a = b`,
  1684  			`SELECT a FROM t1 LEFT JOIN t2 ON a = b`},
  1685  		{`SELECT a FROM t1 RIGHT OUTER JOIN t2 ON a = b`,
  1686  			`SELECT a FROM t1 RIGHT JOIN t2 ON a = b`},
  1687  		{`SELECT a FROM t1 RIGHT OUTER MERGE JOIN t2 ON a = b`,
  1688  			`SELECT a FROM t1 RIGHT MERGE JOIN t2 ON a = b`},
  1689  		// Some functions are nearly keywords.
  1690  		{`SELECT CURRENT_SCHEMA`,
  1691  			`SELECT current_schema()`},
  1692  		{`SELECT CURRENT_CATALOG`,
  1693  			`SELECT current_database()`},
  1694  		{`SELECT CURRENT_TIMESTAMP`,
  1695  			`SELECT current_timestamp()`},
  1696  		{`SELECT current_timestamp(6)`,
  1697  			`SELECT current_timestamp(6)`},
  1698  		{`SELECT CURRENT_TIME`,
  1699  			`SELECT current_time()`},
  1700  		{`SELECT current_time(6)`,
  1701  			`SELECT current_time(6)`},
  1702  		{`SELECT CURRENT_DATE`,
  1703  			`SELECT current_date()`},
  1704  		{`SELECT POSITION(a IN b)`,
  1705  			`SELECT strpos(b, a)`},
  1706  		{`SELECT TRIM(BOTH a FROM b)`,
  1707  			`SELECT btrim(b, a)`},
  1708  		{`SELECT TRIM(LEADING a FROM b)`,
  1709  			`SELECT ltrim(b, a)`},
  1710  		{`SELECT TRIM(TRAILING a FROM b)`,
  1711  			`SELECT rtrim(b, a)`},
  1712  		{`SELECT TRIM(a, b)`,
  1713  			`SELECT btrim(a, b)`},
  1714  		{`SELECT CURRENT_USER`,
  1715  			`SELECT current_user()`},
  1716  		{`SELECT CURRENT_ROLE`,
  1717  			`SELECT current_user()`},
  1718  		{`SELECT SESSION_USER`,
  1719  			`SELECT current_user()`},
  1720  		{`SELECT USER`,
  1721  			`SELECT current_user()`},
  1722  		// Offset has an optional ROW/ROWS keyword.
  1723  		{`SELECT a FROM t1 OFFSET a ROW`,
  1724  			`SELECT a FROM t1 OFFSET a`},
  1725  		{`SELECT a FROM t1 OFFSET a ROWS`,
  1726  			`SELECT a FROM t1 OFFSET a`},
  1727  		// We allow OFFSET before LIMIT, but always output LIMIT first.
  1728  		{`SELECT a FROM t OFFSET a LIMIT b`,
  1729  			`SELECT a FROM t LIMIT b OFFSET a`},
  1730  		// FETCH FIRST ... is alternative syntax for LIMIT.
  1731  		{`SELECT a FROM t FETCH FIRST 3 ROWS ONLY`,
  1732  			`SELECT a FROM t LIMIT 3`},
  1733  		{`SELECT a FROM t FETCH NEXT 3 ROWS ONLY`,
  1734  			`SELECT a FROM t LIMIT 3`},
  1735  		{`SELECT a FROM t FETCH FIRST ROW ONLY`,
  1736  			`SELECT a FROM t LIMIT 1`},
  1737  		{`SELECT a FROM t FETCH FIRST (2 * a) ROWS ONLY`,
  1738  			`SELECT a FROM t LIMIT (2 * a)`},
  1739  		{`SELECT a FROM t OFFSET b FETCH FIRST (2 * a) ROWS ONLY`,
  1740  			`SELECT a FROM t LIMIT (2 * a) OFFSET b`},
  1741  		{`SELECT a FROM t FETCH FIRST (2 * a) ROWS ONLY OFFSET b ROWS`,
  1742  			`SELECT a FROM t LIMIT (2 * a) OFFSET b`},
  1743  		{`SELECT a FROM t FETCH FIRST $1 ROWS ONLY OFFSET $2 ROWS`,
  1744  			`SELECT a FROM t LIMIT $1 OFFSET $2`},
  1745  		{`SELECT a FROM t FETCH FIRST +3 ROWS ONLY OFFSET +3 ROWS`,
  1746  			`SELECT a FROM t LIMIT 3 OFFSET 3`},
  1747  		{`SELECT a FROM t FETCH FIRST -3 ROWS ONLY OFFSET -3 ROWS`,
  1748  			`SELECT a FROM t LIMIT -3 OFFSET -3`},
  1749  		{`SELECT a FROM t FETCH FIRST +3.0 ROWS ONLY OFFSET +3.0 ROWS`,
  1750  			`SELECT a FROM t LIMIT 3.0 OFFSET 3.0`},
  1751  		{`SELECT a FROM t FETCH FIRST -3.0 ROWS ONLY OFFSET -3.0 ROWS`,
  1752  			`SELECT a FROM t LIMIT -3.0 OFFSET -3.0`},
  1753  		// Double negation. See #1800.
  1754  		{`SELECT *,-/* comment */-5`,
  1755  			`SELECT *, 5`},
  1756  		{"SELECT -\n-5",
  1757  			`SELECT 5`},
  1758  		{`SELECT -0.-/*test*/-1`,
  1759  			`SELECT -0. - -1`,
  1760  		},
  1761  		// See #1948.
  1762  		{`SELECT~~+~++~bd(*)`,
  1763  			`SELECT ~(~(~(~bd(*))))`},
  1764  		// See #1957.
  1765  		{`SELECT+y[array[]]`,
  1766  			`SELECT y[ARRAY[]]`},
  1767  		{`SELECT a FROM t UNION DISTINCT SELECT 1 FROM t`,
  1768  			`SELECT a FROM t UNION SELECT 1 FROM t`},
  1769  		{`SELECT a FROM t EXCEPT DISTINCT SELECT 1 FROM t`,
  1770  			`SELECT a FROM t EXCEPT SELECT 1 FROM t`},
  1771  		{`SELECT a FROM t INTERSECT DISTINCT SELECT 1 FROM t`,
  1772  			`SELECT a FROM t INTERSECT SELECT 1 FROM t`},
  1773  
  1774  		{`SELECT a #- '{x}'`, `SELECT json_remove_path(a, '{x}')`},
  1775  
  1776  		{`SELECT 'a' LIKE '\a' ESCAPE '\'`, `SELECT like_escape('a', e'\\a', e'\\')`},
  1777  		{`SELECT '\abc\' LIKE '-\___-\' ESCAPE '-'`, `SELECT like_escape(e'\\abc\\', e'-\\___-\\', '-')`},
  1778  		{`SELECT 'a' LIKE '\a' ESCAPE ''`, `SELECT like_escape('a', e'\\a', '')`},
  1779  		{`SELECT 'a' NOT LIKE '\a' ESCAPE '\'`, `SELECT not_like_escape('a', e'\\a', e'\\')`},
  1780  		{`SELECT '\abc\' NOT LIKE '-\___-\' ESCAPE '-'`, `SELECT not_like_escape(e'\\abc\\', e'-\\___-\\', '-')`},
  1781  		{`SELECT 'a' NOT LIKE '\a' ESCAPE ''`, `SELECT not_like_escape('a', e'\\a', '')`},
  1782  		{`SELECT 'a' ILIKE '\a' ESCAPE '\'`, `SELECT ilike_escape('a', e'\\a', e'\\')`},
  1783  		{`SELECT '\abc\' ILIKE '-\___-\' ESCAPE '-'`, `SELECT ilike_escape(e'\\abc\\', e'-\\___-\\', '-')`},
  1784  		{`SELECT 'a' ILIKE '\a' ESCAPE ''`, `SELECT ilike_escape('a', e'\\a', '')`},
  1785  		{`SELECT 'a' NOT ILIKE '\a' ESCAPE '\'`, `SELECT not_ilike_escape('a', e'\\a', e'\\')`},
  1786  		{`SELECT '\abc\' NOT ILIKE '-\___-\' ESCAPE '-'`, `SELECT not_ilike_escape(e'\\abc\\', e'-\\___-\\', '-')`},
  1787  		{`SELECT 'a' NOT ILIKE '\a' ESCAPE ''`, `SELECT not_ilike_escape('a', e'\\a', '')`},
  1788  		{`SELECT 'a' SIMILAR TO '\a' ESCAPE '\'`, `SELECT similar_to_escape('a', e'\\a', e'\\')`},
  1789  		{`SELECT '\abc\' SIMILAR TO '-\___-\' ESCAPE '-'`, `SELECT similar_to_escape(e'\\abc\\', e'-\\___-\\', '-')`},
  1790  		{`SELECT 'a' SIMILAR TO '\a' ESCAPE ''`, `SELECT similar_to_escape('a', e'\\a', '')`},
  1791  		{`SELECT 'a' NOT SIMILAR TO '\a' ESCAPE '\'`, `SELECT not_similar_to_escape('a', e'\\a', e'\\')`},
  1792  		{`SELECT '\abc\' NOT SIMILAR TO '-\___-\' ESCAPE '-'`, `SELECT not_similar_to_escape(e'\\abc\\', e'-\\___-\\', '-')`},
  1793  		{`SELECT 'a' NOT SIMILAR TO '\a' ESCAPE ''`, `SELECT not_similar_to_escape('a', e'\\a', '')`},
  1794  
  1795  		// using dollar-quotes
  1796  		{`SELECT $$a'a$$`, `SELECT e'a\'a'`},
  1797  		{`SELECT $$a\\na$$`, `SELECT e'a\\\\na'`},
  1798  		{`SELECT $select$\\n$select$`, `SELECT e'\\\\n'`},
  1799  		{`SELECT $$a"a$$`, `SELECT 'a"a'`},
  1800  		{`SELECT $$full$$`, `SELECT 'full'`}, // must quote column name keyword
  1801  		{`SELECT $select$full$select$`, `SELECT 'full'`},
  1802  		{`SELECT $select$a$$b$select$`, `SELECT 'a$$b'`},
  1803  		{`SELECT $$Dianne's horse$$`, `SELECT e'Dianne\'s horse'`},
  1804  		{`SELECT $SomeTag$Dianne's horse$SomeTag$`, `SELECT e'Dianne\'s horse'`},
  1805  		{`SELECT $function$
  1806  BEGIN
  1807  RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
  1808  END;
  1809  $function$`,
  1810  			`SELECT e'\nBEGIN\nRETURN ($1 ~ $q$[\\t\\r\\n\\v\\\\]$q$);\nEND;\n'`},
  1811  
  1812  		{`SELECT (ARRAY (1, 2))[1]`, `SELECT (ARRAY[1, 2])[1]`},
  1813  
  1814  		// Interval constructor gets eagerly processed.
  1815  		{`SELECT INTERVAL '0'`, `SELECT '00:00:00'`},
  1816  		{`SELECT INTERVAL '1' SECOND`, `SELECT '00:00:01'`},
  1817  		{`SELECT INTERVAL(3) '12.1234s'`, `SELECT '00:00:12.123'`},
  1818  		{`SELECT INTERVAL '12.1234s' SECOND(3)`, `SELECT '00:00:12.123'`},
  1819  		{`SELECT INTERVAL '14.7899s' SECOND(3)`, `SELECT '00:00:14.79'`}, // Check rounding.
  1820  
  1821  		{`SELECT '11s'::INTERVAL(3)`, `SELECT '11s'::INTERVAL(3)`},
  1822  		{`SELECT '10:00:13.123456'::INTERVAL SECOND`, `SELECT '10:00:13.123456'::INTERVAL SECOND`},
  1823  		{`SELECT '10:00:13.123456'::INTERVAL SECOND(3)`, `SELECT '10:00:13.123456'::INTERVAL SECOND(3)`},
  1824  		{`SELECT '10:00:13.123456'::INTERVAL MINUTE TO SECOND`, `SELECT '10:00:13.123456'::INTERVAL MINUTE TO SECOND`},
  1825  		{`SELECT '10:00:13.123456'::INTERVAL MINUTE TO SECOND(3)`, `SELECT '10:00:13.123456'::INTERVAL MINUTE TO SECOND(3)`},
  1826  
  1827  		// Pretty printing the FAMILY INET function is not normal due to the grammar
  1828  		// definition of FAMILY.
  1829  		{`SELECT FAMILY(x)`, // lint: uppercase function OK
  1830  			`SELECT "family"(x)`},
  1831  
  1832  		{`SET SCHEMA 'public'`,
  1833  			`SET search_path = 'public'`},
  1834  		{`SET TIME ZONE 'pst8pdt'`,
  1835  			`SET timezone = 'pst8pdt'`},
  1836  		{`SET TIME ZONE 'Europe/Rome'`,
  1837  			`SET timezone = 'Europe/Rome'`},
  1838  		{`SET TIME ZONE -7`,
  1839  			`SET timezone = -7`},
  1840  		{`SET TIME ZONE -7.3`,
  1841  			`SET timezone = -7.3`},
  1842  		{`SET TIME ZONE DEFAULT`,
  1843  			`SET timezone = DEFAULT`},
  1844  		{`SET TIME ZONE LOCAL`,
  1845  			`SET timezone = 'local'`},
  1846  		{`SET TIME ZONE pst8pdt`,
  1847  			`SET timezone = 'pst8pdt'`},
  1848  		{`SET TIME ZONE "Europe/Rome"`,
  1849  			`SET timezone = 'Europe/Rome'`},
  1850  		{`SET TIME ZONE INTERVAL '-7h'`,
  1851  			`SET timezone = '-07:00:00'`},
  1852  		{`SET TIME ZONE INTERVAL(3) '-7h'`,
  1853  			`SET timezone = '-07:00:00'`},
  1854  		{`SET TIME ZONE INTERVAL '-7h0m5s' HOUR TO MINUTE`,
  1855  			`SET timezone = '-06:59:00'`},
  1856  		{`SET CLUSTER SETTING a = on`,
  1857  			`SET CLUSTER SETTING a = "on"`},
  1858  		{`SET a = on`,
  1859  			`SET a = "on"`},
  1860  		{`SET a = default`,
  1861  			`SET a = DEFAULT`},
  1862  
  1863  		// Special substring syntax
  1864  		{`SELECT SUBSTRING('RoacH' from 2 for 3)`,
  1865  			`SELECT substring('RoacH', 2, 3)`},
  1866  		{`SELECT SUBSTRING('RoacH' for 2 from 3)`,
  1867  			`SELECT substring('RoacH', 3, 2)`},
  1868  		{`SELECT SUBSTRING('RoacH' from 2)`,
  1869  			`SELECT substring('RoacH', 2)`},
  1870  		{`SELECT SUBSTRING('RoacH' for 3)`,
  1871  			`SELECT substring('RoacH', 1, 3)`},
  1872  		{`SELECT SUBSTRING('f(oabaroob' from '\(o(.)b')`,
  1873  			`SELECT substring('f(oabaroob', e'\\(o(.)b')`},
  1874  		{`SELECT SUBSTRING('f(oabaroob' from '+(o(.)b' for '+')`,
  1875  			`SELECT substring('f(oabaroob', '+(o(.)b', '+')`},
  1876  		// Special position syntax
  1877  		{`SELECT POSITION('ig' in 'high')`,
  1878  			`SELECT strpos('high', 'ig')`},
  1879  		// Special overlay syntax
  1880  		{`SELECT OVERLAY('w33333rce' PLACING 'resou' FROM 3)`,
  1881  			`SELECT overlay('w33333rce', 'resou', 3)`},
  1882  		{`SELECT OVERLAY('w33333rce' PLACING 'resou' FROM 3 FOR 5)`,
  1883  			`SELECT overlay('w33333rce', 'resou', 3, 5)`},
  1884  		// Special extract syntax
  1885  		{`SELECT EXTRACT(second from now())`,
  1886  			`SELECT extract('second', now())`},
  1887  		{`SELECT EXTRACT('second' from now())`,
  1888  			`SELECT extract('second', now())`},
  1889  		// Special trim syntax
  1890  		{`SELECT TRIM('xy' from 'xyxtrimyyx')`,
  1891  			`SELECT btrim('xyxtrimyyx', 'xy')`},
  1892  		{`SELECT TRIM(both 'xy' from 'xyxtrimyyx')`,
  1893  			`SELECT btrim('xyxtrimyyx', 'xy')`},
  1894  		{`SELECT TRIM(from 'xyxtrimyyx')`,
  1895  			`SELECT btrim('xyxtrimyyx')`},
  1896  		{`SELECT TRIM(both 'xyxtrimyyx')`,
  1897  			`SELECT btrim('xyxtrimyyx')`},
  1898  		{`SELECT TRIM(both from 'xyxtrimyyx')`,
  1899  			`SELECT btrim('xyxtrimyyx')`},
  1900  		{`SELECT TRIM(leading 'xy' from 'xyxtrimyyx')`,
  1901  			`SELECT ltrim('xyxtrimyyx', 'xy')`},
  1902  		{`SELECT TRIM(leading from 'xyxtrimyyx')`,
  1903  			`SELECT ltrim('xyxtrimyyx')`},
  1904  		{`SELECT TRIM(leading 'xyxtrimyyx')`,
  1905  			`SELECT ltrim('xyxtrimyyx')`},
  1906  		{`SELECT TRIM(trailing 'xy' from 'xyxtrimyyx')`,
  1907  			`SELECT rtrim('xyxtrimyyx', 'xy')`},
  1908  		{`SELECT TRIM(trailing from 'xyxtrimyyx')`,
  1909  			`SELECT rtrim('xyxtrimyyx')`},
  1910  		{`SELECT TRIM(trailing 'xyxtrimyyx')`,
  1911  			`SELECT rtrim('xyxtrimyyx')`},
  1912  		{`SELECT a IS NAN`,
  1913  			`SELECT a = 'NaN'`},
  1914  		{`SELECT a IS NOT NAN`,
  1915  			`SELECT a != 'NaN'`},
  1916  
  1917  		{`SELECT a FROM generate_series(1, 32)`,
  1918  			`SELECT a FROM ROWS FROM (generate_series(1, 32))`},
  1919  		{`SELECT a FROM generate_series(1, 32) AS s (x)`,
  1920  			`SELECT a FROM ROWS FROM (generate_series(1, 32)) AS s (x)`},
  1921  		{`SELECT a FROM generate_series(1, 32) WITH ORDINALITY AS s (x)`,
  1922  			`SELECT a FROM ROWS FROM (generate_series(1, 32)) WITH ORDINALITY AS s (x)`},
  1923  		{`SELECT a FROM LATERAL generate_series(1, 32)`,
  1924  			`SELECT a FROM LATERAL ROWS FROM (generate_series(1, 32))`},
  1925  
  1926  		// Tuples
  1927  		{`SELECT 1 IN (b)`, `SELECT 1 IN (b,)`},
  1928  		{`SELECT ROW()`, `SELECT ()`},
  1929  		{`SELECT ROW(1)`, `SELECT (1,)`},
  1930  		{`SELECT (ROW(1) AS a)`, `SELECT ((1,) AS a)`},
  1931  
  1932  		{`SELECT 1 ORDER BY 1 FOR UPDATE LIMIT 1`,
  1933  			`SELECT 1 ORDER BY 1 LIMIT 1 FOR UPDATE`},
  1934  		// FOR READ ONLY is ignored, like in Postgres.
  1935  		{`SELECT 1 FOR READ ONLY`, `SELECT 1`},
  1936  
  1937  		{`SHOW CREATE TABLE t`,
  1938  			`SHOW CREATE t`},
  1939  		{`SHOW CREATE VIEW t`,
  1940  			`SHOW CREATE t`},
  1941  		{`SHOW CREATE SEQUENCE t`,
  1942  			`SHOW CREATE t`},
  1943  		{`SHOW INDEX FROM t`,
  1944  			`SHOW INDEXES FROM t`},
  1945  		{`SHOW CONSTRAINT FROM t`,
  1946  			`SHOW CONSTRAINTS FROM t`},
  1947  		{`SHOW KEYS FROM t`,
  1948  			`SHOW INDEXES FROM t`},
  1949  		{`SHOW SESSION barfoo`, `SHOW barfoo`},
  1950  		{`SHOW SESSION database`, `SHOW database`},
  1951  		{`SHOW SESSION TIME ZONE`, `SHOW timezone`},
  1952  		{`SHOW SESSION TIMEZONE`, `SHOW timezone`},
  1953  
  1954  		{`SHOW ALL ZONE CONFIGURATIONS`, `SHOW ZONE CONFIGURATIONS`},
  1955  
  1956  		{`SHOW ZONE CONFIGURATION FOR TABLE t PARTITION foo`,
  1957  			`SHOW ZONE CONFIGURATION FOR PARTITION foo OF TABLE t`},
  1958  		{`SHOW ZONE CONFIGURATION FOR INDEX t@idx PARTITION foo`,
  1959  			`SHOW ZONE CONFIGURATION FOR PARTITION foo OF INDEX t@idx`},
  1960  
  1961  		{`BEGIN`,
  1962  			`BEGIN TRANSACTION`},
  1963  		{`START TRANSACTION`,
  1964  			`BEGIN TRANSACTION`},
  1965  		{`COMMIT`,
  1966  			`COMMIT TRANSACTION`},
  1967  		{`END`,
  1968  			`COMMIT TRANSACTION`},
  1969  		{`BEGIN TRANSACTION PRIORITY LOW, ISOLATION LEVEL SNAPSHOT`,
  1970  			`BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY LOW`},
  1971  		{`SET TRANSACTION PRIORITY NORMAL, ISOLATION LEVEL SERIALIZABLE`,
  1972  			`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY NORMAL`},
  1973  		{`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ WRITE`,
  1974  			`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE`},
  1975  		{`SET TRANSACTION ISOLATION LEVEL SNAPSHOT READ ONLY`,
  1976  			`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY`},
  1977  		{"SET CLUSTER SETTING a TO 1", "SET CLUSTER SETTING a = 1"},
  1978  		{"SET TRACING TO off", "SET TRACING = off"},
  1979  		{"RELEASE foo", "RELEASE SAVEPOINT foo"},
  1980  		{"RELEASE SAVEPOINT foo", "RELEASE SAVEPOINT foo"},
  1981  		{"ROLLBACK", "ROLLBACK TRANSACTION"},
  1982  		{"ROLLBACK TRANSACTION", "ROLLBACK TRANSACTION"},
  1983  		{"ROLLBACK TO foo", "ROLLBACK TRANSACTION TO SAVEPOINT foo"},
  1984  		{"ROLLBACK TO SAVEPOINT foo", "ROLLBACK TRANSACTION TO SAVEPOINT foo"},
  1985  		{"ROLLBACK TRANSACTION TO foo", "ROLLBACK TRANSACTION TO SAVEPOINT foo"},
  1986  		{"ROLLBACK TRANSACTION TO SAVEPOINT foo", "ROLLBACK TRANSACTION TO SAVEPOINT foo"},
  1987  		{"ABORT TRANSACTION", "ROLLBACK TRANSACTION"},
  1988  		{"ABORT WORK", "ROLLBACK TRANSACTION"},
  1989  		{"ABORT", "ROLLBACK TRANSACTION"},
  1990  		{`DEALLOCATE PREPARE a`,
  1991  			`DEALLOCATE a`},
  1992  		{`DEALLOCATE PREPARE ALL`,
  1993  			`DEALLOCATE ALL`},
  1994  
  1995  		{`CANCEL JOB a`, `CANCEL JOBS VALUES (a)`},
  1996  		{`EXPLAIN CANCEL JOB a`, `EXPLAIN CANCEL JOBS VALUES (a)`},
  1997  		{`RESUME JOB a`, `RESUME JOBS VALUES (a)`},
  1998  		{`EXPLAIN RESUME JOB a`, `EXPLAIN RESUME JOBS VALUES (a)`},
  1999  		{`PAUSE JOB a`, `PAUSE JOBS VALUES (a)`},
  2000  		{`EXPLAIN PAUSE JOB a`, `EXPLAIN PAUSE JOBS VALUES (a)`},
  2001  		{`SHOW JOB a`, `SHOW JOBS VALUES (a)`},
  2002  		{`EXPLAIN SHOW JOB a`, `EXPLAIN SHOW JOBS VALUES (a)`},
  2003  		{`SHOW JOB WHEN COMPLETE a`, `SHOW JOBS WHEN COMPLETE VALUES (a)`},
  2004  		{`EXPLAIN SHOW JOB WHEN COMPLETE a`, `EXPLAIN SHOW JOBS WHEN COMPLETE VALUES (a)`},
  2005  		{`CANCEL QUERY a`, `CANCEL QUERIES VALUES (a)`},
  2006  		{`CANCEL QUERY IF EXISTS a`, `CANCEL QUERIES IF EXISTS VALUES (a)`},
  2007  		{`CANCEL SESSION a`, `CANCEL SESSIONS VALUES (a)`},
  2008  		{`CANCEL SESSION IF EXISTS a`, `CANCEL SESSIONS IF EXISTS VALUES (a)`},
  2009  
  2010  		{`BACKUP DATABASE foo TO bar`,
  2011  			`BACKUP DATABASE foo TO 'bar'`},
  2012  		{`BACKUP DATABASE foo TO "bar.12" INCREMENTAL FROM "baz.34"`,
  2013  			`BACKUP DATABASE foo TO 'bar.12' INCREMENTAL FROM 'baz.34'`},
  2014  		{`RESTORE DATABASE foo FROM bar`,
  2015  			`RESTORE DATABASE foo FROM 'bar'`},
  2016  		{`BACKUP DATABASE foo TO ($1)`, `BACKUP DATABASE foo TO $1`},
  2017  
  2018  		{`RESTORE DATABASE foo FROM ($1)`, `RESTORE DATABASE foo FROM $1`},
  2019  		{`RESTORE DATABASE foo FROM ($1), ($2)`, `RESTORE DATABASE foo FROM $1, $2`},
  2020  		{`RESTORE DATABASE foo FROM ($1), ($2, $3)`, `RESTORE DATABASE foo FROM $1, ($2, $3)`},
  2021  
  2022  		{`CREATE CHANGEFEED FOR TABLE foo INTO sink`,
  2023  			`CREATE CHANGEFEED FOR TABLE foo INTO 'sink'`},
  2024  
  2025  		{`SHOW CLUSTER SETTING ALL`, `SHOW ALL CLUSTER SETTINGS`},
  2026  		{`SHOW CLUSTER SETTINGS`, `SHOW PUBLIC CLUSTER SETTINGS`},
  2027  
  2028  		{`SHOW SESSIONS`, `SHOW CLUSTER SESSIONS`},
  2029  		{`SHOW ALL SESSIONS`, `SHOW ALL CLUSTER SESSIONS`},
  2030  		{`SHOW QUERIES`, `SHOW CLUSTER QUERIES`},
  2031  		{`SHOW ALL QUERIES`, `SHOW ALL CLUSTER QUERIES`},
  2032  
  2033  		{`USE foo`, `SET database = foo`},
  2034  
  2035  		{`SET NAMES foo`, `SET client_encoding = foo`},
  2036  		{`SET NAMES 'foo'`, `SET client_encoding = 'foo'`},
  2037  		{`SET NAMES DEFAULT`, `SET client_encoding = DEFAULT`},
  2038  		{`SET NAMES`, `SET client_encoding = DEFAULT`},
  2039  
  2040  		{`SHOW NAMES`, `SHOW client_encoding`},
  2041  
  2042  		{`SHOW TRANSACTION ISOLATION LEVEL`, `SHOW transaction_isolation`},
  2043  		{`SHOW TRANSACTION PRIORITY`, `SHOW transaction_priority`},
  2044  
  2045  		{`RESET a`, `SET a = DEFAULT`},
  2046  		{`RESET CLUSTER SETTING a`, `SET CLUSTER SETTING a = DEFAULT`},
  2047  
  2048  		{`RESET NAMES`, `SET client_encoding = DEFAULT`},
  2049  
  2050  		{`CREATE USER foo`,
  2051  			`CREATE USER 'foo'`},
  2052  		{`CREATE USER IF NOT EXISTS foo`,
  2053  			`CREATE USER IF NOT EXISTS 'foo'`},
  2054  		{`CREATE USER foo PASSWORD bar`,
  2055  			`CREATE USER 'foo' WITH PASSWORD 'bar'`},
  2056  		{`CREATE USER foo PASSWORD NULL`,
  2057  			`CREATE USER 'foo' WITH PASSWORD NULL`},
  2058  		{`CREATE USER foo LOGIN VALID UNTIL NULL PASSWORD NULL`,
  2059  			`CREATE USER 'foo' WITH LOGIN VALID UNTIL NULL PASSWORD NULL`},
  2060  		{`CREATE USER foo VALID UNTIL '1970-01-01'`,
  2061  			`CREATE USER 'foo' WITH VALID UNTIL '1970-01-01'`},
  2062  		{`DROP USER foo, bar`,
  2063  			`DROP USER 'foo', 'bar'`},
  2064  		{`DROP USER IF EXISTS foo, bar`,
  2065  			`DROP USER IF EXISTS 'foo', 'bar'`},
  2066  		{`ALTER USER foo PASSWORD bar`,
  2067  			`ALTER USER 'foo' WITH PASSWORD 'bar'`},
  2068  		{`ALTER USER foo WITH PASSWORD bar`,
  2069  			`ALTER USER 'foo' WITH PASSWORD 'bar'`},
  2070  		{`ALTER USER foo WITH PASSWORD NULL`,
  2071  			`ALTER USER 'foo' WITH PASSWORD NULL`},
  2072  
  2073  		{`ALTER TABLE a RENAME b TO c`,
  2074  			`ALTER TABLE a RENAME COLUMN b TO c`},
  2075  
  2076  		// Identifier handling for zone configs.
  2077  
  2078  		{`ALTER TABLE t CONFIGURE ZONE = NULL`,
  2079  			`ALTER TABLE t CONFIGURE ZONE DISCARD`},
  2080  		{`ALTER RANGE default CONFIGURE ZONE USING foo.bar = yay`,
  2081  			`ALTER RANGE default CONFIGURE ZONE USING "foo.bar" = yay`},
  2082  		{`ALTER RANGE meta CONFIGURE ZONE USING foo.bar = yay`,
  2083  			`ALTER RANGE meta CONFIGURE ZONE USING "foo.bar" = yay`},
  2084  		{`ALTER DATABASE db CONFIGURE ZONE USING foo.bar = yay`,
  2085  			`ALTER DATABASE db CONFIGURE ZONE USING "foo.bar" = yay`},
  2086  		{`ALTER TABLE db.t CONFIGURE ZONE USING foo.bar = yay`,
  2087  			`ALTER TABLE db.t CONFIGURE ZONE USING "foo.bar" = yay`},
  2088  		{`ALTER PARTITION p OF TABLE db.t CONFIGURE ZONE USING foo.bar = yay`,
  2089  			`ALTER PARTITION p OF TABLE db.t CONFIGURE ZONE USING "foo.bar" = yay`},
  2090  		{`ALTER TABLE t CONFIGURE ZONE USING foo.bar = yay`,
  2091  			`ALTER TABLE t CONFIGURE ZONE USING "foo.bar" = yay`},
  2092  		{`ALTER PARTITION p OF TABLE t CONFIGURE ZONE USING foo.bar = yay`,
  2093  			`ALTER PARTITION p OF TABLE t CONFIGURE ZONE USING "foo.bar" = yay`},
  2094  		{`ALTER INDEX db.t@i CONFIGURE ZONE USING foo.bar = yay`,
  2095  			`ALTER INDEX db.t@i CONFIGURE ZONE USING "foo.bar" = yay`},
  2096  		{`ALTER INDEX t@i CONFIGURE ZONE USING foo.bar = yay`,
  2097  			`ALTER INDEX t@i CONFIGURE ZONE USING "foo.bar" = yay`},
  2098  		{`ALTER INDEX i CONFIGURE ZONE USING foo.bar = yay`,
  2099  			`ALTER INDEX i CONFIGURE ZONE USING "foo.bar" = yay`},
  2100  		{`ALTER INDEX i CONFIGURE ZONE USING foo = COPY FROM PARENT`,
  2101  			`ALTER INDEX i CONFIGURE ZONE USING foo = COPY FROM PARENT`},
  2102  
  2103  		// Alternative forms for table patterns.
  2104  
  2105  		{`SHOW GRANTS ON foo`,
  2106  			`SHOW GRANTS ON TABLE foo`},
  2107  		{`SHOW GRANTS ON foo, db.foo`,
  2108  			`SHOW GRANTS ON TABLE foo, db.foo`},
  2109  		{`BACKUP foo TO 'bar'`,
  2110  			`BACKUP TABLE foo TO 'bar'`},
  2111  		{`BACKUP foo.foo, baz.baz TO 'bar'`,
  2112  			`BACKUP TABLE foo.foo, baz.baz TO 'bar'`},
  2113  		{`BACKUP foo TO 'bar' AS OF SYSTEM TIME '1' INCREMENTAL FROM 'baz'`,
  2114  			`BACKUP TABLE foo TO 'bar' AS OF SYSTEM TIME '1' INCREMENTAL FROM 'baz'`},
  2115  		{`BACKUP foo TO $1 INCREMENTAL FROM 'bar', $2, 'baz'`,
  2116  			`BACKUP TABLE foo TO $1 INCREMENTAL FROM 'bar', $2, 'baz'`},
  2117  		// Tables named "role" are handled specially to support SHOW GRANTS ON ROLE,
  2118  		// but that special handling should not impact BACKUP.
  2119  		{`BACKUP role TO 'bar'`,
  2120  			`BACKUP TABLE role TO 'bar'`},
  2121  		{`RESTORE foo FROM 'bar'`,
  2122  			`RESTORE TABLE foo FROM 'bar'`},
  2123  		{`RESTORE foo FROM $1`,
  2124  			`RESTORE TABLE foo FROM $1`},
  2125  		{`RESTORE foo FROM $1, $2, 'bar'`,
  2126  			`RESTORE TABLE foo FROM $1, $2, 'bar'`},
  2127  		{`RESTORE foo, baz FROM 'bar'`,
  2128  			`RESTORE TABLE foo, baz FROM 'bar'`},
  2129  		{`RESTORE foo, baz FROM 'bar' AS OF SYSTEM TIME '1'`,
  2130  			`RESTORE TABLE foo, baz FROM 'bar' AS OF SYSTEM TIME '1'`},
  2131  		{`BACKUP foo TO 'bar' WITH key1, key2 = 'value'`,
  2132  			`BACKUP TABLE foo TO 'bar' WITH key1, key2 = 'value'`},
  2133  		{`RESTORE foo FROM 'bar' WITH key1, key2 = 'value'`,
  2134  			`RESTORE TABLE foo FROM 'bar' WITH key1, key2 = 'value'`},
  2135  
  2136  		{`CREATE CHANGEFEED FOR foo INTO 'sink'`, `CREATE CHANGEFEED FOR TABLE foo INTO 'sink'`},
  2137  
  2138  		{`GRANT SELECT ON foo TO root`,
  2139  			`GRANT SELECT ON TABLE foo TO root`},
  2140  		{`GRANT SELECT, DELETE, UPDATE ON foo, db.foo TO root, bar`,
  2141  			`GRANT SELECT, DELETE, UPDATE ON TABLE foo, db.foo TO root, bar`},
  2142  		// Tables named "role" are handled specially to support SHOW GRANTS ON ROLE,
  2143  		// but that special handling should not impact GRANT.
  2144  		{`GRANT SELECT ON role TO root`,
  2145  			`GRANT SELECT ON TABLE role TO root`},
  2146  		{`REVOKE SELECT ON foo FROM root`,
  2147  			`REVOKE SELECT ON TABLE foo FROM root`},
  2148  		{`REVOKE UPDATE, DELETE ON foo, db.foo FROM root, bar`,
  2149  			`REVOKE UPDATE, DELETE ON TABLE foo, db.foo FROM root, bar`},
  2150  
  2151  		// RBAC-related statements.
  2152  
  2153  		{`CREATE ROLE foo`,
  2154  			`CREATE ROLE 'foo'`},
  2155  		{`CREATE ROLE IF NOT EXISTS foo`,
  2156  			`CREATE ROLE IF NOT EXISTS 'foo'`},
  2157  		{`CREATE ROLE foo WITH CREATEROLE`,
  2158  			`CREATE ROLE 'foo' WITH CREATEROLE`},
  2159  		{`CREATE ROLE IF NOT EXISTS foo WITH CREATEROLE`,
  2160  			`CREATE ROLE IF NOT EXISTS 'foo' WITH CREATEROLE`},
  2161  		{`CREATE ROLE foo CREATEROLE`,
  2162  			`CREATE ROLE 'foo' WITH CREATEROLE`},
  2163  		{`CREATE ROLE IF NOT EXISTS foo CREATEROLE`,
  2164  			`CREATE ROLE IF NOT EXISTS 'foo' WITH CREATEROLE`},
  2165  		{`ALTER ROLE foo WITH CREATEROLE`,
  2166  			`ALTER ROLE 'foo' WITH CREATEROLE`},
  2167  		{`ALTER ROLE foo CREATEROLE`,
  2168  			`ALTER ROLE 'foo' WITH CREATEROLE`},
  2169  		{`DROP ROLE foo, bar`,
  2170  			`DROP ROLE 'foo', 'bar'`},
  2171  		{`DROP ROLE IF EXISTS foo, bar`,
  2172  			`DROP ROLE IF EXISTS 'foo', 'bar'`},
  2173  
  2174  		// Backward-compat, deprecated IMPORT syntax
  2175  		{`IMPORT PGDUMP ('nodelocal://0/foo/bar') WITH temp = 'path/to/temp'`,
  2176  			`IMPORT PGDUMP 'nodelocal://0/foo/bar' WITH temp = 'path/to/temp'`,
  2177  		},
  2178  		{`IMPORT TABLE foo FROM PGDUMPCREATE ('nodelocal://0/foo/bar') WITH temp = 'path/to/temp'`,
  2179  			`IMPORT TABLE foo FROM PGDUMPCREATE 'nodelocal://0/foo/bar' WITH temp = 'path/to/temp'`,
  2180  		},
  2181  
  2182  		// Clarify the ambiguity between "ON ROLE" (RBAC) and "ON ROLE"
  2183  		// (regular table named "role").
  2184  		{`SHOW GRANTS ON role`, `SHOW GRANTS ON ROLE`},
  2185  		{`SHOW GRANTS ON "role"`, `SHOW GRANTS ON TABLE role`},
  2186  		{`SHOW GRANTS ON role foo`, `SHOW GRANTS ON ROLE foo`},
  2187  		{`SHOW GRANTS ON role, foo`, `SHOW GRANTS ON TABLE role, foo`},
  2188  		{`SHOW GRANTS ON role foo, bar`, `SHOW GRANTS ON ROLE foo, bar`},
  2189  		{`SHOW GRANTS ON "role", foo`, `SHOW GRANTS ON TABLE role, foo`},
  2190  		{`SHOW GRANTS ON "role".foo`, `SHOW GRANTS ON TABLE role.foo`},
  2191  		{`SHOW GRANTS ON role.foo`, `SHOW GRANTS ON TABLE role.foo`},
  2192  		{`SHOW GRANTS ON role.*`, `SHOW GRANTS ON TABLE role.*`},
  2193  
  2194  		// Foreign Keys
  2195  		{
  2196  			`CREATE TABLE a (b INT8, c INT8 REFERENCES foo MATCH SIMPLE)`,
  2197  			`CREATE TABLE a (b INT8, c INT8 REFERENCES foo)`,
  2198  		},
  2199  		{
  2200  			`CREATE TABLE a (b INT8, c INT8 REFERENCES foo MATCH SIMPLE ON UPDATE RESTRICT)`,
  2201  			`CREATE TABLE a (b INT8, c INT8 REFERENCES foo ON UPDATE RESTRICT)`,
  2202  		},
  2203  		{
  2204  			`CREATE TABLE a (b INT8, c INT8 REFERENCES foo (bar) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION)`,
  2205  			`CREATE TABLE a (b INT8, c INT8 REFERENCES foo (bar))`,
  2206  		},
  2207  		{
  2208  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE NO ACTION ON DELETE NO ACTION)`,
  2209  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other)`,
  2210  		},
  2211  		{
  2212  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE RESTRICT ON DELETE RESTRICT)`,
  2213  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE RESTRICT ON UPDATE RESTRICT)`,
  2214  		},
  2215  		{
  2216  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE RESTRICT ON DELETE NO ACTION)`,
  2217  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE RESTRICT)`,
  2218  		},
  2219  		{
  2220  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE NO ACTION ON DELETE RESTRICT)`,
  2221  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE RESTRICT)`,
  2222  		},
  2223  		{
  2224  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE CASCADE ON DELETE CASCADE)`,
  2225  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE CASCADE ON UPDATE CASCADE)`,
  2226  		},
  2227  		{
  2228  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE CASCADE ON DELETE NO ACTION)`,
  2229  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE CASCADE)`,
  2230  		},
  2231  		{
  2232  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE NO ACTION ON DELETE CASCADE)`,
  2233  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE CASCADE)`,
  2234  		},
  2235  		{
  2236  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET NULL ON DELETE SET NULL)`,
  2237  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE SET NULL ON UPDATE SET NULL)`,
  2238  		},
  2239  		{
  2240  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET NULL ON DELETE NO ACTION)`,
  2241  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET NULL)`,
  2242  		},
  2243  		{
  2244  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE NO ACTION ON DELETE SET NULL)`,
  2245  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE SET NULL)`,
  2246  		},
  2247  		{
  2248  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET DEFAULT ON DELETE SET DEFAULT)`,
  2249  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT ON UPDATE SET DEFAULT)`,
  2250  		},
  2251  		{
  2252  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET DEFAULT ON DELETE NO ACTION)`,
  2253  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET DEFAULT)`,
  2254  		},
  2255  		{
  2256  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE NO ACTION ON DELETE SET DEFAULT)`,
  2257  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT)`,
  2258  		},
  2259  		{
  2260  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE RESTRICT ON DELETE CASCADE)`,
  2261  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE CASCADE ON UPDATE RESTRICT)`,
  2262  		},
  2263  		{
  2264  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE CASCADE ON DELETE SET NULL)`,
  2265  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE SET NULL ON UPDATE CASCADE)`,
  2266  		},
  2267  		{
  2268  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET NULL ON DELETE SET DEFAULT)`,
  2269  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT ON UPDATE SET NULL)`,
  2270  		},
  2271  		{
  2272  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON UPDATE SET DEFAULT ON DELETE RESTRICT)`,
  2273  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other ON DELETE RESTRICT ON UPDATE SET DEFAULT)`,
  2274  		},
  2275  		{
  2276  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION)`,
  2277  			`CREATE TABLE a (b INT8, FOREIGN KEY (b) REFERENCES other MATCH FULL)`,
  2278  		},
  2279  		{
  2280  			`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH SIMPLE)`,
  2281  			`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y))`,
  2282  		},
  2283  		{
  2284  			`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH SIMPLE ON UPDATE SET NULL)`,
  2285  			`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) ON UPDATE SET NULL)`,
  2286  		},
  2287  		{
  2288  			`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH SIMPLE ON DELETE SET DEFAULT)`,
  2289  			`CREATE TABLE a (b INT8, c STRING, CONSTRAINT s FOREIGN KEY (b, c) REFERENCES other (x, y) ON DELETE SET DEFAULT)`,
  2290  		},
  2291  		{
  2292  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH SIMPLE ON DELETE SET DEFAULT ON UPDATE SET DEFAULT)`,
  2293  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT ON UPDATE SET DEFAULT)`,
  2294  		},
  2295  		{
  2296  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH SIMPLE ON DELETE RESTRICT ON UPDATE SET DEFAULT)`,
  2297  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE RESTRICT ON UPDATE SET DEFAULT)`,
  2298  		},
  2299  		{
  2300  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH SIMPLE ON DELETE SET DEFAULT ON UPDATE CASCADE)`,
  2301  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET DEFAULT ON UPDATE CASCADE)`,
  2302  		},
  2303  		{
  2304  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH SIMPLE ON DELETE CASCADE ON UPDATE SET NULL)`,
  2305  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE CASCADE ON UPDATE SET NULL)`,
  2306  		},
  2307  		{
  2308  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other MATCH SIMPLE ON DELETE SET NULL ON UPDATE RESTRICT)`,
  2309  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b) REFERENCES other ON DELETE SET NULL ON UPDATE RESTRICT)`,
  2310  		},
  2311  		{
  2312  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other MATCH SIMPLE)`,
  2313  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other)`,
  2314  		},
  2315  		{
  2316  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH SIMPLE)`,
  2317  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y))`,
  2318  		},
  2319  		{
  2320  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH SIMPLE ON UPDATE CASCADE)`,
  2321  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) ON UPDATE CASCADE)`,
  2322  		},
  2323  		{
  2324  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH SIMPLE ON DELETE CASCADE)`,
  2325  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) ON DELETE CASCADE)`,
  2326  		},
  2327  		{
  2328  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) MATCH SIMPLE ON DELETE CASCADE ON UPDATE SET NULL)`,
  2329  			`CREATE TABLE a (b INT8, c STRING, FOREIGN KEY (b, c) REFERENCES other (x, y) ON DELETE CASCADE ON UPDATE SET NULL)`,
  2330  		},
  2331  		{`CREATE TABLE a (b INT8 GENERATED ALWAYS AS (a + b) STORED)`, `CREATE TABLE a (b INT8 AS (a + b) STORED)`},
  2332  
  2333  		{`ALTER TABLE a ALTER b DROP STORED`, `ALTER TABLE a ALTER COLUMN b DROP STORED`},
  2334  		{`ALTER TABLE a ADD b INT8`, `ALTER TABLE a ADD COLUMN b INT8`},
  2335  		{`ALTER TABLE a ADD IF NOT EXISTS b INT8`, `ALTER TABLE a ADD COLUMN IF NOT EXISTS b INT8`},
  2336  		{`ALTER TABLE a ADD b INT8 FAMILY fam_a`, `ALTER TABLE a ADD COLUMN b INT8 FAMILY fam_a`},
  2337  		{`ALTER TABLE a DROP b`, `ALTER TABLE a DROP COLUMN b`},
  2338  		{`ALTER TABLE a ALTER b DROP NOT NULL`, `ALTER TABLE a ALTER COLUMN b DROP NOT NULL`},
  2339  		{`ALTER TABLE a ALTER b TYPE INT8`, `ALTER TABLE a ALTER COLUMN b SET DATA TYPE INT8`},
  2340  
  2341  		{`EXPLAIN ANALYZE SELECT 1`, `EXPLAIN ANALYZE (DISTSQL) SELECT 1`},
  2342  		// Check the alternate spelling.
  2343  		{`EXPLAIN ANALYSE SELECT 1`, `EXPLAIN ANALYZE (DISTSQL) SELECT 1`},
  2344  		{`EXPLAIN ANALYSE (DISTSQL) SELECT 1`, `EXPLAIN ANALYZE (DISTSQL) SELECT 1`},
  2345  		{`EXPLAIN (VERBOSE, OPT) SELECT 1`, `EXPLAIN (OPT, VERBOSE) SELECT 1`},
  2346  
  2347  		{`SET a = INDEX`, `SET a = "index"`},
  2348  		{`SET a = NOTHING`, `SET a = "nothing"`},
  2349  
  2350  		// Regression for #31589
  2351  		{`CREATE TABLE FAMILY (x INT)`,
  2352  			`CREATE TABLE "family" (x INT8)`},
  2353  		{`CREATE TABLE INDEX (x INT)`,
  2354  			`CREATE TABLE "index" (x INT8)`},
  2355  		{`CREATE TABLE NOTHING (x INT)`,
  2356  			`CREATE TABLE "nothing" (x INT8)`},
  2357  
  2358  		// Ensure MINVALUE/MAXVALUE are not reserved.
  2359  		{`CREATE TABLE MINVALUE (x INT)`,
  2360  			`CREATE TABLE minvalue (x INT8)`},
  2361  		{`CREATE TABLE MAXVALUE (x INT)`,
  2362  			`CREATE TABLE maxvalue (x INT8)`},
  2363  		{`CREATE TABLE foo (MINVALUE INT)`,
  2364  			`CREATE TABLE foo (minvalue INT8)`},
  2365  		{`CREATE TABLE foo (MAXVALUE INT)`,
  2366  			`CREATE TABLE foo (maxvalue INT8)`},
  2367  
  2368  		{`CREATE TABLE a (b INT) PARTITION BY RANGE (b) (PARTITION p1 VALUES FROM (MINVALUE) TO (1), PARTITION p2 VALUES FROM (2, MAXVALUE) TO (4, 4), PARTITION p3 VALUES FROM (4, 4) TO (MAXVALUE))`,
  2369  			`CREATE TABLE a (b INT8) PARTITION BY RANGE (b) (PARTITION p1 VALUES FROM (minvalue) TO (1), PARTITION p2 VALUES FROM (2, maxvalue) TO (4, 4), PARTITION p3 VALUES FROM (4, 4) TO (maxvalue))`},
  2370  
  2371  		// Check that JSONB operators have higher precedence than '='.
  2372  		{`SELECT '{}'::JSONB ? 'a' = false`, `SELECT ('{}'::JSONB ? 'a') = false`},
  2373  		{`SELECT '{}'::JSONB ?| 'a' = false`, `SELECT ('{}'::JSONB ?| 'a') = false`},
  2374  		{`SELECT '{}'::JSONB ?& 'a' = false`, `SELECT ('{}'::JSONB ?& 'a') = false`},
  2375  		{`SELECT '{}'::JSONB @> '{}'::JSONB = false`, `SELECT ('{}'::JSONB @> '{}'::JSONB) = false`},
  2376  		{`SELECT '{}'::JSONB <@ '{}'::JSONB = false`, `SELECT ('{}'::JSONB <@ '{}'::JSONB) = false`},
  2377  
  2378  		{`SELECT 1::db.int4.typ array [1]`, `SELECT 1::db.int4.typ[]`},
  2379  		{`SELECT 1::int4.typ array [1]`, `SELECT 1::int4.typ[]`},
  2380  		{`SELECT 1::db.int4.typ array`, `SELECT 1::db.int4.typ[]`},
  2381  		{`CREATE TABLE t (x int4.type array [1])`, `CREATE TABLE t (x int4.type[])`},
  2382  	}
  2383  	for _, d := range testData {
  2384  		t.Run(d.sql, func(t *testing.T) {
  2385  			stmts, err := parser.Parse(d.sql)
  2386  			if err != nil {
  2387  				t.Errorf("%s: expected success, but found %s", d.sql, err)
  2388  				return
  2389  			}
  2390  			s := stmts.StringWithFlags(tree.FmtShowPasswords)
  2391  			if d.expected != s {
  2392  				t.Errorf("%s: expected %s, but found (%d statements): %s", d.sql, d.expected, len(stmts), s)
  2393  			}
  2394  			if _, err := parser.Parse(s); err != nil {
  2395  				t.Errorf("expected string found, but not parsable: %s:\n%s", err, s)
  2396  			}
  2397  			sqlutils.VerifyStatementPrettyRoundtrip(t, d.expected)
  2398  		})
  2399  	}
  2400  }
  2401  
  2402  // TestParseTree checks that the implicit grouping done by the grammar
  2403  // is properly reflected in the parse tree.
  2404  func TestParseTree(t *testing.T) {
  2405  	testData := []struct {
  2406  		sql      string
  2407  		expected string
  2408  	}{
  2409  		{`SELECT 1`, `SELECT (1)`},
  2410  		{`SELECT -1+2`, `SELECT ((-1) + (2))`},
  2411  		{`SELECT -1:::INT8`, `SELECT (-((1):::INT8))`},
  2412  		{`SELECT 1 = 2::INT8`, `SELECT ((1) = ((2)::INT8))`},
  2413  		{`SELECT 1 = ANY 2::INT8`, `SELECT ((1) = ANY ((2)::INT8))`},
  2414  		{`SELECT 1 = ANY ARRAY[1]:::INT8`, `SELECT ((1) = ANY ((ARRAY[(1)]):::INT8))`},
  2415  	}
  2416  
  2417  	for _, d := range testData {
  2418  		t.Run(d.sql, func(t *testing.T) {
  2419  			stmts, err := parser.Parse(d.sql)
  2420  			if err != nil {
  2421  				t.Errorf("%s: expected success, but found %s", d.sql, err)
  2422  				return
  2423  			}
  2424  			s := stmts.StringWithFlags(tree.FmtAlwaysGroupExprs)
  2425  			if d.expected != s {
  2426  				t.Errorf("%s: expected %s, but found (%d statements): %s", d.sql, d.expected, len(stmts), s)
  2427  			}
  2428  			if _, err := parser.Parse(s); err != nil {
  2429  				t.Errorf("expected string found, but not parsable: %s:\n%s", err, s)
  2430  			}
  2431  			sqlutils.VerifyStatementPrettyRoundtrip(t, d.expected)
  2432  		})
  2433  	}
  2434  }
  2435  
  2436  // TestParseSyntax verifies that parsing succeeds, though the syntax tree
  2437  // likely differs. All of the test cases here should eventually be moved
  2438  // elsewhere.
  2439  func TestParseSyntax(t *testing.T) {
  2440  	testData := []struct {
  2441  		sql string
  2442  	}{
  2443  		{`SELECT '\0' FROM a`},
  2444  		{`SELECT ((1)) FROM t WHERE ((a)) IN (((1))) AND ((a, b)) IN ((((1, 1))), ((2, 2)))`},
  2445  		{`SELECT e'\'\"\b\n\r\t\\' FROM t`},
  2446  		{`SELECT '\x' FROM t`},
  2447  	}
  2448  	for _, d := range testData {
  2449  		t.Run(d.sql, func(t *testing.T) {
  2450  			if _, err := parser.Parse(d.sql); err != nil {
  2451  				t.Fatalf("%s: expected success, but not parsable %s", d.sql, err)
  2452  			}
  2453  			sqlutils.VerifyStatementPrettyRoundtrip(t, d.sql)
  2454  		})
  2455  	}
  2456  }
  2457  
  2458  func TestParseError(t *testing.T) {
  2459  	testData := []struct {
  2460  		sql      string
  2461  		expected string
  2462  	}{
  2463  		{`SELECT2 1`,
  2464  			`at or near "select2": syntax error
  2465  DETAIL: source SQL:
  2466  SELECT2 1
  2467  ^`},
  2468  		{`SELECT 1 FROM (t)`,
  2469  			`at or near ")": syntax error
  2470  DETAIL: source SQL:
  2471  SELECT 1 FROM (t)
  2472                  ^
  2473  HINT: try \h <SOURCE>`},
  2474  		{`SET TIME ZONE INTERVAL 'foobar'`,
  2475  			`at or near "EOF": syntax error: could not parse "foobar" as type interval: interval: missing unit at position 0: "foobar"
  2476  DETAIL: source SQL:
  2477  SET TIME ZONE INTERVAL 'foobar'
  2478                                 ^`},
  2479  		{`SELECT INTERVAL 'foo'`,
  2480  			`at or near "EOF": syntax error: could not parse "foo" as type interval: interval: missing unit at position 0: "foo"
  2481  DETAIL: source SQL:
  2482  SELECT INTERVAL 'foo'
  2483                       ^`},
  2484  		{`SELECT 1 /* hello`,
  2485  			`lexical error: unterminated comment
  2486  DETAIL: source SQL:
  2487  SELECT 1 /* hello
  2488           ^`},
  2489  		{`SELECT '1`,
  2490  			`lexical error: unterminated string
  2491  DETAIL: source SQL:
  2492  SELECT '1
  2493         ^
  2494  HINT: try \h SELECT`},
  2495  		{`SELECT * FROM t WHERE k=`,
  2496  			`at or near "EOF": syntax error
  2497  DETAIL: source SQL:
  2498  SELECT * FROM t WHERE k=
  2499                          ^
  2500  HINT: try \h SELECT`,
  2501  		},
  2502  		{`CREATE TABLE test (
  2503    CONSTRAINT foo INDEX (bar)
  2504  )`,
  2505  			`at or near "index": syntax error
  2506  DETAIL: source SQL:
  2507  CREATE TABLE test (
  2508    CONSTRAINT foo INDEX (bar)
  2509                   ^
  2510  HINT: try \h CREATE TABLE`},
  2511  		{`CREATE TABLE test (
  2512    foo BIT(0)
  2513  )`,
  2514  			`at or near ")": syntax error: length for type bit must be at least 1
  2515  DETAIL: source SQL:
  2516  CREATE TABLE test (
  2517    foo BIT(0)
  2518             ^`},
  2519  		{`CREATE TABLE test (
  2520    foo INT8 DEFAULT 1 DEFAULT 2
  2521  )`,
  2522  			`at or near ")": syntax error: multiple default values specified for column "foo"
  2523  DETAIL: source SQL:
  2524  CREATE TABLE test (
  2525    foo INT8 DEFAULT 1 DEFAULT 2
  2526  )
  2527  ^`},
  2528  		{`CREATE TABLE test (
  2529    foo INT8 REFERENCES t1 REFERENCES t2
  2530  )`,
  2531  			`at or near ")": syntax error: multiple foreign key constraints specified for column "foo"
  2532  DETAIL: source SQL:
  2533  CREATE TABLE test (
  2534    foo INT8 REFERENCES t1 REFERENCES t2
  2535  )
  2536  ^`},
  2537  		{`CREATE TABLE test (
  2538    foo INT8 FAMILY a FAMILY b
  2539  )`,
  2540  			`at or near ")": syntax error: multiple column families specified for column "foo"
  2541  DETAIL: source SQL:
  2542  CREATE TABLE test (
  2543    foo INT8 FAMILY a FAMILY b
  2544  )
  2545  ^`},
  2546  		{`SELECT family FROM test`,
  2547  			`at or near "from": syntax error
  2548  DETAIL: source SQL:
  2549  SELECT family FROM test
  2550                ^
  2551  HINT: try \h SELECT`},
  2552  		{`CREATE TABLE test (
  2553    foo INT8 NOT NULL NULL
  2554  )`,
  2555  			`at or near ")": syntax error: conflicting NULL/NOT NULL declarations for column "foo"
  2556  DETAIL: source SQL:
  2557  CREATE TABLE test (
  2558    foo INT8 NOT NULL NULL
  2559  )
  2560  ^`},
  2561  		{`CREATE TABLE test (
  2562    foo INT8 NULL NOT NULL
  2563  )`,
  2564  			`at or near ")": syntax error: conflicting NULL/NOT NULL declarations for column "foo"
  2565  DETAIL: source SQL:
  2566  CREATE TABLE test (
  2567    foo INT8 NULL NOT NULL
  2568  )
  2569  ^`},
  2570  		{`CREATE DATABASE a b`,
  2571  			`at or near "b": syntax error
  2572  DETAIL: source SQL:
  2573  CREATE DATABASE a b
  2574                    ^`},
  2575  		{`CREATE DATABASE a b c`,
  2576  			`at or near "b": syntax error
  2577  DETAIL: source SQL:
  2578  CREATE DATABASE a b c
  2579                    ^`},
  2580  		{`CREATE INDEX ON a (b) STORING ()`,
  2581  			`at or near ")": syntax error
  2582  DETAIL: source SQL:
  2583  CREATE INDEX ON a (b) STORING ()
  2584                                 ^
  2585  HINT: try \h CREATE INDEX`},
  2586  		{`CREATE VIEW a`,
  2587  			`at or near "EOF": syntax error
  2588  DETAIL: source SQL:
  2589  CREATE VIEW a
  2590               ^
  2591  HINT: try \h CREATE VIEW`},
  2592  		{`CREATE VIEW a () AS select * FROM b`,
  2593  			`at or near ")": syntax error
  2594  DETAIL: source SQL:
  2595  CREATE VIEW a () AS select * FROM b
  2596                 ^
  2597  HINT: try \h CREATE VIEW`},
  2598  		{`SELECT FROM t`,
  2599  			`at or near "from": syntax error
  2600  DETAIL: source SQL:
  2601  SELECT FROM t
  2602         ^
  2603  HINT: try \h SELECT`},
  2604  
  2605  		{"SELECT 1e-\n-1",
  2606  			`lexical error: invalid floating point literal
  2607  DETAIL: source SQL:
  2608  SELECT 1e-
  2609         ^
  2610  HINT: try \h SELECT`},
  2611  		{
  2612  			`SELECT 0x FROM t`,
  2613  			`lexical error: invalid hexadecimal numeric literal
  2614  DETAIL: source SQL:
  2615  SELECT 0x FROM t
  2616         ^
  2617  HINT: try \h SELECT`,
  2618  		},
  2619  		{
  2620  			`SELECT x'fail' FROM t`,
  2621  			`lexical error: invalid hexadecimal bytes literal
  2622  DETAIL: source SQL:
  2623  SELECT x'fail' FROM t
  2624         ^
  2625  HINT: try \h SELECT`,
  2626  		},
  2627  		{
  2628  			`SELECT x'AAB' FROM t`,
  2629  			`lexical error: invalid hexadecimal bytes literal
  2630  DETAIL: source SQL:
  2631  SELECT x'AAB' FROM t
  2632         ^
  2633  HINT: try \h SELECT`,
  2634  		},
  2635  		{
  2636  			`SELECT POSITION('high', 'a')`,
  2637  			`at or near ",": syntax error
  2638  DETAIL: source SQL:
  2639  SELECT POSITION('high', 'a')
  2640                        ^
  2641  HINT: try \h SELECT`,
  2642  		},
  2643  		{
  2644  			`SELECT a FROM foo@{FORCE_INDEX}`,
  2645  			`at or near "}": syntax error
  2646  DETAIL: source SQL:
  2647  SELECT a FROM foo@{FORCE_INDEX}
  2648                                ^
  2649  HINT: try \h <SOURCE>`,
  2650  		},
  2651  		{
  2652  			`SELECT a FROM foo@{FORCE_INDEX=}`,
  2653  			`at or near "}": syntax error
  2654  DETAIL: source SQL:
  2655  SELECT a FROM foo@{FORCE_INDEX=}
  2656                                 ^
  2657  HINT: try \h <SOURCE>`,
  2658  		},
  2659  		{
  2660  			`SELECT a FROM foo@{FORCE_INDEX=bar,FORCE_INDEX=baz}`,
  2661  			`at or near "baz": syntax error: FORCE_INDEX specified multiple times
  2662  DETAIL: source SQL:
  2663  SELECT a FROM foo@{FORCE_INDEX=bar,FORCE_INDEX=baz}
  2664                                                 ^`,
  2665  		},
  2666  		{
  2667  			`SELECT a FROM foo@{FORCE_INDEX=bar,NO_INDEX_JOIN}`,
  2668  			`at or near "}": syntax error: FORCE_INDEX cannot be specified in conjunction with NO_INDEX_JOIN
  2669  DETAIL: source SQL:
  2670  SELECT a FROM foo@{FORCE_INDEX=bar,NO_INDEX_JOIN}
  2671                                                  ^`,
  2672  		},
  2673  		{
  2674  			`SELECT a FROM foo@{NO_INDEX_JOIN,NO_INDEX_JOIN}`,
  2675  			`at or near "no_index_join": syntax error: NO_INDEX_JOIN specified multiple times
  2676  DETAIL: source SQL:
  2677  SELECT a FROM foo@{NO_INDEX_JOIN,NO_INDEX_JOIN}
  2678                                   ^`,
  2679  		},
  2680  		{
  2681  			`SELECT a FROM foo@{IGNORE_FOREIGN_KEYS,IGNORE_FOREIGN_KEYS}`,
  2682  			`at or near "ignore_foreign_keys": syntax error: IGNORE_FOREIGN_KEYS specified multiple times
  2683  DETAIL: source SQL:
  2684  SELECT a FROM foo@{IGNORE_FOREIGN_KEYS,IGNORE_FOREIGN_KEYS}
  2685                                         ^`,
  2686  		},
  2687  		{
  2688  			`SELECT a FROM foo@{ASC}`,
  2689  			`at or near "}": syntax error: ASC/DESC must be specified in conjunction with an index
  2690  DETAIL: source SQL:
  2691  SELECT a FROM foo@{ASC}
  2692                        ^`,
  2693  		},
  2694  		{
  2695  			`SELECT a FROM foo@{DESC}`,
  2696  			`at or near "}": syntax error: ASC/DESC must be specified in conjunction with an index
  2697  DETAIL: source SQL:
  2698  SELECT a FROM foo@{DESC}
  2699                         ^`,
  2700  		},
  2701  		{
  2702  			`INSERT INTO a@b VALUES (1, 2)`,
  2703  			`at or near "@": syntax error
  2704  DETAIL: source SQL:
  2705  INSERT INTO a@b VALUES (1, 2)
  2706               ^
  2707  HINT: try \h INSERT`,
  2708  		},
  2709  		{
  2710  			`ALTER TABLE t RENAME COLUMN x TO family`,
  2711  			`at or near "family": syntax error
  2712  DETAIL: source SQL:
  2713  ALTER TABLE t RENAME COLUMN x TO family
  2714                                   ^
  2715  HINT: try \h ALTER TABLE`,
  2716  		},
  2717  		{
  2718  			`CREATE USER foo WITH PASSWORD`,
  2719  			`at or near "EOF": syntax error
  2720  DETAIL: source SQL:
  2721  CREATE USER foo WITH PASSWORD
  2722                               ^
  2723  HINT: try \h CREATE ROLE`,
  2724  		},
  2725  		{
  2726  			`ALTER TABLE t RENAME TO t[TRUE]`,
  2727  			`at or near "[": syntax error
  2728  DETAIL: source SQL:
  2729  ALTER TABLE t RENAME TO t[TRUE]
  2730                           ^`,
  2731  		},
  2732  		{
  2733  			`TABLE abc[TRUE]`,
  2734  			`at or near "[": syntax error
  2735  DETAIL: source SQL:
  2736  TABLE abc[TRUE]
  2737           ^`,
  2738  		},
  2739  		{
  2740  			`UPDATE kv SET k[0] = 9`,
  2741  			`at or near "[": syntax error
  2742  DETAIL: source SQL:
  2743  UPDATE kv SET k[0] = 9
  2744                 ^
  2745  HINT: try \h UPDATE`,
  2746  		},
  2747  		{
  2748  			`SELECT (0) FROM y[array[]]`,
  2749  			`at or near "[": syntax error
  2750  DETAIL: source SQL:
  2751  SELECT (0) FROM y[array[]]
  2752                   ^`,
  2753  		},
  2754  		{
  2755  			`INSERT INTO kv (k[0]) VALUES ('hello')`,
  2756  			`at or near "[": syntax error
  2757  DETAIL: source SQL:
  2758  INSERT INTO kv (k[0]) VALUES ('hello')
  2759                   ^
  2760  HINT: try \h <SELECTCLAUSE>`,
  2761  		},
  2762  		{
  2763  			`SELECT CASE 1 = 1 WHEN true THEN ARRAY[1, 2] ELSE ARRAY[2, 3] END[1]`,
  2764  			`at or near "[": syntax error
  2765  DETAIL: source SQL:
  2766  SELECT CASE 1 = 1 WHEN true THEN ARRAY[1, 2] ELSE ARRAY[2, 3] END[1]
  2767                                                                   ^`,
  2768  		},
  2769  		{
  2770  			`SELECT EXISTS(SELECT 1)[1]`,
  2771  			`at or near "[": syntax error
  2772  DETAIL: source SQL:
  2773  SELECT EXISTS(SELECT 1)[1]
  2774                         ^`,
  2775  		},
  2776  		{
  2777  			`SELECT 1 + ANY ARRAY[1, 2, 3]`,
  2778  			`at or near "EOF": syntax error: + ANY <array> is invalid because "+" is not a boolean operator
  2779  DETAIL: source SQL:
  2780  SELECT 1 + ANY ARRAY[1, 2, 3]
  2781                               ^`,
  2782  		},
  2783  		// Ensure that the support for ON ROLE <namelist> doesn't leak
  2784  		// where it should not be recognized.
  2785  		{
  2786  			`GRANT SELECT ON ROLE foo, bar TO blix`,
  2787  			`at or near "foo": syntax error
  2788  DETAIL: source SQL:
  2789  GRANT SELECT ON ROLE foo, bar TO blix
  2790                       ^
  2791  HINT: try \h GRANT`,
  2792  		},
  2793  		{
  2794  			`REVOKE SELECT ON ROLE foo, bar FROM blix`,
  2795  			`at or near "foo": syntax error
  2796  DETAIL: source SQL:
  2797  REVOKE SELECT ON ROLE foo, bar FROM blix
  2798                        ^
  2799  HINT: try \h REVOKE`,
  2800  		},
  2801  		{
  2802  			`BACKUP ROLE foo, bar TO 'baz'`,
  2803  			`at or near "foo": syntax error
  2804  DETAIL: source SQL:
  2805  BACKUP ROLE foo, bar TO 'baz'
  2806              ^
  2807  HINT: try \h BACKUP`,
  2808  		},
  2809  		{
  2810  			`RESTORE ROLE foo, bar FROM 'baz'`,
  2811  			`at or near "foo": syntax error
  2812  DETAIL: source SQL:
  2813  RESTORE ROLE foo, bar FROM 'baz'
  2814               ^
  2815  HINT: try \h RESTORE`,
  2816  		},
  2817  		{
  2818  			`SELECT avg(1) OVER (ROWS UNBOUNDED FOLLOWING) FROM t`,
  2819  			`at or near "following": syntax error: frame start cannot be UNBOUNDED FOLLOWING
  2820  DETAIL: source SQL:
  2821  SELECT avg(1) OVER (ROWS UNBOUNDED FOLLOWING) FROM t
  2822                                     ^`,
  2823  		},
  2824  		{
  2825  			`SELECT avg(1) OVER (ROWS 1 FOLLOWING) FROM t`,
  2826  			`at or near "following": syntax error: frame starting from following row cannot end with current row
  2827  DETAIL: source SQL:
  2828  SELECT avg(1) OVER (ROWS 1 FOLLOWING) FROM t
  2829                             ^`,
  2830  		},
  2831  		{
  2832  			`SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED FOLLOWING AND UNBOUNDED FOLLOWING) FROM t`,
  2833  			`at or near "following": syntax error: frame start cannot be UNBOUNDED FOLLOWING
  2834  DETAIL: source SQL:
  2835  SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED FOLLOWING AND UNBOUNDED FOLLOWING) FROM t
  2836                                                                     ^`,
  2837  		},
  2838  		{
  2839  			`SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED PRECEDING) FROM t`,
  2840  			`at or near "preceding": syntax error: frame end cannot be UNBOUNDED PRECEDING
  2841  DETAIL: source SQL:
  2842  SELECT avg(1) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED PRECEDING) FROM t
  2843                                                                     ^`,
  2844  		},
  2845  		{
  2846  			`SELECT avg(1) OVER (ROWS BETWEEN CURRENT ROW AND 1 PRECEDING) FROM t`,
  2847  			`at or near "preceding": syntax error: frame starting from current row cannot have preceding rows
  2848  DETAIL: source SQL:
  2849  SELECT avg(1) OVER (ROWS BETWEEN CURRENT ROW AND 1 PRECEDING) FROM t
  2850                                                     ^`,
  2851  		},
  2852  		{
  2853  			`SELECT avg(1) OVER (ROWS BETWEEN 1 FOLLOWING AND 1 PRECEDING) FROM t`,
  2854  			`at or near "preceding": syntax error: frame starting from following row cannot have preceding rows
  2855  DETAIL: source SQL:
  2856  SELECT avg(1) OVER (ROWS BETWEEN 1 FOLLOWING AND 1 PRECEDING) FROM t
  2857                                                     ^`,
  2858  		},
  2859  		{
  2860  			`SELECT avg(1) OVER (ROWS BETWEEN 1 FOLLOWING AND CURRENT ROW) FROM t`,
  2861  			`at or near "row": syntax error: frame starting from following row cannot have preceding rows
  2862  DETAIL: source SQL:
  2863  SELECT avg(1) OVER (ROWS BETWEEN 1 FOLLOWING AND CURRENT ROW) FROM t
  2864                                                           ^`,
  2865  		},
  2866  		{
  2867  			`CREATE TABLE foo(a CHAR(0))`,
  2868  			`at or near ")": syntax error: length for type CHAR must be at least 1
  2869  DETAIL: source SQL:
  2870  CREATE TABLE foo(a CHAR(0))
  2871                           ^`,
  2872  		},
  2873  		{
  2874  			`e'\xad'::string`,
  2875  			`lexical error: invalid UTF-8 byte sequence
  2876  DETAIL: source SQL:
  2877  e'\xad'::string
  2878  ^`,
  2879  		},
  2880  		{
  2881  			`EXPLAIN EXECUTE a`,
  2882  			`at or near "execute": syntax error
  2883  DETAIL: source SQL:
  2884  EXPLAIN EXECUTE a
  2885          ^
  2886  HINT: try \h EXPLAIN`,
  2887  		},
  2888  		{
  2889  			`SELECT $0`,
  2890  			`lexical error: placeholder index must be between 1 and 65536
  2891  DETAIL: source SQL:
  2892  SELECT $0
  2893         ^
  2894  HINT: try \h SELECT`,
  2895  		},
  2896  		{
  2897  			`SELECT $-1`,
  2898  			`at or near "$": syntax error
  2899  DETAIL: source SQL:
  2900  SELECT $-1
  2901         ^
  2902  HINT: try \h SELECT`,
  2903  		},
  2904  		{
  2905  			`SELECT $123456789`,
  2906  			`lexical error: placeholder index must be between 1 and 65536
  2907  DETAIL: source SQL:
  2908  SELECT $123456789
  2909         ^
  2910  HINT: try \h SELECT`,
  2911  		},
  2912  
  2913  		{
  2914  			`CREATE STATISTICS a ON col1 FROM t WITH OPTIONS THROTTLING 2.0`,
  2915  			`at or near "2.0": syntax error: THROTTLING fraction must be between 0 and 1
  2916  DETAIL: source SQL:
  2917  CREATE STATISTICS a ON col1 FROM t WITH OPTIONS THROTTLING 2.0
  2918                                                             ^`,
  2919  		},
  2920  		{
  2921  			`CREATE STATISTICS a ON col1 FROM t WITH OPTIONS THROTTLING 0.1 THROTTLING 0.5`,
  2922  			`at or near "0.5": syntax error: THROTTLING specified multiple times
  2923  DETAIL: source SQL:
  2924  CREATE STATISTICS a ON col1 FROM t WITH OPTIONS THROTTLING 0.1 THROTTLING 0.5
  2925                                                                            ^`,
  2926  		},
  2927  		{
  2928  			`CREATE STATISTICS a ON col1 FROM t WITH OPTIONS AS OF SYSTEM TIME '-1s' THROTTLING 0.1 AS OF SYSTEM TIME '-2s'`,
  2929  			`at or near "EOF": syntax error: AS OF specified multiple times
  2930  DETAIL: source SQL:
  2931  CREATE STATISTICS a ON col1 FROM t WITH OPTIONS AS OF SYSTEM TIME '-1s' THROTTLING 0.1 AS OF SYSTEM TIME '-2s'
  2932                                                                                                                ^`,
  2933  		},
  2934  		{
  2935  			`ALTER PARTITION p OF TABLE tbl@idx CONFIGURE ZONE USING num_replicas = 1`,
  2936  			`at or near "idx": syntax error: index name should not be specified in ALTER PARTITION ... OF TABLE
  2937  DETAIL: source SQL:
  2938  ALTER PARTITION p OF TABLE tbl@idx CONFIGURE ZONE USING num_replicas = 1
  2939                                 ^
  2940  HINT: try ALTER PARTITION ... OF INDEX`,
  2941  		},
  2942  		{
  2943  			`ALTER PARTITION p OF TABLE tbl@* CONFIGURE ZONE USING num_replicas = 1`,
  2944  			`at or near "configure": syntax error: index wildcard unsupported in ALTER PARTITION ... OF TABLE
  2945  DETAIL: source SQL:
  2946  ALTER PARTITION p OF TABLE tbl@* CONFIGURE ZONE USING num_replicas = 1
  2947                                   ^
  2948  HINT: try ALTER PARTITION <partition> OF INDEX <tablename>@*`,
  2949  		},
  2950  		{
  2951  			`SELECT percentile_disc(0.50) WITHIN GROUP (ORDER BY f, s) FROM x;`,
  2952  			`at or near ")": syntax error: multiple ORDER BY clauses are not supported in this function
  2953  DETAIL: source SQL:
  2954  SELECT percentile_disc(0.50) WITHIN GROUP (ORDER BY f, s) FROM x
  2955                                                          ^`,
  2956  		},
  2957  	}
  2958  	for _, d := range testData {
  2959  		t.Run(d.sql, func(t *testing.T) {
  2960  			_, err := parser.Parse(d.sql)
  2961  			if err == nil {
  2962  				t.Errorf("expected error, got nil for:\n%s", d.sql)
  2963  				return
  2964  			}
  2965  			pgerr := pgerror.Flatten(err)
  2966  			msg := pgerr.Message
  2967  			if pgerr.Detail != "" {
  2968  				msg += "\nDETAIL: " + pgerr.Detail
  2969  			}
  2970  			if pgerr.Hint != "" {
  2971  				msg += "\nHINT: " + pgerr.Hint
  2972  			}
  2973  			if msg != d.expected {
  2974  				t.Errorf("%s:\nexpected:\n  %s\n\nbut found:\n  %s", d.sql,
  2975  					strings.ReplaceAll(d.expected, "\n", "\n  "),
  2976  					strings.ReplaceAll(msg, "\n", "\n  "))
  2977  			}
  2978  		})
  2979  	}
  2980  }
  2981  
  2982  func TestParsePanic(t *testing.T) {
  2983  	// Replicates #1801.
  2984  	defer func() {
  2985  		if r := recover(); r != nil {
  2986  			t.Fatal(r)
  2987  		}
  2988  	}()
  2989  	s := "SELECT(F(F(F(F(F(F(F" +
  2990  		"(F(F(F(F(F(F(F(F(F(F" +
  2991  		"(F(F(F(F(F(F(F(F(F(F" +
  2992  		"(F(F(F(F(F(F(F(F(F(F" +
  2993  		"(F(F(F(F(F(F(F(F(F(T" +
  2994  		"(F(F(F(F(F(F(F(F(F(F" +
  2995  		"(F(F(F(F(F(F(F(F(F(F" +
  2996  		"(F(F(F(F(F(F(F(F(F(F" +
  2997  		"(F(F(F(F(F(F(F(F(F(F" +
  2998  		"(F(F(F(F(F(F(F(F(F((" +
  2999  		"F(0"
  3000  	_, err := parser.Parse(s)
  3001  	expected := `at or near "EOF": syntax error`
  3002  	if !testutils.IsError(err, expected) {
  3003  		t.Fatalf("expected %s, but found %v", expected, err)
  3004  	}
  3005  }
  3006  
  3007  func TestParsePrecedence(t *testing.T) {
  3008  	// Precedence levels (highest first):
  3009  	//   0: - ~
  3010  	//   1: * / // %
  3011  	//   2: + -
  3012  	//   3: << >>
  3013  	//   4: &
  3014  	//   5: ^
  3015  	//   6: |
  3016  	//   7: = != > >= < <=
  3017  	//   8: NOT
  3018  	//   9: AND
  3019  	//  10: OR
  3020  
  3021  	unary := func(op tree.UnaryOperator, expr tree.Expr) tree.Expr {
  3022  		return &tree.UnaryExpr{Operator: op, Expr: expr}
  3023  	}
  3024  	binary := func(op tree.BinaryOperator, left, right tree.Expr) tree.Expr {
  3025  		return &tree.BinaryExpr{Operator: op, Left: left, Right: right}
  3026  	}
  3027  	cmp := func(op tree.ComparisonOperator, left, right tree.Expr) tree.Expr {
  3028  		return &tree.ComparisonExpr{Operator: op, Left: left, Right: right}
  3029  	}
  3030  	not := func(expr tree.Expr) tree.Expr {
  3031  		return &tree.NotExpr{Expr: expr}
  3032  	}
  3033  	and := func(left, right tree.Expr) tree.Expr {
  3034  		return &tree.AndExpr{Left: left, Right: right}
  3035  	}
  3036  	or := func(left, right tree.Expr) tree.Expr {
  3037  		return &tree.OrExpr{Left: left, Right: right}
  3038  	}
  3039  	concat := func(left, right tree.Expr) tree.Expr {
  3040  		return &tree.BinaryExpr{Operator: tree.Concat, Left: left, Right: right}
  3041  	}
  3042  	regmatch := func(left, right tree.Expr) tree.Expr {
  3043  		return &tree.ComparisonExpr{Operator: tree.RegMatch, Left: left, Right: right}
  3044  	}
  3045  	regimatch := func(left, right tree.Expr) tree.Expr {
  3046  		return &tree.ComparisonExpr{Operator: tree.RegIMatch, Left: left, Right: right}
  3047  	}
  3048  
  3049  	one := tree.NewNumVal(constant.MakeInt64(1), "1", false /* negative */)
  3050  	minusone := tree.NewNumVal(constant.MakeInt64(1), "1", true /* negative */)
  3051  	two := tree.NewNumVal(constant.MakeInt64(2), "2", false /* negative */)
  3052  	minustwo := tree.NewNumVal(constant.MakeInt64(2), "2", true /* negative */)
  3053  	three := tree.NewNumVal(constant.MakeInt64(3), "3", false /* negative */)
  3054  	a := tree.NewStrVal("a")
  3055  	b := tree.NewStrVal("b")
  3056  	c := tree.NewStrVal("c")
  3057  
  3058  	testData := []struct {
  3059  		sql      string
  3060  		expected tree.Expr
  3061  	}{
  3062  		// Unary plus and complement.
  3063  		{`~-1`, unary(tree.UnaryComplement, minusone)},
  3064  		{`-~1`, unary(tree.UnaryMinus, unary(tree.UnaryComplement, one))},
  3065  
  3066  		// Mul, div, floordiv, mod combined with higher precedence.
  3067  		{`-1*2`, binary(tree.Mult, minusone, two)},
  3068  		{`1*-2`, binary(tree.Mult, one, minustwo)},
  3069  		{`-1/2`, binary(tree.Div, minusone, two)},
  3070  		{`1/-2`, binary(tree.Div, one, minustwo)},
  3071  		{`-1//2`, binary(tree.FloorDiv, minusone, two)},
  3072  		{`1//-2`, binary(tree.FloorDiv, one, minustwo)},
  3073  		{`-1%2`, binary(tree.Mod, minusone, two)},
  3074  		{`1%-2`, binary(tree.Mod, one, minustwo)},
  3075  
  3076  		// Mul, div, floordiv, mod combined with self (left associative).
  3077  		{`1*2*3`, binary(tree.Mult, binary(tree.Mult, one, two), three)},
  3078  		{`1*2/3`, binary(tree.Div, binary(tree.Mult, one, two), three)},
  3079  		{`1/2*3`, binary(tree.Mult, binary(tree.Div, one, two), three)},
  3080  		{`1*2//3`, binary(tree.FloorDiv, binary(tree.Mult, one, two), three)},
  3081  		{`1//2*3`, binary(tree.Mult, binary(tree.FloorDiv, one, two), three)},
  3082  		{`1*2%3`, binary(tree.Mod, binary(tree.Mult, one, two), three)},
  3083  		{`1%2*3`, binary(tree.Mult, binary(tree.Mod, one, two), three)},
  3084  		{`1/2/3`, binary(tree.Div, binary(tree.Div, one, two), three)},
  3085  		{`1/2//3`, binary(tree.FloorDiv, binary(tree.Div, one, two), three)},
  3086  		{`1//2/3`, binary(tree.Div, binary(tree.FloorDiv, one, two), three)},
  3087  		{`1/2%3`, binary(tree.Mod, binary(tree.Div, one, two), three)},
  3088  		{`1%2/3`, binary(tree.Div, binary(tree.Mod, one, two), three)},
  3089  		{`1//2//3`, binary(tree.FloorDiv, binary(tree.FloorDiv, one, two), three)},
  3090  		{`1//2%3`, binary(tree.Mod, binary(tree.FloorDiv, one, two), three)},
  3091  		{`1%2//3`, binary(tree.FloorDiv, binary(tree.Mod, one, two), three)},
  3092  		{`1%2%3`, binary(tree.Mod, binary(tree.Mod, one, two), three)},
  3093  
  3094  		// Binary plus and minus combined with higher precedence.
  3095  		{`1*2+3`, binary(tree.Plus, binary(tree.Mult, one, two), three)},
  3096  		{`1+2*3`, binary(tree.Plus, one, binary(tree.Mult, two, three))},
  3097  		{`1*2-3`, binary(tree.Minus, binary(tree.Mult, one, two), three)},
  3098  		{`1-2*3`, binary(tree.Minus, one, binary(tree.Mult, two, three))},
  3099  
  3100  		// Binary plus and minus combined with self (left associative).
  3101  		{`1+2-3`, binary(tree.Minus, binary(tree.Plus, one, two), three)},
  3102  		{`1-2+3`, binary(tree.Plus, binary(tree.Minus, one, two), three)},
  3103  
  3104  		// Left and right shift combined with higher precedence.
  3105  		{`1<<2+3`, binary(tree.LShift, one, binary(tree.Plus, two, three))},
  3106  		{`1+2<<3`, binary(tree.LShift, binary(tree.Plus, one, two), three)},
  3107  		{`1>>2+3`, binary(tree.RShift, one, binary(tree.Plus, two, three))},
  3108  		{`1+2>>3`, binary(tree.RShift, binary(tree.Plus, one, two), three)},
  3109  
  3110  		// Left and right shift combined with self (left associative).
  3111  		{`1<<2<<3`, binary(tree.LShift, binary(tree.LShift, one, two), three)},
  3112  		{`1<<2>>3`, binary(tree.RShift, binary(tree.LShift, one, two), three)},
  3113  		{`1>>2<<3`, binary(tree.LShift, binary(tree.RShift, one, two), three)},
  3114  		{`1>>2>>3`, binary(tree.RShift, binary(tree.RShift, one, two), three)},
  3115  
  3116  		// Power combined with lower precedence.
  3117  		{`1*2^3`, binary(tree.Mult, one, binary(tree.Pow, two, three))},
  3118  		{`1^2*3`, binary(tree.Mult, binary(tree.Pow, one, two), three)},
  3119  
  3120  		// Bit-and combined with higher precedence.
  3121  		{`1&2<<3`, binary(tree.Bitand, one, binary(tree.LShift, two, three))},
  3122  		{`1<<2&3`, binary(tree.Bitand, binary(tree.LShift, one, two), three)},
  3123  
  3124  		// Bit-and combined with self (left associative)
  3125  		{`1&2&3`, binary(tree.Bitand, binary(tree.Bitand, one, two), three)},
  3126  
  3127  		// Bit-xor combined with higher precedence.
  3128  		{`1#2&3`, binary(tree.Bitxor, one, binary(tree.Bitand, two, three))},
  3129  		{`1&2#3`, binary(tree.Bitxor, binary(tree.Bitand, one, two), three)},
  3130  
  3131  		// Bit-xor combined with self (left associative)
  3132  		{`1#2#3`, binary(tree.Bitxor, binary(tree.Bitxor, one, two), three)},
  3133  
  3134  		// Bit-or combined with higher precedence.
  3135  		{`1|2#3`, binary(tree.Bitor, one, binary(tree.Bitxor, two, three))},
  3136  		{`1#2|3`, binary(tree.Bitor, binary(tree.Bitxor, one, two), three)},
  3137  
  3138  		// Bit-or combined with self (left associative)
  3139  		{`1|2|3`, binary(tree.Bitor, binary(tree.Bitor, one, two), three)},
  3140  
  3141  		// Equals, not-equals, greater-than, greater-than equals, less-than and
  3142  		// less-than equals combined with higher precedence.
  3143  		{`1 = 2|3`, cmp(tree.EQ, one, binary(tree.Bitor, two, three))},
  3144  		{`1|2 = 3`, cmp(tree.EQ, binary(tree.Bitor, one, two), three)},
  3145  		{`1 != 2|3`, cmp(tree.NE, one, binary(tree.Bitor, two, three))},
  3146  		{`1|2 != 3`, cmp(tree.NE, binary(tree.Bitor, one, two), three)},
  3147  		{`1 > 2|3`, cmp(tree.GT, one, binary(tree.Bitor, two, three))},
  3148  		{`1|2 > 3`, cmp(tree.GT, binary(tree.Bitor, one, two), three)},
  3149  		{`1 >= 2|3`, cmp(tree.GE, one, binary(tree.Bitor, two, three))},
  3150  		{`1|2 >= 3`, cmp(tree.GE, binary(tree.Bitor, one, two), three)},
  3151  		{`1 < 2|3`, cmp(tree.LT, one, binary(tree.Bitor, two, three))},
  3152  		{`1|2 < 3`, cmp(tree.LT, binary(tree.Bitor, one, two), three)},
  3153  		{`1 <= 2|3`, cmp(tree.LE, one, binary(tree.Bitor, two, three))},
  3154  		{`1|2 <= 3`, cmp(tree.LE, binary(tree.Bitor, one, two), three)},
  3155  
  3156  		// NOT combined with higher precedence.
  3157  		{`NOT 1 = 2`, not(cmp(tree.EQ, one, two))},
  3158  		{`NOT 1 = NOT 2 = 3`, not(cmp(tree.EQ, one, not(cmp(tree.EQ, two, three))))},
  3159  
  3160  		// NOT combined with self.
  3161  		{`NOT NOT 1 = 2`, not(not(cmp(tree.EQ, one, two)))},
  3162  
  3163  		// AND combined with higher precedence.
  3164  		{`NOT 1 AND 2`, and(not(one), two)},
  3165  		{`1 AND NOT 2`, and(one, not(two))},
  3166  
  3167  		// AND combined with self (left associative).
  3168  		{`1 AND 2 AND 3`, and(and(one, two), three)},
  3169  
  3170  		// OR combined with higher precedence.
  3171  		{`1 AND 2 OR 3`, or(and(one, two), three)},
  3172  		{`1 OR 2 AND 3`, or(one, and(two, three))},
  3173  
  3174  		// OR combined with self (left associative).
  3175  		{`1 OR 2 OR 3`, or(or(one, two), three)},
  3176  
  3177  		// ~ and ~* should both be lower than ||.
  3178  		{`'a' || 'b' ~ 'c'`, regmatch(concat(a, b), c)},
  3179  		{`'a' || 'b' ~* 'c'`, regimatch(concat(a, b), c)},
  3180  
  3181  		// Unary ~ should have highest precedence.
  3182  		{`~1+2`, binary(tree.Plus, unary(tree.UnaryComplement, one), two)},
  3183  	}
  3184  	for _, d := range testData {
  3185  		t.Run(d.sql, func(t *testing.T) {
  3186  			expr, err := parser.ParseExpr(d.sql)
  3187  			if err != nil {
  3188  				t.Fatalf("%s: %v", d.sql, err)
  3189  			}
  3190  			if !reflect.DeepEqual(d.expected, expr) {
  3191  				t.Fatalf("%s: expected %s, but found %s", d.sql, d.expected, expr)
  3192  			}
  3193  		})
  3194  	}
  3195  }
  3196  
  3197  func TestUnimplementedSyntax(t *testing.T) {
  3198  	testData := []struct {
  3199  		sql      string
  3200  		issue    int
  3201  		expected string
  3202  		hint     string
  3203  	}{
  3204  		{`ALTER TABLE a ALTER CONSTRAINT foo`, 31632, `alter constraint`, ``},
  3205  		{`ALTER TABLE a ADD CONSTRAINT foo EXCLUDE USING gist (bar WITH =)`, 46657, `add constraint exclude using`, ``},
  3206  
  3207  		{`CREATE AGGREGATE a`, 0, `create aggregate`, ``},
  3208  		{`CREATE CAST a`, 0, `create cast`, ``},
  3209  		{`CREATE CONSTRAINT TRIGGER a`, 28296, `create constraint`, ``},
  3210  		{`CREATE CONVERSION a`, 0, `create conversion`, ``},
  3211  		{`CREATE DEFAULT CONVERSION a`, 0, `create def conv`, ``},
  3212  		{`CREATE EXTENSION a`, 0, `create extension a`, ``},
  3213  		{`CREATE FOREIGN DATA WRAPPER a`, 0, `create fdw`, ``},
  3214  		{`CREATE FOREIGN TABLE a`, 0, `create foreign table`, ``},
  3215  		{`CREATE FUNCTION a`, 17511, `create`, ``},
  3216  		{`CREATE OR REPLACE FUNCTION a`, 17511, `create`, ``},
  3217  		{`CREATE LANGUAGE a`, 17511, `create language a`, ``},
  3218  		{`CREATE MATERIALIZED VIEW a`, 41649, ``, ``},
  3219  		{`CREATE OPERATOR a`, 0, `create operator`, ``},
  3220  		{`CREATE PUBLICATION a`, 0, `create publication`, ``},
  3221  		{`CREATE RULE a`, 0, `create rule`, ``},
  3222  		{`CREATE SERVER a`, 0, `create server`, ``},
  3223  		{`CREATE SUBSCRIPTION a`, 0, `create subscription`, ``},
  3224  		{`CREATE TEXT SEARCH a`, 7821, `create text`, ``},
  3225  		{`CREATE TRIGGER a`, 28296, `create`, ``},
  3226  
  3227  		{`DROP AGGREGATE a`, 0, `drop aggregate`, ``},
  3228  		{`DROP CAST a`, 0, `drop cast`, ``},
  3229  		{`DROP COLLATION a`, 0, `drop collation`, ``},
  3230  		{`DROP CONVERSION a`, 0, `drop conversion`, ``},
  3231  		{`DROP DOMAIN a`, 27796, `drop`, ``},
  3232  		{`DROP EXTENSION a`, 0, `drop extension a`, ``},
  3233  		{`DROP FOREIGN TABLE a`, 0, `drop foreign table`, ``},
  3234  		{`DROP FOREIGN DATA WRAPPER a`, 0, `drop fdw`, ``},
  3235  		{`DROP FUNCTION a`, 17511, `drop `, ``},
  3236  		{`DROP LANGUAGE a`, 17511, `drop language a`, ``},
  3237  		{`DROP OPERATOR a`, 0, `drop operator`, ``},
  3238  		{`DROP PUBLICATION a`, 0, `drop publication`, ``},
  3239  		{`DROP RULE a`, 0, `drop rule`, ``},
  3240  		{`DROP SCHEMA a`, 26443, `drop`, ``},
  3241  		{`DROP SERVER a`, 0, `drop server`, ``},
  3242  		{`DROP SUBSCRIPTION a`, 0, `drop subscription`, ``},
  3243  		{`DROP TEXT SEARCH a`, 7821, `drop text`, ``},
  3244  		{`DROP TRIGGER a`, 28296, `drop`, ``},
  3245  
  3246  		{`DISCARD PLANS`, 0, `discard plans`, ``},
  3247  		{`DISCARD SEQUENCES`, 0, `discard sequences`, ``},
  3248  		{`DISCARD TEMP`, 0, `discard temp`, ``},
  3249  		{`DISCARD TEMPORARY`, 0, `discard temp`, ``},
  3250  
  3251  		{`SET CONSTRAINTS foo`, 0, `set constraints`, ``},
  3252  		{`SET LOCAL foo = bar`, 32562, ``, ``},
  3253  		{`SET foo FROM CURRENT`, 0, `set from current`, ``},
  3254  
  3255  		{`CREATE UNLOGGED TABLE a(b INT8)`, 0, `create unlogged`, ``},
  3256  
  3257  		{`CREATE TABLE a(x INT[][])`, 32552, ``, ``},
  3258  		{`CREATE TABLE a(x INT[1][2])`, 32552, ``, ``},
  3259  		{`CREATE TABLE a(x INT ARRAY[1][2])`, 32552, ``, ``},
  3260  
  3261  		{`CREATE TABLE a(b INT8) WITH OIDS`, 0, `create table with oids`, ``},
  3262  
  3263  		{`CREATE TABLE a AS SELECT b WITH NO DATA`, 0, `create table as with no data`, ``},
  3264  
  3265  		{`CREATE TABLE a(b INT8 AS (123) VIRTUAL)`, 0, `virtual computed columns`, ``},
  3266  		{`CREATE TABLE a(b INT8 REFERENCES c(x) MATCH PARTIAL`, 20305, `match partial`, ``},
  3267  		{`CREATE TABLE a(b INT8, FOREIGN KEY (b) REFERENCES c(x) MATCH PARTIAL)`, 20305, `match partial`, ``},
  3268  
  3269  		{`CREATE TABLE a(b INT8, FOREIGN KEY (b) REFERENCES c(x) DEFERRABLE)`, 31632, `deferrable`, ``},
  3270  		{`CREATE TABLE a(b INT8, FOREIGN KEY (b) REFERENCES c(x) INITIALLY DEFERRED)`, 31632, `initially deferred`, ``},
  3271  		{`CREATE TABLE a(b INT8, FOREIGN KEY (b) REFERENCES c(x) INITIALLY IMMEDIATE)`, 31632, `initially immediate`, ``},
  3272  		{`CREATE TABLE a(b INT8, FOREIGN KEY (b) REFERENCES c(x) DEFERRABLE INITIALLY DEFERRED)`, 31632, `initially deferred`, ``},
  3273  		{`CREATE TABLE a(b INT8, FOREIGN KEY (b) REFERENCES c(x) DEFERRABLE INITIALLY IMMEDIATE)`, 31632, `initially immediate`, ``},
  3274  		{`CREATE TABLE a(b INT8, UNIQUE (b) DEFERRABLE)`, 31632, `deferrable`, ``},
  3275  		{`CREATE TABLE a(b INT8, CHECK (b > 0) DEFERRABLE)`, 31632, `deferrable`, ``},
  3276  
  3277  		{`CREATE TABLE a (LIKE b INCLUDING COMMENTS)`, 47071, `like table`, ``},
  3278  		{`CREATE TABLE a (LIKE b INCLUDING IDENTITY)`, 47071, `like table`, ``},
  3279  		{`CREATE TABLE a (LIKE b INCLUDING STATISTICS)`, 47071, `like table`, ``},
  3280  		{`CREATE TABLE a (LIKE b INCLUDING STORAGE)`, 47071, `like table`, ``},
  3281  
  3282  		{`CREATE TEMP TABLE a (a int) ON COMMIT DROP`, 46556, `drop`, ``},
  3283  		{`CREATE TEMP TABLE a (a int) ON COMMIT DELETE ROWS`, 46556, `delete rows`, ``},
  3284  		{`CREATE TEMP TABLE IF NOT EXISTS a (a int) ON COMMIT DROP`, 46556, `drop`, ``},
  3285  		{`CREATE TEMP TABLE IF NOT EXISTS a (a int) ON COMMIT DELETE ROWS`, 46556, `delete rows`, ``},
  3286  		{`CREATE TEMP TABLE b AS SELECT a FROM a ON COMMIT DROP`, 46556, `drop`, ``},
  3287  		{`CREATE TEMP TABLE b AS SELECT a FROM a ON COMMIT DELETE ROWS`, 46556, `delete rows`, ``},
  3288  		{`CREATE TEMP TABLE IF NOT EXISTS b AS SELECT a FROM a ON COMMIT DROP`, 46556, `drop`, ``},
  3289  		{`CREATE TEMP TABLE IF NOT EXISTS b AS SELECT a FROM a ON COMMIT DELETE ROWS`, 46556, `delete rows`, ``},
  3290  
  3291  		{`CREATE SEQUENCE a AS DOUBLE PRECISION`, 25110, `FLOAT8`, ``},
  3292  
  3293  		{`CREATE RECURSIVE VIEW a AS SELECT b`, 0, `create recursive view`, ``},
  3294  
  3295  		{`CREATE TYPE a AS (b)`, 27792, ``, ``},
  3296  		{`CREATE TYPE a AS RANGE b`, 27791, ``, ``},
  3297  		{`CREATE TYPE a (b)`, 27793, `base`, ``},
  3298  		{`CREATE TYPE a`, 27793, `shell`, ``},
  3299  		{`CREATE DOMAIN a`, 27796, `create`, ``},
  3300  
  3301  		{`ALTER TYPE t OWNER TO hello`, 48700, `ALTER TYPE OWNER TO`, ``},
  3302  		{`ALTER TYPE t OWNER TO CURRENT_USER`, 48700, `ALTER TYPE OWNER TO`, ``},
  3303  		{`ALTER TYPE t OWNER TO SESSION_USER`, 48700, `ALTER TYPE OWNER TO`, ``},
  3304  		{`ALTER TYPE db.t RENAME ATTRIBUTE foo TO bar`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3305  		{`ALTER TYPE db.s.t ADD ATTRIBUTE foo bar`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3306  		{`ALTER TYPE db.s.t ADD ATTRIBUTE foo bar COLLATE hello`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3307  		{`ALTER TYPE db.s.t ADD ATTRIBUTE foo bar RESTRICT`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3308  		{`ALTER TYPE db.s.t ADD ATTRIBUTE foo bar CASCADE`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3309  		{`ALTER TYPE db.s.t DROP ATTRIBUTE foo`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3310  		{`ALTER TYPE db.s.t DROP ATTRIBUTE foo RESTRICT`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3311  		{`ALTER TYPE db.s.t DROP ATTRIBUTE foo CASCADE`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3312  		{`ALTER TYPE db.s.t ALTER ATTRIBUTE foo TYPE typ`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3313  		{`ALTER TYPE db.s.t ALTER ATTRIBUTE foo TYPE typ COLLATE en`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3314  		{`ALTER TYPE db.s.t ALTER ATTRIBUTE foo TYPE typ COLLATE en CASCADE`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3315  		{`ALTER TYPE db.s.t ALTER ATTRIBUTE foo SET DATA TYPE typ COLLATE en RESTRICT`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3316  		{`ALTER TYPE db.s.t ADD ATTRIBUTE foo bar RESTRICT, DROP ATTRIBUTE foo`, 48701, `ALTER TYPE ATTRIBUTE`, ``},
  3317  
  3318  		{`CREATE INDEX a ON b USING HASH (c)`, 0, `index using hash`, ``},
  3319  		{`CREATE INDEX a ON b USING GIST (c)`, 0, `index using gist`, ``},
  3320  		{`CREATE INDEX a ON b USING SPGIST (c)`, 0, `index using spgist`, ``},
  3321  		{`CREATE INDEX a ON b USING BRIN (c)`, 0, `index using brin`, ``},
  3322  
  3323  		{`CREATE INDEX a ON b(c + d)`, 9682, ``, ``},
  3324  		{`CREATE INDEX a ON b(c[d])`, 9682, ``, ``},
  3325  		{`CREATE INDEX a ON b(foo(c))`, 9682, ``, ``},
  3326  		{`CREATE INDEX a ON b(a NULLS LAST)`, 6224, ``, ``},
  3327  		{`CREATE INDEX a ON b(a ASC NULLS LAST)`, 6224, ``, ``},
  3328  		{`CREATE INDEX a ON b(a DESC NULLS FIRST)`, 6224, ``, ``},
  3329  
  3330  		{`INSERT INTO foo(a, a.b) VALUES (1,2)`, 27792, ``, ``},
  3331  		{`INSERT INTO foo VALUES (1,2) ON CONFLICT ON CONSTRAINT a DO NOTHING`, 28161, ``, ``},
  3332  
  3333  		{`SELECT * FROM ROWS FROM (a(b) AS (d))`, 0, `ROWS FROM with col_def_list`, ``},
  3334  
  3335  		{`SELECT a(b) 'c'`, 0, `a(...) SCONST`, ``},
  3336  		{`SELECT (a,b) OVERLAPS (c,d)`, 0, `overlaps`, ``},
  3337  		{`SELECT UNIQUE (SELECT b)`, 0, `UNIQUE predicate`, ``},
  3338  		{`SELECT GROUPING (a,b,c)`, 0, `d_expr grouping`, ``},
  3339  		{`SELECT a(VARIADIC b)`, 0, `variadic`, ``},
  3340  		{`SELECT a(b, c, VARIADIC b)`, 0, `variadic`, ``},
  3341  		{`SELECT TREAT (a AS INT8)`, 0, `treat`, ``},
  3342  
  3343  		{`SELECT a FROM t ORDER BY a NULLS LAST`, 6224, ``, ``},
  3344  		{`SELECT a FROM t ORDER BY a ASC NULLS LAST`, 6224, ``, ``},
  3345  		{`SELECT a FROM t ORDER BY a DESC NULLS FIRST`, 6224, ``, ``},
  3346  
  3347  		{`CREATE TABLE a(b BOX)`, 21286, `box`, ``},
  3348  		{`CREATE TABLE a(b CIDR)`, 18846, `cidr`, ``},
  3349  		{`CREATE TABLE a(b CIRCLE)`, 21286, `circle`, ``},
  3350  		{`CREATE TABLE a(b LINE)`, 21286, `line`, ``},
  3351  		{`CREATE TABLE a(b LSEG)`, 21286, `lseg`, ``},
  3352  		{`CREATE TABLE a(b MACADDR)`, 0, `macaddr`, ``},
  3353  		{`CREATE TABLE a(b MACADDR8)`, 0, `macaddr8`, ``},
  3354  		{`CREATE TABLE a(b MONEY)`, 0, `money`, ``},
  3355  		{`CREATE TABLE a(b PATH)`, 21286, `path`, ``},
  3356  		{`CREATE TABLE a(b PG_LSN)`, 0, `pg_lsn`, ``},
  3357  		{`CREATE TABLE a(b POINT)`, 21286, `point`, ``},
  3358  		{`CREATE TABLE a(b POLYGON)`, 21286, `polygon`, ``},
  3359  		{`CREATE TABLE a(b TSQUERY)`, 7821, `tsquery`, ``},
  3360  		{`CREATE TABLE a(b TSVECTOR)`, 7821, `tsvector`, ``},
  3361  		{`CREATE TABLE a(b TXID_SNAPSHOT)`, 0, `txid_snapshot`, ``},
  3362  		{`CREATE TABLE a(b XML)`, 0, `xml`, ``},
  3363  
  3364  		{`INSERT INTO a VALUES (1) ON CONFLICT (x) WHERE x > 3 DO NOTHING`, 32557, ``, ``},
  3365  
  3366  		{`UPDATE foo SET (a, a.b) = (1, 2)`, 27792, ``, ``},
  3367  		{`UPDATE foo SET a.b = 1`, 27792, ``, ``},
  3368  		{`UPDATE Foo SET x.y = z`, 27792, ``, ``},
  3369  
  3370  		{`REINDEX INDEX a`, 0, `reindex index`, `CockroachDB does not require reindexing.`},
  3371  		{`REINDEX TABLE a`, 0, `reindex table`, `CockroachDB does not require reindexing.`},
  3372  		{`REINDEX DATABASE a`, 0, `reindex database`, `CockroachDB does not require reindexing.`},
  3373  		{`REINDEX SYSTEM a`, 0, `reindex system`, `CockroachDB does not require reindexing.`},
  3374  
  3375  		{`UPSERT INTO foo(a, a.b) VALUES (1,2)`, 27792, ``, ``},
  3376  	}
  3377  	for _, d := range testData {
  3378  		t.Run(d.sql, func(t *testing.T) {
  3379  			_, err := parser.Parse(d.sql)
  3380  			if err == nil {
  3381  				t.Errorf("%s: expected error, got nil", d.sql)
  3382  				return
  3383  			}
  3384  			if errMsg := err.Error(); !strings.Contains(errMsg, "unimplemented: this syntax") {
  3385  				t.Errorf("%s: expected unimplemented in message, got %q", d.sql, errMsg)
  3386  			}
  3387  			tkeys := errors.GetTelemetryKeys(err)
  3388  			if len(tkeys) == 0 {
  3389  				t.Errorf("%s: expected telemetry key set", d.sql)
  3390  			} else {
  3391  				found := false
  3392  				for _, tk := range tkeys {
  3393  					if strings.Contains(tk, d.expected) {
  3394  						found = true
  3395  						break
  3396  					}
  3397  				}
  3398  				if !found {
  3399  					t.Errorf("%s: expected %q in telemetry keys, got %+v", d.sql, d.expected, tkeys)
  3400  				}
  3401  			}
  3402  			if d.hint != "" {
  3403  				hints := errors.GetAllHints(err)
  3404  				assert.Contains(t, hints, d.hint)
  3405  			}
  3406  			if d.issue != 0 {
  3407  				exp := fmt.Sprintf("syntax.#%d", d.issue)
  3408  				found := false
  3409  				for _, tk := range tkeys {
  3410  					if strings.HasPrefix(tk, exp) {
  3411  						found = true
  3412  						break
  3413  					}
  3414  				}
  3415  				if !found {
  3416  					t.Errorf("%s: expected %q in telemetry keys, got %+v", d.sql, exp, tkeys)
  3417  				}
  3418  
  3419  				exp2 := fmt.Sprintf("issues/%d", d.issue)
  3420  				found = false
  3421  				hints := errors.GetAllHints(err)
  3422  				for _, h := range hints {
  3423  					if strings.HasSuffix(h, exp2) {
  3424  						found = true
  3425  						break
  3426  					}
  3427  				}
  3428  				if !found {
  3429  					t.Errorf("%s: expected %q at end of hint, got %+v", d.sql, exp2, hints)
  3430  				}
  3431  			}
  3432  		})
  3433  	}
  3434  }
  3435  
  3436  // TestParseSQL verifies that Statement.SQL is set correctly.
  3437  func TestParseSQL(t *testing.T) {
  3438  	testData := []struct {
  3439  		in  string
  3440  		exp []string
  3441  	}{
  3442  		{in: ``, exp: nil},
  3443  		{in: `SELECT 1`, exp: []string{`SELECT 1`}},
  3444  		{in: `SELECT 1;`, exp: []string{`SELECT 1`}},
  3445  		{in: `SELECT 1 /* comment */`, exp: []string{`SELECT 1`}},
  3446  		{in: `SELECT 1;SELECT 2`, exp: []string{`SELECT 1`, `SELECT 2`}},
  3447  		{in: `SELECT 1 /* comment */ ;SELECT 2`, exp: []string{`SELECT 1`, `SELECT 2`}},
  3448  		{in: `SELECT 1 /* comment */ ; /* comment */ SELECT 2`, exp: []string{`SELECT 1`, `SELECT 2`}},
  3449  	}
  3450  	var p parser.Parser // Verify that the same parser can be reused.
  3451  	for _, d := range testData {
  3452  		t.Run(d.in, func(t *testing.T) {
  3453  			stmts, err := p.Parse(d.in)
  3454  			if err != nil {
  3455  				t.Fatalf("expected success, but found %s", err)
  3456  			}
  3457  			var res []string
  3458  			for i := range stmts {
  3459  				res = append(res, stmts[i].SQL)
  3460  			}
  3461  			if !reflect.DeepEqual(res, d.exp) {
  3462  				t.Errorf("expected \n%v\n, but found %v", res, d.exp)
  3463  			}
  3464  		})
  3465  	}
  3466  }
  3467  
  3468  // TestParseNumPlaceholders verifies that Statement.NumPlaceholders is set
  3469  // correctly.
  3470  func TestParseNumPlaceholders(t *testing.T) {
  3471  	testData := []struct {
  3472  		in  string
  3473  		exp []int
  3474  	}{
  3475  		{in: ``, exp: nil},
  3476  
  3477  		{in: `SELECT 1`, exp: []int{0}},
  3478  		{in: `SELECT $1`, exp: []int{1}},
  3479  		{in: `SELECT $1 + $1`, exp: []int{1}},
  3480  		{in: `SELECT $1 + $2`, exp: []int{2}},
  3481  		{in: `SELECT $1 + $2 + $1 + $2`, exp: []int{2}},
  3482  		{in: `SELECT $2`, exp: []int{2}},
  3483  		{in: `SELECT $1, $1 + $2, $1 + $2 + $3`, exp: []int{3}},
  3484  
  3485  		{in: `SELECT $1; SELECT $1`, exp: []int{1, 1}},
  3486  		{in: `SELECT $1; SELECT $1 + $2 + $3; SELECT $1 + $2`, exp: []int{1, 3, 2}},
  3487  	}
  3488  
  3489  	var p parser.Parser // Verify that the same parser can be reused.
  3490  	for _, d := range testData {
  3491  		t.Run(d.in, func(t *testing.T) {
  3492  			stmts, err := p.Parse(d.in)
  3493  			if err != nil {
  3494  				t.Fatalf("expected success, but found %s", err)
  3495  			}
  3496  			var res []int
  3497  			for i := range stmts {
  3498  				res = append(res, stmts[i].NumPlaceholders)
  3499  			}
  3500  			if !reflect.DeepEqual(res, d.exp) {
  3501  				t.Errorf("expected \n%v\n, but found %v", res, d.exp)
  3502  			}
  3503  		})
  3504  	}
  3505  }
  3506  
  3507  func TestParseOne(t *testing.T) {
  3508  	_, err := parser.ParseOne("SELECT 1; SELECT 2")
  3509  	if !testutils.IsError(err, "expected 1 statement") {
  3510  		t.Errorf("unexpected error %s", err)
  3511  	}
  3512  }
  3513  
  3514  func BenchmarkParse(b *testing.B) {
  3515  	testCases := []struct {
  3516  		name, query string
  3517  	}{
  3518  		{
  3519  			"simple",
  3520  			`SELECT a FROM t WHERE a = 1`,
  3521  		},
  3522  		{
  3523  			"string",
  3524  			`SELECT a FROM t WHERE a = 'some-string' AND b = 'some-other-string'`,
  3525  		},
  3526  		{
  3527  			"tpcc-delivery",
  3528  			`SELECT no_o_id FROM new_order WHERE no_w_id = $1 AND no_d_id = $2 ORDER BY no_o_id ASC LIMIT 1`,
  3529  		},
  3530  		{
  3531  			"account",
  3532  			`BEGIN;
  3533  			 UPDATE pgbench_accounts SET abalance = abalance + 77 WHERE aid = 5;
  3534  			 SELECT abalance FROM pgbench_accounts WHERE aid = 5;
  3535  			 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (1, 2, 5, 77, CURRENT_TIMESTAMP);
  3536  			 END`,
  3537  		},
  3538  	}
  3539  	for _, tc := range testCases {
  3540  		b.Run(tc.name, func(b *testing.B) {
  3541  			for i := 0; i < b.N; i++ {
  3542  				if _, err := parser.Parse(tc.query); err != nil {
  3543  					b.Fatal(err)
  3544  				}
  3545  			}
  3546  		})
  3547  	}
  3548  }