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

     1  // Copyright 2019 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  	"context"
    15  	"fmt"
    16  
    17  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    19  )
    20  
    21  // RunShowSyntax analyzes the syntax and reports its structure as data
    22  // for the client. Even an error is reported as data.
    23  //
    24  // Since errors won't propagate to the client as an error, but as
    25  // a result, the usual code path to capture and record errors will not
    26  // be triggered. Instead, the caller can pass a reportErr closure to
    27  // capture errors instead. May be nil.
    28  func RunShowSyntax(
    29  	ctx context.Context,
    30  	stmt string,
    31  	report func(ctx context.Context, field, msg string),
    32  	reportErr func(ctx context.Context, err error),
    33  ) {
    34  	stmts, err := Parse(stmt)
    35  	if err != nil {
    36  		if reportErr != nil {
    37  			reportErr(ctx, err)
    38  		}
    39  
    40  		pqErr := pgerror.Flatten(err)
    41  		report(ctx, "error", pqErr.Message)
    42  		report(ctx, "code", pqErr.Code)
    43  		if pqErr.Source != nil {
    44  			if pqErr.Source.File != "" {
    45  				report(ctx, "file", pqErr.Source.File)
    46  			}
    47  			if pqErr.Source.Line > 0 {
    48  				report(ctx, "line", fmt.Sprintf("%d", pqErr.Source.Line))
    49  			}
    50  			if pqErr.Source.Function != "" {
    51  				report(ctx, "function", pqErr.Source.Function)
    52  			}
    53  		}
    54  		if pqErr.Detail != "" {
    55  			report(ctx, "detail", pqErr.Detail)
    56  		}
    57  		if pqErr.Hint != "" {
    58  			report(ctx, "hint", pqErr.Hint)
    59  		}
    60  	} else {
    61  		for i := range stmts {
    62  			report(ctx, "sql", tree.AsStringWithFlags(stmts[i].AST, tree.FmtParsable))
    63  		}
    64  	}
    65  }