11import { SplitterOptions , defaultSplitterOptions } from './options' ;
22
33const 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' ) ;
48
59type SplitterSpecialMarkerType = 'copy_stdin_start' | 'copy_stdin_end' | 'copy_stdin_line' ;
610export interface SplitStreamContext {
@@ -40,6 +44,7 @@ export interface ScannerContext {
4044 readonly wasDataOnLine : boolean ;
4145 readonly isCopyFromStdin : boolean ;
4246 readonly isCopyFromStdinCandidate : boolean ;
47+ readonly beginEndIdentLevel : number ;
4348}
4449
4550export interface SplitLineContext extends SplitStreamContext {
@@ -49,6 +54,7 @@ export interface SplitLineContext extends SplitStreamContext {
4954 end : number ;
5055 wasDataOnLine : boolean ;
5156 currentCommandStart : number ;
57+ beginEndIdentLevel : number ;
5258
5359 // unread: string;
5460 // currentStatement: string;
@@ -111,6 +117,8 @@ interface Token {
111117 type :
112118 | 'string'
113119 | 'delimiter'
120+ | 'end'
121+ | 'begin'
114122 | 'whitespace'
115123 | 'eoln'
116124 | 'data'
@@ -228,7 +236,8 @@ export function scanToken(context: ScannerContext): Token {
228236 } ;
229237 }
230238
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 ) {
232241 return {
233242 type : 'delimiter' ,
234243 length : context . currentDelimiter . length ,
@@ -350,6 +359,35 @@ export function scanToken(context: ScannerContext): Token {
350359 } ;
351360 }
352361
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+
353391 const dollarString = scanDollarQuotedString ( context ) ;
354392 if ( dollarString ) return dollarString ;
355393
@@ -366,6 +404,7 @@ function containsDataAfterDelimiterOnLine(context: ScannerContext, delimiter: To
366404 wasDataOnLine : context . wasDataOnLine ,
367405 isCopyFromStdinCandidate : context . isCopyFromStdinCandidate ,
368406 isCopyFromStdin : context . isCopyFromStdin ,
407+ beginEndIdentLevel : context . beginEndIdentLevel ,
369408 } ;
370409
371410 cloned . position += delimiter . length ;
@@ -594,6 +633,18 @@ export function splitQueryLine(context: SplitLineContext) {
594633 markStartCommand ( context ) ;
595634 context . isCopyFromStdinCandidate = false ;
596635 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 ;
597648 }
598649 }
599650
@@ -660,6 +711,7 @@ export function splitQuery(sql: string, options: SplitterOptions = null): SplitR
660711 trimCommandStartPosition : 0 ,
661712 trimCommandStartLine : 0 ,
662713 trimCommandStartColumn : 0 ,
714+ beginEndIdentLevel : 0 ,
663715
664716 wasDataInCommand : false ,
665717 isCopyFromStdin : false ,
0 commit comments