github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/patches/0005-delete-plpgsql-files.patch (about)

     1  From 6f5dc3ecb62864562a1a715962e4c70d0e19c91e Mon Sep 17 00:00:00 2001
     2  From: Jeremy Yang <jyang@cockroachlabs.com>
     3  Date: Mon, 12 Feb 2024 13:19:27 -0800
     4  Subject: [PATCH] delete plpgsql files
     5  
     6  ---
     7   pkg/sql/plpgsql/parser/lexbase/keywords.go |  356 -----
     8   pkg/sql/plpgsql/parser/lexbase/tokens.go   |  134 --
     9   pkg/sql/plpgsql/parser/lexbase/utils.go    |   12 -
    10   pkg/sql/plpgsql/parser/lexer.go            |  501 ------
    11   pkg/sql/plpgsql/parser/parse.go            |  136 --
    12   pkg/sql/plpgsql/parser/plpgsql.y           | 1647 --------------------
    13   pkg/sql/scanner/plpgsql_scan.go            |  246 ---
    14   7 files changed, 3032 deletions(-)
    15   delete mode 100644 pkg/sql/plpgsql/parser/lexbase/keywords.go
    16   delete mode 100644 pkg/sql/plpgsql/parser/lexbase/tokens.go
    17   delete mode 100644 pkg/sql/plpgsql/parser/lexbase/utils.go
    18   delete mode 100644 pkg/sql/plpgsql/parser/lexer.go
    19   delete mode 100644 pkg/sql/plpgsql/parser/parse.go
    20   delete mode 100644 pkg/sql/plpgsql/parser/plpgsql.y
    21   delete mode 100644 pkg/sql/scanner/plpgsql_scan.go
    22  
    23  diff --git a/pkg/sql/plpgsql/parser/lexbase/keywords.go b/pkg/sql/plpgsql/parser/lexbase/keywords.go
    24  deleted file mode 100644
    25  index 8cd3bc1..0000000
    26  --- a/pkg/sql/plpgsql/parser/lexbase/keywords.go
    27  +++ /dev/null
    28  @@ -1,356 +0,0 @@
    29  -// Code generated by pkg/sql/lexbase/allkeywords. DO NOT EDIT.
    30  -
    31  -package lexbase
    32  -
    33  -var KeywordsCategories = map[string]string{
    34  -"absolute": "U",
    35  -"alias": "U",
    36  -"all": "R",
    37  -"and": "U",
    38  -"array": "U",
    39  -"assert": "U",
    40  -"backward": "U",
    41  -"begin": "R",
    42  -"by": "R",
    43  -"call": "U",
    44  -"case": "R",
    45  -"chain": "U",
    46  -"close": "U",
    47  -"collate": "U",
    48  -"column": "U",
    49  -"column_name": "U",
    50  -"commit": "U",
    51  -"constant": "U",
    52  -"constraint": "U",
    53  -"constraint_name": "U",
    54  -"continue": "U",
    55  -"current": "U",
    56  -"cursor": "U",
    57  -"datatype": "U",
    58  -"debug": "U",
    59  -"declare": "R",
    60  -"default": "U",
    61  -"detail": "U",
    62  -"diagnostics": "U",
    63  -"do": "U",
    64  -"dump": "U",
    65  -"else": "R",
    66  -"elsif": "U",
    67  -"end": "R",
    68  -"end_case": "R",
    69  -"end_if": "R",
    70  -"errcode": "U",
    71  -"error": "U",
    72  -"exception": "U",
    73  -"execute": "R",
    74  -"exit": "U",
    75  -"fetch": "U",
    76  -"first": "U",
    77  -"for": "R",
    78  -"foreach": "R",
    79  -"forward": "U",
    80  -"from": "R",
    81  -"get": "U",
    82  -"hint": "U",
    83  -"if": "R",
    84  -"import": "U",
    85  -"in": "R",
    86  -"info": "U",
    87  -"insert": "U",
    88  -"into": "R",
    89  -"is": "U",
    90  -"last": "U",
    91  -"log": "U",
    92  -"loop": "R",
    93  -"merge": "U",
    94  -"message": "U",
    95  -"message_text": "U",
    96  -"move": "U",
    97  -"next": "U",
    98  -"no": "U",
    99  -"not": "R",
   100  -"notice": "U",
   101  -"no_scroll": "U",
   102  -"null": "R",
   103  -"open": "U",
   104  -"option": "U",
   105  -"or": "R",
   106  -"perform": "U",
   107  -"pg_context": "U",
   108  -"pg_datatype_name": "U",
   109  -"pg_exception_context": "U",
   110  -"pg_exception_detail": "U",
   111  -"pg_exception_hint": "U",
   112  -"print_strict_params": "U",
   113  -"prior": "U",
   114  -"query": "U",
   115  -"raise": "U",
   116  -"relative": "U",
   117  -"return": "U",
   118  -"returned_sqlstate": "U",
   119  -"return_next": "U",
   120  -"return_query": "U",
   121  -"reverse": "U",
   122  -"rollback": "U",
   123  -"rowtype": "U",
   124  -"row_count": "U",
   125  -"schema": "U",
   126  -"schema_name": "U",
   127  -"scroll": "U",
   128  -"slice": "U",
   129  -"sqlstate": "U",
   130  -"stacked": "U",
   131  -"strict": "R",
   132  -"table": "U",
   133  -"table_name": "U",
   134  -"then": "R",
   135  -"to": "R",
   136  -"type": "U",
   137  -"upsert": "U",
   138  -"use_column": "U",
   139  -"use_variable": "U",
   140  -"using": "R",
   141  -"variable_conflict": "U",
   142  -"warning": "U",
   143  -"when": "R",
   144  -"while": "R",
   145  -}
   146  -
   147  -// KeywordNames contains all keywords sorted, so that pg_get_keywords returns
   148  -// deterministic results.
   149  -var KeywordNames = []string{
   150  -"absolute",
   151  -"alias",
   152  -"all",
   153  -"and",
   154  -"array",
   155  -"assert",
   156  -"backward",
   157  -"begin",
   158  -"by",
   159  -"call",
   160  -"case",
   161  -"chain",
   162  -"close",
   163  -"collate",
   164  -"column",
   165  -"column_name",
   166  -"commit",
   167  -"constant",
   168  -"constraint",
   169  -"constraint_name",
   170  -"continue",
   171  -"current",
   172  -"cursor",
   173  -"datatype",
   174  -"debug",
   175  -"declare",
   176  -"default",
   177  -"detail",
   178  -"diagnostics",
   179  -"do",
   180  -"dump",
   181  -"else",
   182  -"elsif",
   183  -"end",
   184  -"end_case",
   185  -"end_if",
   186  -"errcode",
   187  -"error",
   188  -"exception",
   189  -"execute",
   190  -"exit",
   191  -"fetch",
   192  -"first",
   193  -"for",
   194  -"foreach",
   195  -"forward",
   196  -"from",
   197  -"get",
   198  -"hint",
   199  -"if",
   200  -"import",
   201  -"in",
   202  -"info",
   203  -"insert",
   204  -"into",
   205  -"is",
   206  -"last",
   207  -"log",
   208  -"loop",
   209  -"merge",
   210  -"message",
   211  -"message_text",
   212  -"move",
   213  -"next",
   214  -"no",
   215  -"not",
   216  -"notice",
   217  -"no_scroll",
   218  -"null",
   219  -"open",
   220  -"option",
   221  -"or",
   222  -"perform",
   223  -"pg_context",
   224  -"pg_datatype_name",
   225  -"pg_exception_context",
   226  -"pg_exception_detail",
   227  -"pg_exception_hint",
   228  -"print_strict_params",
   229  -"prior",
   230  -"query",
   231  -"raise",
   232  -"relative",
   233  -"return",
   234  -"returned_sqlstate",
   235  -"return_next",
   236  -"return_query",
   237  -"reverse",
   238  -"rollback",
   239  -"rowtype",
   240  -"row_count",
   241  -"schema",
   242  -"schema_name",
   243  -"scroll",
   244  -"slice",
   245  -"sqlstate",
   246  -"stacked",
   247  -"strict",
   248  -"table",
   249  -"table_name",
   250  -"then",
   251  -"to",
   252  -"type",
   253  -"upsert",
   254  -"use_column",
   255  -"use_variable",
   256  -"using",
   257  -"variable_conflict",
   258  -"warning",
   259  -"when",
   260  -"while",
   261  -}
   262  -
   263  -// GetKeywordID returns the lex id of the SQL keyword k or IDENT if k is
   264  -// not a keyword.
   265  -func GetKeywordID(k string) int32 {
   266  -	// The previous implementation generated a map that did a string ->
   267  -	// id lookup. Various ideas were benchmarked and the implementation below
   268  -	// was the fastest of those, between 3% and 10% faster (at parsing, so the
   269  -	// scanning speedup is even more) than the map implementation.
   270  -	switch k {
   271  -	case "absolute": return ABSOLUTE
   272  -	case "alias": return ALIAS
   273  -	case "all": return ALL
   274  -	case "and": return AND
   275  -	case "array": return ARRAY
   276  -	case "assert": return ASSERT
   277  -	case "backward": return BACKWARD
   278  -	case "begin": return BEGIN
   279  -	case "by": return BY
   280  -	case "call": return CALL
   281  -	case "case": return CASE
   282  -	case "chain": return CHAIN
   283  -	case "close": return CLOSE
   284  -	case "collate": return COLLATE
   285  -	case "column": return COLUMN
   286  -	case "column_name": return COLUMN_NAME
   287  -	case "commit": return COMMIT
   288  -	case "constant": return CONSTANT
   289  -	case "constraint": return CONSTRAINT
   290  -	case "constraint_name": return CONSTRAINT_NAME
   291  -	case "continue": return CONTINUE
   292  -	case "current": return CURRENT
   293  -	case "cursor": return CURSOR
   294  -	case "datatype": return DATATYPE
   295  -	case "debug": return DEBUG
   296  -	case "declare": return DECLARE
   297  -	case "default": return DEFAULT
   298  -	case "detail": return DETAIL
   299  -	case "diagnostics": return DIAGNOSTICS
   300  -	case "do": return DO
   301  -	case "dump": return DUMP
   302  -	case "else": return ELSE
   303  -	case "elsif": return ELSIF
   304  -	case "end": return END
   305  -	case "end_case": return END_CASE
   306  -	case "end_if": return END_IF
   307  -	case "errcode": return ERRCODE
   308  -	case "error": return ERROR
   309  -	case "exception": return EXCEPTION
   310  -	case "execute": return EXECUTE
   311  -	case "exit": return EXIT
   312  -	case "fetch": return FETCH
   313  -	case "first": return FIRST
   314  -	case "for": return FOR
   315  -	case "foreach": return FOREACH
   316  -	case "forward": return FORWARD
   317  -	case "from": return FROM
   318  -	case "get": return GET
   319  -	case "hint": return HINT
   320  -	case "if": return IF
   321  -	case "import": return IMPORT
   322  -	case "in": return IN
   323  -	case "info": return INFO
   324  -	case "insert": return INSERT
   325  -	case "into": return INTO
   326  -	case "is": return IS
   327  -	case "last": return LAST
   328  -	case "log": return LOG
   329  -	case "loop": return LOOP
   330  -	case "merge": return MERGE
   331  -	case "message": return MESSAGE
   332  -	case "message_text": return MESSAGE_TEXT
   333  -	case "move": return MOVE
   334  -	case "next": return NEXT
   335  -	case "no": return NO
   336  -	case "not": return NOT
   337  -	case "notice": return NOTICE
   338  -	case "no_scroll": return NO_SCROLL
   339  -	case "null": return NULL
   340  -	case "open": return OPEN
   341  -	case "option": return OPTION
   342  -	case "or": return OR
   343  -	case "perform": return PERFORM
   344  -	case "pg_context": return PG_CONTEXT
   345  -	case "pg_datatype_name": return PG_DATATYPE_NAME
   346  -	case "pg_exception_context": return PG_EXCEPTION_CONTEXT
   347  -	case "pg_exception_detail": return PG_EXCEPTION_DETAIL
   348  -	case "pg_exception_hint": return PG_EXCEPTION_HINT
   349  -	case "print_strict_params": return PRINT_STRICT_PARAMS
   350  -	case "prior": return PRIOR
   351  -	case "query": return QUERY
   352  -	case "raise": return RAISE
   353  -	case "relative": return RELATIVE
   354  -	case "return": return RETURN
   355  -	case "returned_sqlstate": return RETURNED_SQLSTATE
   356  -	case "return_next": return RETURN_NEXT
   357  -	case "return_query": return RETURN_QUERY
   358  -	case "reverse": return REVERSE
   359  -	case "rollback": return ROLLBACK
   360  -	case "rowtype": return ROWTYPE
   361  -	case "row_count": return ROW_COUNT
   362  -	case "schema": return SCHEMA
   363  -	case "schema_name": return SCHEMA_NAME
   364  -	case "scroll": return SCROLL
   365  -	case "slice": return SLICE
   366  -	case "sqlstate": return SQLSTATE
   367  -	case "stacked": return STACKED
   368  -	case "strict": return STRICT
   369  -	case "table": return TABLE
   370  -	case "table_name": return TABLE_NAME
   371  -	case "then": return THEN
   372  -	case "to": return TO
   373  -	case "type": return TYPE
   374  -	case "upsert": return UPSERT
   375  -	case "use_column": return USE_COLUMN
   376  -	case "use_variable": return USE_VARIABLE
   377  -	case "using": return USING
   378  -	case "variable_conflict": return VARIABLE_CONFLICT
   379  -	case "warning": return WARNING
   380  -	case "when": return WHEN
   381  -	case "while": return WHILE
   382  -	default: return IDENT
   383  -	}
   384  -}
   385  diff --git a/pkg/sql/plpgsql/parser/lexbase/tokens.go b/pkg/sql/plpgsql/parser/lexbase/tokens.go
   386  deleted file mode 100644
   387  index 56ac04c..0000000
   388  --- a/pkg/sql/plpgsql/parser/lexbase/tokens.go
   389  +++ /dev/null
   390  @@ -1,134 +0,0 @@
   391  -// Code generated by make. DO NOT EDIT.
   392  -// GENERATED FILE DO NOT EDIT
   393  -
   394  -package lexbase
   395  -
   396  -const IDENT = 57346
   397  -const UIDENT = 57347
   398  -const FCONST = 57348
   399  -const SCONST = 57349
   400  -const USCONST = 57350
   401  -const BCONST = 57351
   402  -const XCONST = 57352
   403  -const ICONST = 57354
   404  -const PARAM = 57355
   405  -const TYPECAST = 57356
   406  -const DOT_DOT = 57357
   407  -const COLON_EQUALS = 57358
   408  -const EQUALS_GREATER = 57359
   409  -const LESS_EQUALS = 57360
   410  -const GREATER_EQUALS = 57361
   411  -const NOT_EQUALS = 57362
   412  -const LESS_LESS = 57363
   413  -const GREATER_GREATER = 57364
   414  -const ABSOLUTE = 57365
   415  -const ALIAS = 57366
   416  -const ALL = 57367
   417  -const AND = 57368
   418  -const ARRAY = 57369
   419  -const ASSERT = 57370
   420  -const BACKWARD = 57371
   421  -const BEGIN = 57372
   422  -const BY = 57373
   423  -const CALL = 57374
   424  -const CASE = 57375
   425  -const CHAIN = 57376
   426  -const CLOSE = 57377
   427  -const COLLATE = 57378
   428  -const COLUMN = 57379
   429  -const COLUMN_NAME = 57380
   430  -const COMMIT = 57381
   431  -const CONSTANT = 57382
   432  -const CONSTRAINT = 57383
   433  -const CONSTRAINT_NAME = 57384
   434  -const CONTINUE = 57385
   435  -const CURRENT = 57386
   436  -const CURSOR = 57387
   437  -const DATATYPE = 57388
   438  -const DEBUG = 57389
   439  -const DECLARE = 57390
   440  -const DEFAULT = 57391
   441  -const DETAIL = 57392
   442  -const DIAGNOSTICS = 57393
   443  -const DO = 57394
   444  -const DUMP = 57395
   445  -const ELSE = 57396
   446  -const ELSIF = 57397
   447  -const END = 57398
   448  -const END_CASE = 57399
   449  -const END_IF = 57400
   450  -const ERRCODE = 57401
   451  -const ERROR = 57402
   452  -const EXCEPTION = 57403
   453  -const EXECUTE = 57404
   454  -const EXIT = 57405
   455  -const FETCH = 57406
   456  -const FIRST = 57407
   457  -const FOR = 57408
   458  -const FOREACH = 57409
   459  -const FORWARD = 57410
   460  -const FROM = 57411
   461  -const GET = 57412
   462  -const HINT = 57413
   463  -const IF = 57414
   464  -const IMPORT = 57415
   465  -const IN = 57416
   466  -const INFO = 57417
   467  -const INSERT = 57418
   468  -const INTO = 57419
   469  -const IS = 57420
   470  -const LAST = 57421
   471  -const LOG = 57422
   472  -const LOOP = 57423
   473  -const MERGE = 57424
   474  -const MESSAGE = 57425
   475  -const MESSAGE_TEXT = 57426
   476  -const MOVE = 57427
   477  -const NEXT = 57428
   478  -const NO = 57429
   479  -const NO_SCROLL = 57430
   480  -const NOT = 57431
   481  -const NOTICE = 57432
   482  -const NULL = 57433
   483  -const OPEN = 57434
   484  -const OPTION = 57435
   485  -const OR = 57436
   486  -const PERFORM = 57437
   487  -const PG_CONTEXT = 57438
   488  -const PG_DATATYPE_NAME = 57439
   489  -const PG_EXCEPTION_CONTEXT = 57440
   490  -const PG_EXCEPTION_DETAIL = 57441
   491  -const PG_EXCEPTION_HINT = 57442
   492  -const PRINT_STRICT_PARAMS = 57443
   493  -const PRIOR = 57444
   494  -const QUERY = 57445
   495  -const RAISE = 57446
   496  -const RELATIVE = 57447
   497  -const RETURN = 57448
   498  -const RETURN_NEXT = 57449
   499  -const RETURN_QUERY = 57450
   500  -const RETURNED_SQLSTATE = 57451
   501  -const REVERSE = 57452
   502  -const ROLLBACK = 57453
   503  -const ROW_COUNT = 57454
   504  -const ROWTYPE = 57455
   505  -const SCHEMA = 57456
   506  -const SCHEMA_NAME = 57457
   507  -const SCROLL = 57458
   508  -const SLICE = 57459
   509  -const SQLSTATE = 57460
   510  -const STACKED = 57461
   511  -const STRICT = 57462
   512  -const TABLE = 57463
   513  -const TABLE_NAME = 57464
   514  -const THEN = 57465
   515  -const TO = 57466
   516  -const TYPE = 57467
   517  -const UPSERT = 57468
   518  -const USE_COLUMN = 57469
   519  -const USE_VARIABLE = 57470
   520  -const USING = 57471
   521  -const VARIABLE_CONFLICT = 57472
   522  -const WARNING = 57473
   523  -const WHEN = 57474
   524  -const WHILE = 57475
   525  diff --git a/pkg/sql/plpgsql/parser/lexbase/utils.go b/pkg/sql/plpgsql/parser/lexbase/utils.go
   526  deleted file mode 100644
   527  index 66596bf..0000000
   528  --- a/pkg/sql/plpgsql/parser/lexbase/utils.go
   529  +++ /dev/null
   530  @@ -1,12 +0,0 @@
   531  -// Copyright 2023 The Cockroach Authors.
   532  -//
   533  -// Use of this software is governed by the Business Source License
   534  -// included in the file licenses/BSL.txt.
   535  -//
   536  -// As of the Change Date specified in that file, in accordance with
   537  -// the Business Source License, use of this software will be governed
   538  -// by the Apache License, Version 2.0, included in the file
   539  -// licenses/APL.txt.
   540  -
   541  -// Package lexbase contains utilities for lexing plpgsql.
   542  -package lexbase
   543  diff --git a/pkg/sql/plpgsql/parser/lexer.go b/pkg/sql/plpgsql/parser/lexer.go
   544  deleted file mode 100644
   545  index 9201b03..0000000
   546  --- a/pkg/sql/plpgsql/parser/lexer.go
   547  +++ /dev/null
   548  @@ -1,501 +0,0 @@
   549  -// Copyright 2023 The Cockroach Authors.
   550  -//
   551  -// Use of this software is governed by the Business Source License
   552  -// included in the file licenses/BSL.txt.
   553  -//
   554  -// As of the Change Date specified in that file, in accordance with
   555  -// the Business Source License, use of this software will be governed
   556  -// by the Apache License, Version 2.0, included in the file
   557  -// licenses/APL.txt.
   558  -
   559  -package parser
   560  -
   561  -import (
   562  -	"strings"
   563  -
   564  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser"
   565  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
   566  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
   567  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/plpgsqltree"
   568  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
   569  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
   570  -	unimp "github.com/cockroachdb/cockroachdb-parser/pkg/util/errorutil/unimplemented"
   571  -	"github.com/cockroachdb/errors"
   572  -)
   573  -
   574  -type lexer struct {
   575  -	in string
   576  -	// tokens contains tokens generated by the scanner.
   577  -	tokens []plpgsqlSymType
   578  -
   579  -	// The type that should be used when an INT or SERIAL is encountered.
   580  -	nakedIntType *types.T
   581  -
   582  -	// lastPos is the position into the tokens slice of the last
   583  -	// token returned by Lex().
   584  -	lastPos int
   585  -
   586  -	stmt *plpgsqltree.Block
   587  -
   588  -	// numPlaceholders is 1 + the highest placeholder index encountered.
   589  -	numPlaceholders int
   590  -	numAnnotations  tree.AnnotationIdx
   591  -
   592  -	lastError error
   593  -
   594  -	parser plpgsqlParser
   595  -}
   596  -
   597  -func (l *lexer) init(sql string, tokens []plpgsqlSymType, nakedIntType *types.T, p plpgsqlParser) {
   598  -	l.in = sql
   599  -	l.tokens = tokens
   600  -	l.lastPos = -1
   601  -	l.stmt = nil
   602  -	l.numPlaceholders = 0
   603  -	l.numAnnotations = 0
   604  -	l.lastError = nil
   605  -	l.nakedIntType = nakedIntType
   606  -	l.parser = p
   607  -}
   608  -
   609  -// cleanup is used to avoid holding on to memory unnecessarily (for the cases
   610  -// where we reuse a scanner).
   611  -func (l *lexer) cleanup() {
   612  -	l.tokens = nil
   613  -	l.stmt = nil
   614  -	l.lastError = nil
   615  -}
   616  -
   617  -// Lex lexes a token from input.
   618  -// to push the tokens back (move l.pos back).
   619  -func (l *lexer) Lex(lval *plpgsqlSymType) int {
   620  -	l.lastPos++
   621  -	// The core lexing takes place in the scanner. Here we do a small bit of post
   622  -	// processing of the lexical tokens so that the grammar only requires
   623  -	// one-token lookahead despite SQL requiring multi-token lookahead in some
   624  -	// cases. These special cases are handled below and the returned tokens are
   625  -	// adjusted to reflect the lookahead (LA) that occurred.
   626  -	if l.lastPos >= len(l.tokens) {
   627  -		lval.id = 0
   628  -		lval.pos = int32(len(l.in))
   629  -		lval.str = "EOF"
   630  -		return 0
   631  -	}
   632  -	*lval = l.tokens[l.lastPos]
   633  -
   634  -	switch lval.id {
   635  -	case RETURN:
   636  -		nextToken := plpgsqlSymType{}
   637  -		if l.lastPos+1 < len(l.tokens) {
   638  -			nextToken = l.tokens[l.lastPos+1]
   639  -		}
   640  -		switch nextToken.id {
   641  -		case NEXT:
   642  -			lval.id = RETURN_NEXT
   643  -		case QUERY:
   644  -			lval.id = RETURN_QUERY
   645  -		}
   646  -	case END:
   647  -		nextToken := plpgsqlSymType{}
   648  -		if l.lastPos+1 < len(l.tokens) {
   649  -			nextToken = l.tokens[l.lastPos+1]
   650  -		}
   651  -		switch nextToken.id {
   652  -		case IF:
   653  -			lval.id = END_IF
   654  -		case CASE:
   655  -			lval.id = END_CASE
   656  -		}
   657  -	case NO:
   658  -		nextToken := plpgsqlSymType{}
   659  -		if l.lastPos+1 < len(l.tokens) {
   660  -			nextToken = l.tokens[l.lastPos+1]
   661  -		}
   662  -		switch nextToken.id {
   663  -		case SCROLL:
   664  -			lval.id = NO_SCROLL
   665  -		}
   666  -	}
   667  -
   668  -	return int(lval.id)
   669  -}
   670  -
   671  -// MakeExecSqlStmt makes an Execute node.
   672  -func (l *lexer) MakeExecSqlStmt() (*plpgsqltree.Execute, error) {
   673  -	if l.parser.Lookahead() != -1 {
   674  -		// Push back the lookahead token so that it can be included.
   675  -		l.PushBack(1)
   676  -	}
   677  -	// Push back the first token so that it's included in the SQL string.
   678  -	l.PushBack(1)
   679  -	startPos, endPos, _, err := l.readSQLConstruct(false /* isExpr */, ';')
   680  -	if err != nil {
   681  -		return nil, err
   682  -	}
   683  -	// Move past the semicolon.
   684  -	l.lastPos++
   685  -
   686  -	var haveInto, haveStrict bool
   687  -	var intoStartPos, intoEndPos int
   688  -	var target []plpgsqltree.Variable
   689  -	firstTok := l.tokens[startPos]
   690  -	tok := firstTok
   691  -	for pos := startPos; pos < endPos; pos++ {
   692  -		prevTok := tok
   693  -		tok = l.tokens[pos]
   694  -		if tok.id == INTO {
   695  -			if prevTok.id == INSERT || prevTok.id == UPSERT ||
   696  -				prevTok.id == MERGE || firstTok.id == IMPORT {
   697  -				// INSERT INTO, UPSERT INTO, MERGE INTO, and IMPORT ... INTO are not
   698  -				// INTO-targets.
   699  -				continue
   700  -			}
   701  -			if haveInto {
   702  -				return nil, errors.New("INTO specified more than once")
   703  -			}
   704  -			haveInto = true
   705  -			intoStartPos = pos
   706  -			pos++
   707  -			if pos+1 < endPos && l.tokens[pos].id == STRICT {
   708  -				haveStrict = true
   709  -				pos++
   710  -			}
   711  -			// Read in one or more comma-separated variables as the INTO target.
   712  -			for ; pos < endPos; pos += 2 {
   713  -				tok = l.tokens[pos]
   714  -				if tok.id != IDENT {
   715  -					return nil, errors.Newf("\"%s\" is not a scalar variable", tok.str)
   716  -				}
   717  -				variable := plpgsqltree.Variable(strings.TrimSpace(l.getStr(pos, pos+1)))
   718  -				target = append(target, variable)
   719  -				if pos+1 == endPos || l.tokens[pos+1].id != ',' {
   720  -					// This is the end of the target list.
   721  -					break
   722  -				}
   723  -			}
   724  -			intoEndPos = pos + 1
   725  -		}
   726  -	}
   727  -
   728  -	var sql string
   729  -	if haveInto {
   730  -		sql = l.getStr(startPos, intoStartPos) + l.getStr(intoEndPos, endPos)
   731  -	} else {
   732  -		sql = l.getStr(startPos, endPos)
   733  -	}
   734  -	sqlStmt, err := parser.ParseOne(sql)
   735  -	if err != nil {
   736  -		return nil, err
   737  -	}
   738  -
   739  -	// Note: PG disallows directly writing SQL statements that return rows, like
   740  -	// a SELECT or a mutation with RETURNING. It is difficult to determine this
   741  -	// for all possible statements, and execution is able to handle it, so we
   742  -	// allow SQL statements that return rows.
   743  -	if target != nil && sqlStmt.AST.StatementReturnType() != tree.Rows {
   744  -		return nil, pgerror.New(pgcode.Syntax, "INTO used with a command that cannot return data")
   745  -	}
   746  -	return &plpgsqltree.Execute{
   747  -		SqlStmt: sqlStmt.AST,
   748  -		Strict:  haveStrict,
   749  -		Target:  target,
   750  -	}, nil
   751  -}
   752  -
   753  -func (l *lexer) MakeDynamicExecuteStmt() (*plpgsqltree.DynamicExecute, error) {
   754  -	cmdStr, _, err := l.ReadSqlStatement(INTO, USING, ';')
   755  -	if err != nil {
   756  -		return nil, err
   757  -	}
   758  -	ret := &plpgsqltree.DynamicExecute{
   759  -		Query: cmdStr,
   760  -	}
   761  -
   762  -	var lval plpgsqlSymType
   763  -	l.Lex(&lval)
   764  -	for {
   765  -		if lval.id == INTO {
   766  -			if ret.Into {
   767  -				return nil, errors.New("multiple INTO keywords")
   768  -			}
   769  -			ret.Into = true
   770  -			nextTok := l.Peek()
   771  -			if nextTok.id == int32(STRICT) {
   772  -				l.Lex(&lval)
   773  -				ret.Strict = true
   774  -			}
   775  -			// TODO we need to read each "INTO" variable name instead of just a
   776  -			// string.
   777  -			_, _, err = l.ReadSqlExpr(USING, ';')
   778  -			if err != nil {
   779  -				return nil, err
   780  -			}
   781  -			l.Lex(&lval)
   782  -		} else if lval.id == USING {
   783  -			if ret.Params != nil {
   784  -				return nil, errors.New("multiple USING keywords")
   785  -			}
   786  -			ret.Params = make([]plpgsqltree.Expr, 0)
   787  -			for {
   788  -				_, _, err = l.ReadSqlExpr(',', ';', INTO)
   789  -				if err != nil {
   790  -					return nil, err
   791  -				}
   792  -				ret.Params = append(ret.Params, nil)
   793  -				l.Lex(&lval)
   794  -				if lval.id == ';' {
   795  -					break
   796  -				}
   797  -			}
   798  -		} else if lval.id == ';' {
   799  -			break
   800  -		} else {
   801  -			return nil, errors.Newf("unexpected token: %s", lval.id)
   802  -		}
   803  -	}
   804  -
   805  -	return ret, nil
   806  -}
   807  -
   808  -func (l *lexer) readSQLConstruct(
   809  -	isExpr bool, terminator1 int, terminators ...int,
   810  -) (startPos, endPos, terminatorMet int, err error) {
   811  -	if l.parser.Lookahead() != -1 {
   812  -		// Push back the lookahead token so that it can be included.
   813  -		l.PushBack(1)
   814  -	}
   815  -	parenLevel := 0
   816  -	startPos = l.lastPos + 1
   817  -	for l.lastPos < len(l.tokens) {
   818  -		tok := l.Peek()
   819  -		if int(tok.id) == terminator1 && parenLevel == 0 {
   820  -			terminatorMet = terminator1
   821  -			break
   822  -		}
   823  -		for _, term := range terminators {
   824  -			if int(tok.id) == term && parenLevel == 0 {
   825  -				terminatorMet = term
   826  -			}
   827  -		}
   828  -		if terminatorMet != 0 {
   829  -			break
   830  -		}
   831  -		if tok.id == '(' || tok.id == '[' {
   832  -			parenLevel++
   833  -		} else if tok.id == ')' || tok.id == ']' {
   834  -			parenLevel--
   835  -			if parenLevel < 0 {
   836  -				return 0, 0, 0, errors.New("mismatched parentheses")
   837  -			}
   838  -		}
   839  -		l.lastPos++
   840  -	}
   841  -	if parenLevel != 0 {
   842  -		return 0, 0, 0, errors.New("mismatched parentheses")
   843  -	}
   844  -	endPos = l.lastPos + 1
   845  -	if endPos > len(l.tokens) {
   846  -		endPos = len(l.tokens)
   847  -	}
   848  -	if endPos <= startPos {
   849  -		if isExpr {
   850  -			return 0, 0, 0, errors.New("missing expression")
   851  -		} else {
   852  -			return 0, 0, 0, errors.New("missing SQL statement")
   853  -		}
   854  -	}
   855  -	return startPos, endPos, terminatorMet, nil
   856  -}
   857  -
   858  -func (l *lexer) MakeFetchOrMoveStmt(isMove bool) (plpgsqltree.Statement, error) {
   859  -	if l.parser.Lookahead() != -1 {
   860  -		// Push back the lookahead token so that it can be included.
   861  -		l.PushBack(1)
   862  -	}
   863  -	prefix := "FETCH "
   864  -	if isMove {
   865  -		prefix = "MOVE "
   866  -	}
   867  -	sqlStr, terminator, err := l.ReadSqlStatement(INTO, ';')
   868  -	if err != nil {
   869  -		return nil, err
   870  -	}
   871  -	sqlStr = prefix + sqlStr
   872  -	sqlStmt, err := parser.ParseOne(sqlStr)
   873  -	if err != nil {
   874  -		return nil, err
   875  -	}
   876  -	var cursor tree.CursorStmt
   877  -	switch t := sqlStmt.AST.(type) {
   878  -	case *tree.FetchCursor:
   879  -		cursor = t.CursorStmt
   880  -	case *tree.MoveCursor:
   881  -		cursor = t.CursorStmt
   882  -	default:
   883  -		return nil, errors.Newf("invalid FETCH or MOVE syntax")
   884  -	}
   885  -	var target []plpgsqltree.Variable
   886  -	if !isMove {
   887  -		if terminator != INTO {
   888  -			return nil, errors.Newf("invalid syntax for FETCH")
   889  -		}
   890  -		// Read past the INTO.
   891  -		l.lastPos++
   892  -		startPos, endPos, _, err := l.readSQLConstruct(true /* isExpr */, ';')
   893  -		if err != nil {
   894  -			return nil, err
   895  -		}
   896  -		for pos := startPos; pos < endPos; pos += 2 {
   897  -			tok := l.tokens[pos]
   898  -			if tok.id != IDENT {
   899  -				return nil, errors.Newf("\"%s\" is not a scalar variable", tok.str)
   900  -			}
   901  -			if pos+1 != endPos && l.tokens[pos+1].id != ',' {
   902  -				return nil, errors.Newf("expected INTO target to be a comma-separated list")
   903  -			}
   904  -			variable := plpgsqltree.Variable(strings.TrimSpace(l.getStr(pos, pos+1)))
   905  -			target = append(target, variable)
   906  -		}
   907  -		if len(target) == 0 {
   908  -			return nil, errors.Newf("expected INTO target")
   909  -		}
   910  -	}
   911  -	// Move past the semicolon.
   912  -	l.lastPos++
   913  -	return &plpgsqltree.Fetch{
   914  -		Cursor: cursor,
   915  -		Target: target,
   916  -		IsMove: isMove,
   917  -	}, nil
   918  -}
   919  -
   920  -func (l *lexer) ReadSqlExpr(
   921  -	terminator1 int, terminators ...int,
   922  -) (sqlStr string, terminatorMet int, err error) {
   923  -	var startPos, endPos int
   924  -	startPos, endPos, terminatorMet, err = l.readSQLConstruct(
   925  -		true /* isExpr */, terminator1, terminators...,
   926  -	)
   927  -	return l.getStr(startPos, endPos), terminatorMet, err
   928  -}
   929  -
   930  -func (l *lexer) ReadSqlStatement(
   931  -	terminator1 int, terminators ...int,
   932  -) (sqlStr string, terminatorMet int, err error) {
   933  -	var startPos, endPos int
   934  -	startPos, endPos, terminatorMet, err = l.readSQLConstruct(
   935  -		false /* isExpr */, terminator1, terminators...,
   936  -	)
   937  -	return l.getStr(startPos, endPos), terminatorMet, err
   938  -}
   939  -
   940  -func (l *lexer) getStr(startPos, endPos int) string {
   941  -	if endPos <= startPos {
   942  -		return ""
   943  -	}
   944  -	end := len(l.in)
   945  -	if endPos < len(l.tokens) {
   946  -		end = int(l.tokens[endPos].Pos())
   947  -	}
   948  -	start := int(l.tokens[startPos].Pos())
   949  -	return l.in[start:end]
   950  -}
   951  -
   952  -// Peek peeks
   953  -func (l *lexer) Peek() plpgsqlSymType {
   954  -	if l.lastPos+1 < len(l.tokens) {
   955  -		return l.tokens[l.lastPos+1]
   956  -	}
   957  -	return plpgsqlSymType{}
   958  -}
   959  -
   960  -// PushBack rewinds the lexer by n tokens.
   961  -func (l *lexer) PushBack(n int) {
   962  -	if n < 0 {
   963  -		panic(errors.AssertionFailedf("negative n provided to PushBack"))
   964  -	}
   965  -	l.lastPos -= n
   966  -	if l.lastPos < -1 {
   967  -		// Return to the initialized state.
   968  -		l.lastPos = -1
   969  -	}
   970  -	if n >= 1 {
   971  -		// Invalidate the parser lookahead token.
   972  -		l.parser.(*plpgsqlParserImpl).char = -1
   973  -	}
   974  -}
   975  -
   976  -func (l *lexer) lastToken() plpgsqlSymType {
   977  -	if l.lastPos < 0 {
   978  -		return plpgsqlSymType{}
   979  -	}
   980  -
   981  -	if l.lastPos >= len(l.tokens) {
   982  -		return plpgsqlSymType{
   983  -			id:  0,
   984  -			pos: int32(len(l.in)),
   985  -			str: "EOF",
   986  -		}
   987  -	}
   988  -	return l.tokens[l.lastPos]
   989  -}
   990  -
   991  -// SetStmt is called from the parser when the statement is constructed.
   992  -func (l *lexer) SetStmt(stmt plpgsqltree.Statement) {
   993  -	l.stmt = stmt.(*plpgsqltree.Block)
   994  -}
   995  -
   996  -// setErr is called from parsing action rules to register an error observed
   997  -// while running the action. That error becomes the actual "cause" of the
   998  -// syntax error.
   999  -func (l *lexer) setErr(err error) {
  1000  -	err = pgerror.WithCandidateCode(err, pgcode.Syntax)
  1001  -	l.lastError = err
  1002  -	lastTok := l.lastToken()
  1003  -	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
  1004  -}
  1005  -
  1006  -func (l *lexer) Error(e string) {
  1007  -	e = strings.TrimPrefix(e, "syntax error: ") // we'll add it again below.
  1008  -	err := pgerror.WithCandidateCode(errors.Newf("%s", e), pgcode.Syntax)
  1009  -	lastTok := l.lastToken()
  1010  -	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, err, l.in)
  1011  -}
  1012  -
  1013  -// Unimplemented wraps Error, setting lastUnimplementedError.
  1014  -func (l *lexer) Unimplemented(feature string) {
  1015  -	l.lastError = unimp.New(feature, "this syntax")
  1016  -	lastTok := l.lastToken()
  1017  -	l.lastError = parser.PopulateErrorDetails(lastTok.id, lastTok.str, lastTok.pos, l.lastError, l.in)
  1018  -	l.lastError = &tree.UnsupportedError{
  1019  -		Err:         l.lastError,
  1020  -		FeatureName: feature,
  1021  -	}
  1022  -}
  1023  -
  1024  -func (l *lexer) GetTypeFromValidSQLSyntax(sqlStr string) (tree.ResolvableTypeReference, error) {
  1025  -	return parser.GetTypeFromValidSQLSyntax(sqlStr)
  1026  -}
  1027  -
  1028  -func (l *lexer) ParseExpr(sqlStr string) (plpgsqltree.Expr, error) {
  1029  -	// Use ParseExprs instead of ParseExpr in order to correctly handle the case
  1030  -	// when multiple expressions are incorrectly passed.
  1031  -	exprs, err := parser.ParseExprs([]string{sqlStr})
  1032  -	if err != nil {
  1033  -		return nil, err
  1034  -	}
  1035  -	if len(exprs) != 1 {
  1036  -		return nil, pgerror.Newf(pgcode.Syntax, "query returned %d columns", len(exprs))
  1037  -	}
  1038  -	return exprs[0], nil
  1039  -}
  1040  -
  1041  -func checkLoopLabels(start, end string) error {
  1042  -	if start == "" && end != "" {
  1043  -		return errors.Newf("end label \"%s\" specified for unlabeled block", end)
  1044  -	}
  1045  -	if end != "" && start != end {
  1046  -		return errors.Newf("end label \"%s\" differs from block's label \"%s\"", end, start)
  1047  -	}
  1048  -	return nil
  1049  -}
  1050  diff --git a/pkg/sql/plpgsql/parser/parse.go b/pkg/sql/plpgsql/parser/parse.go
  1051  deleted file mode 100644
  1052  index 520830a..0000000
  1053  --- a/pkg/sql/plpgsql/parser/parse.go
  1054  +++ /dev/null
  1055  @@ -1,136 +0,0 @@
  1056  -// Copyright 2023 The Cockroach Authors.
  1057  -//
  1058  -// Use of this software is governed by the Business Source License
  1059  -// included in the file licenses/BSL.txt.
  1060  -//
  1061  -// As of the Change Date specified in that file, in accordance with
  1062  -// the Business Source License, use of this software will be governed
  1063  -// by the Apache License, Version 2.0, included in the file
  1064  -// licenses/APL.txt.
  1065  -
  1066  -// Package parser exposes a parser for plpgsql.
  1067  -package parser
  1068  -
  1069  -import (
  1070  -	"go/constant"
  1071  -
  1072  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/parser/statements"
  1073  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/scanner"
  1074  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/sem/tree"
  1075  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
  1076  -	"github.com/cockroachdb/errors"
  1077  -)
  1078  -
  1079  -func init() {
  1080  -	scanner.NewNumValFn = func(a constant.Value, s string, b bool) interface{} { return tree.NewNumVal(a, s, b) }
  1081  -	scanner.NewPlaceholderFn = func(s string) (interface{}, error) { return tree.NewPlaceholder(s) }
  1082  -}
  1083  -
  1084  -// Parser wraps a scanner, parser and other utilities present in the parser
  1085  -// package.
  1086  -type Parser struct {
  1087  -	scanner    scanner.PLpgSQLScanner
  1088  -	lexer      lexer
  1089  -	parserImpl plpgsqlParserImpl
  1090  -	tokBuf     [8]plpgsqlSymType
  1091  -}
  1092  -
  1093  -// INT8 is the historical interpretation of INT. This should be left
  1094  -// alone in the future, since there are many sql fragments stored
  1095  -// in various descriptors. Any user input that was created after
  1096  -// INT := INT4 will simply use INT4 in any resulting code.
  1097  -var defaultNakedIntType = types.Int
  1098  -
  1099  -// Parse parses the sql and returns a list of statements.
  1100  -func (p *Parser) Parse(sql string) (statements.PLpgStatement, error) {
  1101  -	return p.parseWithDepth(1, sql, defaultNakedIntType)
  1102  -}
  1103  -
  1104  -func (p *Parser) scanFnBlock() (sql string, tokens []plpgsqlSymType, done bool) {
  1105  -	var lval plpgsqlSymType
  1106  -	tokens = p.tokBuf[:0]
  1107  -
  1108  -	// Scan the first token.
  1109  -	p.scanner.Scan(&lval)
  1110  -	if lval.id == 0 {
  1111  -		return "", nil, true
  1112  -	}
  1113  -
  1114  -	startPos := lval.pos
  1115  -	// We make the resulting token positions match the returned string.
  1116  -	lval.pos = 0
  1117  -	tokens = append(tokens, lval)
  1118  -	for {
  1119  -		if lval.id == ERROR {
  1120  -			return p.scanner.In()[startPos:], tokens, true
  1121  -		}
  1122  -		// Reset the plpgsqlSymType struct before scanning.
  1123  -		lval = plpgsqlSymType{}
  1124  -		posBeforeScan := p.scanner.Pos()
  1125  -		p.scanner.Scan(&lval)
  1126  -		if lval.id == 0 {
  1127  -			return p.scanner.In()[startPos:posBeforeScan], tokens, (lval.id == 0)
  1128  -		}
  1129  -		lval.pos -= startPos
  1130  -		tokens = append(tokens, lval)
  1131  -	}
  1132  -}
  1133  -
  1134  -func (p *Parser) parseWithDepth(
  1135  -	depth int, plpgsql string, nakedIntType *types.T,
  1136  -) (statements.PLpgStatement, error) {
  1137  -	p.scanner.Init(plpgsql)
  1138  -	defer p.scanner.Cleanup()
  1139  -	sql, tokens, done := p.scanFnBlock()
  1140  -	stmt, err := p.parse(depth+1, sql, tokens, nakedIntType)
  1141  -	if err != nil {
  1142  -		return statements.PLpgStatement{}, err
  1143  -	}
  1144  -	if !done {
  1145  -		return statements.PLpgStatement{}, errors.AssertionFailedf("invalid plpgsql function: %s", plpgsql)
  1146  -	}
  1147  -	return stmt, nil
  1148  -}
  1149  -
  1150  -// parse parses a statement from the given scanned tokens.
  1151  -func (p *Parser) parse(
  1152  -	depth int, sql string, tokens []plpgsqlSymType, nakedIntType *types.T,
  1153  -) (statements.PLpgStatement, error) {
  1154  -	p.lexer.init(sql, tokens, nakedIntType, &p.parserImpl)
  1155  -	defer p.lexer.cleanup()
  1156  -	if p.parserImpl.Parse(&p.lexer) != 0 {
  1157  -		if p.lexer.lastError == nil {
  1158  -			// This should never happen -- there should be an error object
  1159  -			// every time Parse() returns nonzero. We're just playing safe
  1160  -			// here.
  1161  -			p.lexer.Error("syntax error")
  1162  -		}
  1163  -		err := p.lexer.lastError
  1164  -
  1165  -		// Compatibility with 19.1 telemetry: prefix the telemetry keys
  1166  -		// with the "syntax." prefix.
  1167  -		// TODO(knz): move the auto-prefixing of feature names to a
  1168  -		// higher level in the call stack.
  1169  -		tkeys := errors.GetTelemetryKeys(err)
  1170  -		if len(tkeys) > 0 {
  1171  -			for i := range tkeys {
  1172  -				tkeys[i] = "syntax." + tkeys[i]
  1173  -			}
  1174  -			err = errors.WithTelemetry(err, tkeys...)
  1175  -		}
  1176  -
  1177  -		return statements.PLpgStatement{}, err
  1178  -	}
  1179  -	return statements.PLpgStatement{
  1180  -		AST:             p.lexer.stmt,
  1181  -		SQL:             sql,
  1182  -		NumPlaceholders: p.lexer.numPlaceholders,
  1183  -		NumAnnotations:  p.lexer.numAnnotations,
  1184  -	}, nil
  1185  -}
  1186  -
  1187  -// Parse parses a sql statement string and returns a list of Statements.
  1188  -func Parse(sql string) (statements.PLpgStatement, error) {
  1189  -	var p Parser
  1190  -	return p.parseWithDepth(1, sql, defaultNakedIntType)
  1191  -}
  1192  diff --git a/pkg/sql/plpgsql/parser/plpgsql.y b/pkg/sql/plpgsql/parser/plpgsql.y
  1193  deleted file mode 100644
  1194  index 8ee4069..0000000
  1195  --- a/pkg/sql/plpgsql/parser/plpgsql.y
  1196  +++ /dev/null
  1197  @@ -1,1647 +0,0 @@
  1198  -%{
  1199  -package parser
  1200  -
  1201  -import (
  1202  -  "github.com/cockroachdb/cockroach/pkg/sql/parser"
  1203  -  "github.com/cockroachdb/cockroach/pkg/sql/scanner"
  1204  -  "github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
  1205  -  "github.com/cockroachdb/cockroach/pkg/sql/sem/plpgsqltree"
  1206  -  "github.com/cockroachdb/errors"
  1207  -  "github.com/cockroachdb/redact"
  1208  -)
  1209  -%}
  1210  -
  1211  -%{
  1212  -func setErr(plpgsqllex plpgsqlLexer, err error) int {
  1213  -    plpgsqllex.(*lexer).setErr(err)
  1214  -    return 1
  1215  -}
  1216  -
  1217  -func unimplemented(plpgsqllex plpgsqlLexer, feature string) int {
  1218  -    plpgsqllex.(*lexer).Unimplemented(feature)
  1219  -    return 1
  1220  -}
  1221  -
  1222  -//functions to cast plpgsqlSymType/sqlSymUnion to other types.
  1223  -var _ scanner.ScanSymType = &plpgsqlSymType{}
  1224  -
  1225  -func (s *plpgsqlSymType) ID() int32 {
  1226  -  return s.id
  1227  -}
  1228  -
  1229  -func (s *plpgsqlSymType) SetID(id int32) {
  1230  -  s.id = id
  1231  -}
  1232  -
  1233  -func (s *plpgsqlSymType) Pos() int32 {
  1234  -  return s.pos
  1235  -}
  1236  -
  1237  -func (s *plpgsqlSymType) SetPos(pos int32) {
  1238  -  s.pos = pos
  1239  -}
  1240  -
  1241  -func (s *plpgsqlSymType) Str() string {
  1242  -  return s.str
  1243  -}
  1244  -
  1245  -func (s *plpgsqlSymType) SetStr(str string) {
  1246  -  s.str = str
  1247  -}
  1248  -
  1249  -func (s *plpgsqlSymType) UnionVal() interface{} {
  1250  -  return s.union.val
  1251  -}
  1252  -
  1253  -func (s *plpgsqlSymType) SetUnionVal(val interface{}) {
  1254  -  s.union.val = val
  1255  -}
  1256  -
  1257  -func (s *plpgsqlSymType) plpgsqlScanSymType() {}
  1258  -
  1259  -type plpgsqlSymUnion struct {
  1260  -    val interface{}
  1261  -}
  1262  -
  1263  -func (u *plpgsqlSymUnion) block() *plpgsqltree.Block {
  1264  -    return u.val.(*plpgsqltree.Block)
  1265  -}
  1266  -
  1267  -func (u *plpgsqlSymUnion) caseWhen() *plpgsqltree.CaseWhen {
  1268  -    return u.val.(*plpgsqltree.CaseWhen)
  1269  -}
  1270  -
  1271  -func (u *plpgsqlSymUnion) caseWhens() []*plpgsqltree.CaseWhen {
  1272  -    return u.val.([]*plpgsqltree.CaseWhen)
  1273  -}
  1274  -
  1275  -func (u *plpgsqlSymUnion) statement() plpgsqltree.Statement {
  1276  -    return u.val.(plpgsqltree.Statement)
  1277  -}
  1278  -
  1279  -func (u *plpgsqlSymUnion) statements() []plpgsqltree.Statement {
  1280  -    return u.val.([]plpgsqltree.Statement)
  1281  -}
  1282  -
  1283  -func (u *plpgsqlSymUnion) int32() int32 {
  1284  -    return u.val.(int32)
  1285  -}
  1286  -
  1287  -func (u *plpgsqlSymUnion) uint32() uint32 {
  1288  -    return u.val.(uint32)
  1289  -}
  1290  -
  1291  -func (u *plpgsqlSymUnion) bool() bool {
  1292  -    return u.val.(bool)
  1293  -}
  1294  -
  1295  -func (u *plpgsqlSymUnion) numVal() *tree.NumVal {
  1296  -    return u.val.(*tree.NumVal)
  1297  -}
  1298  -
  1299  -func (u *plpgsqlSymUnion) typ() tree.ResolvableTypeReference {
  1300  -    return u.val.(tree.ResolvableTypeReference)
  1301  -}
  1302  -
  1303  -func (u *plpgsqlSymUnion) getDiagnosticsKind() plpgsqltree.GetDiagnosticsKind {
  1304  -    return u.val.(plpgsqltree.GetDiagnosticsKind)
  1305  -}
  1306  -
  1307  -func (u *plpgsqlSymUnion) getDiagnosticsItem() *plpgsqltree.GetDiagnosticsItem {
  1308  -    return u.val.(*plpgsqltree.GetDiagnosticsItem)
  1309  -}
  1310  -
  1311  -func (u *plpgsqlSymUnion) getDiagnosticsItemList() plpgsqltree.GetDiagnosticsItemList {
  1312  -    return u.val.(plpgsqltree.GetDiagnosticsItemList)
  1313  -}
  1314  -
  1315  -func (u *plpgsqlSymUnion) elseIf() []plpgsqltree.ElseIf {
  1316  -    return u.val.([]plpgsqltree.ElseIf)
  1317  -}
  1318  -
  1319  -func (u *plpgsqlSymUnion) open() *plpgsqltree.Open {
  1320  -    return u.val.(*plpgsqltree.Open)
  1321  -}
  1322  -
  1323  -func (u *plpgsqlSymUnion) expr() plpgsqltree.Expr {
  1324  -    if u.val == nil {
  1325  -        return nil
  1326  -    }
  1327  -    return u.val.(plpgsqltree.Expr)
  1328  -}
  1329  -
  1330  -func (u *plpgsqlSymUnion) exprs() []plpgsqltree.Expr {
  1331  -    return u.val.([]plpgsqltree.Expr)
  1332  -}
  1333  -
  1334  -func (u *plpgsqlSymUnion) raiseOption() *plpgsqltree.RaiseOption {
  1335  -    return u.val.(*plpgsqltree.RaiseOption)
  1336  -}
  1337  -
  1338  -func (u *plpgsqlSymUnion) raiseOptions() []plpgsqltree.RaiseOption {
  1339  -    return u.val.([]plpgsqltree.RaiseOption)
  1340  -}
  1341  -
  1342  -
  1343  -func (u *plpgsqlSymUnion) exception() *plpgsqltree.Exception {
  1344  -    return u.val.(*plpgsqltree.Exception)
  1345  -}
  1346  -
  1347  -func (u *plpgsqlSymUnion) exceptions() []plpgsqltree.Exception {
  1348  -    return u.val.([]plpgsqltree.Exception)
  1349  -}
  1350  -
  1351  -func (u *plpgsqlSymUnion) condition() *plpgsqltree.Condition {
  1352  -    return u.val.(*plpgsqltree.Condition)
  1353  -}
  1354  -
  1355  -func (u *plpgsqlSymUnion) conditions() []plpgsqltree.Condition {
  1356  -    return u.val.([]plpgsqltree.Condition)
  1357  -}
  1358  -
  1359  -func (u *plpgsqlSymUnion) cursorScrollOption() tree.CursorScrollOption {
  1360  -    return u.val.(tree.CursorScrollOption)
  1361  -}
  1362  -
  1363  -func (u *plpgsqlSymUnion) sqlStatement() tree.Statement {
  1364  -    return u.val.(tree.Statement)
  1365  -}
  1366  -
  1367  -%}
  1368  -/*
  1369  - * Basic non-keyword token types.  These are hard-wired into the core lexer.
  1370  - * They must be listed first so that their numeric codes do not depend on
  1371  - * the set of keywords.  Keep this list in sync with backend/parser/gram.y!
  1372  - *
  1373  - * Some of these are not directly referenced in this file, but they must be
  1374  - * here anyway.
  1375  - */
  1376  -%token <str> IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op
  1377  -%token <*tree.NumVal>	ICONST PARAM
  1378  -%token <str> TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
  1379  -%token <str> LESS_EQUALS GREATER_EQUALS NOT_EQUALS
  1380  -
  1381  -/*
  1382  - * Other tokens recognized by plpgsql's lexer interface layer (pl_scanner.c).
  1383  - */
  1384  -%token <str> LESS_LESS GREATER_GREATER
  1385  -
  1386  -/*
  1387  - * Keyword tokens.  Some of these are reserved and some are not;
  1388  - * see pl_scanner.c for info.  Be sure unreserved keywords are listed
  1389  - * in the "unreserved_keyword" production below.
  1390  - */
  1391  -%token <str>  ABSOLUTE
  1392  -%token <str>  ALIAS
  1393  -%token <str>  ALL
  1394  -%token <str>  AND
  1395  -%token <str>  ARRAY
  1396  -%token <str>  ASSERT
  1397  -%token <str>  BACKWARD
  1398  -%token <str>  BEGIN
  1399  -%token <str>  BY
  1400  -%token <str>  CALL
  1401  -%token <str>  CASE
  1402  -%token <str>  CHAIN
  1403  -%token <str>  CLOSE
  1404  -%token <str>  COLLATE
  1405  -%token <str>  COLUMN
  1406  -%token <str>  COLUMN_NAME
  1407  -%token <str>  COMMIT
  1408  -%token <str>  CONSTANT
  1409  -%token <str>  CONSTRAINT
  1410  -%token <str>  CONSTRAINT_NAME
  1411  -%token <str>  CONTINUE
  1412  -%token <str>  CURRENT
  1413  -%token <str>  CURSOR
  1414  -%token <str>  DATATYPE
  1415  -%token <str>  DEBUG
  1416  -%token <str>  DECLARE
  1417  -%token <str>  DEFAULT
  1418  -%token <str>  DETAIL
  1419  -%token <str>  DIAGNOSTICS
  1420  -%token <str>  DO
  1421  -%token <str>  DUMP
  1422  -%token <str>  ELSE
  1423  -%token <str>  ELSIF
  1424  -%token <str>  END
  1425  -%token <str>  END_CASE
  1426  -%token <str>  END_IF
  1427  -%token <str>  ERRCODE
  1428  -%token <str>  ERROR
  1429  -%token <str>  EXCEPTION
  1430  -%token <str>  EXECUTE
  1431  -%token <str>  EXIT
  1432  -%token <str>  FETCH
  1433  -%token <str>  FIRST
  1434  -%token <str>  FOR
  1435  -%token <str>  FOREACH
  1436  -%token <str>  FORWARD
  1437  -%token <str>  FROM
  1438  -%token <str>  GET
  1439  -%token <str>  HINT
  1440  -%token <str>  IF
  1441  -%token <str>  IMPORT
  1442  -%token <str>  IN
  1443  -%token <str>  INFO
  1444  -%token <str>  INSERT
  1445  -%token <str>  INTO
  1446  -%token <str>  IS
  1447  -%token <str>  LAST
  1448  -%token <str>  LOG
  1449  -%token <str>  LOOP
  1450  -%token <str>  MERGE
  1451  -%token <str>  MESSAGE
  1452  -%token <str>  MESSAGE_TEXT
  1453  -%token <str>  MOVE
  1454  -%token <str>  NEXT
  1455  -%token <str>  NO
  1456  -%token <str>  NO_SCROLL
  1457  -%token <str>  NOT
  1458  -%token <str>  NOTICE
  1459  -%token <str>  NULL
  1460  -%token <str>  OPEN
  1461  -%token <str>  OPTION
  1462  -%token <str>  OR
  1463  -%token <str>  PERFORM
  1464  -%token <str>  PG_CONTEXT
  1465  -%token <str>  PG_DATATYPE_NAME
  1466  -%token <str>  PG_EXCEPTION_CONTEXT
  1467  -%token <str>  PG_EXCEPTION_DETAIL
  1468  -%token <str>  PG_EXCEPTION_HINT
  1469  -%token <str>  PRINT_STRICT_PARAMS
  1470  -%token <str>  PRIOR
  1471  -%token <str>  QUERY
  1472  -%token <str>  RAISE
  1473  -%token <str>  RELATIVE
  1474  -%token <str>  RETURN
  1475  -%token <str>  RETURN_NEXT
  1476  -%token <str>  RETURN_QUERY
  1477  -%token <str>  RETURNED_SQLSTATE
  1478  -%token <str>  REVERSE
  1479  -%token <str>  ROLLBACK
  1480  -%token <str>  ROW_COUNT
  1481  -%token <str>  ROWTYPE
  1482  -%token <str>  SCHEMA
  1483  -%token <str>  SCHEMA_NAME
  1484  -%token <str>  SCROLL
  1485  -%token <str>  SLICE
  1486  -%token <str>  SQLSTATE
  1487  -%token <str>  STACKED
  1488  -%token <str>  STRICT
  1489  -%token <str>  TABLE
  1490  -%token <str>  TABLE_NAME
  1491  -%token <str>  THEN
  1492  -%token <str>  TO
  1493  -%token <str>  TYPE
  1494  -%token <str>  UPSERT
  1495  -%token <str>  USE_COLUMN
  1496  -%token <str>  USE_VARIABLE
  1497  -%token <str>  USING
  1498  -%token <str>  VARIABLE_CONFLICT
  1499  -%token <str>  WARNING
  1500  -%token <str>  WHEN
  1501  -%token <str>  WHILE
  1502  -
  1503  -
  1504  -%union {
  1505  -  id    int32
  1506  -  pos   int32
  1507  -  str   string
  1508  -  union plpgsqlSymUnion
  1509  -}
  1510  -
  1511  -%type <str> decl_varname decl_defkey
  1512  -%type <bool>	decl_const decl_notnull
  1513  -%type <plpgsqltree.Expr>	decl_defval decl_cursor_query
  1514  -%type <tree.ResolvableTypeReference>	decl_datatype
  1515  -%type <str>		decl_collate
  1516  -
  1517  -%type <str>	expr_until_semi expr_until_paren stmt_until_semi
  1518  -%type <str>	expr_until_then expr_until_loop opt_expr_until_when
  1519  -%type <plpgsqltree.Expr>	opt_exitcond
  1520  -
  1521  -%type <forvariable>	for_variable
  1522  -%type <plpgsqltree.Expr>	return_variable
  1523  -%type <*tree.NumVal>	foreach_slice
  1524  -%type <plpgsqltree.Statement>	for_control
  1525  -
  1526  -%type <str> any_identifier opt_block_label opt_loop_label opt_label query_options
  1527  -%type <str> opt_error_level option_type
  1528  -
  1529  -%type <[]plpgsqltree.Statement> proc_sect
  1530  -%type <[]plpgsqltree.ElseIf> stmt_elsifs
  1531  -%type <[]plpgsqltree.Statement> stmt_else loop_body // TODO is this a list of statement?
  1532  -%type <plpgsqltree.Statement>  pl_block
  1533  -%type <plpgsqltree.Statement>	proc_stmt
  1534  -%type <plpgsqltree.Statement>	stmt_assign stmt_if stmt_loop stmt_while stmt_exit stmt_continue
  1535  -%type <plpgsqltree.Statement>	stmt_return stmt_raise stmt_assert stmt_execsql
  1536  -%type <plpgsqltree.Statement>	stmt_dynexecute stmt_for stmt_perform stmt_call stmt_getdiag
  1537  -%type <plpgsqltree.Statement>	stmt_open stmt_fetch stmt_move stmt_close stmt_null
  1538  -%type <plpgsqltree.Statement>	stmt_commit stmt_rollback
  1539  -%type <plpgsqltree.Statement>	stmt_case stmt_foreach_a
  1540  -
  1541  -%type <plpgsqltree.Statement> decl_stmt decl_statement
  1542  -%type <[]plpgsqltree.Statement> decl_sect opt_decl_stmts decl_stmts
  1543  -
  1544  -%type <[]plpgsqltree.Exception> exception_sect proc_exceptions
  1545  -%type <*plpgsqltree.Exception>	proc_exception
  1546  -%type <[]plpgsqltree.Condition> proc_conditions
  1547  -%type <*plpgsqltree.Condition> proc_condition
  1548  -
  1549  -%type <*plpgsqltree.CaseWhen>	case_when
  1550  -%type <[]*plpgsqltree.CaseWhen>	case_when_list
  1551  -%type <[]plpgsqltree.Statement> opt_case_else
  1552  -
  1553  -%type <bool>	getdiag_area_opt
  1554  -%type <plpgsqltree.GetDiagnosticsItemList>	getdiag_list // TODO don't know what this is
  1555  -%type <*plpgsqltree.GetDiagnosticsItem> getdiag_list_item // TODO don't know what this is
  1556  -%type <int32> getdiag_item
  1557  -
  1558  -%type <*plpgsqltree.RaiseOption> option_expr
  1559  -%type <[]plpgsqltree.RaiseOption> option_exprs opt_option_exprs
  1560  -%type <plpgsqltree.Expr> format_expr
  1561  -%type <[]plpgsqltree.Expr> opt_format_exprs format_exprs
  1562  -
  1563  -%type <tree.CursorScrollOption>	opt_scrollable
  1564  -
  1565  -%type <*tree.NumVal>	opt_transaction_chain
  1566  -
  1567  -%type <str>	unreserved_keyword
  1568  -%%
  1569  -
  1570  -pl_function:
  1571  -  pl_block opt_semi
  1572  -  {
  1573  -    plpgsqllex.(*lexer).SetStmt($1.statement())
  1574  -  }
  1575  -
  1576  -opt_semi:
  1577  -| ';'
  1578  -;
  1579  -
  1580  -pl_block: opt_block_label decl_sect BEGIN proc_sect exception_sect END opt_label
  1581  -  {
  1582  -    $$.val = &plpgsqltree.Block{
  1583  -      Label: $1,
  1584  -      Decls: $2.statements(),
  1585  -      Body: $4.statements(),
  1586  -      Exceptions: $5.exceptions(),
  1587  -    }
  1588  -  }
  1589  -;
  1590  -
  1591  -decl_sect: DECLARE opt_decl_stmts
  1592  -  {
  1593  -    $$.val = $2.statements()
  1594  -  }
  1595  -| /* EMPTY */
  1596  -  {
  1597  -    // Use a nil slice to indicate DECLARE was not used.
  1598  -    $$.val = []plpgsqltree.Statement(nil)
  1599  -  }
  1600  -;
  1601  -
  1602  -opt_decl_stmts: decl_stmts
  1603  -  {
  1604  -    $$.val = $1.statements()
  1605  -  }
  1606  -| /* EMPTY */
  1607  -  {
  1608  -    $$.val = []plpgsqltree.Statement{}
  1609  -  }
  1610  -;
  1611  -
  1612  -decl_stmts: decl_stmts decl_stmt
  1613  -  {
  1614  -    decs := $1.statements()
  1615  -    dec := $2.statement()
  1616  -    $$.val = append(decs, dec)
  1617  -  }
  1618  -| decl_stmt
  1619  -  {
  1620  -    dec := $1.statement()
  1621  -    $$.val = []plpgsqltree.Statement{dec}
  1622  -	}
  1623  -;
  1624  -
  1625  -decl_stmt	: decl_statement
  1626  -  {
  1627  -    $$.val = $1.statement()
  1628  -  }
  1629  -| DECLARE
  1630  -  {
  1631  -    // This is to allow useless extra "DECLARE" keywords in the declare section.
  1632  -    $$.val = (plpgsqltree.Statement)(nil)
  1633  -  }
  1634  -// TODO(chengxiong): turn this block on and throw useful error if user
  1635  -// tries to put the block label just before BEGIN instead of before
  1636  -// DECLARE.
  1637  -//| LESS_LESS any_identifier GREATER_GREATER
  1638  -//  {
  1639  -//  }
  1640  -;
  1641  -
  1642  -decl_statement: decl_varname decl_const decl_datatype decl_collate decl_notnull decl_defval
  1643  -  {
  1644  -    $$.val = &plpgsqltree.Declaration{
  1645  -      Var: plpgsqltree.Variable($1),
  1646  -      Constant: $2.bool(),
  1647  -      Typ: $3.typ(),
  1648  -      Collate: $4,
  1649  -      NotNull: $5.bool(),
  1650  -      Expr: $6.expr(),
  1651  -    }
  1652  -  }
  1653  -| decl_varname ALIAS FOR decl_aliasitem ';'
  1654  -  {
  1655  -    return unimplemented(plpgsqllex, "alias for")
  1656  -  }
  1657  -| decl_varname opt_scrollable CURSOR decl_cursor_args decl_is_for decl_cursor_query
  1658  -  {
  1659  -    $$.val = &plpgsqltree.CursorDeclaration{
  1660  -      Name: plpgsqltree.Variable($1),
  1661  -      Scroll: $2.cursorScrollOption(),
  1662  -      Query: $6.sqlStatement(),
  1663  -    }
  1664  -  }
  1665  -;
  1666  -
  1667  -opt_scrollable:
  1668  -  {
  1669  -    $$.val = tree.UnspecifiedScroll
  1670  -  }
  1671  -| NO_SCROLL SCROLL
  1672  -  {
  1673  -    $$.val = tree.NoScroll
  1674  -  }
  1675  -| SCROLL
  1676  -  {
  1677  -    $$.val = tree.Scroll
  1678  -  }
  1679  -;
  1680  -
  1681  -decl_cursor_query: stmt_until_semi ';'
  1682  -  {
  1683  -    stmts, err := parser.Parse($1)
  1684  -    if err != nil {
  1685  -      return setErr(plpgsqllex, err)
  1686  -    }
  1687  -    if len(stmts) != 1 {
  1688  -      return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
  1689  -    }
  1690  -    $$.val = stmts[0].AST
  1691  -  }
  1692  -;
  1693  -
  1694  -decl_cursor_args: '('
  1695  -  {
  1696  -    return unimplemented(plpgsqllex, "cursor arguments")
  1697  -  }
  1698  -| /* EMPTY */
  1699  -  {
  1700  -  }
  1701  -;
  1702  -
  1703  -decl_cursor_arglist: decl_cursor_arg
  1704  -  {
  1705  -  }
  1706  -| decl_cursor_arglist ',' decl_cursor_arg
  1707  -  {
  1708  -  }
  1709  -;
  1710  -
  1711  -decl_cursor_arg: decl_varname decl_datatype
  1712  -  {
  1713  -  }
  1714  -;
  1715  -
  1716  -decl_is_for:
  1717  -  IS   /* Oracle */
  1718  -| FOR  /* SQL standard */
  1719  -
  1720  -decl_aliasitem: IDENT
  1721  -  {
  1722  -  }
  1723  -| unreserved_keyword
  1724  -  {
  1725  -  }
  1726  -;
  1727  -
  1728  -decl_varname: IDENT
  1729  -| unreserved_keyword
  1730  -;
  1731  -
  1732  -decl_const:
  1733  -  {
  1734  -    $$.val = false
  1735  -  }
  1736  -| CONSTANT
  1737  -  {
  1738  -    $$.val = true
  1739  -  }
  1740  -;
  1741  -
  1742  -decl_datatype:
  1743  -  {
  1744  -    // Read until reaching one of the tokens that can follow a declaration
  1745  -    // data type.
  1746  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(
  1747  -      ';', COLLATE, NOT, '=', COLON_EQUALS, DECLARE,
  1748  -    )
  1749  -    if err != nil {
  1750  -      return setErr(plpgsqllex, err)
  1751  -    }
  1752  -    typ, err := plpgsqllex.(*lexer).GetTypeFromValidSQLSyntax(sqlStr)
  1753  -    if err != nil {
  1754  -      return setErr(plpgsqllex, err)
  1755  -    }
  1756  -    $$.val = typ
  1757  -  }
  1758  -;
  1759  -
  1760  -decl_collate:
  1761  -  {
  1762  -    $$ = ""
  1763  -  }
  1764  -| COLLATE IDENT
  1765  -  {
  1766  -    $$ = $2
  1767  -  }
  1768  -| COLLATE unreserved_keyword
  1769  -  {
  1770  -    $$ = $2
  1771  -  }
  1772  -;
  1773  -
  1774  -decl_notnull:
  1775  -  {
  1776  -    $$.val = false
  1777  -  }
  1778  -| NOT NULL
  1779  -  {
  1780  -    $$.val = true
  1781  -  }
  1782  -;
  1783  -
  1784  -decl_defval: ';'
  1785  -  {
  1786  -    $$.val = (plpgsqltree.Expr)(nil)
  1787  -  }
  1788  -| decl_defkey ';'
  1789  -  {
  1790  -    expr, err := plpgsqllex.(*lexer).ParseExpr($1)
  1791  -    if err != nil {
  1792  -      return setErr(plpgsqllex, err)
  1793  -    }
  1794  -    $$.val = expr
  1795  -  }
  1796  -;
  1797  -
  1798  -decl_defkey: assign_operator
  1799  -  {
  1800  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
  1801  -    if err != nil {
  1802  -      return setErr(plpgsqllex, err)
  1803  -    }
  1804  -    $$ = sqlStr
  1805  -  }
  1806  -| DEFAULT
  1807  -  {
  1808  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
  1809  -    if err != nil {
  1810  -      return setErr(plpgsqllex, err)
  1811  -    }
  1812  -    $$ = sqlStr
  1813  -  }
  1814  -;
  1815  -
  1816  -/*
  1817  - * Ada-based PL/SQL uses := for assignment and variable defaults, while
  1818  - * the SQL standard uses equals for these cases and for GET
  1819  - * DIAGNOSTICS, so we support both.  FOR and OPEN only support :=.
  1820  - */
  1821  -assign_operator: '='
  1822  -| COLON_EQUALS
  1823  -;
  1824  -
  1825  -proc_sect:
  1826  -  {
  1827  -    $$.val = []plpgsqltree.Statement{}
  1828  -  }
  1829  -| proc_sect proc_stmt
  1830  -  {
  1831  -    stmts := $1.statements()
  1832  -    stmts = append(stmts, $2.statement())
  1833  -    $$.val = stmts
  1834  -  }
  1835  -;
  1836  -
  1837  -proc_stmt:pl_block ';'
  1838  -  {
  1839  -    $$.val = $1.block()
  1840  -  }
  1841  -| stmt_assign
  1842  -  {
  1843  -    $$.val = $1.statement()
  1844  -  }
  1845  -| stmt_if
  1846  -  {
  1847  -    $$.val = $1.statement()
  1848  -  }
  1849  -| stmt_case
  1850  -  {
  1851  -    $$.val = $1.statement()
  1852  -  }
  1853  -| stmt_loop
  1854  -  {
  1855  -    $$.val = $1.statement()
  1856  -  }
  1857  -| stmt_while
  1858  -  { }
  1859  -| stmt_for
  1860  -  { }
  1861  -| stmt_foreach_a
  1862  -  { }
  1863  -| stmt_exit
  1864  -  {
  1865  -    $$.val = $1.statement()
  1866  -  }
  1867  -| stmt_continue
  1868  -  {
  1869  -    $$.val = $1.statement()
  1870  -  }
  1871  -| stmt_return
  1872  -  {
  1873  -    $$.val = $1.statement()
  1874  -  }
  1875  -| stmt_raise
  1876  -  {
  1877  -    $$.val = $1.statement()
  1878  -  }
  1879  -| stmt_assert
  1880  -  {
  1881  -    $$.val = $1.statement()
  1882  -  }
  1883  -| stmt_execsql
  1884  -  {
  1885  -    $$.val = $1.statement()
  1886  -  }
  1887  -| stmt_dynexecute
  1888  -  {
  1889  -    $$.val = $1.statement()
  1890  -  }
  1891  -| stmt_perform
  1892  -  { }
  1893  -| stmt_call
  1894  -  {
  1895  -    $$.val = $1.statement()
  1896  -  }
  1897  -| stmt_getdiag
  1898  -  { }
  1899  -| stmt_open
  1900  -  {
  1901  -    $$.val = $1.statement()
  1902  -  }
  1903  -| stmt_fetch
  1904  -  {
  1905  -    $$.val = $1.statement()
  1906  -  }
  1907  -| stmt_move
  1908  -  {
  1909  -    $$.val = $1.statement()
  1910  -  }
  1911  -| stmt_close
  1912  -  {
  1913  -    $$.val = $1.statement()
  1914  -  }
  1915  -| stmt_null
  1916  -  { }
  1917  -| stmt_commit
  1918  -  { }
  1919  -| stmt_rollback
  1920  -  { }
  1921  -;
  1922  -
  1923  -stmt_perform: PERFORM stmt_until_semi ';'
  1924  -  {
  1925  -    return unimplemented(plpgsqllex, "perform")
  1926  -  }
  1927  -;
  1928  -
  1929  -stmt_call: CALL call_cmd ';'
  1930  -  {
  1931  -    $$.val = &plpgsqltree.Call{IsCall: true}
  1932  -  }
  1933  -| DO call_cmd ';'
  1934  -  {
  1935  -    $$.val = &plpgsqltree.Call{IsCall: false}
  1936  -  }
  1937  -;
  1938  -
  1939  -call_cmd:
  1940  -  {
  1941  -    _, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
  1942  -    if err != nil {
  1943  -      return setErr(plpgsqllex, err)
  1944  -    }
  1945  -  }
  1946  -;
  1947  -
  1948  -stmt_assign: IDENT assign_operator expr_until_semi ';'
  1949  -  {
  1950  -    expr, err := plpgsqllex.(*lexer).ParseExpr($3)
  1951  -    if err != nil {
  1952  -      return setErr(plpgsqllex, err)
  1953  -    }
  1954  -    $$.val = &plpgsqltree.Assignment{
  1955  -      Var: plpgsqltree.Variable($1),
  1956  -      Value: expr,
  1957  -    }
  1958  -  }
  1959  -;
  1960  -
  1961  -stmt_getdiag: GET getdiag_area_opt DIAGNOSTICS getdiag_list ';'
  1962  -  {
  1963  -  $$.val = &plpgsqltree.GetDiagnostics{
  1964  -    IsStacked: $2.bool(),
  1965  -    DiagItems: $4.getDiagnosticsItemList(),
  1966  -  }
  1967  -  // TODO(jane): Check information items are valid for area option.
  1968  -  }
  1969  -;
  1970  -
  1971  -getdiag_area_opt:
  1972  -  {
  1973  -    $$.val = false
  1974  -  }
  1975  -| CURRENT
  1976  -  {
  1977  -    $$.val = false
  1978  -  }
  1979  -| STACKED
  1980  -  {
  1981  -    $$.val = true
  1982  -  }
  1983  -;
  1984  -
  1985  -getdiag_list: getdiag_list ',' getdiag_list_item
  1986  -  {
  1987  -    $$.val = append($1.getDiagnosticsItemList(), $3.getDiagnosticsItem())
  1988  -  }
  1989  -| getdiag_list_item
  1990  -  {
  1991  -    $$.val = plpgsqltree.GetDiagnosticsItemList{$1.getDiagnosticsItem()}
  1992  -  }
  1993  -;
  1994  -
  1995  -getdiag_list_item: IDENT assign_operator getdiag_item
  1996  -  {
  1997  -    $$.val = &plpgsqltree.GetDiagnosticsItem{
  1998  -      Kind : $3.getDiagnosticsKind(),
  1999  -      TargetName: $1,
  2000  -      // TODO(jane): set the target from $1.
  2001  -    }
  2002  -  }
  2003  -;
  2004  -
  2005  -getdiag_item: unreserved_keyword {
  2006  -  switch $1 {
  2007  -    case "row_count":
  2008  -      $$.val = plpgsqltree.GetDiagnosticsRowCount;
  2009  -    case "pg_context":
  2010  -      $$.val = plpgsqltree.GetDiagnosticsContext;
  2011  -    case "pg_exception_detail":
  2012  -      $$.val = plpgsqltree.GetDiagnosticsErrorDetail;
  2013  -    case "pg_exception_hint":
  2014  -      $$.val = plpgsqltree.GetDiagnosticsErrorHint;
  2015  -    case "pg_exception_context":
  2016  -      $$.val = plpgsqltree.GetDiagnosticsErrorContext;
  2017  -    case "column_name":
  2018  -      $$.val = plpgsqltree.GetDiagnosticsColumnName;
  2019  -    case "constraint_name":
  2020  -      $$.val = plpgsqltree.GetDiagnosticsConstraintName;
  2021  -    case "pg_datatype_name":
  2022  -      $$.val = plpgsqltree.GetDiagnosticsDatatypeName;
  2023  -    case "message_text":
  2024  -      $$.val = plpgsqltree.GetDiagnosticsMessageText;
  2025  -    case "table_name":
  2026  -      $$.val = plpgsqltree.GetDiagnosticsTableName;
  2027  -    case "schema_name":
  2028  -      $$.val = plpgsqltree.GetDiagnosticsSchemaName;
  2029  -    case "returned_sqlstate":
  2030  -      $$.val = plpgsqltree.GetDiagnosticsReturnedSQLState;
  2031  -    default:
  2032  -      // TODO(jane): Should this use an unimplemented error instead?
  2033  -      return setErr(plpgsqllex, errors.Newf("unrecognized GET DIAGNOSTICS item: %s", redact.Safe($1)))
  2034  -  }
  2035  -}
  2036  -;
  2037  -
  2038  -getdiag_target:
  2039  -// TODO(jane): remove ident.
  2040  -IDENT
  2041  -  {
  2042  -  }
  2043  -;
  2044  -
  2045  -stmt_if: IF expr_until_then THEN proc_sect stmt_elsifs stmt_else END_IF IF ';'
  2046  -  {
  2047  -    cond, err := plpgsqllex.(*lexer).ParseExpr($2)
  2048  -    if err != nil {
  2049  -      return setErr(plpgsqllex, err)
  2050  -    }
  2051  -    $$.val = &plpgsqltree.If{
  2052  -      Condition: cond,
  2053  -      ThenBody: $4.statements(),
  2054  -      ElseIfList: $5.elseIf(),
  2055  -      ElseBody: $6.statements(),
  2056  -    }
  2057  -  }
  2058  -;
  2059  -
  2060  -stmt_elsifs:
  2061  -  {
  2062  -    $$.val = []plpgsqltree.ElseIf{};
  2063  -  }
  2064  -| stmt_elsifs ELSIF expr_until_then THEN proc_sect
  2065  -  {
  2066  -    cond, err := plpgsqllex.(*lexer).ParseExpr($3)
  2067  -    if err != nil {
  2068  -      return setErr(plpgsqllex, err)
  2069  -    }
  2070  -    newStmt := plpgsqltree.ElseIf{
  2071  -      Condition: cond,
  2072  -      Stmts: $5.statements(),
  2073  -    }
  2074  -    $$.val = append($1.elseIf() , newStmt)
  2075  -  }
  2076  -;
  2077  -
  2078  -stmt_else:
  2079  -  {
  2080  -    $$.val = []plpgsqltree.Statement{};
  2081  -  }
  2082  -| ELSE proc_sect
  2083  -  {
  2084  -    $$.val = $2.statements();
  2085  -  }
  2086  -;
  2087  -
  2088  -stmt_case: CASE opt_expr_until_when case_when_list opt_case_else END_CASE CASE ';'
  2089  -  {
  2090  -    expr := &plpgsqltree.Case {
  2091  -      TestExpr: $2,
  2092  -      CaseWhenList: $3.caseWhens(),
  2093  -    }
  2094  -    if $4.val != nil {
  2095  -       expr.HaveElse = true
  2096  -       expr.ElseStmts = $4.statements()
  2097  -    }
  2098  -    $$.val = expr
  2099  -  }
  2100  -;
  2101  -
  2102  -opt_expr_until_when:
  2103  -  {
  2104  -    if plpgsqllex.(*lexer).Peek().id != WHEN {
  2105  -      sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(WHEN)
  2106  -      if err != nil {
  2107  -        return setErr(plpgsqllex, err)
  2108  -      }
  2109  -      $$ = sqlStr
  2110  -    } else {
  2111  -      $$ = ""
  2112  -    }
  2113  -  }
  2114  -;
  2115  -
  2116  -case_when_list: case_when_list case_when
  2117  -  {
  2118  -    stmts := $1.caseWhens()
  2119  -    stmts = append(stmts, $2.caseWhen())
  2120  -    $$.val = stmts
  2121  -  }
  2122  -| case_when
  2123  -  {
  2124  -    stmts := []*plpgsqltree.CaseWhen{}
  2125  -    stmts = append(stmts, $1.caseWhen())
  2126  -    $$.val = stmts
  2127  -  }
  2128  -;
  2129  -
  2130  -case_when: WHEN expr_until_then THEN proc_sect
  2131  -  {
  2132  -     expr := &plpgsqltree.CaseWhen{
  2133  -       Expr: $2,
  2134  -       Stmts: $4.statements(),
  2135  -     }
  2136  -     $$.val = expr
  2137  -  }
  2138  -;
  2139  -
  2140  -opt_case_else:
  2141  -  {
  2142  -    $$.val = nil
  2143  -  }
  2144  -| ELSE proc_sect
  2145  -  {
  2146  -    $$.val = $2.statements()
  2147  -  }
  2148  -;
  2149  -
  2150  -stmt_loop: opt_loop_label LOOP loop_body opt_label ';'
  2151  -  {
  2152  -    loopLabel, loopEndLabel := $1, $4
  2153  -    if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
  2154  -      return setErr(plpgsqllex, err)
  2155  -    }
  2156  -    $$.val = &plpgsqltree.Loop{
  2157  -      Label: $1,
  2158  -      Body: $3.statements(),
  2159  -    }
  2160  -  }
  2161  -;
  2162  -
  2163  -stmt_while: opt_loop_label WHILE expr_until_loop LOOP loop_body opt_label ';'
  2164  -  {
  2165  -    loopLabel, loopEndLabel := $1, $6
  2166  -    if err := checkLoopLabels(loopLabel, loopEndLabel); err != nil {
  2167  -      return setErr(plpgsqllex, err)
  2168  -    }
  2169  -    cond, err := plpgsqllex.(*lexer).ParseExpr($3)
  2170  -    if err != nil {
  2171  -      return setErr(plpgsqllex, err)
  2172  -    }
  2173  -    $$.val = &plpgsqltree.While{
  2174  -      Label: $1,
  2175  -      Condition: cond,
  2176  -      Body: $5.statements(),
  2177  -    }
  2178  -  }
  2179  -;
  2180  -
  2181  -stmt_for: opt_loop_label FOR for_control loop_body
  2182  -  {
  2183  -    return unimplemented(plpgsqllex, "for loop")
  2184  -  }
  2185  -;
  2186  -
  2187  -for_control: for_variable IN
  2188  -  // TODO need to parse the sql expression here.
  2189  -  {
  2190  -    return unimplemented(plpgsqllex, "for loop")
  2191  -  }
  2192  -;
  2193  -
  2194  -/*
  2195  - * Processing the for_variable is tricky because we don't yet know if the
  2196  - * FOR is an integer FOR loop or a loop over query results.  In the former
  2197  - * case, the variable is just a name that we must instantiate as a loop
  2198  - * local variable, regardless of any other definition it might have.
  2199  - * Therefore, we always save the actual identifier into $$.name where it
  2200  - * can be used for that case.  We also save the outer-variable definition,
  2201  - * if any, because that's what we need for the loop-over-query case.  Note
  2202  - * that we must NOT apply check_assignable() or any other semantic check
  2203  - * until we know what's what.
  2204  - *
  2205  - * However, if we see a comma-separated list of names, we know that it
  2206  - * can't be an integer FOR loop and so it's OK to check the variables
  2207  - * immediately.  In particular, for T_WORD followed by comma, we should
  2208  - * complain that the name is not known rather than say it's a syntax error.
  2209  - * Note that the non-error result of this case sets *both* $$.scalar and
  2210  - * $$.row; see the for_control production.
  2211  - */
  2212  -for_variable: any_identifier
  2213  -  {
  2214  -    return unimplemented(plpgsqllex, "for loop")
  2215  -  }
  2216  -;
  2217  -
  2218  -stmt_foreach_a: opt_loop_label FOREACH for_variable foreach_slice IN ARRAY expr_until_loop loop_body
  2219  -  {
  2220  -    return unimplemented(plpgsqllex, "for each loop")
  2221  -  }
  2222  -;
  2223  -
  2224  -foreach_slice:
  2225  -  {
  2226  -  }
  2227  -| SLICE ICONST
  2228  -  {
  2229  -  }
  2230  -;
  2231  -
  2232  -stmt_exit: EXIT opt_label opt_exitcond
  2233  -  {
  2234  -    $$.val = &plpgsqltree.Exit{
  2235  -      Label: $2,
  2236  -      Condition: $3.expr(),
  2237  -    }
  2238  -  }
  2239  -;
  2240  -
  2241  -stmt_continue: CONTINUE opt_label opt_exitcond
  2242  -  {
  2243  -    $$.val = &plpgsqltree.Continue{
  2244  -      Label: $2,
  2245  -      Condition: $3.expr(),
  2246  -    }
  2247  -  }
  2248  -;
  2249  -
  2250  -  // TODO handle variable names
  2251  -  // 1. verify if the first token is a variable (this means that we need to track variable scope during parsing)
  2252  -  // 2. if yes, check next token is ';'
  2253  -  // 3. if no, expecting a sql expression "read_sql_expression"
  2254  -  //    we can just read until a ';', then do the sql expression validation during compile time.
  2255  -
  2256  -stmt_return: RETURN return_variable ';'
  2257  -  {
  2258  -    $$.val = &plpgsqltree.Return{
  2259  -      Expr: $2.expr(),
  2260  -    }
  2261  -  }
  2262  -| RETURN_NEXT NEXT
  2263  -  {
  2264  -    return unimplemented(plpgsqllex, "return next")
  2265  -  }
  2266  -| RETURN_QUERY QUERY
  2267  - {
  2268  -   return unimplemented (plpgsqllex, "return query")
  2269  - }
  2270  -;
  2271  -
  2272  -
  2273  -query_options:
  2274  -  {
  2275  -    _, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(EXECUTE, ';')
  2276  -    if err != nil {
  2277  -      return setErr(plpgsqllex, err)
  2278  -    }
  2279  -    if terminator == EXECUTE {
  2280  -      return unimplemented (plpgsqllex, "return dynamic sql query")
  2281  -    }
  2282  -    _, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';')
  2283  -    if err != nil {
  2284  -      return setErr(plpgsqllex, err)
  2285  -    }
  2286  -  }
  2287  -;
  2288  -
  2289  -
  2290  -return_variable: expr_until_semi
  2291  -  {
  2292  -    expr, err := plpgsqllex.(*lexer).ParseExpr($1)
  2293  -    if err != nil {
  2294  -      return setErr(plpgsqllex, err)
  2295  -    }
  2296  -    $$.val = expr
  2297  -  }
  2298  -;
  2299  -
  2300  -stmt_raise:
  2301  -  RAISE ';'
  2302  -  {
  2303  -    return unimplemented(plpgsqllex, "empty RAISE statement")
  2304  -  }
  2305  -| RAISE opt_error_level SCONST opt_format_exprs opt_option_exprs ';'
  2306  -  {
  2307  -    $$.val = &plpgsqltree.Raise{
  2308  -      LogLevel: $2,
  2309  -      Message: $3,
  2310  -      Params: $4.exprs(),
  2311  -      Options: $5.raiseOptions(),
  2312  -    }
  2313  -  }
  2314  -| RAISE opt_error_level IDENT opt_option_exprs ';'
  2315  -  {
  2316  -    $$.val = &plpgsqltree.Raise{
  2317  -      LogLevel: $2,
  2318  -      CodeName: $3,
  2319  -      Options: $4.raiseOptions(),
  2320  -    }
  2321  -  }
  2322  -| RAISE opt_error_level SQLSTATE SCONST opt_option_exprs ';'
  2323  -  {
  2324  -    $$.val = &plpgsqltree.Raise{
  2325  -      LogLevel: $2,
  2326  -      Code: $4,
  2327  -      Options: $5.raiseOptions(),
  2328  -    }
  2329  -  }
  2330  -| RAISE opt_error_level USING option_exprs ';'
  2331  -  {
  2332  -    $$.val = &plpgsqltree.Raise{
  2333  -      LogLevel: $2,
  2334  -      Options: $4.raiseOptions(),
  2335  -    }
  2336  -  }
  2337  -;
  2338  -
  2339  -opt_error_level:
  2340  -  DEBUG
  2341  -| LOG
  2342  -| INFO
  2343  -| NOTICE
  2344  -| WARNING
  2345  -| EXCEPTION
  2346  -| /* EMPTY */
  2347  -  {
  2348  -    $$ = ""
  2349  -  }
  2350  -;
  2351  -
  2352  -opt_option_exprs:
  2353  -  USING option_exprs
  2354  -  {
  2355  -    $$.val = $2.raiseOptions()
  2356  -  }
  2357  -| /* EMPTY */
  2358  -  {
  2359  -    $$.val = []plpgsqltree.RaiseOption{}
  2360  -  }
  2361  -;
  2362  -
  2363  -option_exprs:
  2364  -  option_exprs ',' option_expr
  2365  -  {
  2366  -    option := $3.raiseOption()
  2367  -    $$.val = append($1.raiseOptions(), *option)
  2368  -  }
  2369  -| option_expr
  2370  -  {
  2371  -    option := $1.raiseOption()
  2372  -    $$.val = []plpgsqltree.RaiseOption{*option}
  2373  -  }
  2374  -;
  2375  -
  2376  -option_expr:
  2377  -  option_type assign_operator
  2378  -  {
  2379  -    // Read until reaching one of the tokens that can follow a raise option.
  2380  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
  2381  -    if err != nil {
  2382  -      return setErr(plpgsqllex, err)
  2383  -    }
  2384  -    optionExpr, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
  2385  -    if err != nil {
  2386  -      return setErr(plpgsqllex, err)
  2387  -    }
  2388  -    $$.val = &plpgsqltree.RaiseOption{
  2389  -      OptType: $1,
  2390  -      Expr: optionExpr,
  2391  -    }
  2392  -  }
  2393  -;
  2394  -
  2395  -option_type:
  2396  -  MESSAGE
  2397  -| DETAIL
  2398  -| HINT
  2399  -| ERRCODE
  2400  -| COLUMN
  2401  -| CONSTRAINT
  2402  -| DATATYPE
  2403  -| TABLE
  2404  -| SCHEMA
  2405  -;
  2406  -
  2407  -opt_format_exprs:
  2408  -  format_exprs
  2409  -  {
  2410  -    $$.val = $1.exprs()
  2411  -  }
  2412  - | /* EMPTY */
  2413  -  {
  2414  -    $$.val = []plpgsqltree.Expr{}
  2415  -  }
  2416  -;
  2417  -
  2418  -format_exprs:
  2419  -  format_expr
  2420  -  {
  2421  -    $$.val = []plpgsqltree.Expr{$1.expr()}
  2422  -  }
  2423  -| format_exprs format_expr
  2424  -  {
  2425  -    $$.val = append($1.exprs(), $2.expr())
  2426  -  }
  2427  -;
  2428  -
  2429  -format_expr: ','
  2430  -  {
  2431  -    // Read until reaching a token that can follow a raise format parameter.
  2432  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';', USING)
  2433  -    if err != nil {
  2434  -      return setErr(plpgsqllex, err)
  2435  -    }
  2436  -    param, err := plpgsqllex.(*lexer).ParseExpr(sqlStr)
  2437  -    if err != nil {
  2438  -      return setErr(plpgsqllex, err)
  2439  -    }
  2440  -    $$.val = param
  2441  -  }
  2442  -;
  2443  -
  2444  -stmt_assert: ASSERT assert_cond ';'
  2445  -  {
  2446  -    $$.val = &plpgsqltree.Assert{}
  2447  -  }
  2448  -;
  2449  -
  2450  -assert_cond:
  2451  -  {
  2452  -    _, terminator, err := plpgsqllex.(*lexer).ReadSqlExpr(',', ';')
  2453  -    if err != nil {
  2454  -      return setErr(plpgsqllex, err)
  2455  -    }
  2456  -    if terminator == ',' {
  2457  -      _, _, err = plpgsqllex.(*lexer).ReadSqlExpr(';')
  2458  -      if err != nil {
  2459  -        return setErr(plpgsqllex, err)
  2460  -      }
  2461  -    }
  2462  -  }
  2463  -;
  2464  -
  2465  -loop_body: proc_sect END LOOP
  2466  -  {
  2467  -    $$.val = $1.statements()
  2468  -  }
  2469  -;
  2470  -
  2471  -stmt_execsql: stmt_execsql_start
  2472  -  {
  2473  -    stmt, err := plpgsqllex.(*lexer).MakeExecSqlStmt()
  2474  -    if err != nil {
  2475  -      return setErr(plpgsqllex, err)
  2476  -    }
  2477  -    $$.val = stmt
  2478  -  }
  2479  -;
  2480  -
  2481  -stmt_execsql_start:
  2482  -  IMPORT
  2483  -| INSERT
  2484  -| UPSERT
  2485  -| MERGE
  2486  -| IDENT
  2487  -;
  2488  -
  2489  -stmt_dynexecute: EXECUTE
  2490  -  {
  2491  -    stmt, err := plpgsqllex.(*lexer).MakeDynamicExecuteStmt()
  2492  -    if err != nil {
  2493  -      return setErr(plpgsqllex, err)
  2494  -    }
  2495  -    $$.val = stmt
  2496  -  }
  2497  -;
  2498  -
  2499  -stmt_open: OPEN IDENT ';'
  2500  -  {
  2501  -    $$.val = &plpgsqltree.Open{CurVar: plpgsqltree.Variable($2)}
  2502  -  }
  2503  -| OPEN IDENT opt_scrollable FOR EXECUTE 
  2504  -  {
  2505  -    return unimplemented(plpgsqllex, "cursor for execute")
  2506  -  }
  2507  -| OPEN IDENT opt_scrollable FOR stmt_until_semi ';'
  2508  -  {
  2509  -    stmts, err := parser.Parse($5)
  2510  -    if err != nil {
  2511  -      return setErr(plpgsqllex, err)
  2512  -    }
  2513  -    if len(stmts) != 1 {
  2514  -      return setErr(plpgsqllex, errors.New("expected exactly one SQL statement for cursor"))
  2515  -    }
  2516  -    $$.val = &plpgsqltree.Open{
  2517  -      CurVar: plpgsqltree.Variable($2),
  2518  -      Scroll: $3.cursorScrollOption(),
  2519  -      Query: stmts[0].AST,
  2520  -    }
  2521  -  }
  2522  -;
  2523  -
  2524  -stmt_fetch: FETCH
  2525  -  {
  2526  -    fetch, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(false)
  2527  -    if err != nil {
  2528  -      return setErr(plpgsqllex, err)
  2529  -    }
  2530  -    $$.val = fetch
  2531  -  }
  2532  -;
  2533  -
  2534  -stmt_move: MOVE
  2535  -  {
  2536  -    move, err := plpgsqllex.(*lexer).MakeFetchOrMoveStmt(true)
  2537  -    if err != nil {
  2538  -      return setErr(plpgsqllex, err)
  2539  -    }
  2540  -    $$.val = move
  2541  -  }
  2542  -;
  2543  -
  2544  -stmt_close: CLOSE IDENT ';'
  2545  -  {
  2546  -    $$.val = &plpgsqltree.Close{CurVar: plpgsqltree.Variable($2)}
  2547  -  }
  2548  -;
  2549  -
  2550  -stmt_null: NULL ';'
  2551  -  {
  2552  -  $$.val = &plpgsqltree.Null{};
  2553  -  }
  2554  -;
  2555  -
  2556  -stmt_commit: COMMIT opt_transaction_chain ';'
  2557  -  {
  2558  -    return unimplemented(plpgsqllex, "commit")
  2559  -  }
  2560  -;
  2561  -
  2562  -stmt_rollback: ROLLBACK opt_transaction_chain ';'
  2563  -  {
  2564  -    return unimplemented(plpgsqllex, "rollback")
  2565  -  }
  2566  -;
  2567  -
  2568  -opt_transaction_chain:
  2569  -AND CHAIN
  2570  -  { }
  2571  -| AND NO CHAIN
  2572  -  { }
  2573  -| /* EMPTY */
  2574  -  { }
  2575  -
  2576  -exception_sect: /* EMPTY */
  2577  -  {
  2578  -    $$.val = []plpgsqltree.Exception(nil)
  2579  -  }
  2580  -| EXCEPTION proc_exceptions
  2581  -  {
  2582  -    $$.val = $2.exceptions()
  2583  -  }
  2584  -;
  2585  -
  2586  -proc_exceptions: proc_exceptions proc_exception
  2587  -  {
  2588  -    e := $2.exception()
  2589  -    $$.val = append($1.exceptions(), *e)
  2590  -  }
  2591  -| proc_exception
  2592  -  {
  2593  -    e := $1.exception()
  2594  -    $$.val = []plpgsqltree.Exception{*e}
  2595  -  }
  2596  -;
  2597  -
  2598  -proc_exception: WHEN proc_conditions THEN proc_sect
  2599  -  {
  2600  -    $$.val = &plpgsqltree.Exception{
  2601  -      Conditions: $2.conditions(),
  2602  -      Action: $4.statements(),
  2603  -    }
  2604  -  }
  2605  -;
  2606  -
  2607  -proc_conditions: proc_conditions OR proc_condition
  2608  -  {
  2609  -    c := $3.condition()
  2610  -    $$.val = append($1.conditions(), *c)
  2611  -  }
  2612  -| proc_condition
  2613  -  {
  2614  -    c := $1.condition()
  2615  -    $$.val = []plpgsqltree.Condition{*c}
  2616  -  }
  2617  -;
  2618  -
  2619  -proc_condition: any_identifier
  2620  -  {
  2621  -    $$.val = &plpgsqltree.Condition{SqlErrName: $1}
  2622  -  }
  2623  -| SQLSTATE SCONST
  2624  -  {
  2625  -    $$.val = &plpgsqltree.Condition{SqlErrState: $2}
  2626  -  }
  2627  -;
  2628  -
  2629  -expr_until_semi:
  2630  -  {
  2631  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(';')
  2632  -    if err != nil {
  2633  -      return setErr(plpgsqllex, err)
  2634  -    }
  2635  -    $$ = sqlStr
  2636  -  }
  2637  -;
  2638  -
  2639  -stmt_until_semi:
  2640  -  {
  2641  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlStatement(';')
  2642  -    if err != nil {
  2643  -      return setErr(plpgsqllex, err)
  2644  -    }
  2645  -    $$ = sqlStr
  2646  -  }
  2647  -;
  2648  -
  2649  -expr_until_then:
  2650  -  {
  2651  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(THEN)
  2652  -    if err != nil {
  2653  -      return setErr(plpgsqllex, err)
  2654  -    }
  2655  -    $$ = sqlStr
  2656  -  }
  2657  -;
  2658  -
  2659  -expr_until_loop:
  2660  -  {
  2661  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(LOOP)
  2662  -    if err != nil {
  2663  -      return setErr(plpgsqllex, err)
  2664  -    }
  2665  -    $$ = sqlStr
  2666  -  }
  2667  -;
  2668  -
  2669  -expr_until_paren :
  2670  -  {
  2671  -    sqlStr, _, err := plpgsqllex.(*lexer).ReadSqlExpr(')')
  2672  -    if err != nil {
  2673  -      return setErr(plpgsqllex, err)
  2674  -    }
  2675  -    $$ = sqlStr
  2676  -  }
  2677  -;
  2678  -
  2679  -opt_block_label	:
  2680  -  {
  2681  -    $$ = ""
  2682  -  }
  2683  -| LESS_LESS any_identifier GREATER_GREATER
  2684  -  {
  2685  -    $$ = $2
  2686  -  }
  2687  -;
  2688  -
  2689  -opt_loop_label:
  2690  -  {
  2691  -    $$ = ""
  2692  -  }
  2693  -| LESS_LESS any_identifier GREATER_GREATER
  2694  -  {
  2695  -    $$ = $2
  2696  -  }
  2697  -;
  2698  -
  2699  -opt_label:
  2700  -  {
  2701  -    $$ = ""
  2702  -  }
  2703  -| any_identifier
  2704  -  {
  2705  -    $$ = $1
  2706  -  }
  2707  -;
  2708  -
  2709  -opt_exitcond: ';'
  2710  -  { }
  2711  -| WHEN expr_until_semi ';'
  2712  -  {
  2713  -    expr, err := plpgsqllex.(*lexer).ParseExpr($2)
  2714  -    if err != nil {
  2715  -      return setErr(plpgsqllex, err)
  2716  -    }
  2717  -    $$.val = expr
  2718  -  }
  2719  -;
  2720  -
  2721  -/*
  2722  - * need to allow DATUM because scanner will have tried to resolve as variable
  2723  - */
  2724  -any_identifier:
  2725  -IDENT
  2726  -| unreserved_keyword
  2727  -;
  2728  -
  2729  -unreserved_keyword:
  2730  -  ABSOLUTE
  2731  -| ALIAS
  2732  -| AND
  2733  -| ARRAY
  2734  -| ASSERT
  2735  -| BACKWARD
  2736  -| CALL
  2737  -| CHAIN
  2738  -| CLOSE
  2739  -| COLLATE
  2740  -| COLUMN
  2741  -| COLUMN_NAME
  2742  -| COMMIT
  2743  -| CONSTANT
  2744  -| CONSTRAINT
  2745  -| CONSTRAINT_NAME
  2746  -| CONTINUE
  2747  -| CURRENT
  2748  -| CURSOR
  2749  -| DATATYPE
  2750  -| DEBUG
  2751  -| DEFAULT
  2752  -| DETAIL
  2753  -| DIAGNOSTICS
  2754  -| DO
  2755  -| DUMP
  2756  -| ELSIF
  2757  -| ERRCODE
  2758  -| ERROR
  2759  -| EXCEPTION
  2760  -| EXIT
  2761  -| FETCH
  2762  -| FIRST
  2763  -| FORWARD
  2764  -| GET
  2765  -| HINT
  2766  -| IMPORT
  2767  -| INFO
  2768  -| INSERT
  2769  -| IS
  2770  -| LAST
  2771  -| LOG
  2772  -| MERGE
  2773  -| MESSAGE
  2774  -| MESSAGE_TEXT
  2775  -| MOVE
  2776  -| NEXT
  2777  -| NO
  2778  -| NO_SCROLL
  2779  -| NOTICE
  2780  -| OPEN
  2781  -| OPTION
  2782  -| PERFORM
  2783  -| PG_CONTEXT
  2784  -| PG_DATATYPE_NAME
  2785  -| PG_EXCEPTION_CONTEXT
  2786  -| PG_EXCEPTION_DETAIL
  2787  -| PG_EXCEPTION_HINT
  2788  -| PRINT_STRICT_PARAMS
  2789  -| PRIOR
  2790  -| QUERY
  2791  -| RAISE
  2792  -| RELATIVE
  2793  -| RETURN
  2794  -| RETURN_NEXT
  2795  -| RETURN_QUERY
  2796  -| RETURNED_SQLSTATE
  2797  -| REVERSE
  2798  -| ROLLBACK
  2799  -| ROW_COUNT
  2800  -| ROWTYPE
  2801  -| SCHEMA
  2802  -| SCHEMA_NAME
  2803  -| SCROLL
  2804  -| SLICE
  2805  -| SQLSTATE
  2806  -| STACKED
  2807  -| TABLE
  2808  -| TABLE_NAME
  2809  -| TYPE
  2810  -| UPSERT
  2811  -| USE_COLUMN
  2812  -| USE_VARIABLE
  2813  -| VARIABLE_CONFLICT
  2814  -| WARNING
  2815  -
  2816  -reserved_keyword:
  2817  -  ALL
  2818  -| BEGIN
  2819  -| BY
  2820  -| CASE
  2821  -| DECLARE
  2822  -| ELSE
  2823  -| END
  2824  -| END_CASE
  2825  -| END_IF
  2826  -| EXECUTE
  2827  -| FOR
  2828  -| FOREACH
  2829  -| FROM
  2830  -| IF
  2831  -| IN
  2832  -| INTO
  2833  -| LOOP
  2834  -| NOT
  2835  -| NULL
  2836  -| OR
  2837  -| STRICT
  2838  -| THEN
  2839  -| TO
  2840  -| USING
  2841  -| WHEN
  2842  -| WHILE
  2843  -
  2844  -%%
  2845  diff --git a/pkg/sql/scanner/plpgsql_scan.go b/pkg/sql/scanner/plpgsql_scan.go
  2846  deleted file mode 100644
  2847  index 3dc5500..0000000
  2848  --- a/pkg/sql/scanner/plpgsql_scan.go
  2849  +++ /dev/null
  2850  @@ -1,246 +0,0 @@
  2851  -// Copyright 2023 The Cockroach Authors.
  2852  -//
  2853  -// Use of this software is governed by the Business Source License
  2854  -// included in the file licenses/BSL.txt.
  2855  -//
  2856  -// As of the Change Date specified in that file, in accordance with
  2857  -// the Business Source License, use of this software will be governed
  2858  -// by the Apache License, Version 2.0, included in the file
  2859  -// licenses/APL.txt.
  2860  -
  2861  -package scanner
  2862  -
  2863  -import (
  2864  -	"fmt"
  2865  -	"go/constant"
  2866  -	"go/token"
  2867  -
  2868  -	sqllex "github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
  2869  -	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/plpgsql/parser/lexbase"
  2870  -)
  2871  -
  2872  -// PLpgSQLScanner is a scanner with a PLPGSQL specific scan function
  2873  -type PLpgSQLScanner struct {
  2874  -	Scanner
  2875  -}
  2876  -
  2877  -// Scan scans the next token and populates its information into lval.
  2878  -// This scan function contains rules for plpgsql.
  2879  -func (s *PLpgSQLScanner) Scan(lval ScanSymType) {
  2880  -	ch, skipWhiteSpace := s.scanSetup(lval)
  2881  -
  2882  -	if skipWhiteSpace {
  2883  -		return
  2884  -	}
  2885  -
  2886  -	switch ch {
  2887  -	case '$':
  2888  -		if s.scanDollarQuotedString(lval) {
  2889  -			lval.SetID(lexbase.SCONST)
  2890  -			return
  2891  -		}
  2892  -		return
  2893  -
  2894  -	case identQuote:
  2895  -		// "[^"]"
  2896  -		if s.scanString(lval, identQuote, false /* allowEscapes */, true /* requireUTF8 */) {
  2897  -			lval.SetID(lexbase.IDENT)
  2898  -		}
  2899  -		return
  2900  -
  2901  -	case singleQuote:
  2902  -		// '[^']'
  2903  -		if s.scanString(lval, ch, false /* allowEscapes */, true /* requireUTF8 */) {
  2904  -			lval.SetID(lexbase.SCONST)
  2905  -		}
  2906  -		return
  2907  -
  2908  -	case 'b':
  2909  -		// Bytes?
  2910  -		if s.peek() == singleQuote {
  2911  -			// b'[^']'
  2912  -			s.pos++
  2913  -			if s.scanString(lval, singleQuote, true /* allowEscapes */, false /* requireUTF8 */) {
  2914  -				lval.SetID(lexbase.BCONST)
  2915  -			}
  2916  -			return
  2917  -		}
  2918  -		s.scanIdent(lval)
  2919  -		return
  2920  -
  2921  -	case '.':
  2922  -		switch t := s.peek(); {
  2923  -		case t == '.': // ..
  2924  -			s.pos++
  2925  -			lval.SetID(lexbase.DOT_DOT)
  2926  -			return
  2927  -		case sqllex.IsDigit(t):
  2928  -			s.scanNumber(lval, ch)
  2929  -			return
  2930  -		}
  2931  -		return
  2932  -
  2933  -	case '!':
  2934  -		switch s.peek() {
  2935  -		case '=': // !=
  2936  -			s.pos++
  2937  -			lval.SetID(lexbase.NOT_EQUALS)
  2938  -			return
  2939  -		}
  2940  -		return
  2941  -
  2942  -	case '<':
  2943  -		switch s.peek() {
  2944  -		case '<': // <<
  2945  -			s.pos++
  2946  -			lval.SetID(lexbase.LESS_LESS)
  2947  -			return
  2948  -		case '=': // <=
  2949  -			s.pos++
  2950  -			lval.SetID(lexbase.LESS_EQUALS)
  2951  -			return
  2952  -		}
  2953  -		return
  2954  -
  2955  -	case '>':
  2956  -		switch s.peek() {
  2957  -		case '>': // >>
  2958  -			s.pos++
  2959  -			lval.SetID(lexbase.GREATER_GREATER)
  2960  -			return
  2961  -		case '=': // >=
  2962  -			s.pos++
  2963  -			lval.SetID(lexbase.GREATER_EQUALS)
  2964  -			return
  2965  -		}
  2966  -		return
  2967  -
  2968  -	case ':':
  2969  -		switch s.peek() {
  2970  -		case ':':
  2971  -			s.pos++
  2972  -			lval.SetID(lexbase.TYPECAST)
  2973  -			return
  2974  -		case '=':
  2975  -			s.pos++
  2976  -			lval.SetID(lexbase.COLON_EQUALS)
  2977  -			return
  2978  -		}
  2979  -		return
  2980  -
  2981  -	default:
  2982  -		if sqllex.IsDigit(ch) {
  2983  -			s.scanNumber(lval, ch)
  2984  -			return
  2985  -		}
  2986  -		if sqllex.IsIdentStart(ch) {
  2987  -			s.scanIdent(lval)
  2988  -			return
  2989  -		}
  2990  -	}
  2991  -	// Everything else is a single character token which we already initialized
  2992  -	// lval for above.
  2993  -}
  2994  -
  2995  -func (s *PLpgSQLScanner) scanNumber(lval ScanSymType, ch int) {
  2996  -	start := s.pos - 1
  2997  -	isHex := false
  2998  -	hasDecimal := ch == '.'
  2999  -	hasExponent := false
  3000  -
  3001  -	for {
  3002  -		ch := s.peek()
  3003  -		if (isHex && sqllex.IsHexDigit(ch)) || sqllex.IsDigit(ch) {
  3004  -			s.pos++
  3005  -			continue
  3006  -		}
  3007  -		if ch == 'x' || ch == 'X' {
  3008  -			if isHex || s.in[start] != '0' || s.pos != start+1 {
  3009  -				lval.SetID(lexbase.ERROR)
  3010  -				lval.SetStr(errInvalidHexNumeric)
  3011  -				return
  3012  -			}
  3013  -			s.pos++
  3014  -			isHex = true
  3015  -			continue
  3016  -		}
  3017  -		if isHex {
  3018  -			break
  3019  -		}
  3020  -		if ch == '.' {
  3021  -			if hasDecimal || hasExponent {
  3022  -				break
  3023  -			}
  3024  -			s.pos++
  3025  -			if s.peek() == '.' {
  3026  -				// Found ".." while scanning a number: back up to the end of the
  3027  -				// integer.
  3028  -				s.pos--
  3029  -				break
  3030  -			}
  3031  -			hasDecimal = true
  3032  -			continue
  3033  -		}
  3034  -		if ch == 'e' || ch == 'E' {
  3035  -			if hasExponent {
  3036  -				break
  3037  -			}
  3038  -			hasExponent = true
  3039  -			s.pos++
  3040  -			ch = s.peek()
  3041  -			if ch == '-' || ch == '+' {
  3042  -				s.pos++
  3043  -			}
  3044  -			ch = s.peek()
  3045  -			if !sqllex.IsDigit(ch) {
  3046  -				lval.SetID(lexbase.ERROR)
  3047  -				lval.SetStr("invalid floating point literal")
  3048  -				return
  3049  -			}
  3050  -			continue
  3051  -		}
  3052  -		break
  3053  -	}
  3054  -
  3055  -	lval.SetStr(s.in[start:s.pos])
  3056  -	if hasDecimal || hasExponent {
  3057  -		lval.SetID(lexbase.FCONST)
  3058  -		floatConst := constant.MakeFromLiteral(lval.Str(), token.FLOAT, 0)
  3059  -		if floatConst.Kind() == constant.Unknown {
  3060  -			lval.SetID(lexbase.ERROR)
  3061  -			lval.SetStr(fmt.Sprintf("could not make constant float from literal %q", lval.Str()))
  3062  -			return
  3063  -		}
  3064  -		lval.SetUnionVal(NewNumValFn(floatConst, lval.Str(), false /* negative */))
  3065  -	} else {
  3066  -		if isHex && s.pos == start+2 {
  3067  -			lval.SetID(lexbase.ERROR)
  3068  -			lval.SetStr(errInvalidHexNumeric)
  3069  -			return
  3070  -		}
  3071  -
  3072  -		// Strip off leading zeros from non-hex (decimal) literals so that
  3073  -		// constant.MakeFromLiteral doesn't inappropriately interpret the
  3074  -		// string as an octal literal. Note: we can't use strings.TrimLeft
  3075  -		// here, because it will truncate '0' to ''.
  3076  -		if !isHex {
  3077  -			for len(lval.Str()) > 1 && lval.Str()[0] == '0' {
  3078  -				lval.SetStr(lval.Str()[1:])
  3079  -			}
  3080  -		}
  3081  -
  3082  -		lval.SetID(lexbase.ICONST)
  3083  -		intConst := constant.MakeFromLiteral(lval.Str(), token.INT, 0)
  3084  -		if intConst.Kind() == constant.Unknown {
  3085  -			lval.SetID(lexbase.ERROR)
  3086  -			lval.SetStr(fmt.Sprintf("could not make constant int from literal %q", lval.Str()))
  3087  -			return
  3088  -		}
  3089  -		lval.SetUnionVal(NewNumValFn(intConst, lval.Str(), false /* negative */))
  3090  -	}
  3091  -}
  3092  -
  3093  -func (s *PLpgSQLScanner) scanIdent(lval ScanSymType) {
  3094  -	s.lowerCaseAndNormalizeIdent(lval)
  3095  -	lval.SetID(lexbase.GetKeywordID(lval.Str()))
  3096  -}
  3097  -- 
  3098  2.38.1
  3099