MCPcopy Create free account
hub / github.com/ajitpratap0/GoSQLX / parseFromTableReference

Method parseFromTableReference

pkg/sql/parser/select_subquery.go:32–258  ·  view source on GitHub ↗

parseFromTableReference parses a single table reference in a FROM clause, including derived tables (subqueries), LATERAL, and optional aliases.

()

Source from the content-addressed store, hash-verified

30// parseFromTableReference parses a single table reference in a FROM clause,
31// including derived tables (subqueries), LATERAL, and optional aliases.
32func (p *Parser) parseFromTableReference() (ast.TableReference, error) {
33 var tableRef ast.TableReference
34
35 // Check for LATERAL keyword (PostgreSQL)
36 isLateral := false
37 if p.isType(models.TokenTypeLateral) {
38 isLateral = true
39 p.advance() // Consume LATERAL
40 }
41
42 // Check for derived table (subquery in parentheses)
43 if p.isType(models.TokenTypeLParen) {
44 p.advance() // Consume (
45
46 // Check if this is a subquery (starts with SELECT or WITH)
47 if !p.isType(models.TokenTypeSelect) && !p.isType(models.TokenTypeWith) {
48 return tableRef, p.expectedError("SELECT in derived table")
49 }
50
51 // Consume SELECT token before calling parseSelectStatement
52 p.advance() // Consume SELECT
53
54 // Parse the subquery
55 subquery, err := p.parseSelectStatement()
56 if err != nil {
57 return tableRef, err
58 }
59 selectStmt, ok := subquery.(*ast.SelectStatement)
60 if !ok {
61 return tableRef, p.expectedError("SELECT statement in derived table")
62 }
63
64 // Expect closing parenthesis
65 if !p.isType(models.TokenTypeRParen) {
66 return tableRef, p.expectedError(")")
67 }
68 p.advance() // Consume )
69
70 tableRef = ast.TableReference{
71 Subquery: selectStmt,
72 Lateral: isLateral,
73 }
74 } else if p.dialect == string(keywords.DialectSnowflake) &&
75 p.isType(models.TokenTypePlaceholder) && strings.HasPrefix(p.currentToken.Token.Value, "@") {
76 // Snowflake stage reference: @stage_name or @db.schema.stage/path.
77 // Tokenized as PLACEHOLDER; consume as a table name.
78 // Gated to Snowflake to avoid misinterpreting @variable in other dialects.
79 stageName := p.currentToken.Token.Value
80 p.advance()
81 // Optional /path suffix — consume tokens joined by / until a space boundary.
82 // Slash tokenizes as TokenTypeDiv.
83 for p.isType(models.TokenTypeDiv) {
84 stageName += "/"
85 p.advance()
86 if p.isIdentifier() || p.isType(models.TokenTypeKeyword) {
87 stageName += p.currentToken.Token.Value
88 p.advance()
89 }

Callers 1

parseFromClauseMethod · 0.95

Calls 15

isTypeMethod · 0.95
advanceMethod · 0.95
expectedErrorMethod · 0.95
parseSelectStatementMethod · 0.95
isIdentifierMethod · 0.95
parseFunctionCallMethod · 0.95
parseQualifiedNameMethod · 0.95
supportsTableFunctionMethod · 0.95
isMariaDBClauseStartMethod · 0.95
isPivotKeywordMethod · 0.95

Tested by

no test coverage detected