Skip to content

Commit ce3ef59

Browse files
committed
Add ForceSeekTableHint and FORCESCAN support for table hints
- Add ForceSeekTableHint AST type for FORCESEEK with optional index and column parameters - Add FORCESEEK parsing with index name/number and column list support - Add FORCESCAN to table hint kind mapping - Add JSON marshaling for ForceSeekTableHint - Enable Baselines100_FromClauseTests100 test
1 parent 14332f3 commit ce3ef59

4 files changed

Lines changed: 87 additions & 1 deletion

File tree

ast/table_hint.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,12 @@ type LiteralTableHint struct {
2727
}
2828

2929
func (*LiteralTableHint) tableHint() {}
30+
31+
// ForceSeekTableHint represents FORCESEEK table hint with optional index and column list.
32+
type ForceSeekTableHint struct {
33+
HintKind string `json:"HintKind,omitempty"`
34+
IndexValue *IdentifierOrValueExpression `json:"IndexValue,omitempty"`
35+
ColumnValues []*ColumnReferenceExpression `json:"ColumnValues,omitempty"`
36+
}
37+
38+
func (*ForceSeekTableHint) tableHint() {}

parser/marshal.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,6 +3363,24 @@ func tableHintToJSON(h ast.TableHintType) jsonNode {
33633363
node["HintKind"] = th.HintKind
33643364
}
33653365
return node
3366+
case *ast.ForceSeekTableHint:
3367+
node := jsonNode{
3368+
"$type": "ForceSeekTableHint",
3369+
}
3370+
if th.IndexValue != nil {
3371+
node["IndexValue"] = identifierOrValueExpressionToJSON(th.IndexValue)
3372+
}
3373+
if len(th.ColumnValues) > 0 {
3374+
cols := make([]jsonNode, len(th.ColumnValues))
3375+
for i, c := range th.ColumnValues {
3376+
cols[i] = columnReferenceExpressionToJSON(c)
3377+
}
3378+
node["ColumnValues"] = cols
3379+
}
3380+
if th.HintKind != "" {
3381+
node["HintKind"] = th.HintKind
3382+
}
3383+
return node
33663384
default:
33673385
return jsonNode{"$type": "TableHint"}
33683386
}

parser/parse_select.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,6 +3174,61 @@ func (p *Parser) parseTableHint() (ast.TableHintType, error) {
31743174
return hint, nil
31753175
}
31763176

3177+
// FORCESEEK hint with optional index and column list
3178+
if hintName == "FORCESEEK" {
3179+
hint := &ast.ForceSeekTableHint{
3180+
HintKind: "ForceSeek",
3181+
}
3182+
// Check for optional parenthesis with index and columns
3183+
if p.curTok.Type != TokenLParen {
3184+
return hint, nil
3185+
}
3186+
p.nextToken() // consume (
3187+
// Parse index value (identifier or number)
3188+
if p.curTok.Type == TokenNumber {
3189+
hint.IndexValue = &ast.IdentifierOrValueExpression{
3190+
Value: p.curTok.Literal,
3191+
ValueExpression: &ast.IntegerLiteral{
3192+
LiteralType: "Integer",
3193+
Value: p.curTok.Literal,
3194+
},
3195+
}
3196+
p.nextToken()
3197+
} else if p.curTok.Type == TokenIdent {
3198+
hint.IndexValue = &ast.IdentifierOrValueExpression{
3199+
Value: p.curTok.Literal,
3200+
Identifier: &ast.Identifier{
3201+
Value: p.curTok.Literal,
3202+
QuoteType: "NotQuoted",
3203+
},
3204+
}
3205+
p.nextToken()
3206+
}
3207+
// Parse optional column list
3208+
if p.curTok.Type == TokenLParen {
3209+
p.nextToken() // consume (
3210+
for p.curTok.Type != TokenRParen && p.curTok.Type != TokenEOF {
3211+
col, _ := p.parseColumnReference()
3212+
if col != nil {
3213+
hint.ColumnValues = append(hint.ColumnValues, col)
3214+
}
3215+
if p.curTok.Type == TokenComma {
3216+
p.nextToken()
3217+
} else if p.curTok.Type != TokenRParen {
3218+
break
3219+
}
3220+
}
3221+
if p.curTok.Type == TokenRParen {
3222+
p.nextToken() // consume )
3223+
}
3224+
}
3225+
// Consume outer )
3226+
if p.curTok.Type == TokenRParen {
3227+
p.nextToken()
3228+
}
3229+
return hint, nil
3230+
}
3231+
31773232
// Map hint names to HintKind
31783233
hintKind := getTableHintKind(hintName)
31793234
if hintKind == "" {
@@ -3218,6 +3273,10 @@ func getTableHintKind(name string) string {
32183273
return "XLock"
32193274
case "NOWAIT":
32203275
return "NoWait"
3276+
case "FORCESEEK":
3277+
return "ForceSeek"
3278+
case "FORCESCAN":
3279+
return "ForceScan"
32213280
default:
32223281
return ""
32233282
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}

0 commit comments

Comments
 (0)