Skip to content

Commit 019ec08

Browse files
author
Jaco Labuschagne
committed
Enhance error handling and documentation in PL/SQL splitter
- Improved error reporting by adding context lines around syntax errors, allowing users to see surrounding code for better debugging. - Updated README.md to include new features and usage examples for enhanced error handling. - Introduced a new funding configuration file for project support. - Adjusted command-line flags to support context line configuration for error reporting. - Enhanced tests to validate the new error context functionality and ensure accurate error messages. - Updated parser grammar to support additional PL/SQL constructs, including declare blocks.
1 parent 1c32033 commit 019ec08

15 files changed

Lines changed: 26667 additions & 25629 deletions

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ko_fi: zodimo

README.md

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
A Go library for accurately splitting Oracle PL/SQL scripts into individual statements with precise boundary detection using ANTLR4 for parsing.
44

55
# DISCLAIMER
6-
This project was created with the help of an ai coding assistent.
6+
This project was created with the help of AI assistance:
7+
- Development performed using [Cursor IDE](https://cursor.com), an AI-powered code editor
8+
- Project structure and development methodology based on the [VAN Memory Bank](https://github.com/vanzan01/cursor-memory-bank) framework
79

810
## Overview
911

@@ -324,4 +326,69 @@ Planned enhancements for future releases:
324326
- Streaming support for processing very large files
325327
- Enhanced error recovery for incomplete statements
326328
- Support for additional Oracle-specific syntax
327-
- Performance optimizations for large scripts
329+
- Performance optimizations for large scripts
330+
331+
### Advanced Error Handling
332+
333+
The library provides detailed error reporting capabilities to help diagnose and fix syntax errors:
334+
335+
```go
336+
package main
337+
338+
import (
339+
"fmt"
340+
"log"
341+
342+
"github.com/zodimo/go-plsql-statement-splitter/pkg/splitter"
343+
)
344+
345+
func main() {
346+
// Create a splitter with enhanced error reporting
347+
s := splitter.NewSplitter(
348+
splitter.WithVerboseErrors(true), // Include detailed error messages
349+
splitter.WithMaxErrors(5), // Maximum number of errors to report
350+
splitter.WithErrorContext(true), // Include error context
351+
splitter.WithErrorContextLines(5), // Show 5 lines before and after each error
352+
splitter.WithErrorStatement(true), // Include statement causing error
353+
)
354+
355+
// Try to split statements and handle errors
356+
_, err := s.SplitFile("path/to/script.sql")
357+
if err != nil {
358+
syntaxErr, isSyntaxErr := err.(*splitter.SyntaxError)
359+
if isSyntaxErr {
360+
// This will print the error with context showing 5 lines before and after
361+
fmt.Printf("Syntax error detected:\n%s\n", syntaxErr.Error())
362+
} else {
363+
log.Fatalf("Error: %v", err)
364+
}
365+
}
366+
}
367+
```
368+
369+
An example of the enhanced error output:
370+
371+
```
372+
Syntax error at line 42, column 10: mismatched input 'END' expecting {';', ','}
373+
40 | FOR emp IN (SELECT * FROM employees) LOOP
374+
41 | DBMS_OUTPUT.PUT_LINE('Employee: ' || emp.name)
375+
42 | END LOOP
376+
^
377+
43 | END;
378+
44 | /
379+
```
380+
381+
The error output includes:
382+
- Error message with line and column number
383+
- Context showing several lines before and after the error
384+
- A marker (^) pointing precisely to the error position
385+
386+
## Acknowledgements
387+
388+
### Development Tools
389+
390+
- [Cursor](https://cursor.com) - An advanced IDE powered by AI that was used for the development of this project.
391+
392+
### Development Methodology
393+
394+
This project utilizes the structured memory bank system developed by [vanzan01 - cursor-memory-bank](https://github.com/vanzan01/cursor-memory-bank), which provides an organized framework for AI-assisted software development.

cmd/splitter/main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func main() {
2626
allErrors bool
2727
jsonPretty bool
2828
jsonIndent string
29+
contextLines int
2930
)
3031

3132
flag.StringVar(&outputFormat, "format", "text", "Output format: text or json")
@@ -40,6 +41,7 @@ func main() {
4041
flag.BoolVar(&allErrors, "all-errors", false, "Show all errors, ignoring max-errors setting")
4142
flag.BoolVar(&jsonPretty, "pretty", true, "Pretty print JSON output")
4243
flag.StringVar(&jsonIndent, "indent", " ", "Indentation for JSON output")
44+
flag.IntVar(&contextLines, "context-lines", 3, "Number of context lines to show before and after errors")
4345
flag.Parse()
4446

4547
// Check if a file path was provided
@@ -55,7 +57,7 @@ func main() {
5557
fmt.Println(" splitter -format=json script.sql")
5658
fmt.Println(" splitter -format=json -output=result.json script.sql")
5759
fmt.Println(" splitter -verbose-errors script.sql")
58-
fmt.Println(" splitter -all-errors -error-context invalid.sql")
60+
fmt.Println(" splitter -all-errors -error-context -context-lines=5 invalid.sql")
5961

6062
fmt.Println("\nRunning demo...")
6163
demoSplitString()
@@ -77,6 +79,7 @@ func main() {
7779
}
7880
if includeErrorContext {
7981
splitterOpts = append(splitterOpts, splitter.WithErrorContext(true))
82+
splitterOpts = append(splitterOpts, splitter.WithErrorContextLines(contextLines))
8083
}
8184
if includeErrorStmt {
8285
splitterOpts = append(splitterOpts, splitter.WithErrorStatement(true))
@@ -234,6 +237,7 @@ INSERT INTO employees (id, name) VALUES (1, 'John);
234237
s := splitter.NewSplitter(
235238
splitter.WithVerboseErrors(true),
236239
splitter.WithErrorContext(true),
240+
splitter.WithErrorContextLines(5),
237241
splitter.WithMaxErrors(5),
238242
)
239243

internal/parser/PlSqlParser.g4

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5467,7 +5467,7 @@ primary_key_clause
54675467
// Anonymous PL/SQL code block
54685468

54695469
anonymous_block
5470-
: (DECLARE seq_of_declare_specs)? BEGIN seq_of_statements (EXCEPTION exception_handler+)? END SEMICOLON
5470+
: (DECLARE seq_of_declare_specs)? BEGIN seq_of_statements (EXCEPTION exception_handler+)? END (SEMICOLON)?
54715471
;
54725472

54735473
// Common DDL Clauses
@@ -5591,7 +5591,11 @@ varray_type_def
55915591
// Statements
55925592

55935593
seq_of_statements
5594-
: (statement (';' | EOF) | label_declaration)+
5594+
: (statement (';' | EOF) | label_declaration | declare_block)+
5595+
;
5596+
5597+
declare_block
5598+
: DECLARE seq_of_declare_specs? BEGIN seq_of_statements (EXCEPTION exception_handler+)? END (';')?
55955599
;
55965600

55975601
label_declaration

internal/parser/gen/PlSqlParser.interp

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)