@@ -29,6 +29,8 @@ import type { EntityCollector } from './entityCollector';
29
29
import { EntityContext } from './entityCollector' ;
30
30
import SemanticContextCollector from './semanticContextCollector' ;
31
31
32
+ export const SQL_SPLIT_SYMBOL_TEXT = ';' ;
33
+
32
34
/**
33
35
* Basic SQL class, every sql needs extends it.
34
36
*/
@@ -286,7 +288,6 @@ export abstract class BasicSQL<
286
288
if ( errors . length || ! this . _parseTree ) {
287
289
return null ;
288
290
}
289
-
290
291
const splitListener = this . splitListener ;
291
292
this . listen ( splitListener , this . _parseTree ) ;
292
293
@@ -299,6 +300,78 @@ export abstract class BasicSQL<
299
300
return res ;
300
301
}
301
302
303
+ /**
304
+ * Get the smaller range of input
305
+ * @param input string
306
+ * @param allTokens all tokens from input
307
+ * @param tokenIndexOffset offset of the tokenIndex in the range of input
308
+ * @param caretTokenIndex tokenIndex of caretPosition
309
+ * @returns inputSlice: string, caretTokenIndex: number
310
+ */
311
+ private splitInputBySymbolText (
312
+ input : string ,
313
+ allTokens : Token [ ] ,
314
+ tokenIndexOffset : number ,
315
+ caretTokenIndex : number
316
+ ) : { inputSlice : string ; allTokens : Token [ ] ; caretTokenIndex : number } {
317
+ const tokens = allTokens . slice ( tokenIndexOffset ) ;
318
+ /**
319
+ * Set startToken
320
+ */
321
+ let startToken : Token | null = null ;
322
+ for ( let tokenIndex = caretTokenIndex - tokenIndexOffset ; tokenIndex >= 0 ; tokenIndex -- ) {
323
+ const token = tokens [ tokenIndex ] ;
324
+ if ( token ?. text === SQL_SPLIT_SYMBOL_TEXT ) {
325
+ startToken = tokens [ tokenIndex + 1 ] ;
326
+ break ;
327
+ }
328
+ }
329
+ if ( startToken === null ) {
330
+ startToken = tokens [ 0 ] ;
331
+ }
332
+
333
+ /**
334
+ * Set stopToken
335
+ */
336
+ let stopToken : Token | null = null ;
337
+ for (
338
+ let tokenIndex = caretTokenIndex - tokenIndexOffset ;
339
+ tokenIndex < tokens . length ;
340
+ tokenIndex ++
341
+ ) {
342
+ const token = tokens [ tokenIndex ] ;
343
+ if ( token ?. text === SQL_SPLIT_SYMBOL_TEXT ) {
344
+ stopToken = token ;
345
+ break ;
346
+ }
347
+ }
348
+ if ( stopToken === null ) {
349
+ stopToken = tokens [ tokens . length - 1 ] ;
350
+ }
351
+
352
+ const indexOffset = tokens [ 0 ] . start ;
353
+ let startIndex = startToken . start - indexOffset ;
354
+ let stopIndex = stopToken . stop + 1 - indexOffset ;
355
+
356
+ /**
357
+ * Save offset of the tokenIndex in the range of input
358
+ * compared to the tokenIndex in the whole input
359
+ */
360
+ const _tokenIndexOffset = startToken . tokenIndex ;
361
+ const _caretTokenIndex = caretTokenIndex - _tokenIndexOffset ;
362
+
363
+ /**
364
+ * Get the smaller range of _input
365
+ */
366
+ const _input = input . slice ( startIndex , stopIndex ) ;
367
+
368
+ return {
369
+ inputSlice : _input ,
370
+ allTokens : allTokens . slice ( _tokenIndexOffset ) ,
371
+ caretTokenIndex : _caretTokenIndex ,
372
+ } ;
373
+ }
374
+
302
375
/**
303
376
* Get the minimum input string that can be parsed successfully by c3.
304
377
* @param input source string
@@ -448,10 +521,33 @@ export abstract class BasicSQL<
448
521
449
522
const inputInfo = this . getMinimumInputInfo ( input , caretTokenIndex , this . _parseTree ) ;
450
523
if ( ! inputInfo ) return null ;
451
- const { input : _input , tokenIndexOffset } = inputInfo ;
452
- caretTokenIndex = caretTokenIndex - tokenIndexOffset ;
524
+ const { input : _input , tokenIndexOffset, statementCount } = inputInfo ;
453
525
let inputSlice = _input ;
454
526
527
+ /**
528
+ * Split the inputSlice by separator to get the smaller range of inputSlice.
529
+ */
530
+ if ( inputSlice . includes ( SQL_SPLIT_SYMBOL_TEXT ) ) {
531
+ const {
532
+ inputSlice : _inputSlice ,
533
+ allTokens : _allTokens ,
534
+ caretTokenIndex : _caretTokenIndex ,
535
+ } = this . splitInputBySymbolText (
536
+ inputSlice ,
537
+ allTokens ,
538
+ tokenIndexOffset ,
539
+ caretTokenIndex
540
+ ) ;
541
+
542
+ allTokens = _allTokens ;
543
+ caretTokenIndex = _caretTokenIndex ;
544
+ inputSlice = _inputSlice ;
545
+ } else {
546
+ if ( statementCount > 1 ) {
547
+ caretTokenIndex = caretTokenIndex - tokenIndexOffset ;
548
+ }
549
+ }
550
+
455
551
let sqlParserIns = this . _parser ;
456
552
let parseTree = this . _parseTree ;
457
553
@@ -475,7 +571,8 @@ export abstract class BasicSQL<
475
571
candidates ,
476
572
allTokens ,
477
573
caretTokenIndex ,
478
- tokenIndexOffset
574
+ 0
575
+ // tokenIndexOffset
479
576
) ;
480
577
481
578
const syntaxSuggestions : SyntaxSuggestion < WordRange > [ ] = originalSuggestions . syntax . map (
0 commit comments