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

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package parser
    12  
    13  import (
    14  	"reflect"
    15  	"testing"
    16  )
    17  
    18  func TestScanOneStmt(t *testing.T) {
    19  	type stmt struct {
    20  		sql string
    21  		tok []int
    22  	}
    23  	testData := []struct {
    24  		sql string
    25  		exp []stmt
    26  	}{
    27  		{sql: ``, exp: nil},
    28  		{sql: `;`, exp: nil},
    29  		{sql: `  ;  ; `, exp: nil},
    30  		{
    31  			sql: `SELECT 1`,
    32  			exp: []stmt{{
    33  				sql: `SELECT 1`,
    34  				tok: []int{SELECT, ICONST},
    35  			}},
    36  		},
    37  		{
    38  			sql: `SELECT 1;`,
    39  			exp: []stmt{{
    40  				sql: `SELECT 1`,
    41  				tok: []int{SELECT, ICONST},
    42  			}},
    43  		},
    44  		{
    45  			sql: `SELECT 1 /* comment */  ; /* comment */  ; /* comment */ `,
    46  			exp: []stmt{{
    47  				sql: `SELECT 1`,
    48  				tok: []int{SELECT, ICONST},
    49  			}},
    50  		},
    51  		{
    52  			sql: `;SELECT 1`,
    53  			exp: []stmt{{
    54  				sql: `SELECT 1`,
    55  				tok: []int{SELECT, ICONST},
    56  			}},
    57  		},
    58  		{
    59  			sql: `  ; /* comment */ ;  SELECT 1`,
    60  			exp: []stmt{{
    61  				sql: `SELECT 1`,
    62  				tok: []int{SELECT, ICONST},
    63  			}},
    64  		},
    65  		{
    66  			sql: `;;SELECT 1;;`,
    67  			exp: []stmt{{
    68  				sql: `SELECT 1`,
    69  				tok: []int{SELECT, ICONST},
    70  			}},
    71  		},
    72  		{
    73  			sql: ` ; /* x */ SELECT 1  ; SET /* y */ ; ;  INSERT INTO table;  ;`,
    74  			exp: []stmt{
    75  				{
    76  					sql: `SELECT 1`,
    77  					tok: []int{SELECT, ICONST},
    78  				},
    79  				{
    80  					sql: `SET`,
    81  					tok: []int{SET},
    82  				},
    83  				{
    84  					sql: `INSERT INTO table`,
    85  					tok: []int{INSERT, INTO, TABLE},
    86  				},
    87  			},
    88  		},
    89  		{
    90  			sql: `SELECT ';'`,
    91  			exp: []stmt{{
    92  				sql: `SELECT ';'`,
    93  				tok: []int{SELECT, SCONST},
    94  			}},
    95  		},
    96  		{
    97  			sql: `SELECT ';';`,
    98  			exp: []stmt{{
    99  				sql: `SELECT ';'`,
   100  				tok: []int{SELECT, SCONST},
   101  			}},
   102  		},
   103  		{
   104  			// An error should stop the scanning and return the rest of the string.
   105  			sql: `SELECT 1; SELECT 0x FROM t; SELECT 2`,
   106  			exp: []stmt{
   107  				{
   108  					sql: `SELECT 1`,
   109  					tok: []int{SELECT, ICONST},
   110  				},
   111  				{
   112  					sql: `SELECT 0x FROM t; SELECT 2`,
   113  					tok: []int{SELECT, ERROR},
   114  				},
   115  			},
   116  		},
   117  	}
   118  
   119  	for _, tc := range testData {
   120  		var p Parser
   121  		p.scanner.init(tc.sql)
   122  
   123  		var result []stmt
   124  		for {
   125  			sql, tokens, done := p.scanOneStmt()
   126  			if sql == "" {
   127  				break
   128  			}
   129  			s := stmt{sql: sql}
   130  			for _, t := range tokens {
   131  				s.tok = append(s.tok, int(t.id))
   132  			}
   133  			result = append(result, s)
   134  			if done {
   135  				break
   136  			}
   137  		}
   138  		if !reflect.DeepEqual(result, tc.exp) {
   139  			t.Errorf("expected\n  %+v, but found\n  %+v", tc.exp, result)
   140  		}
   141  	}
   142  }