parseJoinCondition parses the ON / USING clause that follows a joined table reference. CROSS JOIN, APPLY, and NATURAL JOIN variants do not require a condition.
(joinType string, isNatural, isApply bool)
| 257 | // parseJoinCondition parses the ON / USING clause that follows a joined table reference. |
| 258 | // CROSS JOIN, APPLY, and NATURAL JOIN variants do not require a condition. |
| 259 | func (p *Parser) parseJoinCondition(joinType string, isNatural, isApply bool) (ast.Expression, error) { |
| 260 | isCrossJoin := joinType == "CROSS" || isApply |
| 261 | if isCrossJoin || isNatural { |
| 262 | return nil, nil |
| 263 | } |
| 264 | |
| 265 | if p.isType(models.TokenTypeOn) { |
| 266 | p.advance() // Consume ON |
| 267 | cond, err := p.parseExpression() |
| 268 | if err != nil { |
| 269 | return nil, goerrors.InvalidSyntaxError( |
| 270 | fmt.Sprintf("error parsing ON condition for %s JOIN: %v", joinType, err), |
| 271 | p.currentLocation(), |
| 272 | "", |
| 273 | ) |
| 274 | } |
| 275 | return cond, nil |
| 276 | } |
| 277 | |
| 278 | if p.isType(models.TokenTypeUsing) { |
| 279 | p.advance() // Consume USING |
| 280 | if !p.isType(models.TokenTypeLParen) { |
| 281 | return nil, p.expectedError("( after USING") |
| 282 | } |
| 283 | p.advance() |
| 284 | |
| 285 | var usingColumns []ast.Expression |
| 286 | for { |
| 287 | if !p.isIdentifier() { |
| 288 | return nil, p.expectedError("column name in USING") |
| 289 | } |
| 290 | usingColumns = append(usingColumns, &ast.Identifier{Name: p.currentToken.Token.Value}) |
| 291 | p.advance() |
| 292 | if !p.isType(models.TokenTypeComma) { |
| 293 | break |
| 294 | } |
| 295 | p.advance() |
| 296 | } |
| 297 | |
| 298 | if !p.isType(models.TokenTypeRParen) { |
| 299 | return nil, p.expectedError(") after USING column list") |
| 300 | } |
| 301 | p.advance() |
| 302 | |
| 303 | if len(usingColumns) == 1 { |
| 304 | return usingColumns[0], nil |
| 305 | } |
| 306 | return &ast.ListExpression{Values: usingColumns}, nil |
| 307 | } |
| 308 | |
| 309 | return nil, p.expectedError("ON or USING") |
| 310 | } |
| 311 | |
| 312 | // parseSampleClause parses the ClickHouse SAMPLE clause that specifies data sampling. |
| 313 | // It is called when the current token is SAMPLE (already verified by caller). |
no test coverage detected