@@ -21,7 +21,9 @@ import { LogQueryPlugin, LogQueryContext } from './log-query-plugin-interface';
2121
2222/**
2323 * Bound the query to the panel time range using a PPL `where` clause on @timestamp.
24- * If the user already filters on @timestamp we append another clause — PPL ANDs them.
24+ * The bound is injected immediately after the source clause so it runs before any
25+ * pipe that drops the timestamp column from the schema (stats, fields, top, etc.).
26+ * If the user already filters on @timestamp themselves, PPL ANDs the two clauses.
2527 */
2628export function buildBoundedPPL (
2729 userQuery : string ,
@@ -30,16 +32,24 @@ export function buildBoundedPPL(
3032 index ?: string ,
3133 timestampField : string = '@timestamp'
3234) : string {
33- const trimmed = userQuery . trim ( ) ;
34- let base = trimmed ;
35+ let trimmed = userQuery . trim ( ) ;
3536
36- if ( index && ! / ^ s o u r c e \s * = / i. test ( trimmed ) ) {
37- base = `source=${ index } | ${ trimmed } ` ;
37+ if ( index && ! / ^ (?: s e a r c h \s + ) ? s o u r c e \s * = / i. test ( trimmed ) ) {
38+ trimmed = `source=${ index } | ${ trimmed } ` ;
3839 }
3940
4041 const startIso = start . toISOString ( ) ;
4142 const endIso = end . toISOString ( ) ;
42- return `${ base } | where \`${ timestampField } \` >= '${ startIso } ' and \`${ timestampField } \` <= '${ endIso } '` ;
43+ const bound = `where \`${ timestampField } \` >= '${ startIso } ' and \`${ timestampField } \` <= '${ endIso } '` ;
44+
45+ const firstPipe = trimmed . indexOf ( '|' ) ;
46+ if ( firstPipe === - 1 ) {
47+ return `${ trimmed } | ${ bound } ` ;
48+ }
49+
50+ const sourceClause = trimmed . slice ( 0 , firstPipe ) . trimEnd ( ) ;
51+ const rest = trimmed . slice ( firstPipe + 1 ) . trimStart ( ) ;
52+ return `${ sourceClause } | ${ bound } | ${ rest } ` ;
4353}
4454
4555function pickIndex ( cols : Array < { name : string } > , candidates : string [ ] ) : number {
0 commit comments