normalizeSelectForDialect converts generic LIMIT/OFFSET fields into dialect-specific AST fields (TOP for SQL Server, FETCH for Oracle) on a shallow copy of the statement. This keeps the rendering code simple — each clause renderer only handles its own field.
(s *ast.SelectStatement, dialect string)
| 334 | // shallow copy of the statement. This keeps the rendering code simple — |
| 335 | // each clause renderer only handles its own field. |
| 336 | func normalizeSelectForDialect(s *ast.SelectStatement, dialect string) { |
| 337 | switch dialect { |
| 338 | case "sqlserver": |
| 339 | if s.Top == nil && s.Limit != nil { |
| 340 | if s.Offset != nil || len(s.OrderBy) > 0 { |
| 341 | // SQL Server 2012+ OFFSET/FETCH syntax (requires ORDER BY in practice, |
| 342 | // but we emit it faithfully and let the database validate). |
| 343 | fetchVal := int64(*s.Limit) |
| 344 | s.Fetch = &ast.FetchClause{ |
| 345 | FetchValue: &fetchVal, |
| 346 | FetchType: "NEXT", |
| 347 | } |
| 348 | offsetVal := int64(0) |
| 349 | if s.Offset != nil { |
| 350 | offsetVal = int64(*s.Offset) |
| 351 | } |
| 352 | s.Fetch.OffsetValue = &offsetVal |
| 353 | s.Limit = nil |
| 354 | s.Offset = nil |
| 355 | } else { |
| 356 | // Simple TOP N |
| 357 | s.Top = &ast.TopClause{ |
| 358 | Count: &ast.LiteralValue{Value: *s.Limit, Type: "int"}, |
| 359 | } |
| 360 | s.Limit = nil |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | case "oracle": |
| 365 | if s.Fetch == nil && s.Limit != nil { |
| 366 | fetchVal := int64(*s.Limit) |
| 367 | s.Fetch = &ast.FetchClause{ |
| 368 | FetchValue: &fetchVal, |
| 369 | FetchType: "FIRST", |
| 370 | } |
| 371 | if s.Offset != nil { |
| 372 | offsetVal := int64(*s.Offset) |
| 373 | s.Fetch.OffsetValue = &offsetVal |
| 374 | s.Offset = nil |
| 375 | } |
| 376 | s.Limit = nil |
| 377 | } |
| 378 | } |
| 379 | } |
| 380 | |
| 381 | func renderInsert(i *ast.InsertStatement, opts ast.FormatOptions) string { |
| 382 | if i == nil { |