1
1
import { SplitterOptions , defaultSplitterOptions } from './options' ;
2
2
3
3
const SEMICOLON = ';' ;
4
+ const BEGIN_EXTRA_KEYWORDS = [ 'DEFERRED' , 'IMMEDIATE' , 'EXCLUSIVE' , 'TRANSACTION' ] ;
5
+ const BEGIN_EXTRA_KEYWORDS_REGEX = new RegExp ( `^(?:${ BEGIN_EXTRA_KEYWORDS . join ( '|' ) } )` , 'i' ) ;
6
+ const END_EXTRA_KEYWORDS = [ 'TRANSACTION' , 'IF' ] ;
7
+ const END_EXTRA_KEYWORDS_REGEX = new RegExp ( `^(?:${ END_EXTRA_KEYWORDS . join ( '|' ) } )` , 'i' ) ;
4
8
5
9
type SplitterSpecialMarkerType = 'copy_stdin_start' | 'copy_stdin_end' | 'copy_stdin_line' ;
6
10
export interface SplitStreamContext {
@@ -40,6 +44,7 @@ export interface ScannerContext {
40
44
readonly wasDataOnLine : boolean ;
41
45
readonly isCopyFromStdin : boolean ;
42
46
readonly isCopyFromStdinCandidate : boolean ;
47
+ readonly beginEndIdentLevel : number ;
43
48
}
44
49
45
50
export interface SplitLineContext extends SplitStreamContext {
@@ -49,6 +54,7 @@ export interface SplitLineContext extends SplitStreamContext {
49
54
end : number ;
50
55
wasDataOnLine : boolean ;
51
56
currentCommandStart : number ;
57
+ beginEndIdentLevel : number ;
52
58
53
59
// unread: string;
54
60
// currentStatement: string;
@@ -111,6 +117,8 @@ interface Token {
111
117
type :
112
118
| 'string'
113
119
| 'delimiter'
120
+ | 'end'
121
+ | 'begin'
114
122
| 'whitespace'
115
123
| 'eoln'
116
124
| 'data'
@@ -228,7 +236,8 @@ export function scanToken(context: ScannerContext): Token {
228
236
} ;
229
237
}
230
238
231
- if ( context . currentDelimiter && s . slice ( pos ) . startsWith ( context . currentDelimiter ) ) {
239
+ const isInBeginEnd = context . options . skipSeparatorBeginEnd && context . beginEndIdentLevel > 0 ;
240
+ if ( context . currentDelimiter && s . slice ( pos ) . startsWith ( context . currentDelimiter ) && ! isInBeginEnd ) {
232
241
return {
233
242
type : 'delimiter' ,
234
243
length : context . currentDelimiter . length ,
@@ -350,6 +359,35 @@ export function scanToken(context: ScannerContext): Token {
350
359
} ;
351
360
}
352
361
362
+ if ( context . options . skipSeparatorBeginEnd && s . slice ( pos ) . match ( / ^ b e g i n / i) ) {
363
+ let pos2 = pos + 'BEGIN' . length ;
364
+ let pos0 = pos2 ;
365
+
366
+ while ( pos0 < context . end && / [ ^ a - z A - Z 0 - 9 ] / . test ( s [ pos0 ] ) ) pos0 ++ ;
367
+
368
+ if ( ! BEGIN_EXTRA_KEYWORDS_REGEX . test ( s . slice ( pos0 ) ) ) {
369
+ return {
370
+ type : 'begin' ,
371
+ length : pos2 - pos ,
372
+ lengthWithoutWhitespace : pos0 - pos ,
373
+ } ;
374
+ }
375
+ }
376
+
377
+ if ( context . options . skipSeparatorBeginEnd && s . slice ( pos ) . match ( / ^ e n d / i) ) {
378
+ let pos2 = pos + 'END' . length ;
379
+ let pos0 = pos2 ;
380
+
381
+ while ( pos0 < context . end && / [ ^ a - z A - Z 0 - 9 ] / . test ( s [ pos0 ] ) ) pos0 ++ ;
382
+
383
+ if ( ! END_EXTRA_KEYWORDS_REGEX . test ( s . slice ( pos0 ) ) ) {
384
+ return {
385
+ type : 'end' ,
386
+ length : pos2 - pos ,
387
+ } ;
388
+ }
389
+ }
390
+
353
391
const dollarString = scanDollarQuotedString ( context ) ;
354
392
if ( dollarString ) return dollarString ;
355
393
@@ -366,6 +404,7 @@ function containsDataAfterDelimiterOnLine(context: ScannerContext, delimiter: To
366
404
wasDataOnLine : context . wasDataOnLine ,
367
405
isCopyFromStdinCandidate : context . isCopyFromStdinCandidate ,
368
406
isCopyFromStdin : context . isCopyFromStdin ,
407
+ beginEndIdentLevel : context . beginEndIdentLevel ,
369
408
} ;
370
409
371
410
cloned . position += delimiter . length ;
@@ -594,6 +633,18 @@ export function splitQueryLine(context: SplitLineContext) {
594
633
markStartCommand ( context ) ;
595
634
context . isCopyFromStdinCandidate = false ;
596
635
break ;
636
+ case 'begin' :
637
+ if ( context . options . skipSeparatorBeginEnd ) {
638
+ context . beginEndIdentLevel ++ ;
639
+ }
640
+ movePosition ( context , token . length , false ) ;
641
+ break ;
642
+ case 'end' :
643
+ if ( context . options . skipSeparatorBeginEnd && context . beginEndIdentLevel > 0 ) {
644
+ context . beginEndIdentLevel -- ;
645
+ }
646
+ movePosition ( context , token . length , false ) ;
647
+ break ;
597
648
}
598
649
}
599
650
@@ -660,6 +711,7 @@ export function splitQuery(sql: string, options: SplitterOptions = null): SplitR
660
711
trimCommandStartPosition : 0 ,
661
712
trimCommandStartLine : 0 ,
662
713
trimCommandStartColumn : 0 ,
714
+ beginEndIdentLevel : 0 ,
663
715
664
716
wasDataInCommand : false ,
665
717
isCopyFromStdin : false ,
0 commit comments